qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View File

@ -0,0 +1,59 @@
APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
TARGET_FOR_ANDROID_DEPLOYMENT_SETTINGS = $$TARGET
!contains(TEMPLATE, subdirs): {
apk_install_target.target = apk_install_target
apk_install_target.depends = first
apk_install_target.commands = $(MAKE) -f $(MAKEFILE) INSTALL_ROOT=$$shell_path($$OUT_PWD/android-build) install
qtPrepareTool(ANDROIDDEPLOYQT, androiddeployqt)
isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET-deployment-settings.json
contains(QMAKE_HOST.os, Windows): extension = .exe
apk.target = apk
apk.depends = apk_install_target
apk.commands = $$ANDROIDDEPLOYQT --input $$ANDROID_DEPLOYMENT_SETTINGS_FILE --output $$OUT_PWD/android-build --apk $$APK_PATH
aab.target = aab
aab.depends = apk_install_target
aab.commands = $$ANDROIDDEPLOYQT --input $$ANDROID_DEPLOYMENT_SETTINGS_FILE --output $$OUT_PWD/android-build --aab --apk $$APK_PATH
} else {
prepareRecursiveTarget(aab)
prepareRecursiveTarget(apk)
prepareRecursiveTarget(apk_install_target)
}
# Apply Android arch specific settings in the following cases:
# - build_pass == true aka Qt was configured with multi-ABI (2+ arches)
# - single_android_abi == true aka Qt was configuring with a single ABI / arch
# modifications are omitted when building config.tests
# during Qt configuration, by checkking for the presence of single_arch
build_pass|if(single_android_abi:!single_arch) {
contains(TEMPLATE, ".*app") {
!android_app {
!contains(TARGET, ".so") {
single_arch:TARGET = lib$${TARGET}.so
else:TARGET = lib$${TARGET}_$${QT_ARCH}.so
}
QMAKE_LFLAGS += -Wl,-soname,$$shell_quote($$TARGET)
android_install {
target.path=/libs/$$ANDROID_TARGET_ARCH/
INSTALLS *= target
}
}
} else: contains(TEMPLATE, "lib"):!QTDIR_build:android_install {
tmpvar = $$str_member($$TARGET, -$$str_size($${QT_ARCH}), -1)
!equals(tmpvar, $${QT_ARCH}): TARGET = $${TARGET}_$${QT_ARCH}
!static {
target.path = /libs/$$ANDROID_TARGET_ARCH/
INSTALLS *= target
}
}
} else {
android-build-distclean.commands = \
$$QMAKE_DEL_TREE $$shell_quote($$shell_path($$OUT_PWD/android-build))
QMAKE_EXTRA_TARGETS *= android-build-distclean
CLEAN_DEPS += android-build-distclean
}
QMAKE_EXTRA_TARGETS *= aab apk apk_install_target

View File

@ -0,0 +1,127 @@
contains(TEMPLATE, ".*app"):!build_pass {
defineReplace(emitString) {
return("\"$$clean_path($$1)\"")
}
FILE_CONTENT = "{"
FILE_CONTENT += " \"description\": \"This file is generated by qmake to be read by androiddeployqt and should not be modified by hand.\","
FILE_CONTENT += " \"qt\": $$emitString($$[QT_INSTALL_PREFIX]),"
FILE_CONTENT += " \"qtDataDirectory\": $$emitString($$relative_path($$[QT_INSTALL_DATA], $$[QT_INSTALL_PREFIX])),"
FILE_CONTENT += " \"qtLibExecsDirectory\": $$emitString($$relative_path($$[QT_INSTALL_LIBEXECS], $$[QT_INSTALL_PREFIX])),"
FILE_CONTENT += " \"qtLibsDirectory\": $$emitString($$relative_path($$[QT_INSTALL_LIBS], $$[QT_INSTALL_PREFIX])),"
FILE_CONTENT += " \"qtPluginsDirectory\": $$emitString($$relative_path($$[QT_INSTALL_PLUGINS], $$[QT_INSTALL_PREFIX])),"
FILE_CONTENT += " \"qtQmlDirectory\": $$emitString($$relative_path($$[QT_INSTALL_QML], $$[QT_INSTALL_PREFIX])),"
# Settings from mkspecs/environment
FILE_CONTENT += " \"sdk\": $$emitString($$ANDROID_SDK_ROOT),"
FILE_CONTENT += " \"sdkBuildToolsRevision\": $$emitString($$ANDROID_SDK_BUILD_TOOLS_REVISION),"
isEmpty(NDK_ROOT): NDK_ROOT = $$(ANDROID_NDK_ROOT)
isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
FILE_CONTENT += " \"ndk\": $$emitString($$NDK_ROOT),"
FILE_CONTENT += " \"toolchain-prefix\": \"llvm\","
FILE_CONTENT += " \"tool-prefix\": \"llvm\","
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
FILE_CONTENT += " \"ndk-host\": $$emitString($$NDK_HOST),"
for (arch, ANDROID_ABIS) {
equals(arch, x86): libs_arch = i686-linux-android
else: equals(arch, x86_64): libs_arch = x86_64-linux-android
else: equals(arch, arm64-v8a): libs_arch = aarch64-linux-android
else: libs_arch = arm-linux-androideabi
ARCHS += "$$emitString($$arch):$$emitString($$libs_arch)"
}
FILE_CONTENT += " \"architectures\": {$$join(ARCHS,", ")},"
# Explicitly set qt dependencies of application for deployment
!isEmpty(ANDROID_DEPLOYMENT_DEPENDENCIES): \
FILE_CONTENT += " \"deployment-dependencies\": $$emitString($$join(ANDROID_DEPLOYMENT_DEPENDENCIES, ",")),"
# Explicitly set external dependencies of application for deployment
!isEmpty(ANDROID_EXTRA_PLUGINS): \
FILE_CONTENT += " \"android-extra-plugins\": $$emitString($$join(ANDROID_EXTRA_PLUGINS, ",")),"
# Android-specific settings of Project
!isEmpty(ANDROID_PACKAGE_SOURCE_DIR): \
FILE_CONTENT += " \"android-package-source-directory\": $$emitString($$ANDROID_PACKAGE_SOURCE_DIR),"
# Android-specific version string
!isEmpty(ANDROID_VERSION_NAME): \
FILE_CONTENT += " \"android-version-name\": $$emitString($$ANDROID_VERSION_NAME),"
# Android-specific version number
!isEmpty(ANDROID_VERSION_CODE): \
FILE_CONTENT += " \"android-version-code\": $$emitString($$ANDROID_VERSION_CODE),"
!isEmpty(ANDROID_MIN_SDK_VERSION): \
FILE_CONTENT += " \"android-min-sdk-version\": $$emitString($$ANDROID_MIN_SDK_VERSION),"
!isEmpty(ANDROID_TARGET_SDK_VERSION): \
FILE_CONTENT += " \"android-target-sdk-version\": $$emitString($$ANDROID_TARGET_SDK_VERSION),"
!isEmpty(ANDROID_EXTRA_LIBS): \
FILE_CONTENT += " \"android-extra-libs\": $$emitString($$join(ANDROID_EXTRA_LIBS, ",")),"
tool_extension = ""
contains(QMAKE_HOST.os, Windows): tool_extension = ".exe"
FILE_CONTENT += " \"rcc-binary\": $$emitString($$[QT_HOST_LIBEXECS]/rcc$${tool_extension}),"
contains(QT_MODULES, qml) {
FILE_CONTENT += " \"qml-importscanner-binary\": $$emitString($$[QT_HOST_LIBEXECS]/qmlimportscanner$${tool_extension}),"
qml_import_paths = $$(QML2_IMPORT_PATH)
qml_import_paths = $$split(qml_import_paths, $$DIRLIST_SEPARATOR)
qml_import_paths += $$QML_IMPORT_PATH
!isEmpty(qml_import_paths) {
FILE_CONTENT += " \"qml-import-paths\": $$emitString($$join(qml_import_paths, ",")),"
}
unset(qml_import_paths)
isEmpty(QML_ROOT_PATH): \
QML_ROOT_PATH = $$_PRO_FILE_PWD_
FILE_CONTENT += " \"qml-root-path\": $$emitString($$QML_ROOT_PATH),"
} else {
FILE_CONTENT += " \"qml-skip-import-scanning\": true,"
}
!isEmpty(ANDROID_APPLICATION_ARGUMENTS): \
FILE_CONTENT += " \"android-application-arguments\": $$emitString($$ANDROID_APPLICATION_ARGUMENTS),"
FILE_CONTENT += " \"stdcpp-path\": $$emitString($$ANDROID_STDCPP_PATH),"
!isEmpty(RESOURCES)|!isEmpty(QMLCACHE_RESOURCE_FILES) {
# Make sure that qmake generated qrc files are accounted for
load(resources_functions)
qtFlattenResources()
NEWRESOURCES = $$RESOURCES $$QMLCACHE_RESOURCE_FILES
for(resource, NEWRESOURCES) {
contains(resource, ".*qmake_qmake_immediate\\.qrc$") {
# They will be created for each architecture, since they could be different
# we need to account for all of them
qmake_qrc_path = "qmake_qmake_immediate.qrc"
base_out_path = $$OUT_PWD/$$RCC_DIR
multi_android_abi {
for (arch, ANDROID_ABIS): \
rescopy += $$absolute_path($$qmake_qrc_path, $$base_out_path/$$arch)
} else {
rescopy += $$absolute_path($$qmake_qrc_path, $$base_out_path)
}
} else {
contains(resource, ".*\\.qrc$"): rescopy += $$absolute_path($$resource, $$_PRO_FILE_PWD_)
}
}
FILE_CONTENT += " \"qrcFiles\": $$emitString($$join(rescopy, ",")),"
}
FILE_CONTENT += ""
FILE_CONTENT += " \"application-binary\": $$emitString($$TARGET_FOR_ANDROID_DEPLOYMENT_SETTINGS)"
FILE_CONTENT += "}"
isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET_FOR_ANDROID_DEPLOYMENT_SETTINGS-deployment-settings.json
write_file($$ANDROID_DEPLOYMENT_SETTINGS_FILE, FILE_CONTENT)|error()
}

View File

@ -0,0 +1,81 @@
load(default_pre)
build_pass:armeabi-v7a {
QT_ARCH = armeabi-v7a
} else:build_pass:arm64-v8a {
QT_ARCH = arm64-v8a
} else:build_pass:x86 {
QT_ARCH = x86
} else:build_pass:x86_64 {
QT_ARCH = x86_64
} else:count(ALL_ANDROID_ABIS, 1) {
QT_ARCH = $$ALL_ANDROID_ABIS
CONFIG += single_android_abi $$QT_ARCH
} else {
# default architecture
QT_ARCH = arm64-v8a
}
DEFAULT_ANDROID_TARGET_ARCH=$${QT_ARCH}
ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
# Follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_CFLAGS = -target armv7a-linux-androideabi$$replace(ANDROID_PLATFORM, "android-", "")
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \
QMAKE_CFLAGS = -target aarch64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
else: equals(ANDROID_TARGET_ARCH, x86): \
QMAKE_CFLAGS = -target i686-linux-android$$replace(ANDROID_PLATFORM, "android-", "") -mstackrealign
else: equals(ANDROID_TARGET_ARCH, x86_64): \
QMAKE_CFLAGS = -target x86_64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
QMAKE_CFLAGS += -fno-limit-debug-info
QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_LINK += -Wl,--exclude-libs,libunwind.a
ANDROID_STDCPP_PATH = $$NDK_LLVM_PATH/sysroot/usr/lib/
# -fstack-protector-strong offers good protection against stack smashing attacks.
# It is (currently) enabled only on Android because we know for sure that Android compilers supports it
QMAKE_CFLAGS += -fPIC -fstack-protector-strong -DANDROID
equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) {
CONFIG += optimize_size
QMAKE_CFLAGS_DEBUG = -g -marm -O0
QMAKE_CFLAGS_RELEASE += -mthumb
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb
}
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_STRIP =
#$${CROSS_COMPILE}strip
equals(QT_ARCH, x86): CROSS_COMPILE = $$NDK_LLVM_PATH/bin/i686-linux-android-
else: equals(QT_ARCH, x86_64): CROSS_COMPILE = $$NDK_LLVM_PATH/bin/x86_64-linux-android-
else: equals(QT_ARCH, arm64-v8a): CROSS_COMPILE = $$NDK_LLVM_PATH/bin/aarch64-linux-android-
else: CROSS_COMPILE = $$NDK_LLVM_PATH/bin/arm-linux-androideabi-
QMAKE_LFLAGS =
QMAKE_LIBS_PRIVATE = -llog -lz -lm -ldl -lc

View File

@ -0,0 +1,29 @@
load(resolve_config)
!equals(TEMPLATE, aux):!host_build:!single_arch:!java:!single_android_abi:android {
isEmpty(ANDROID_ABIS): ANDROID_ABIS = $$ALL_ANDROID_ABIS
ALL_ABIS = $$join(ANDROID_ABIS, _and_)
CONFIG += $$ALL_ABIS build_all
addExclusiveBuildsProper($$ALL_ABIS, $$ANDROID_ABIS)
unset(ALL_ABIS)
CONFIG += multi_android_abi
}
# single_arch is set qtConfTest_compile and is a marker that a config test is being built, and
# thus all Android ABI file name modifications should be avoided (prefix / suffix of
# the built binary).
# single_android_abi means ANDROID_ABI only has one value
# multi_android_abi means ANDROID_ABI has more than one value (Qt configured with 2+ arches)
#
# Assign $$ALL_ANDROID_ABIS to ANDROID_ABIS only if ANDROID_ABIS was not provided by the user
# on the qmake command line and Qt was not configured with 2+ arches.
#
# Note that in config.tests, ANDROID_ABIS ends up being empty (due to !single_arch check) regardless
# of how many ABIs Qt is configured with, which in turns causes the 'architectures' field in
# in android-arch-deployment-settings.json be empty.
!equals(TEMPLATE, aux):!host_build:!single_arch:!java:!multi_android_abi:android:isEmpty(ANDROID_ABIS) {
# Needed for the generated deployment-settings.json not to have an empty list
# of architectures.
ANDROID_ABIS = $$ALL_ANDROID_ABIS
}

View File

@ -0,0 +1,3 @@
load(resolve_config)
load(android)
load(resolve_target)

View File

@ -0,0 +1,21 @@
API_VERSION_TO_USE = $$(ANDROID_API_VERSION)
isEmpty(API_VERSION_TO_USE): API_VERSION_TO_USE = $$API_VERSION
isEmpty(API_VERSION_TO_USE): API_VERSION_TO_USE = android-33
ANDROID_JAR_FILE = $$ANDROID_SDK_ROOT/platforms/$$API_VERSION_TO_USE/android.jar
!exists($$ANDROID_JAR_FILE) {
ANDROID_API_VERSION = $$section(API_VERSION_TO_USE, -, 1, 1) # Get version number from android-XY to ensure numeric comparison
ANDROID_API_VERSIONS = $$files($$ANDROID_SDK_ROOT/platforms/*)
for (VERSION, ANDROID_API_VERSIONS) {
BASENAME = $$basename(VERSION)
BASENAME = $$section(BASENAME, -, 1, 1)
greaterThan(BASENAME, $$ANDROID_API_VERSION): ANDROID_API_VERSION = $$BASENAME
}
API_VERSION_TO_USE = android-$$ANDROID_API_VERSION
ANDROID_JAR_FILE = $$ANDROID_SDK_ROOT/platforms/$$API_VERSION_TO_USE/android.jar
}
!exists($$ANDROID_JAR_FILE) {
error("No suitable Android SDK platform found. Minimum version is $${API_VERSION_TO_USE}.")
}
JAVACLASSPATH += $$ANDROID_JAR_FILE

View File

@ -0,0 +1,6 @@
load(spec_post)
# Work around idiosyncracy in Android NDK's make executable
# which tries to call the shell-builtin "move" as direct process
equals(QMAKE_HOST.os, Windows):equals(QMAKE_MOVE, move): \
QMAKE_MOVE = cmd /c move

View File

@ -0,0 +1 @@
load(testcase)

View File

@ -0,0 +1 @@
CONFIG += no_autoqmake

View File

@ -0,0 +1,77 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
defineReplace(cmakeModuleName) {
_module = $$1
_name = $$eval(QT.$${_module}.name)
cmake_module_name = $$replace(_name, ^Qt, )
return ($$cmake_module_name)
}
defineReplace(cmakeModuleList) {
variable = $$1
out =
for(v, variable) {
out += $$cmakeModuleName($$v)
}
return ($$join(out, ";"))
}
defineReplace(cmakeTargetPath) {
SYSR = $$[QT_SYSROOT]
!isEmpty(SYSR): path = /$$relative_path($$1, $$[QT_SYSROOT])
else: path = $$1
return($$clean_path($$path))
}
defineReplace(cmakeTargetPaths) {
variable = $$1
out =
for(v, variable) {
out += \"$$cmakeTargetPath($$v)\"
}
return ($$join(out, " "))
}
defineReplace(cmakePortablePaths) {
SYSR = $$[QT_SYSROOT]
!isEmpty(SYSR): SYSR = ${CMAKE_SYSROOT}
variable = $$1
out =
for(v, variable) {
path = $$cmakeTargetPath($$v)
contains(path, /.*): \
sysroot_prefix = $$SYSR
else: \
sysroot_prefix = $$SYSR/
out += $${sysroot_prefix}$${path}
}
return ($$join(out, ";"))
}
defineReplace(cmakeProcessLibs) {
variable = $$1
out =
for(v, variable) {
if(!equals(v, -framework):!contains(v, -L.*)) {
v ~= s,^-l,,
v ~= s,^-lib,,
v ~= s,.lib$,,
out += $$v
}
}
return ($$join(out, ";"))
}
defineReplace(cmakeRelativePath) {
path = $$relative_path($$1, $$2)
return($$replace(path, ([^/])$, \\1/))
}

View File

@ -0,0 +1,2 @@
win32: CONFIG *= console
macos: CONFIG -= app_bundle

View File

@ -0,0 +1,82 @@
# Ensure that a cache is present. If none was found on startup, this will create
# one in the build directory of the project which loads this feature.
cache()
load(configure_base)
isEmpty(QMAKE_CONFIG_VERBOSE): QMAKE_CONFIG_VERBOSE = false
QMAKE_CONFIG_LOG = $$dirname(_QMAKE_CACHE_)/config.log
recheck: write_file($$QMAKE_CONFIG_LOG, "")
isEmpty(QMAKE_CONFIG_TESTS_DIR): QMAKE_CONFIG_TESTS_DIR = $$_PRO_FILE_PWD_/config.tests
# Try to build the test project in $$QMAKE_CONFIG_TESTS_DIR/$$1
# ($$_PRO_FILE_PWD_/config.tests/$$1 by default).
#
# If the test passes, config_$$1 will be added to CONFIG.
# The result is automatically cached. Use of cached results
# can be suppressed by passing CONFIG+=recheck to qmake.
#
# Returns: true iff the test passes
defineTest(qtCompileTest) {
positive = config_$$1
done = done_config_$$1
$$done:!recheck {
$$positive:return(true)
return(false)
}
log("Checking for $${1}... ")
msg = "executing config test $$1"
write_file($$QMAKE_CONFIG_LOG, msg, append)
test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$1
test_out_dir = $$shadowed($$test_dir)
test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&"
# Disable qmake features which are typically counterproductive for tests
qmake_configs = "\"CONFIG -= qt debug_and_release app_bundle lib_bundle\""
# Clean up after previous run
exists($$test_out_dir/Makefile):qtRunLoggedCommand("$$test_cmd_base $$QMAKE_MAKE distclean")
mkpath($$test_out_dir)|error()
!isEmpty (QMAKE_QTCONF): qtconfarg = -qtconf $$QMAKE_QTCONF
qtRunLoggedCommand("$$test_cmd_base $$system_quote($$system_path($$QMAKE_QMAKE)) $$qtconfarg -spec $$QMAKESPEC $$qmake_configs $$shell_quote($$test_dir)") {
qtRunLoggedCommand("$$test_cmd_base $$QMAKE_MAKE") {
log("yes$$escape_expand(\\n)")
msg = "test $$1 succeeded"
write_file($$QMAKE_CONFIG_LOG, msg, append)
!$$positive {
CONFIG += $$positive
cache(CONFIG, add, positive)
}
!$$done {
CONFIG += $$done
cache(CONFIG, add, done)
}
export(CONFIG)
return(true)
}
}
log("no$$escape_expand(\\n)")
msg = "test $$1 FAILED"
write_file($$QMAKE_CONFIG_LOG, msg, append)
$$positive {
CONFIG -= $$positive
cache(CONFIG, sub, positive)
}
!$$done {
CONFIG += $$done
cache(CONFIG, add, done)
}
export(CONFIG)
return(false)
}

View File

@ -0,0 +1,68 @@
equals(QMAKE_HOST.os, Windows) {
SETENV_PFX = "set "
SETENV_SFX = "&"
} else {
SETENV_PFX =
SETENV_SFX =
}
QMAKE_MAKE = $$(MAKE)
!isEmpty(QMAKE_MAKE) {
# We were called recursively. Use the same make.
} else: if(equals(MAKEFILE_GENERATOR, UNIX)|equals(MAKEFILE_GENERATOR, MINGW)) {
!equals(QMAKE_HOST.os, Windows): \
QMAKE_MAKE = make
else: \
QMAKE_MAKE = mingw32-make
} else: if(equals(MAKEFILE_GENERATOR, MSVC.NET)|equals(MAKEFILE_GENERATOR, MSBUILD)) {
QMAKE_MAKE = nmake
} else {
error("Configure tests are not supported with the $$MAKEFILE_GENERATOR Makefile generator.")
}
QMAKE_MAKE_NAME = $$basename(QMAKE_MAKE)
# Make sure we don't inherit MAKEFLAGS - -i in particular is fatal.
QMAKE_MAKE = "$${SETENV_PFX}MAKEFLAGS=$$SETENV_SFX $$QMAKE_MAKE"
QMAKE_PERSIST_LOG = false
QMAKE_PERSISTED_LOG =
defineTest(qtLog) {
write_file($$QMAKE_CONFIG_LOG, 1, append)
$$QMAKE_CONFIG_VERBOSE: for (l, 1): log("$$l$$escape_expand(\\n)")
$$QMAKE_PERSIST_LOG {
QMAKE_PERSISTED_LOG += $$1
export(QMAKE_PERSISTED_LOG)
}
}
defineTest(qtPersistLog) {
QMAKE_PERSIST_LOG = true
QMAKE_PERSISTED_LOG =
export(QMAKE_PERSIST_LOG)
export(QMAKE_PERSISTED_LOG)
}
defineReplace(qtPersistedLog) {
QMAKE_PERSIST_LOG = false
export(QMAKE_PERSIST_LOG)
return($$QMAKE_PERSISTED_LOG)
}
defineTest(qtRunLoggedCommand) {
qtLog("+ $$1")
!equals(3, false): \
1 = "( $$1 ) 2>&1"
output = $$system("$$1", lines, result)
lg =
for (l, output): \
lg += "> $$l"
qtLog($$lg)
!isEmpty(2) {
$$2 = $$output
export($$2)
}
!equals(result, 0): return(false)
return(true)
}

View File

@ -0,0 +1,13 @@
# Coverage flags
coverage_trace_pc_guard {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_COVERAGE_TRACE_PC_GUARD
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_COVERAGE_TRACE_PC_GUARD
QMAKE_LFLAGS += $$QMAKE_LFLAGS_COVERAGE_TRACE_PC_GUARD
}
coverage_source_based {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_COVERAGE_SOURCE_BASED
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_COVERAGE_SOURCE_BASED
QMAKE_LFLAGS += $$QMAKE_LFLAGS_COVERAGE_SOURCE_BASED
}

View File

@ -0,0 +1,416 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
load(cmake_functions)
# Several distros (ArchLinux, Fedora) have in the past installed libraries
# in /lib(64)?, but are now moving to install libraries in /usr/lib(64)?/.
# The /lib paths are made symlinks to the /usr/lib paths. If someone searching
# for a Qt 5 package finds it in /lib/cmake/Qt5Core, although it has been
# installed in /usr/lib/cmake/Qt5Core, relative paths to the includes and
# executables will not work.
# To work around this, we insert code into the generated config files to check
# at cmake time whether package has been found via a symlink, and correct
# that to an absolute path. This is only done for installations to
# the /usr or / prefix.
CMAKE_INSTALL_LIBS_DIR = $$cmakeTargetPath($$[QT_INSTALL_LIBS])
contains(CMAKE_INSTALL_LIBS_DIR, ^(/usr)?/lib(64)?.*): CMAKE_USR_MOVE_WORKAROUND = $$CMAKE_INSTALL_LIBS_DIR
CMAKE_OUT_DIR = $$MODULE_BASE_OUTDIR/lib/cmake
internal_module {
MODULE = "$${MODULE}_private"
}
# Core, Network, an external module named Foo
CMAKE_MODULE_NAME = $$cmakeModuleName($${MODULE})
# QtCore, QtNetwork, still Foo
CMAKE_INCLUDE_NAME = $$eval(QT.$${MODULE}.name)
# TARGET here is the one changed at the end of qt_module.prf,
# which already contains the Qt5 prefix and QT_LIBINFIX suffix :
# Qt5Core_{libinfix_suffix}, Qt5Network_{libinfix_suffix}, Foo_{libinfix_suffix}
# (or QtCore_{libinfix_suffix}, Foo_{libinfix_suffix} on macos with -framework).
CMAKE_QT_STEM = $${TARGET}
# ANDROID_ABI is set by the android toolchain file, see https://developer.android.com/ndk/guides/cmake
android: CMAKE_QT_STEM = $$replace(CMAKE_QT_STEM, "_$${QT_ARCH}", '_\$\{ANDROID_ABI\}')
# On macOS when building just a debug configuration which is not part of debug_and_release,
# $${TARGET} already contains a _debug suffix, as per the following call chain:
# qt_module.prf -> qt5LibraryTarget -> qtLibraryTarget -> qtPlatformTargetSuffix.
# Remove the _debug suffix in the stem, to keep all further uses of CMAKE_QT_STEM consistent.
# The _debug suffix is then re-added where needed regardless if it's a debug_and_release build
# or just debug.
darwin:!qt_framework:!debug_and_release:CONFIG(debug, debug|release) {
CMAKE_QT_STEM = $$replace(CMAKE_QT_STEM, _debug$, )
}
!generated_privates {
isEmpty(SYNCQT.INJECTED_PRIVATE_HEADER_FILES):isEmpty(SYNCQT.PRIVATE_HEADER_FILES): \
CMAKE_NO_PRIVATE_INCLUDES = true
}
split_incpath {
CMAKE_ADD_SOURCE_INCLUDE_DIRS = true
CMAKE_SOURCE_INCLUDES = \
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/$${CMAKE_INCLUDE_NAME})
CMAKE_SOURCE_PRIVATE_INCLUDES = \
$$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE/$${CMAKE_INCLUDE_NAME}/$$eval(QT.$${MODULE}.VERSION) \
$$QT_MODULE_INCLUDE_BASE/$${CMAKE_INCLUDE_NAME}/$$eval(QT.$${MODULE}.VERSION)/$${CMAKE_INCLUDE_NAME})
cmake_extra_source_includes.input = $$PWD/data/cmake/ExtraSourceIncludes.cmake.in
cmake_extra_source_includes.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/ExtraSourceIncludes.cmake
!build_pass:QMAKE_SUBSTITUTES += \
cmake_extra_source_includes
cmake_qt5_module_files.files = \
$$cmake_extra_source_includes.output
}
CMAKE_INCLUDE_DIR = $$cmakeRelativePath($$[QT_INSTALL_HEADERS], $$[QT_INSTALL_PREFIX])
contains(CMAKE_INCLUDE_DIR, "^\\.\\./.*") {
CMAKE_INCLUDE_DIR = $$[QT_INSTALL_HEADERS]/
CMAKE_INCLUDE_DIR_IS_ABSOLUTE = True
}
CMAKE_LIB_DIR = $$cmakeRelativePath($$[QT_INSTALL_LIBS], $$[QT_INSTALL_PREFIX])
contains(CMAKE_LIB_DIR,"^\\.\\./.*") {
CMAKE_LIB_DIR = $$[QT_INSTALL_LIBS]/
CMAKE_LIB_DIR_IS_ABSOLUTE = True
} else {
CMAKE_RELATIVE_INSTALL_LIBS_DIR = $$cmakeRelativePath($$[QT_INSTALL_PREFIX], $$[QT_INSTALL_LIBS])
# We need to go up another two levels because the CMake files are
# installed in $${CMAKE_LIB_DIR}/cmake/Qt5$${CMAKE_MODULE_NAME}
CMAKE_RELATIVE_INSTALL_DIR = "$${CMAKE_RELATIVE_INSTALL_LIBS_DIR}../../"
}
CMAKE_BIN_DIR = $$cmakeRelativePath($$[QT_HOST_BINS], $$[QT_INSTALL_PREFIX])
contains(CMAKE_BIN_DIR, "^\\.\\./.*") {
CMAKE_BIN_DIR = $$[QT_HOST_BINS]/
CMAKE_BIN_DIR_IS_ABSOLUTE = True
}
CMAKE_PLUGIN_DIR = $$cmakeRelativePath($$[QT_INSTALL_PLUGINS], $$[QT_INSTALL_PREFIX])
contains(CMAKE_PLUGIN_DIR, "^\\.\\./.*") {
CMAKE_PLUGIN_DIR = $$[QT_INSTALL_PLUGINS]/
CMAKE_PLUGIN_DIR_IS_ABSOLUTE = True
}
win32:!static:!staticlib {
CMAKE_DLL_DIR = $$cmakeRelativePath($$[QT_INSTALL_BINS], $$[QT_INSTALL_PREFIX])
contains(CMAKE_DLL_DIR, "^\\.\\./.*") {
CMAKE_DLL_DIR = $$[QT_INSTALL_BINS]/
CMAKE_DLL_DIR_IS_ABSOLUTE = True
}
} else {
CMAKE_DLL_DIR = $$CMAKE_LIB_DIR
CMAKE_DLL_DIR_IS_ABSOLUTE = $$CMAKE_LIB_DIR_IS_ABSOLUTE
}
static|staticlib:CMAKE_STATIC_TYPE = true
internal_module {
CMAKE_INTERNAL_MODULE = true
}
CMAKE_DEBUG_TYPE =
CMAKE_RELEASE_TYPE =
# Requirements:
# * If Qt is configured with -debug, we're creating debug libraries and not
# release libraries, regardless of whether we're on a platform where
# debug_and_release is true.
# * If Qt is configured with -release, we're creating release libraries and not
# debug libraries, regardless of whether we're on a platform where
# debug_and_release is true.
# * If Qt is configured with neither -debug nor -release, and we are on a
# platform where debug_and_release is true, we're creating both
# debug and release libraries.
# * If Qt is configured with -debug on a platform where debug_and_release is
# true, and 'make release' is subsequently invoked, CMake is only aware of
# the debug libraries at build time.
equals(QMAKE_HOST.os, Windows): CMAKE_BIN_SUFFIX = ".exe"
if(debug_and_release:build_all)|CONFIG(debug, debug|release): CMAKE_DEBUG_TYPE = debug
if(debug_and_release:build_all)|CONFIG(release, debug|release): CMAKE_RELEASE_TYPE = release
# CMAKE_DEBUG_AND_RELEASE is used to tell the _populate_$${CMAKE_MODULE_NAME}_target_properties
# functions whether a Configuration specific generator expression needs to be added to the values
# of INTERFACE_LINK_LIBRARIES and INTERFACE_LINK_OPTIONS. For debug_and_release builds, we do need
# configuration specific values. For singular builds (only release or only debug), we want the
# values to be applied regardless of the configuration.
# This would allow on Linux and macOS (and with a recent enough version of CMake on Windows) to
# build a Debug configuration of an application, even if Qt was built in a Release configuration.
#
# All IMPORTED_LOCATION_<CONFIG> paths are automatically considered by CMake if there is no
# <CONFIG> equivalent to the value specified by CMAKE_BUILD_TYPE.
# This means that when Qt was built in a Release configuration, and the application in a Debug
# configuration, IMPORTED_LOCATION_RELEASE will be used for the Qt libraries.
#
# Note that we need to check for the "debug_and_release" feature, and not the CONFIG value, because
# the CONFIG value is always set to true on Windows in msvc-desktop.conf disregarding whether the
# configure line specified just -debug or just -release.
# This also means that if a user configures and builds Qt with -release, and then calls nmake debug
# to build debug libraries of Qt, the generated CMake file won't know about debug libraries,
# and will always link against the release libraries.
qtConfig(debug_and_release) {
CMAKE_DEBUG_AND_RELEASE = TRUE
} else {
CMAKE_DEBUG_AND_RELEASE = FALSE
}
contains(CONFIG, plugin) {
equals(PLUGIN_EXTENDS, -) {
CMAKE_PLUGIN_EXTENDS = -
} else {
list_plugin_extends =
for (p, PLUGIN_EXTENDS) {
m = $$cmakeModuleName($$p)
list_plugin_extends += Qt::$$m
}
CMAKE_PLUGIN_EXTENDS = $$join(list_plugin_extends, ";")
}
PLUGIN_MODULE_NAME =
unique_qt_modules = $$unique(QT_MODULES) # In case modules appear in multiple places
for (mod, unique_qt_modules) {
contains(QT.$${mod}.plugin_types, $$PLUGIN_TYPE) {
!isEmpty(PLUGIN_MODULE_NAME): \
error("Multiple modules claim plugin type '$$PLUGIN_TYPE' ($$mod, in addition to $$PLUGIN_MODULE_NAME)")
PLUGIN_MODULE_NAME = $$mod
}
}
isEmpty(PLUGIN_MODULE_NAME): error("No module claims plugin type '$$PLUGIN_TYPE'")
sorted_deps = $$sort_depends(QT_PLUGIN.$${CMAKE_QT_STEM}.DEPENDS, QT.)
mod_deps =
lib_deps =
aux_mod_deps =
aux_lib_deps =
for (dep, sorted_deps) {
cdep = $$cmakeModuleName($$dep)
mod_deps += $$cdep
lib_deps += Qt5::$$cdep
}
CMAKE_PLUGIN_MODULE_DEPS = $$join(mod_deps, ";")
CMAKE_PLUGIN_QT5_MODULE_DEPS = $$join(lib_deps, ";")
CMAKE_MODULE_NAME = $$cmakeModuleName($$PLUGIN_MODULE_NAME)
CMAKE_PLUGIN_NAME = $$PLUGIN_CLASS_NAME
CMAKE_PLUGIN_TYPE = $$PLUGIN_TYPE
CMAKE_PLUGIN_TYPE_ESCAPED = $$replace(PLUGIN_TYPE, [-/], _)
win32 {
!mingw|qtConfig(debug_and_release): debug_suffix="d"
CMAKE_PRL_FILE_LOCATION_RELEASE = $$PLUGIN_TYPE/$${CMAKE_QT_STEM}.prl
CMAKE_PRL_FILE_LOCATION_DEBUG = $$PLUGIN_TYPE/$${CMAKE_QT_STEM}$${debug_suffix}.prl
isEmpty(CMAKE_STATIC_TYPE) {
CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/$${CMAKE_QT_STEM}.dll
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/$${CMAKE_QT_STEM}$${debug_suffix}.dll
} else:mingw {
CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}.a
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}$${debug_suffix}.a
} else { # MSVC static
CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/$${CMAKE_QT_STEM}.lib
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/$${CMAKE_QT_STEM}$${debug_suffix}.lib
}
} else {
mac {
isEmpty(CMAKE_STATIC_TYPE): CMAKE_PLUGIN_EXT = .dylib
else: CMAKE_PLUGIN_EXT = .a
CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}$${CMAKE_PLUGIN_EXT}
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}_debug$${CMAKE_PLUGIN_EXT}
CMAKE_PRL_FILE_LOCATION_RELEASE = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}.prl
CMAKE_PRL_FILE_LOCATION_DEBUG = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}_debug.prl
} else {
isEmpty(CMAKE_STATIC_TYPE): CMAKE_PLUGIN_EXT = .so
else: CMAKE_PLUGIN_EXT = .a
CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}$${CMAKE_PLUGIN_EXT}
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}$${CMAKE_PLUGIN_EXT}
CMAKE_PRL_FILE_LOCATION_RELEASE = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}.prl
CMAKE_PRL_FILE_LOCATION_DEBUG = $$PLUGIN_TYPE/lib$${CMAKE_QT_STEM}.prl
}
}
cmake_target_file.input = $$PWD/data/cmake/Qt5PluginTarget.cmake.in
cmake_target_file.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}_$${PLUGIN_CLASS_NAME}.cmake
cmake_qt5_plugin_import_file.input = $$PWD/data/cmake/Qt5ImportPlugin.cpp.in
cmake_qt5_plugin_import_file.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}_$${PLUGIN_CLASS_NAME}_Import.cpp
!build_pass {
QMAKE_SUBSTITUTES += cmake_target_file
static|staticlib: QMAKE_SUBSTITUTES += cmake_qt5_plugin_import_file
}
cmake_qt5_plugin_file.files = $$cmake_target_file.output
static|staticlib: cmake_qt5_plugin_file.files += $$cmake_qt5_plugin_import_file.output
cmake_qt5_plugin_file.path = $$[QT_INSTALL_LIBS]/cmake/Qt5$${CMAKE_MODULE_NAME}
INSTALLS += cmake_qt5_plugin_file
return()
}
CMAKE_MKSPEC = $$[QMAKE_XSPEC]
sorted_deps = $$sort_depends(QT.$${MODULE}.depends, QT.)
mod_deps =
lib_deps =
aux_mod_deps =
aux_lib_deps =
# Until CMake 3.0 is the minimum requirement of Qt 5, we need to filter
# out header-only modules from dependencies. CMake 3.0 provides INTERFACE
# libraries which are equivalent to header-only modules.
for (dep, sorted_deps) {
cdep = $$cmakeModuleName($$dep)
!contains(QT.$${dep}.module_config, no_link) {
mod_deps += $$cdep
lib_deps += Qt5::$$cdep
} else {
aux_mod_deps += $$cdep
aux_lib_deps += Qt5::$$cdep
}
}
CMAKE_MODULE_DEPS = $$join(mod_deps, ";")
CMAKE_QT5_MODULE_DEPS = $$join(lib_deps, ";")
CMAKE_INTERFACE_MODULE_DEPS = $$join(aux_mod_deps, ";")
CMAKE_INTERFACE_QT5_MODULE_DEPS = $$join(aux_lib_deps, ";")
CMAKE_MODULE_PLUGIN_TYPES = $$join(QT.$${MODULE}.plugin_types, ";")
# Interface libraries have to have all properties starting with "INTERFACE_".
CMAKE_FEATURE_PROPERTY_PREFIX = ""
equals(TEMPLATE, aux): CMAKE_FEATURE_PROPERTY_PREFIX = "INTERFACE_"
mac {
!isEmpty(CMAKE_STATIC_TYPE) {
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}_debug.a
CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.a
CMAKE_PRL_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}_debug.prl
CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl
} else {
qt_framework {
# Intentionally there is no '_debug' infix for framework builds.
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
CMAKE_BUILD_IS_FRAMEWORK = "true"
} else {
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}_debug.$$eval(QT.$${MODULE}.VERSION).dylib
CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.$$eval(QT.$${MODULE}.VERSION).dylib
}
}
} else:win32 {
CMAKE_WINDOWS_BUILD = "true"
CMAKE_FIND_OTHER_LIBRARY_BUILD = "true"
!mingw|qtConfig(debug_and_release): debug_suffix="d"
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}$${debug_suffix}.dll
CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.dll
!isEmpty(CMAKE_STATIC_TYPE) {
CMAKE_STATIC_WINDOWS_BUILD = "true"
CMAKE_PRL_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}$${debug_suffix}.prl
CMAKE_PRL_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.prl
}
mingw {
CMAKE_WINMAIN_FILE_LOCATION_DEBUG = libqtmain$${QT_LIBINFIX}$${debug_suffix}.a
CMAKE_WINMAIN_FILE_LOCATION_RELEASE = libqtmain$${QT_LIBINFIX}.a
CMAKE_IMPLIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}$${debug_suffix}.a
CMAKE_IMPLIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.a
} else {
CMAKE_WINMAIN_FILE_LOCATION_DEBUG = qtmain$${QT_LIBINFIX}$${debug_suffix}.lib
CMAKE_WINMAIN_FILE_LOCATION_RELEASE = qtmain$${QT_LIBINFIX}.lib
CMAKE_IMPLIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}$${debug_suffix}.lib
CMAKE_IMPLIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.lib
}
} else {
!isEmpty(CMAKE_STATIC_TYPE) {
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}.a
CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.a
CMAKE_PRL_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}.prl
CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl
} else:unversioned_libname {
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}.so
CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.so
CMAKE_LIB_SONAME = lib$${CMAKE_QT_STEM}.so
} else {
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}.so.$$eval(QT.$${MODULE}.VERSION)
CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.so.$$eval(QT.$${MODULE}.VERSION)
CMAKE_LIB_SONAME = lib$${CMAKE_QT_STEM}.so.$$section(QT.$${MODULE}.VERSION, ., 0, 0)
}
}
INSTALLS += cmake_qt5_module_files
cmake_config_file.input = $$PWD/data/cmake/Qt5BasicConfig.cmake.in
cmake_config_file.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}Config.cmake
CMAKE_PACKAGE_VERSION = $$eval(QT.$${MODULE}.VERSION)
cmake_config_version_file.input = $$PWD/data/cmake/Qt5ConfigVersion.cmake.in
cmake_config_version_file.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}ConfigVersion.cmake
!build_pass:QMAKE_SUBSTITUTES += \
cmake_config_file \
cmake_config_version_file
cmake_qt5_module_files.files = \
$$cmake_config_file.output \
$$cmake_config_version_file.output
cmake_extras_file.input = $$_PRO_FILE_PWD_/Qt5$${CMAKE_MODULE_NAME}ConfigExtras.cmake.in
exists($$cmake_extras_file.input) {
CMAKE_MODULE_EXTRAS = "true"
cmake_extras_file.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}ConfigExtras.cmake
!build_pass:QMAKE_SUBSTITUTES += cmake_extras_file
cmake_qt5_module_files.files += \
$$cmake_extras_file.output
}
cmake_macros_file.input = $$_PRO_FILE_PWD_/Qt5$${CMAKE_MODULE_NAME}Macros.cmake
exists($$cmake_macros_file.input) {
CMAKE_MODULE_MACROS = "true"
cmake_macros_file.output = $$CMAKE_OUT_DIR/Qt5$${CMAKE_MODULE_NAME}/Qt5$${CMAKE_MODULE_NAME}Macros.cmake
cmake_macros_file.CONFIG = verbatim
!build_pass:QMAKE_SUBSTITUTES += cmake_macros_file
cmake_qt5_module_files.files += $$cmake_macros_file.output
}
cmake_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5$${CMAKE_MODULE_NAME}
# We are generating cmake files. Most developers of Qt are not aware of cmake,
# so we require automatic tests to be available. The only module which should
# set CMAKE_MODULE_TESTS to '-' is enginio because that is known to be broken.
# Other modules should either create proper tests in tests/auto/cmake or, as
# a temporary measure, disable the generation of cmake files
# with 'CONFIG -= create_cmake'
!internal_module:!equals(CMAKE_MODULE_TESTS, -) {
isEmpty(CMAKE_MODULE_TESTS): CMAKE_MODULE_TESTS = $$MODULE_BASE_INDIR/tests/auto/cmake
!exists($$CMAKE_MODULE_TESTS): \
error("Missing CMake tests. Either create tests in tests/auto/cmake," \
"or disable cmake config file creation with CONFIG-=create_cmake.")
}

View File

@ -0,0 +1,9 @@
CMAKE_TEST_LOCATION = $$_PRO_FILE_PWD_
for(d, $$list($$split($$list($$[QMAKE_MKSPECS]), $$DIRLIST_SEPARATOR))) {
CMAKE_PREFIX_PATH *= $$clean_path($$dirname(d))
}
CMAKE_PREFIX_PATH=\"$$join(CMAKE_PREFIX_PATH, ;)\"
include(ctest_testcase_common.prf)

View File

@ -0,0 +1,83 @@
cmake_version_output = $$system(cmake --version 2>$$QMAKE_SYSTEM_NULL_DEVICE, lines)
# First line
cmake_version_output = $$first(cmake_version_output)
# Format is "cmake version X.Y.Z"
cmake_version_output = $$split(cmake_version_output)
CMAKE_VERSION = $$last(cmake_version_output)
check.commands =
QMAKE_EXTRA_TARGETS *= check
isEmpty(CMAKE_VERSION) {
message("cmake executable not found. Not running CMake unit tests")
return()
}
CTEST_VERSION = $$system(ctest --version 2>$$QMAKE_SYSTEM_NULL_DEVICE)
isEmpty(CTEST_VERSION) {
message("ctest executable not found. Not running CMake unit tests")
return()
}
!versionAtLeast(CMAKE_VERSION, 3.1.0) {
message("cmake $$CMAKE_VERSION is too old for this test.")
return()
}
load(cmake_functions)
CMAKE_BUILD_TYPE = Debug
CONFIG(release, debug|release):CMAKE_BUILD_TYPE = Release
win32: CMAKE_GENERATOR = -G \"NMake Makefiles\"
mingw:isEmpty(CROSS_COMPILE):CMAKE_GENERATOR = -G \"MinGW Makefiles\"
BUILD_DIR = $$replace($$list($$OUT_PWD/build), /, $$QMAKE_DIR_SEP)
!qtHaveModule(gui): CMAKE_MODULE_DEFINES += -DNO_GUI=True
!qtHaveModule(widgets): CMAKE_MODULE_DEFINES += -DNO_WIDGETS=True
!qtHaveModule(dbus): CMAKE_MODULE_DEFINES += -DNO_DBUS=True
dependentmodules = $$resolve_depends(CMAKE_QT_MODULES_UNDER_TEST, "QT.")
dependentmodules -= $$CMAKE_QT_MODULES_UNDER_TEST
mod_deps =
for (dep, dependentmodules): \
!contains(QT.$${dep}.module_config, no_link): \
mod_deps += $$cmakeModuleName($$dep)
dependentmodules = $$join(mod_deps, ";")
QT_FOR_CONFIG += gui-private
qtHaveModule(gui):!qtConfig(egl): CMAKE_GL_DEFINES += -DNO_EGL=True
CMAKE_MODULE_VERSIONS =
CMAKE_MODULES_UNDER_TEST =
for (MODULE_UNDER_TEST, CMAKE_QT_MODULES_UNDER_TEST) {
CMAKE_NAME = $$cmakeModuleName($$MODULE_UNDER_TEST)
ver = $$eval(QT.$${MODULE_UNDER_TEST}.VERSION)
CMAKE_MODULE_VERSIONS += \
-DCMAKE_$${CMAKE_NAME}_MODULE_MAJOR_VERSION=$$section(ver, ., 0, 0) \
-DCMAKE_$${CMAKE_NAME}_MODULE_MINOR_VERSION=$$section(ver, ., 1, 1) \
-DCMAKE_$${CMAKE_NAME}_MODULE_PATCH_VERSION=$$section(ver, ., 2, 2)
CMAKE_MODULES_UNDER_TEST += $$CMAKE_NAME
}
CMAKE_MODULES_UNDER_TEST = $$join(CMAKE_MODULES_UNDER_TEST, ;)
check.commands = \
$$sprintf($$QMAKE_MKDIR_CMD, $$BUILD_DIR) $$escape_expand(\\n\\t) \
$$QMAKE_CD $$BUILD_DIR && \
cmake $$CMAKE_TEST_LOCATION $$CMAKE_GENERATOR \
-DCMAKE_C_COMPILER=$$QMAKE_CC \
-DCMAKE_CXX_COMPILER=$$QMAKE_CXX \
-DCMAKE_VERBOSE_MAKEFILE=1 \
$$CMAKE_MODULE_DEFINES \
$$CMAKE_GL_DEFINES \
-DCMAKE_BUILD_TYPE=$${CMAKE_BUILD_TYPE} \
-DCMAKE_PREFIX_PATH=$$CMAKE_PREFIX_PATH \
-DQt5_MODULE_TEST_DEPENDS=\"$${dependentmodules}\" \
$${CMAKE_MODULE_VERSIONS} \
-DCMAKE_MODULES_UNDER_TEST=\"$$CMAKE_MODULES_UNDER_TEST\" && \
$(TESTRUNNER) ctest --output-on-failure
insignificant_test:!isEmpty(check.commands): \
check.commands = -$${check.commands}

View File

@ -0,0 +1,10 @@
prefix_build {
CMAKE_TEST_LOCATION = $$_PRO_FILE_PWD_/../cmake
CMAKE_PREFIX_PATH = $$[QT_INSTALL_PREFIX]
CONFIG += insignificant_test
include(ctest_testcase_common.prf)
}

View File

@ -0,0 +1,31 @@
{
"files": {
},
"commandline": {
"options": {
"v": { "type": "enum", "name": "verbose", "values": { "yes": "true", "no": "false" } },
"verbose": { "type": "enum", "values": { "yes": "true", "no": "false" } },
"continue": "void",
"recheck": { "type": "optionalString", "name": "cache_recheck" },
"recheck-all": { "type": "void", "name": "cache_use", "value": "none" },
"redo": { "type": "redo" },
"list-features": "void",
"list-libraries": "void"
}
},
"testTypeDependencies": {
"library": [ "library-paths" ]
},
"features": {
"library-paths": {
"output": [ "libraryPaths" ]
}
}
}

View File

@ -0,0 +1,2 @@
// Used when we need to compile with no source code
// (controls are in the command-line)

View File

@ -0,0 +1,19 @@
:: Copyright (C) 2018 The Qt Company Ltd.
:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
@echo off
REM We clear INCLUDE and LIB, because we want to obtain pristine values.
REM PATH cannot be cleared, because then the script does not even run,
REM and it would be counterproductive anyway (see toolchain.prf).
set INCLUDE=
set LIB=
call %* || exit 1
REM VS2015 does not set errorlevel in case of failure.
if "%INCLUDE%" == "" exit 1
echo =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
echo %INCLUDE%
echo %LIB%
echo %PATH%

View File

@ -0,0 +1,227 @@
#!/bin/bash
# Copyright (C) 2017 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
script_argument_prefix="-Wobjc_namespace,--"
required_arguments="target suffix original_ld"
optional_arguments="exclude_list exclude_regex silent"
for argument in $required_arguments $optional_arguments; do
declare "$argument="
done
declare -i silent=0
declare -a linker_arguments
for i in "$@"; do
case $1 in
$script_argument_prefix*)
declare "${1#$script_argument_prefix}"
;;
-o)
if [ -n "$2" ]; then
target="$2"
fi
linker_arguments+=("$1")
;;
*)
linker_arguments+=("$1")
;;
esac
shift
done
get_entry() {
local map=$1 key=$2
local i="${map}_map_${2}"
printf '%s' "${!i}"
}
error() {
echo "$0: error: $*" >&2
exit 1
}
for argument in $required_arguments; do
if [ -z "${!argument}" ]; then
error "missing argument --${argument}"
fi
done
# Normalize suffix so we can use it as a bash variable
suffix=${suffix//[-. ]/_}
link_binary() {
(PS4=; test $silent -ne 1 && set -x; $original_ld "${linker_arguments[@]}" "$@") 2>&1 || exit 1
}
sanitize_address() {
local address="$1"
address=${address#0x} # Remove hex prefix
address=${address: ${#address} < 8 ? 0 : -8} # Limit to 32-bit
echo "0x$address"
}
arch_offset=0
read_binary() {
local address=$1
local length=$2
seek=$(($address + $arch_offset))
dd if="$target" bs=1 iseek=$seek count=$length 2>|/dev/null
}
read_32bit_value() {
local address=$1
read_binary $address 4 | xxd -p | dd conv=swab 2>/dev/null | rev
}
otool_args=
otool() {
command otool $otool_args "$@"
}
declare -a extra_classnames_files
inspect_binary() {
inspect_mode="$1"
classnames_section="__objc_classname"
classnames=$(otool -v -s __TEXT $classnames_section "$target" | tail -n +3)
if [ -z "$classnames" ]; then
echo " No Objective-C classes found in binary"
return 1
fi
while read -a classname; do
address=$(sanitize_address ${classname[0]})
name=${classname[1]}
declare "address_to_classname_map_$address=$name"
declare "classname_to_address_map_$name=$address"
done <<< "$classnames"
extra_classnames_file="$(mktemp -t ${classnames_section}_additions).S"
extra_classnames_files+=("$extra_classnames_file")
if [ "$inspect_mode" == "inject_classnames" ]; then
echo " Class names have not been namespaced, adding suffix '$suffix'..."
printf ".section __TEXT,$classnames_section,cstring_literals,no_dead_strip\n" > $extra_classnames_file
elif [ "$inspect_mode" == "patch_classes" ]; then
echo " Found namespaced class names, updating class entries..."
fi
classes=$(otool -o -v "$target" | grep "OBJC_CLASS_RO\|OBJC_METACLASS_RO")
if [ -z "$classes" ]; then
echo " 💥 Failed to read class entries from binary"
exit 1
fi
while read -a class; do
address="$(sanitize_address ${class[1]})"
class_flags="0x$(read_32bit_value $address)"
if [ -z "$class_flags" ]; then
echo " 💥 Failed to read class flags for class at $address"
continue
fi
is_metaclass=$(($class_flags & 0x1))
name_offset=$(($address + 24))
classname_address="0x$(read_32bit_value $name_offset)"
if [ -z "$classname_address" ]; then
echo " 💥 Failed to read class name address for class at $address"
continue
fi
classname=$(get_entry address_to_classname $classname_address)
if [ -z "$classname" ]; then
echo " 💥 Failed to resolve class name for address '$classname_address'"
continue
fi
if [[ $exclude_list =~ $classname || $classname =~ $exclude_regex ]]; then
if [ $is_metaclass -eq 1 ]; then
class_type="meta class"
else
class_type="class"
fi
echo " 🚽 Skipping excluded $class_type '$classname'"
continue
fi
newclassname="${classname}_${suffix}"
if [ "$inspect_mode" == "inject_classnames" ]; then
if [ $is_metaclass -eq 1 ]; then
continue
fi
echo " 💉 Injecting $classnames_section entry '$newclassname' for '$classname'"
printf ".asciz \"$newclassname\"\n" >> $extra_classnames_file
elif [ "$inspect_mode" == "patch_classes" ]; then
newclassname_address=$(get_entry classname_to_address ${newclassname})
if [ -z "$newclassname_address" ]; then
echo " 💥 Failed to resolve class name address for class '$newclassname'"
continue
fi
if [ $is_metaclass -eq 1 ]; then
class_type="meta"
else
class_type="class"
fi
name_offset=$(($name_offset + $arch_offset))
echo " 🔨 Patching class_ro_t at $address ($class_type) from $classname_address ($classname) to $newclassname_address ($newclassname)"
echo ${newclassname_address: -8} | rev | dd conv=swab 2>/dev/null | xxd -p -r -seek $name_offset -l 4 - "$target"
fi
done <<< "$classes"
}
echo "🔩 Linking binary using '$original_ld'..."
link_binary
echo "🔎 Inspecting binary '$target'..."
if [ ! -f "$target" ]; then
echo " 💥 Target does not exist!"
exit 1
fi
read -a mach_header <<< "$(otool -h "$target" -v | tail -n 1)"
if [ "${mach_header[0]}" != "MH_MAGIC_64" ]; then
echo " 💥 Binary is not 64-bit, only 64-bit binaries are supported!"
exit 1
fi
architectures=$(otool -f -v "$target" | grep architecture)
setup_arch() {
arch="$1"
if [ ! -z "$arch" ]; then
otool_args="-arch $arch"
offset=$(otool -f -v "$target" | grep -A 6 "architecture $arch" | grep offset)
offset="${offset##*( )}"
arch_offset="$(echo $offset | cut -d ' ' -f 2)"
echo "🤖 Processing architecture '$arch' at offset $arch_offset..."
fi
}
while read -a arch; do
setup_arch "${arch[1]}"
inspect_binary inject_classnames
if [ $? -ne 0 ]; then
exit
fi
done <<< "$architectures"
echo "🔩 Re-linking binary with extra __objc_classname section(s)..."
link_binary "${extra_classnames_files[@]}"
while read -a arch; do
setup_arch "${arch[1]}"
inspect_binary patch_classes
done <<< "$architectures"

View File

@ -0,0 +1,32 @@
// Keep this file small. The pre-processed contents are eval'd by qmake.
QT_COMPILER_STDCXX = __cplusplus
#ifdef _MSC_VER
QMAKE_MSC_VER = _MSC_VER
QMAKE_MSC_FULL_VER = _MSC_FULL_VER
#endif
#ifdef __INTEL_COMPILER
QMAKE_ICC_VER = __INTEL_COMPILER
QMAKE_ICC_UPDATE_VER = __INTEL_COMPILER_UPDATE
#endif
#ifdef __APPLE_CC__
QMAKE_APPLE_CC = __APPLE_CC__
#endif
#ifdef __clang__
#ifdef __APPLE_CC__
QMAKE_APPLE_CLANG_MAJOR_VERSION = __clang_major__
QMAKE_APPLE_CLANG_MINOR_VERSION = __clang_minor__
QMAKE_APPLE_CLANG_PATCH_VERSION = __clang_patchlevel__
#else
QMAKE_CLANG_MAJOR_VERSION = __clang_major__
QMAKE_CLANG_MINOR_VERSION = __clang_minor__
QMAKE_CLANG_PATCH_VERSION = __clang_patchlevel__
#endif
#endif
#ifdef __GNUC__
QMAKE_GCC_MAJOR_VERSION = __GNUC__
QMAKE_GCC_MINOR_VERSION = __GNUC_MINOR__
QMAKE_GCC_PATCH_VERSION = __GNUC_PATCHLEVEL__
#endif
#ifdef __ghs__
QMAKE_GHS_VERSION = __GHS_VERSION_NUMBER
#endif

View File

@ -0,0 +1,29 @@
# This Dockerfile is used to provision the shared scripts (e.g. startup.sh) and configurations. It
# relies on the arguments passed by docker-compose file to build additional images for each service.
# To lean more how it works, please check the topic "Use multi-stage builds".
# https://docs.docker.com/develop/develop-images/multistage-build/
ARG provisioningImage
FROM $provisioningImage as testserver_tier2
# Add and merge the testdata into service folder
ARG serviceDir
ARG shareDir=$serviceDir
COPY $serviceDir $shareDir service/
# create the shared script of testserver
RUN echo "#!/usr/bin/env bash\n" \
"set -ex\n" \
"for RUN_CMD; do \$RUN_CMD; done\n" \
"service dbus restart\n" \
"service avahi-daemon restart\n" \
"sleep infinity\n" > startup.sh
RUN chmod +x startup.sh
# rewrite the default configurations of avahi-daemon
# Disable IPv6 of avahi-daemon to resolve the unstable connections on Windows
ARG test_domain
RUN sed -i -e "s,#domain-name=local,domain-name=${test_domain:-test-net.qt.local}," \
-e "s,#publish-aaaa-on-ipv4=yes,publish-aaaa-on-ipv4=no," \
-e "s,use-ipv6=yes,use-ipv6=no," \
/etc/avahi/avahi-daemon.conf

View File

@ -0,0 +1,38 @@
version: '2.1'
# This is a template docker-compose file shared with all modules. It is based
# on 'extending services' feature of compose file version 2.1.
# See https://docs.docker.com/compose/extends/#extending-services for details.
#
# Example: testserver/docker-compose.yml
# services:
# foo:
# extends:
# file: ${SHARED_DATA}/docker-compose-common.yml
# service: ${SHARED_SERVICE}
# container_name: qt-test-server-foo
# hostname: ${HOST_NAME:-foo}
# build:
# context: .
# args:
# provisioningImage: qt-test-server-foo:537fe302f61851d1663...
# serviceDir: ./foo
# command: service/foo.sh
x-services:
&default-service
domainname: ${TEST_DOMAIN}
build:
context: .
dockerfile: ${SHARED_DATA}/Dockerfile
args:
test_domain: ${TEST_DOMAIN}
entrypoint: ./startup.sh
services:
bridge-network: *default-service
host-network:
<< : *default-service
network_mode: "host"
extra_hosts:
- "qt-test-server.${TEST_DOMAIN}:${MACHINE_IP}"

View File

@ -0,0 +1,4 @@
dbus_type = adaptor
qdbusxml2cpp_option = -a
include(dbuscommon.pri)

View File

@ -0,0 +1,82 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
load(moc)
qtPrepareTool(QMAKE_QDBUSXML2CPP, qdbusxml2cpp)
defineReplace(qdbusOutputBasename) {
return($$lower($$section($$list($$basename(1)),.,-2,-2)))
}
dbus_TYPE = $$upper($$dbus_type)
groups =
for(entry, DBUS_$${dbus_TYPE}S) {
files = $$eval($${entry}.files)
isEmpty(files) {
files = $$entry
group = dbus_$${dbus_type}
} else {
group = $${entry}_dbus_$${dbus_type}
}
groups *= $$group
input_list = $$upper($$group)_LIST
for(subent, $$list($$unique(files))) {
!contains(subent, .*\\w\\.xml$) {
warning("Invalid D-BUS $${dbus_type}: '$$subent', please use 'com.mydomain.myinterface.xml' instead.")
next()
}
$$input_list += $$subent
}
}
for(group, groups) {
GROUP = $$upper($$group)
input_list = $${GROUP}_LIST
# qmake does not keep empty elements in lists, so we reverse-engineer the short name
grp = $$replace(group, _?dbus_$${dbus_type}\$, )
isEmpty(grp) {
hdr_flags = $$eval(QDBUSXML2CPP_$${dbus_TYPE}_HEADER_FLAGS)
src_flags = $$eval(QDBUSXML2CPP_$${dbus_TYPE}_SOURCE_FLAGS)
} else {
hdr_flags = $$eval($${grp}.header_flags)
src_flags = $$eval($${grp}.source_flags)
}
$${group}_header.commands = $$QMAKE_QDBUSXML2CPP $$hdr_flags $$qdbusxml2cpp_option ${QMAKE_FILE_OUT}: ${QMAKE_FILE_IN}
$${group}_header.depends += $$QMAKE_QDBUSXML2CPP_EXE
$${group}_header.output = ${QMAKE_FUNC_FILE_IN_qdbusOutputBasename}_$${dbus_type}.h
$${group}_header.name = DBUSXML2CPP $${dbus_TYPE} HEADER ${QMAKE_FILE_IN}
$${group}_header.variable_out = $${GROUP}_HEADERS
$${group}_header.input = $$input_list
$${group}_source.commands = $$QMAKE_QDBUSXML2CPP -i ${QMAKE_FILE_OUT_BASE}.h $$src_flags $$qdbusxml2cpp_option :${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
$${group}_source.depends += $$QMAKE_QDBUSXML2CPP_EXE
$${group}_source.output = ${QMAKE_FUNC_FILE_IN_qdbusOutputBasename}_$${dbus_type}.cpp
$${group}_source.name = DBUSXML2CPP $${dbus_TYPE} SOURCE ${QMAKE_FILE_IN}
$${group}_source.variable_out = SOURCES
$${group}_source.input = $$input_list
$${group}_source.depends += $$eval($${group}_header.output) # this actually belongs to the object file
$${group}_moc.commands = $$moc_header.commands
$${group}_moc.depends += $$QMAKE_MOC_EXE
$${group}_moc.output = $$moc_header.output
$${group}_moc.input = $${GROUP}_HEADERS
$${group}_moc.variable_out = GENERATED_SOURCES
$${group}_moc.name = $${GROUP}_$$moc_header.name
QMAKE_EXTRA_COMPILERS += $${group}_header $${group}_source $${group}_moc
}

View File

@ -0,0 +1,4 @@
dbus_type = interface
qdbusxml2cpp_option = -p
include(dbuscommon.pri)

View File

@ -0,0 +1 @@
DEFINES += QT_DECLARATIVE_DEBUG

View File

@ -0,0 +1,177 @@
# This file is loaded by qmake right after loading the actual project file.
contains(TEMPLATE, ".*(lib|app)"):CONFIG += have_target
!have_target:!force_qt: CONFIG -= qt
load(resolve_config)
exclusive_builds: load(exclusive_builds_post)
# If the TARGET looks like a path, split it into DESTDIR and the resulting TARGET
target_dir_part = $$dirname(TARGET)
!isEmpty(target_dir_part) {
isEmpty(DESTDIR): \
DESTDIR = $$target_dir_part
else: \
DESTDIR = $$DESTDIR/$$target_dir_part
TARGET = $$basename(TARGET)
DESTDIR = $$clean_path($$DESTDIR)
}
QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
!isEmpty(QT_BREAKPAD_ROOT_PATH): \ # quick test first whether requested ...
!static:release:have_target: \ # is it applicable?
!contains(TARGET, .*phony_target.*): \ # monster hack, you don't really see this here, right? ;)
system($$QT_BREAKPAD_ROOT_PATH/qtbreakpadsymbols --breakpad-exists) { # do we really have it?
CONFIG += breakpad force_debug_info
CONFIG -= no_debug_info separate_debug_info
}
force_debug_info|debug: \
CONFIG += debug_info
force_debug_info {
QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
}
optimize_size {
!isEmpty(QMAKE_CFLAGS_OPTIMIZE):!isEmpty(QMAKE_CFLAGS_OPTIMIZE_SIZE) {
QMAKE_CFLAGS_RELEASE -= $$QMAKE_CFLAGS_OPTIMIZE
QMAKE_CXXFLAGS_RELEASE -= $$QMAKE_CFLAGS_OPTIMIZE
QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE_SIZE
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE_SIZE
}
} else: optimize_full {
!isEmpty(QMAKE_CFLAGS_OPTIMIZE):!isEmpty(QMAKE_CFLAGS_OPTIMIZE_FULL) {
QMAKE_CFLAGS_RELEASE -= $$QMAKE_CFLAGS_OPTIMIZE
QMAKE_CXXFLAGS_RELEASE -= $$QMAKE_CFLAGS_OPTIMIZE
QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE_FULL
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE_FULL
}
}
optimize_debug {
QMAKE_CFLAGS_DEBUG += $$QMAKE_CFLAGS_OPTIMIZE_DEBUG
QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_OPTIMIZE_DEBUG
}
debug {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_DEBUG
QMAKE_LFLAGS += $$QMAKE_LFLAGS_DEBUG
QMAKE_LIBFLAGS += $$QMAKE_LIBFLAGS_DEBUG
DEFINES += $$DEFINES_DEBUG
} else {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_RELEASE
QMAKE_LFLAGS += $$QMAKE_LFLAGS_RELEASE
QMAKE_LIBFLAGS += $$QMAKE_LIBFLAGS_RELEASE
DEFINES += $$DEFINES_RELEASE
}
stack_protector_strong {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_STACK_PROTECTOR_STRONG
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_STACK_PROTECTOR_STRONG
}
# disable special linker flags for host builds (no proper test for host support yet)
!host_build|!cross_compile {
use_bfd_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_BFD
use_gold_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_GOLD
use_lld_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_LLD
enable_new_dtags: QMAKE_LFLAGS += $$QMAKE_LFLAGS_NEW_DTAGS
enable_gdb_index: QMAKE_LFLAGS += $$QMAKE_LFLAGS_GDB_INDEX
}
dll:win32: QMAKE_LFLAGS += $$QMAKE_LFLAGS_DLL
static:mac: QMAKE_LFLAGS += $$QMAKE_LFLAGS_STATIC_LIB
staticlib:unix {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_STATIC_LIB
}
defined(WINDOWS_TARGET_PLATFORM_VERSION, var):isEmpty(WINDOWS_TARGET_PLATFORM_MIN_VERSION) {
WINDOWS_TARGET_PLATFORM_MIN_VERSION = $$WINDOWS_TARGET_PLATFORM_VERSION
}
incredibuild_xge {
CONFIG -= incredibuild_xge
CONFIG = incredibuild_xge $$CONFIG
}
silent {
# Ensure that we process silent.prf last, as it will mangle QMAKE_CXX
# and friends in a way that some of the other features (sdk.prf and
# simd.prf eg) do not handle.
CONFIG -= silent
CONFIG = silent $$CONFIG
}
breakpad {
load(resolve_target)
DEBUGFILENAME = $$shell_quote($$system_path($$QMAKE_RESOLVED_TARGET))
PROJECTPATH = $$shell_quote($$system_path($$OUT_PWD))
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)
QMAKE_POST_LINK = $$QMAKE_POST_LINK$$quote($${QT_BREAKPAD_ROOT_PATH}$${QMAKE_DIR_SEP}qtbreakpadsymbols $$DEBUGFILENAME $$PROJECTPATH)
!isEmpty(QMAKE_STRIP):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote($$QMAKE_STRIP $$DEBUGFILENAME)
}
c++17: CONFIG += c++1z
c++20: CONFIG += c++2a
c++latest: CONFIG *= c++2b c++2a c++1z c++14 c++11
!c++1z:!c++2a:!c++2b {
# Qt requires C++17
QT_COMPILER_STDCXX_no_L = $$replace(QT_COMPILER_STDCXX, "L$", "")
!greaterThan(QT_COMPILER_STDCXX_no_L, 201402): CONFIG += c++1z
}
c++1z|c++2a|c++2b {
# Disable special compiler flags for host builds
!host_build|!cross_compile {
c++2b: cxxstd = CXX2B
else:c++2a: cxxstd = CXX2A
else: cxxstd = CXX1Z
} else {
# Fall back to c++17, because C++17 is required everywhere,
# including host builds
cxxstd = CXX1Z
}
# Check if we should disable compiler extensions or not
isEmpty(QMAKE_CXXFLAGS_GNU$$cxxstd) {
strict_c++: QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_STRICTCXX
} else {
!strict_c++|isEmpty(QMAKE_CXXFLAGS_$$cxxstd): cxxstd = GNU$$cxxstd
}
QMAKE_CXXFLAGS += $$eval(QMAKE_CXXFLAGS_$$cxxstd)
QMAKE_LFLAGS += $$eval(QMAKE_LFLAGS_$$cxxstd)
unset(cxxstd)
}
c99|c11|c17|c18 {
c17|c18: cstd = C17
c11: cstd = C11
else: cstd = C99
!isEmpty(QMAKE_CFLAGS_GNU$$cstd) {
!strict_c|isEmpty(QMAKE_CFLAGS_$$cstd): cstd = GNU$$cstd
}
QMAKE_CFLAGS += $$eval(QMAKE_CFLAGS_$$cstd)
unset(cstd)
}
!no_utf8_source {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_UTF8_SOURCE
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_UTF8_SOURCE
}
!precompile_header: SOURCES += $$NO_PCH_SOURCES

View File

@ -0,0 +1,14 @@
# This file is loaded by qmake right before each actual project file.
# Note that evaluating variable assignments from the command line
# still happens in between these two steps.
# In early configure setup; nothing useful to be done here.
isEmpty(QMAKE_CXX): return()
load(exclusive_builds)
CONFIG = \
lex yacc debug exceptions depend_includepath \
testcase_targets import_plugins import_qpa_plugin \
$$CONFIG
load(toolchain)

View File

@ -0,0 +1 @@
plugin:DEFINES += QDESIGNER_EXPORT_WIDGETS

View File

@ -0,0 +1,12 @@
# This file is loaded by some qmakespecs to get early configuration data.
# Some of these qmakespecs can be used also in host mode, but they are not
# supposed to be influenced by -device-option then.
host_build: return()
DEVICE_PRI = $$[QT_HOST_DATA/get]/mkspecs/qdevice.pri
exists($$DEVICE_PRI):include($$DEVICE_PRI)
unset(DEVICE_PRI)
# this variable can be persisted via qmake -set CROSS_COMPILE /foo
isEmpty(CROSS_COMPILE): CROSS_COMPILE = $$[CROSS_COMPILE]

9
mkspecs/features/egl.prf Normal file
View File

@ -0,0 +1,9 @@
INCLUDEPATH += $$QMAKE_INCDIR_EGL
LIBS_PRIVATE += $$QMAKE_LIBS_EGL
QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL
DEFINES += $$QMAKE_DEFINES_EGL
LIBS += $$QMAKE_LFLAGS_EGL
for(p, QMAKE_LIBDIR_EGL) {
LIBS_PRIVATE += -L$$p
}

View File

@ -0,0 +1,10 @@
!qt: return()
win32 {
!console:contains(TEMPLATE, ".*app"): \
QT_PRIVATE += entrypoint_private
} else:uikit {
qt_depends = $$resolve_depends(QT, "QT.")
!watchos:equals(TEMPLATE, app):contains(qt_depends, gui(-private)?): \
QT_PRIVATE += entrypoint_private
}

View File

@ -0,0 +1,6 @@
CONFIG -= exceptions_off
QMAKE_CFLAGS *= $$QMAKE_CFLAGS_EXCEPTIONS_ON
QMAKE_CXXFLAGS *= $$QMAKE_CXXFLAGS_EXCEPTIONS_ON
QMAKE_LFLAGS *= $$QMAKE_LFLAGS_EXCEPTIONS_ON
DEFINES -= QT_NO_EXCEPTIONS

View File

@ -0,0 +1,5 @@
CONFIG -= exceptions
QMAKE_CFLAGS += $$QMAKE_CFLAGS_EXCEPTIONS_OFF
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_EXCEPTIONS_OFF
QMAKE_LFLAGS += $$QMAKE_LFLAGS_EXCEPTIONS_OFF
DEFINES += QT_NO_EXCEPTIONS

View File

@ -0,0 +1,45 @@
defineTest(addExclusiveBuildsProper) {
!$$1:!fix_output_dirs: \
return(true)
for(build, 2) {
isEmpty($${build}.name) {
$${build}.name = $$title($$build)
export($${build}.name)
}
isEmpty($${build}.target) {
$${build}.target = $$lower($$build)
export($${build}.target)
}
isEmpty($${build}.dir_affix) {
$${build}.dir_affix = $$lower($$build)
export($${build}.dir_affix)
}
$${build}.exclusive = $$2
export($${build}.exclusive)
QMAKE_EXCLUSIVE_BUILDS += $$build
}
CONFIG *= exclusive_builds
export(CONFIG)
export(QMAKE_EXCLUSIVE_BUILDS)
return(true)
}
defineTest(addExclusiveBuilds) {
lessThan(ARGC, 2): \
error("addExclusiveBuilds() requires at least two arguments")
addExclusiveBuildsProper($$join(ARGS, _and_), $$ARGS)
}
QMAKE_DEFAULT_DIRS_TO_PROCESS = QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR LEX_DIR YACC_DIR
QMAKE_DIR_REPLACE_SANE += $$QMAKE_DEFAULT_DIRS_TO_PROCESS
QMAKE_DIR_REPLACE = \
OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR DESTDIR \
$$QMAKE_DEFAULT_DIRS_TO_PROCESS
unset(QMAKE_DEFAULT_DIRS_TO_PROCESS)

View File

@ -0,0 +1,162 @@
load(qt_functions)
contains(TEMPLATE, subdirs) {
for(build, QMAKE_EXCLUSIVE_BUILDS) {
prepareRecursiveTarget($$build)
QMAKE_EXTRA_TARGETS += $$build
}
} else {
# Recursively combines a list of exclusive builds into combinations
# of non-exclusive builds (separated by a ':' character), eg the
# list [debug, release, static, shared] will result in the four
# combinations [debug:static, debug:shared, release:static,
# release:shared].
defineReplace(combineExclusiveBuilds) {
permutationBuilds = $$1
existingBuilds = $$2
isEmpty(permutationBuilds): \
# Exit-condition, no more recursing
return($$existingBuilds)
# Choose the first build of the permutations and use the set of exclusive
# builds associated with that build as the list of existing builds. This
# partitions the permutations into one set of exclusive builds + the rest
# of the unknown permutations.
newExistingBuilds = $$eval($$first(permutationBuilds).exclusive)
permutationBuilds -= $$newExistingBuilds
# Recursively compute the combination of these two sets
recursiveCombination = $$combineExclusiveBuilds($$permutationBuilds, $$newExistingBuilds)
isEmpty(existingBuilds): \
# No need to combine further
return($$recursiveCombination)
result =
for(existingBuild, existingBuilds) {
for(combination, recursiveCombination): \
result += "$${existingBuild}:$${combination}"
}
return($$result)
}
buildCombinations = $$combineExclusiveBuilds($$QMAKE_EXCLUSIVE_BUILDS)
for(combination, buildCombinations) {
builds = $$split(combination, :)
key =
config =
target =
priority =
for(build, builds) {
key = $${key}$$eval($${build}.name)
config *= $$eval($${build}.CONFIG) $${build} $$eval($${build}.name)Build
target += $$eval($${build}.target)
# If a build has been prioritized through CONFIG we prefer that
CONFIG($$build, $$join($${build}.exclusive, |)): \
priority += 1
}
$${key}.name = $$key
$${key}.target = $$join(target, -)
$${key}.CONFIG = $$config
$${key}.builds = $$builds
BUILDS.$$size(priority) += $$key
# Add makefile targets for each exclusive build that will aggregate all targets
# that include the exclusive build. This matches the targets in the SUBDIR files
# so that you can recursivly build a single exclusive build.
!build_pass:count(builds, 1, >) {
for(build, builds) {
$${build}.depends += $$eval($${key}.target)
QMAKE_EXTRA_TARGETS *= $$build
}
}
}
BUILDS =
priority =
for(ever) {
# Keep the order in BUILDS matching the priority from CONFIG, so that the first
# entry in BUILDS will be the first/default target when not CONFIG(build_all).
BUILDS = $$eval(BUILDS.$$size(priority)) $$BUILDS
count(BUILDS, $$size(buildCombinations), >=): break()
priority += 1
}
build_pass|fix_output_dirs {
!build_pass {
# The builds are sorted by priority based on the current config
# so choosing the first one gives us the most appropriate build.
BUILD_PASS = $$first(BUILDS)
}
for(dir, QMAKE_DIR_REPLACE) {
# Limit builds to ones that should affect the current $$dir
builds =
for(build, $${BUILD_PASS}.builds) {
equals(dir, DESTDIR) {
!$$join($${build}.exclusive, _and_)_target: \
next()
}
builds += $$build
}
isEmpty(builds): \
next()
affixes =
for(build, builds): \
affixes += $$eval($${build}.dir_affix)
full_dir_affix = $$join(affixes, -)
isEmpty($$dir)|isEqual($$dir, .) {
# Use affix directly
$$dir = $$full_dir_affix
next()
}
contains(QMAKE_DIR_REPLACE_SANE, $$dir) {
# Suffix output dir
$$dir = $$clean_path($$eval($$dir)/$$full_dir_affix)
} else {
# "Compatibility mode" with QTBUG-491
for(build, builds) {
did_replace = false
build_affix = $$eval($${build}.dir_affix)
for(exclusive, $${build}.exclusive) {
equals(exclusive, $$build): \
next()
exclusive_affix = $$eval($${exclusive}.dir_affix)
contains($$dir, .*$${exclusive_affix}.*) {
$$dir ~= s/$${exclusive_affix}/$${build_affix}/gi
did_replace = true
}
}
$$did_replace: next()
# Append (as subdir or as suffix)
!build_pass {
dir_affix = $$eval($${build}.dir_affix)
!contains($$dir, .*$${dir_affix}.*) {
contains($$dir, .*/$) {
# Subdir
$$dir = $$eval($$dir)$$dir_affix
} else {
# Suffix
$$dir = $$eval($$dir)-$${dir_affix}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,53 @@
isEmpty(COPIES): return()
contains(TEMPLATE, .*subdirs): error("COPIES does not work with TEMPLATE=subdirs")
build_pass:build_all:!isEqual(BUILD_PASS, $$first(BUILDS)) {
# Avoid that multiple build passes race with each other.
# This will fail to copy anything if the user explicitly invokes
# only the non-primary build. This is unfixable, as at qmake time
# we cannot possibly know how make will be invoked, yet we must
# predict it here.
return()
}
defineReplace(qtStripProPwd) {
return($$relative_path($$1, $$_PRO_FILE_PWD_))
}
for (cp, COPIES) {
isEmpty($${cp}.files): next()
pfx = copy_$${cp}
notdir = false
dir = false
for (f, $${cp}.files) {
fil = $$absolute_path($$f, $$_PRO_FILE_PWD_)
tfiles = $$files($$fil/*)
isEmpty(tfiles): \
notdir = true
else: \
dir = true
$${pfx}.files += $$fil
}
$$dir:$$notdir: \
error("COPIES entry $$cp lists both files and directories.")
path = $$eval($${cp}.path)
isEmpty(path): error("COPIES entry $$cp defines no .path")
base = $$eval($${cp}.base)
isEmpty(base) {
$${pfx}.output = $$path/${QMAKE_FILE_IN_NAME}
} else: isEqual(base, $$_PRO_FILE_PWD_) {
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd}
} else {
eval(defineReplace(qtStripSrcDir_$$cp) { \
return(\$\$relative_path(\$\$1, $$val_escape(base))) \
})
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp}
}
$${pfx}.input = $${pfx}.files
contains(TEMPLATE, "vc.*"): copycommand = $$QMAKE_QMAKE -install qinstall
else: copycommand = $(QINSTALL)
$${pfx}.commands = $$copycommand ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
$${pfx}.name = COPY ${QMAKE_FILE_IN}
$${pfx}.CONFIG = no_link no_clean target_predeps
QMAKE_EXTRA_COMPILERS += $${pfx}
}

View File

@ -0,0 +1,3 @@
QMAKE_CFLAGS += $$QMAKE_CFLAGS_SPLIT_SECTIONS
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SPLIT_SECTIONS
QMAKE_LFLAGS += $$QMAKE_LFLAGS_GCSECTIONS

30
mkspecs/features/gcov.prf Normal file
View File

@ -0,0 +1,30 @@
#
# Tested with gcov 4.8.1
# http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Gcov.html
# To instrument a Qt application or library with the gcov coverage
# tool, do `CONFIG+=gcov' in the application .pro file.
#
# To instrument Qt itself with gcov, use the `-gcov' configure
# option.
# The .gcno file is generated when the source file is compiled.
# The .gcda file is generated when a program is executed.
# Example how to generate the html output after you've run the program or test
#
# lcov --capture --directory . --output-file coverage-gcov.info --no-external
# lcov --output-file coverage-gcov.info --remove coverage-gcov.info '*.moc*' '.*rcc*' '*3rdparty*'
# genhtml coverage-gcov.info --output-directory doc/coverage
# If you want to use gcov directly, you most likely need to manually move the .gcda and .gcno files
# along with the program.
#
# mv .obj/debug-shared/tst_example.gc* .
# gcov -b -c tst_example.cpp
QMAKE_CFLAGS += -fprofile-arcs -ftest-coverage
QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage
QMAKE_LFLAGS += -fprofile-arcs -ftest-coverage
QMAKE_CLEAN += $(OBJECTS_DIR)*.gcno and $(OBJECTS_DIR)*.gcda

View File

@ -0,0 +1 @@
!equals(_PRO_FILE_PWD_, $$OUT_PWD):INCLUDEPATH *= .

View File

@ -0,0 +1,8 @@
contains(TEMPLATE, "vc.*") {
# The VCPROJ generator will replace the \r\h with the coded \r\n: &#x0d;&#x0a;
EOC = $$escape_expand(\\r\\h)
for(xge, INCREDIBUILD_XGE) {
$${xge}.commands = Rem IncrediBuild_AllowRemote $$EOC Rem IncrediBuild_OutputFile $$system_path($${xge}.output) $$EOC $$eval($${xge}.commands)
}
}

53
mkspecs/features/java.prf Normal file
View File

@ -0,0 +1,53 @@
TEMPLATE = lib
android {
load(sdk)
# FIXME: This is a hack to work around some hardcoded values in the android.prf. The
# android.prf should be fixed and this should be removed.
CONFIG += android_app
}
isEmpty(CLASS_DIR): \
CLASS_DIR = .classes
CONFIG -= qt
# Without these, qmake adds a name prefix and versioning postfixes (as well as file
# links) to the target. This is hardcoded in the qmake code, so for now we use
# the plugin configs to get what we want.
CONFIG += plugin no_plugin_name_prefix
javac.input = JAVASOURCES
javac.output = $$CLASS_DIR
javac.CONFIG += combine
# Check for user defined javac build version
javac_target_version = $$ANDROID_JAVAC_TARGET_VERSION
isEmpty(javac_target_version): javac_target_version = 8
javac_source_version = $$ANDROID_JAVAC_SOURCE_VERSION
isEmpty(javac_source_version): javac_source_version = 8
javac.commands = javac -source $$javac_source_version -target $$javac_target_version -Xlint:unchecked -bootclasspath $$ANDROID_JAR_FILE -cp $$shell_quote($$system_path($$join(JAVACLASSPATH, $$DIRLIST_SEPARATOR))) -d $$shell_quote($$CLASS_DIR) ${QMAKE_FILE_IN}
# Force rebuild every time, because we don't know the paths of the destination files
# as they depend on the code.
javac.depends = FORCE
QMAKE_EXTRA_COMPILERS += javac
mkpath($$absolute_path($$CLASS_DIR, $$OUT_PWD))|error()
# Disable all linker flags since we are overriding the regular linker
QMAKE_LFLAGS =
QMAKE_CFLAGS =
QMAKE_LFLAGS_RPATH =
QMAKE_LFLAGS_PLUGIN =
QMAKE_LIBS =
QMAKE_LIBS_OPENGL_ES2 =
QMAKE_LIBDIR =
QMAKE_EXTENSION_SHLIB = jar
QMAKE_LINK_SHLIB_CMD = jar cf $(TARGET) -C $$CLASS_DIR .
# Force link step to always happen, since we are always updating the
# .class files
PRE_TARGETDEPS += FORCE

50
mkspecs/features/lex.prf Normal file
View File

@ -0,0 +1,50 @@
#
# Lex extra-compiler for handling files specified in the LEXSOURCES variable
#
isEmpty(LEX_DIR): LEX_DIR = .
defineReplace(lexCommands) {
input = $$relative_path($$absolute_path($$1, $$OUT_PWD), $$OUT_PWD/$$LEX_DIR)
output = $$basename(2)
input_base = $$basename(1)
input_base ~= s/\.[^.]*$//
isEmpty(QMAKE_LEXFLAGS_MANGLE): QMAKE_LEXFLAGS_MANGLE = -P$${input_base}
QMAKE_LEXEXTRAFLAGS = $$QMAKE_LEXFLAGS
!yacc_no_name_mangle: QMAKE_LEXEXTRAFLAGS += $$QMAKE_LEXFLAGS_MANGLE
contains(QMAKE_LEX, .*flex) {
# GNU flex, we can use -o outfile
commands = $$QMAKE_LEX $$QMAKE_LEXEXTRAFLAGS --nounistd -o $$output $$input
} else {
# stupid POSIX lex, it only generates a file called lex.yy.c
# or lex.prefix.c if the -P<prefix> option is active
intermediate_file = lex.yy.c
QMAKE_LEXEXTRAFLAGS = $$QMAKE_LEXFLAGS $$QMAKE_LEXFLAGS_MANGLE
commands = \
-$(DEL_FILE) $${output}$$escape_expand(\\n\\t) \
$$QMAKE_LEX $$QMAKE_LEXEXTRAFLAGS $${input}$$escape_expand(\\n\\t) \
$(MOVE) $$intermediate_file $$output $$escape_expand(\\n\\t)
}
!equals(LEX_DIR, .): \
commands = cd $$LEX_DIR && $$commands
silent: commands = @echo Lex $$1 && $$commands
return($$commands)
}
{
lex.name = Lex ${QMAKE_FILE_IN}
lex.input = LEXSOURCES
lex.dependency_type = TYPE_C
lex_included {
lex.CONFIG += no_link
} else {
lex.variable_out = GENERATED_SOURCES
}
lex.commands = ${QMAKE_FUNC_lexCommands}
lex.output = $$LEX_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_LEX}$${first(QMAKE_EXT_CPP)}
QMAKE_EXTRA_COMPILERS += lex
}

View File

@ -0,0 +1,26 @@
gcc {
# on Windows, MinGW's support for -flto=N is broken
intel_icc {
QMAKE_LFLAGS_LTCG ~= s/-ipo/-ipo=$$QMAKE_HOST.cpu_count/
} else: !clang:!equals(QMAKE_HOST.os, Windows):greaterThan(QMAKE_HOST.cpu_count, 1) {
# Override LTO number of jobs
QMAKE_LFLAGS_LTCG ~= s/^-flto$/-flto=$$QMAKE_HOST.cpu_count/
}
# When doing link-time code generation, we need to pass the compiler
# flags during linking the stage too. This file is processed after
# default_post.prf, so the QMAKE_CXXFLAGS already contains
# QMAKE_CXXFLAGS_DEBUG or _RELEASE.
use_c_linker {
# use_c_linker.prf is in effect, use the C flags
QMAKE_LFLAGS_LTCG += $$QMAKE_CFLAGS $$QMAKE_CFLAGS_LTCG
QMAKE_LFLAGS_APP += $$QMAKE_CFLAGS_APP
QMAKE_LFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB
QMAKE_LFLAGS_PLUGIN += $$QMAKE_CFLAGS_SHLIB
} else {
QMAKE_LFLAGS_LTCG = $$QMAKE_CXXFLAGS $$QMAKE_LFLAGS_LTCG
QMAKE_LFLAGS_APP += $$QMAKE_CXXFLAGS_APP
QMAKE_LFLAGS_SHLIB += $$QMAKE_CXXFLAGS_SHLIB
QMAKE_LFLAGS_PLUGIN += $$QMAKE_CFLAGS_SHLIB
}
}

View File

@ -0,0 +1,32 @@
PKG_CONFIG = $$pkgConfigExecutable()
# qmake supports no empty list elements, so the outer loop is a bit arcane
pkgsfx =
for(ever) {
pkgvar = PKGCONFIG$$pkgsfx
libvar = LIBS$$pkgsfx
for(PKGCONFIG_LIB, $$list($$unique($$pkgvar))) {
# don't proceed if the .pro asks for a package we don't have!
!packagesExist($$PKGCONFIG_LIB): error("$$PKGCONFIG_LIB development package not found")
PKGCONFIG_CFLAGS = $$system($$PKG_CONFIG --cflags $$PKGCONFIG_LIB)
PKGCONFIG_INCLUDEPATH = $$find(PKGCONFIG_CFLAGS, ^-I.*)
PKGCONFIG_INCLUDEPATH ~= s/^-I(.*)/\\1/g
PKGCONFIG_DEFINES = $$find(PKGCONFIG_CFLAGS, ^-D.*)
PKGCONFIG_DEFINES ~= s/^-D(.*)/\\1/g
PKGCONFIG_CFLAGS ~= s/^-[ID].*//g
INCLUDEPATH *= $$PKGCONFIG_INCLUDEPATH
DEFINES *= $$PKGCONFIG_DEFINES
QMAKE_CXXFLAGS += $$PKGCONFIG_CFLAGS
QMAKE_CFLAGS += $$PKGCONFIG_CFLAGS
$$libvar += $$system($$PKG_CONFIG --libs $$PKGCONFIG_LIB)
}
!isEmpty(pkgsfx): break()
pkgsfx = _PRIVATE
}

View File

@ -0,0 +1,42 @@
# Automatically generate .qm files out of .ts files in TRANSLATIONS and
# EXTRA_TRANSLATIONS.
#
# If embed_translations is enabled, the generated .qm files are made available
# in the resource system under :/i18n/.
#
# Otherwise, the .qm files are available in the build directory in LRELEASE_DIR.
# They can also be automatically installed by setting QM_FILES_INSTALL_PATH.
qtPrepareTool(QMAKE_LRELEASE, lrelease)
isEmpty(LRELEASE_DIR): LRELEASE_DIR = .qm
isEmpty(QM_FILES_RESOURCE_PREFIX): QM_FILES_RESOURCE_PREFIX = i18n
lrelease.name = lrelease
lrelease.input = TRANSLATIONS EXTRA_TRANSLATIONS
lrelease.output = $$LRELEASE_DIR/${QMAKE_FILE_IN_BASE}.qm
lrelease.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} $$QMAKE_LRELEASE_FLAGS -qm ${QMAKE_FILE_OUT}
silent: lrelease.commands = @echo lrelease ${QMAKE_FILE_IN} && $$lrelease.commands
lrelease.CONFIG = no_link
QMAKE_EXTRA_COMPILERS += lrelease
all_translations = $$TRANSLATIONS $$EXTRA_TRANSLATIONS
for (translation, all_translations) {
# mirrors $$LRELEASE_DIR/${QMAKE_FILE_IN_BASE}.qm above
translation = $$basename(translation)
QM_FILES += $$OUT_PWD/$$LRELEASE_DIR/$$replace(translation, \\.[^.]+$, .qm)
}
embed_translations {
qmake_qm_files.files = $$QM_FILES
qmake_qm_files.base = $$OUT_PWD/$$LRELEASE_DIR
qmake_qm_files.prefix = $$QM_FILES_RESOURCE_PREFIX
RESOURCES += qmake_qm_files
} else {
!isEmpty(QM_FILES_INSTALL_PATH) {
qm_files.files = $$QM_FILES
qm_files.path = $$QM_FILES_INSTALL_PATH
qm_files.CONFIG = no_check_exist
INSTALLS += qm_files
}
lrelease.CONFIG += target_predeps no_clean
}

45
mkspecs/features/ltcg.prf Normal file
View File

@ -0,0 +1,45 @@
static:no-static-ltcg {
# Static library but no-static-ltcg enabled: skip LTCG
} else: CONFIG(release, debug|release) {
separate_debug_info {
# Evaluate single-$ variable references that have no valid value at mkspec loading time
QMAKE_LFLAGS_LTCG_SEPARATE_DEBUG_INFO ~= s/\\$\\{/\$\$\{/
eval(QMAKE_LFLAGS_LTCG += $$QMAKE_LFLAGS_LTCG_SEPARATE_DEBUG_INFO)
}
# We need fat object files when creating static libraries on some platforms
# so the linker will know to load a particular object from the library
# in the first place. On others, we have special ar and nm to create the symbol
# tables so the linker will know better. For other compilers, we disable LTCG
# for static libraries.
msvc {
# Nothing to do
} else {
!isEmpty(QMAKE_AR_LTCG): QMAKE_AR = $$QMAKE_AR_LTCG
!isEmpty(QMAKE_NM_LTCG): QMAKE_NM = $$QMAKE_NM_LTCG
equals(QMAKE_RANLIB_LTCG, true): QMAKE_RANLIB =
else: !isEmpty(QMAKE_RANLIB_LTCG): QMAKE_RANLIB = $$QMAKE_RANLIB_LTCG
static:isEmpty(QMAKE_AR_LTCG):isEmpty(QMAKE_RANLIB_LTCG) {
# We don't know how to create symbol tables for static libs with this
# compiler, so disable LTCG
QMAKE_CFLAGS_LTCG =
QMAKE_CXXFLAGS_LTCG =
QMAKE_LFLAGS_LTCG =
}
}
fat-lto|if(static:fat-static-lto) {
QMAKE_CFLAGS_LTCG += $$QMAKE_CFLAGS_LTCG_FATOBJECTS
QMAKE_CXXFLAGS_LTCG += $$QMAKE_CXXFLAGS_LTCG_FATOBJECTS
}
load(link_ltcg)
QMAKE_CFLAGS -= $$QMAKE_CFLAGS_LTCG
QMAKE_CFLAGS += $$QMAKE_CFLAGS_LTCG
QMAKE_CXXFLAGS -= $$QMAKE_CXXFLAGS_LTCG
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_LTCG
QMAKE_LFLAGS -= $$QMAKE_LFLAGS_LTCG
QMAKE_LFLAGS += $$QMAKE_LFLAGS_LTCG
}

View File

@ -0,0 +1,124 @@
# QMAKE_ASSET_CATALOGS
# Paths to xcassets directories to be compiled
#
# QMAKE_ASSET_CATALOGS_BUILD_PATH
# Location which asset catalogs will be compiled to.
# If the current target is an app bundle, defaults to its Resources directory.
# Otherwise, this value must be set manually.
#
# QMAKE_ASSET_CATALOGS_APP_ICON
# Name of the icon resource in the asset catalogs that will be used as the app icon.
# Defaults to AppIcon.
#
# QMAKE_ASSET_CATALOGS_LAUNCH_IMAGE
# Name of the launch image resource in the asset catalogs that will be used as the launch image.
#
# QMAKE_ASSET_CATALOGS_INSTALL_PATH
# Base path to install files to. Falls back to a path relative to the target install path,
# based on QMAKE_ASSET_CATALOGS_BUILD_PATH.
!have_target|if(!build_pass:!isEmpty(BUILDS)): \
return()
!isEmpty(QMAKE_ASSET_CATALOGS) {
load(resolve_target)
isEmpty(QMAKE_ASSET_CATALOGS_BUILD_PATH) {
!isEmpty(QMAKE_RESOLVED_BUNDLE):equals(TEMPLATE, app):app_bundle {
macos: \
QMAKE_ASSET_CATALOGS_BUILD_PATH = $$QMAKE_RESOLVED_BUNDLE/Contents/Resources
else: \
QMAKE_ASSET_CATALOGS_BUILD_PATH = $$QMAKE_RESOLVED_BUNDLE
} else {
error("QMAKE_ASSET_CATALOGS_BUILD_PATH must be set when using QMAKE_ASSET_CATALOGS.")
}
}
QMAKE_ASSET_CATALOGS_BUILD_PATH = $$clean_path($$QMAKE_ASSET_CATALOGS_BUILD_PATH)
macx-xcode {
!isEmpty(QMAKE_ASSET_CATALOGS_APP_ICON) {
asset_catalog_appicon.name = "ASSETCATALOG_COMPILER_APPICON_NAME"
asset_catalog_appicon.value = $$QMAKE_ASSET_CATALOGS_APP_ICON
QMAKE_MAC_XCODE_SETTINGS += asset_catalog_appicon
}
!isEmpty(QMAKE_ASSET_CATALOGS_LAUNCH_IMAGE) {
asset_catalog_launchimage.name = "ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME"
asset_catalog_launchimage.value = $$QMAKE_ASSET_CATALOGS_LAUNCH_IMAGE
QMAKE_MAC_XCODE_SETTINGS += asset_catalog_launchimage
}
asset_catalog_compiler.files = $$QMAKE_ASSET_CATALOGS
macos: asset_catalog_compiler.path = Contents/Resources
QMAKE_BUNDLE_DATA += asset_catalog_compiler
} else {
!isEmpty(QMAKE_ASSET_CATALOGS_APP_ICON) {
asset_catalog_app_icon_arg = \
--app-icon $$shell_quote($$QMAKE_ASSET_CATALOGS_APP_ICON)
}
!isEmpty(QMAKE_ASSET_CATALOGS_LAUNCH_IMAGE) {
asset_catalog_launch_image_arg = \
--launch-image $$shell_quote($$QMAKE_ASSET_CATALOGS_LAUNCH_IMAGE)
}
asset_catalog_compiler.target = $$OUT_PWD/asset_catalog_compiler.Info.plist
asset_catalog_compiler.commands = $$shell_quote($$QMAKE_ACTOOL) \
$$asset_catalog_app_icon_arg \
$$asset_catalog_launch_image_arg \
--output-partial-info-plist $$shell_quote($$asset_catalog_compiler.target) \
--platform $${platform_identifier} \
--minimum-deployment-target $${deployment_target} \
--compile $$shell_quote($$QMAKE_ASSET_CATALOGS_BUILD_PATH)
for (catalog, QMAKE_ASSET_CATALOGS) {
asset_catalog_compiler.commands += $${catalog}
asset_catalog_compiler.depends += $$files($$catalog/*, true)
}
actool_output_files = $$system(\
mkdir -p $$system_quote($$QMAKE_ASSET_CATALOGS_BUILD_PATH) && \
/usr/libexec/PlistBuddy -c \'Print :com.apple.actool.compilation-results:output-files\' \
/dev/stdin <<< $($${asset_catalog_compiler.commands} 2>/dev/null) | sed -Ene \'s/^ +//p\', lines)
for (output_file, actool_output_files) {
!equals(output_file, $$asset_catalog_compiler.target): \
actool_output_files_rel += $$relative_path($$output_file, $$QMAKE_ASSET_CATALOGS_BUILD_PATH)
}
QMAKE_EXTRA_TARGETS += asset_catalog_compiler
PRE_TARGETDEPS += $$asset_catalog_compiler.target
isEmpty(QMAKE_ASSET_CATALOGS_INSTALL_PATH) {
!isEmpty(target.path): \
QMAKE_ASSET_CATALOGS_INSTALL_PATH = $${target.path}/
QMAKE_ASSET_CATALOGS_INSTALL_PATH = $${QMAKE_ASSET_CATALOGS_INSTALL_PATH}$$relative_path(\
$$QMAKE_ASSET_CATALOGS_BUILD_PATH, $$absolute_path($$DESTDIR, $$OUT_PWD))
}
for (ac_install_file, actool_output_files_rel) {
asset_catalogs_files.files += \
$$QMAKE_ASSET_CATALOGS_BUILD_PATH/$$ac_install_file
}
contains(INSTALLS, target): asset_catalogs_files.depends += install_target
asset_catalogs_files.path = $$QMAKE_ASSET_CATALOGS_INSTALL_PATH
asset_catalogs_files.CONFIG += no_check_exist
INSTALLS += asset_catalogs_files
}
} else: macx-xcode {
# Backwards compatibility
for (bundle_data, QMAKE_BUNDLE_DATA) {
for (bundle_file, $${bundle_data}.files) {
!contains(bundle_file, .*\\.xcassets$): next()
warning("*.xcassets in QMAKE_BUNDLE_DATA is deprecated. Use QMAKE_ASSET_CATALOGS instead.")
!exists($$absolute_path($$bundle_file/AppIcon.appiconset, $$_PRO_FILE_PWD_)): next()
asset_catalog_appicon.name = "ASSETCATALOG_COMPILER_APPICON_NAME"
asset_catalog_appicon.value = "AppIcon"
QMAKE_MAC_XCODE_SETTINGS += asset_catalog_appicon
break()
}
!isEmpty(asset_catalog_appicon.name): break()
}
}

View File

@ -0,0 +1,309 @@
load(default_post)
# Recompute SDK version in case the user set it explicitly
sdk_version = $$QMAKE_MAC_SDK_VERSION
QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion)
contains(TEMPLATE, .*app) {
!macx-xcode:if(isEmpty(BUILDS)|build_pass) {
# Detect changes to the platform SDK
QMAKE_EXTRA_VARIABLES += \
QMAKE_MAC_SDK \
QMAKE_MAC_SDK_VERSION \
QMAKE_XCODE_DEVELOPER_PATH \
_QMAKE_STASH_ \
QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk)
}
# Detect incompatible SDK versions
isEmpty(QT_MAC_SDK_VERSION_MIN): \
QT_MAC_SDK_VERSION_MIN = $$QT_MAC_SDK_VERSION
!versionAtLeast(QMAKE_MAC_SDK_VERSION, $$QT_MAC_SDK_VERSION_MIN): \
warning("Qt requires at least version $$QT_MAC_SDK_VERSION_MIN of the platform SDK," \
"you're building against version $${QMAKE_MAC_SDK_VERSION}. Please upgrade.")
!isEmpty(QT_MAC_SDK_VERSION_MAX) {
# For Qt developers only
!isEmpty($$list($$(QT_MAC_SDK_NO_VERSION_CHECK))): \
CONFIG += sdk_no_version_check
QMAKE_MAC_SDK_MAJOR_VERSION = $$replace(QMAKE_MAC_SDK_VERSION, "(\\d+)(\\.\\d+)(\\.\\d+)?", \\1)
!sdk_no_version_check:!versionAtMost(QMAKE_MAC_SDK_MAJOR_VERSION, $$QT_MAC_SDK_VERSION_MAX) {
warning("Qt has only been tested with version $$QT_MAC_SDK_VERSION_MAX"\
"of the platform SDK, you're using $${QMAKE_MAC_SDK_MAJOR_VERSION}.")
warning("This is an unsupported configuration. You may experience build issues," \
"and by using")
warning("the $$QMAKE_MAC_SDK_VERSION SDK you are opting in to new features" \
"that Qt has not been prepared for.")
warning("Please downgrade the SDK you use to build your app to version" \
"$$QT_MAC_SDK_VERSION_MAX, or configure")
warning("with CONFIG+=sdk_no_version_check when running qmake" \
"to silence this warning.")
}
}
}
!no_objective_c:CONFIG += objective_c
qt {
qtConfig(static) {
# C++11 support means using libc++ instead of libstd++. As the
# two libraries are incompatible we need to ensure the end user
# project is built using the same C++11 support/no support as Qt.
qtConfig(c++11) {
CONFIG += c++11
} else: c++11 {
warning("Qt was not built with C++11 enabled, disabling feature")
CONFIG -= c++11
}
!c++11 {
# Explicitly use libstdc++ if C++11 support is not enabled,
# as otherwise the compiler will choose the standard library
# based on the deployment target, which for iOS 7 and OS X 10.9
# is libc++, and we can't mix and match the two.
QMAKE_CXXFLAGS += -stdlib=libstdc++
QMAKE_LFLAGS += -stdlib=libstdc++
}
}
}
# Add the same default rpaths as Xcode does for new projects.
# This is especially important for iOS/tvOS/watchOS where no other option is possible.
!no_default_rpath {
uikit: QMAKE_RPATHDIR += @executable_path/Frameworks
else: QMAKE_RPATHDIR += @executable_path/../Frameworks
equals(TEMPLATE, lib):!plugin:lib_bundle: QMAKE_RPATHDIR += @loader_path/Frameworks
}
# Don't pass -headerpad_max_install_names when using Bitcode.
# In that case the linker emits a warning stating that the flag is ignored when
# used with bitcode, for reasons that cannot be determined (rdar://problem/20748962).
# Using this flag is also unnecessary in practice on UIKit platforms since they
# are sandboxed, and only UIKit platforms support bitcode to begin with.
!bitcode: QMAKE_LFLAGS += $$QMAKE_LFLAGS_HEADERPAD
app_extension_api_only {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_APPLICATION_EXTENSION
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_APPLICATION_EXTENSION
QMAKE_CXXFLAGS_PRECOMPILE += $$QMAKE_CFLAGS_APPLICATION_EXTENSION
QMAKE_LFLAGS += $$QMAKE_CFLAGS_APPLICATION_EXTENSION
}
macos {
!isEmpty(QMAKE_APPLE_DEVICE_ARCHS) {
# If the user has requested a specific set of architectures,
# build all of those by default, but limited to only those.
CONFIG -= only_active_arch
} else {
# Otherwise allow building all of the architectures available
# in Qt, but only build the active arch (unless the user has
# manually overridden this via CONFIG -= only_active_arch).
QMAKE_APPLE_DEVICE_ARCHS = $$QT_ARCHS
}
}
macx-xcode {
qmake_pkginfo_typeinfo.name = QMAKE_PKGINFO_TYPEINFO
!isEmpty(QMAKE_PKGINFO_TYPEINFO): \
qmake_pkginfo_typeinfo.value = $$QMAKE_PKGINFO_TYPEINFO
else: \
qmake_pkginfo_typeinfo.value = "????"
QMAKE_MAC_XCODE_SETTINGS += qmake_pkginfo_typeinfo
bundle_version = $$VERSION
isEmpty(bundle_version): bundle_version = 1.0.0
l = $$split(bundle_version, '.') 0 0 # make sure there are at least three
VER_MAJ = $$member(l, 0, 0)
VER_MIN = $$member(l, 1, 1)
VER_PAT = $$member(l, 2, 2)
unset(l)
qmake_full_version.name = QMAKE_FULL_VERSION
qmake_full_version.value = $${VER_MAJ}.$${VER_MIN}.$${VER_PAT}
QMAKE_MAC_XCODE_SETTINGS += qmake_full_version
qmake_short_version.name = QMAKE_SHORT_VERSION
qmake_short_version.value = $${VER_MAJ}.$${VER_MIN}
QMAKE_MAC_XCODE_SETTINGS += qmake_short_version
!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) {
debug_information_format.name = DEBUG_INFORMATION_FORMAT
debug_information_format.value = $$QMAKE_XCODE_DEBUG_INFORMATION_FORMAT
debug_information_format.build = debug
QMAKE_MAC_XCODE_SETTINGS += debug_information_format
}
QMAKE_XCODE_ARCHS =
arch_device.name = "ARCHS[sdk=$${device.sdk}*]"
arch_device.value = $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_MAC_XCODE_SETTINGS += arch_device
ios:simulator {
arch_simulator.name = "ARCHS[sdk=$${simulator.sdk}*]"
arch_simulator.value = $$QMAKE_APPLE_SIMULATOR_ARCHS
QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_SIMULATOR_ARCHS
QMAKE_MAC_XCODE_SETTINGS += arch_simulator
}
only_active_arch.name = ONLY_ACTIVE_ARCH
only_active_arch.value = YES
only_active_arch.build = debug
QMAKE_MAC_XCODE_SETTINGS += only_active_arch
} else {
device|!simulator: VALID_DEVICE_ARCHS = $$QMAKE_APPLE_DEVICE_ARCHS
ios:simulator: VALID_SIMULATOR_ARCHS = $$QMAKE_APPLE_SIMULATOR_ARCHS
VALID_ARCHS = $$VALID_DEVICE_ARCHS $$VALID_SIMULATOR_ARCHS
single_arch: VALID_ARCHS = $$first(VALID_ARCHS)
macos {
only_active_arch: DEFAULT_ARCHS = $$system("uname -m")
else: DEFAULT_ARCHS = $$VALID_ARCHS
}
ARCHS = $(filter $(EXPORT_VALID_ARCHS), \
$(if $(ARCHS), $(ARCHS), \
$(if $(EXPORT_DEFAULT_ARCHS), $(EXPORT_DEFAULT_ARCHS), \
$(EXPORT_VALID_ARCHS))))
ARCH_ARGS = $(foreach arch, $(if $(EXPORT_ARCHS), $(EXPORT_ARCHS), $(EXPORT_VALID_ARCHS)), -arch $(arch))
QMAKE_EXTRA_VARIABLES += VALID_ARCHS DEFAULT_ARCHS ARCHS ARCH_ARGS
arch_flags = $(EXPORT_ARCH_ARGS)
QMAKE_CFLAGS += $$arch_flags
QMAKE_CXXFLAGS += $$arch_flags
QMAKE_LFLAGS += $$arch_flags
QMAKE_PCH_ARCHS = $$VALID_ARCHS
macos: deployment_target = $$QMAKE_MACOSX_DEPLOYMENT_TARGET
ios: deployment_target = $$QMAKE_IOS_DEPLOYMENT_TARGET
tvos: deployment_target = $$QMAKE_TVOS_DEPLOYMENT_TARGET
watchos: deployment_target = $$QMAKE_WATCHOS_DEPLOYMENT_TARGET
# If we're doing a simulator and device build, device and simulator
# architectures use different paths and flags for the sysroot and
# deployment target switch, so we must multiplex them across multiple
# architectures using -Xarch. Otherwise we fall back to the simple path.
# This is not strictly necessary, but results in cleaner command lines
# and makes it easier for people to override EXPORT_VALID_ARCHS to limit
# individual rules to a different set of architecture(s) from the overall
# build (such as machtest in QtCore).
ios:simulator:device {
QMAKE_XARCH_CFLAGS =
QMAKE_XARCH_LFLAGS =
QMAKE_EXTRA_VARIABLES += QMAKE_XARCH_CFLAGS QMAKE_XARCH_LFLAGS
for (arch, VALID_ARCHS) {
contains(VALID_SIMULATOR_ARCHS, $$arch) {
sdk = $$simulator.sdk
version_identifier = $$simulator.deployment_identifier
platform_identifier = $$simulator.sdk
} else {
sdk = $$device.sdk
version_identifier = $$device.deployment_identifier
platform_identifier = $$device.sdk
}
version_min_flags = \
-Xarch_$${arch} \
-m$${version_identifier}-version-min=$$deployment_target
QMAKE_XARCH_CFLAGS_$${arch} = $$version_min_flags \
-Xarch_$${arch} \
-isysroot$$xcodeSDKInfo(Path, $$sdk)
QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \
-Xarch_$${arch} \
-isysroot$$xcodeSDKInfo(Path, $$sdk)
QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch})
QMAKE_XARCH_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS_$${arch})
QMAKE_EXTRA_VARIABLES += \
QMAKE_XARCH_CFLAGS_$${arch} \
QMAKE_XARCH_LFLAGS_$${arch}
}
QMAKE_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS)
QMAKE_CXXFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS)
QMAKE_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS)
} else {
ios:simulator {
version_identifier = $$simulator.deployment_identifier
platform_identifier = $$simulator.sdk
sysroot_path = $$xcodeSDKInfo(Path, $$simulator.sdk)
} else {
version_identifier = $$device.deployment_identifier
platform_identifier = $$device.sdk
sysroot_path = $$xcodeSDKInfo(Path, $$device.sdk)
}
version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
QMAKE_CFLAGS += -isysroot $$sysroot_path $$version_min_flag
QMAKE_CXXFLAGS += -isysroot $$sysroot_path $$version_min_flag
QMAKE_LFLAGS += -isysroot $$sysroot_path $$version_min_flag
}
# Enable precompiled headers for multiple architectures
QMAKE_CFLAGS_USE_PRECOMPILE =
for (arch, VALID_ARCHS) {
icc_pch_style: \
use_flag = "-pch-use "
else: \
use_flag = -include
# Only use Xarch with multi-arch, as the option confuses ccache
count(VALID_ARCHS, 1, greaterThan): \
QMAKE_CFLAGS_USE_PRECOMPILE += \
-Xarch_$${arch}
QMAKE_CFLAGS_USE_PRECOMPILE += \
$${use_flag}${QMAKE_PCH_OUTPUT_$${arch}}
}
icc_pch_style {
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE -include ${QMAKE_PCH_INPUT}
QMAKE_CFLAGS_USE_PRECOMPILE =
} else {
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
}
QMAKE_PCH_OUTPUT_EXT = _${QMAKE_PCH_ARCH}$${QMAKE_PCH_OUTPUT_EXT}
}
!equals(sdk_version, $$QMAKE_MAC_SDK_VERSION) {
# Explicit SDK version has been set, respect that
QMAKE_LFLAGS += -Wl,-sdk_version -Wl,$$sdk_version
}
cache(QMAKE_XCODE_DEVELOPER_PATH, stash)
!isEmpty(QMAKE_XCODE_VERSION): \
cache(QMAKE_XCODE_VERSION, stash)
QMAKE_XCODE_LIBRARY_SUFFIX = $$qtPlatformTargetSuffix()
xcode_product_bundle_identifier_setting.name = PRODUCT_BUNDLE_IDENTIFIER
xcode_product_bundle_identifier_setting.value = $$QMAKE_TARGET_BUNDLE_PREFIX
isEmpty(xcode_product_bundle_identifier_setting.value): \
xcode_product_bundle_identifier_setting.value = "com.yourcompany"
xcode_product_bundle_target = $$QMAKE_BUNDLE
isEmpty(xcode_product_bundle_target): \
xcode_product_bundle_target = ${PRODUCT_NAME:rfc1034identifier}
xcode_product_bundle_identifier_setting.value = "$${xcode_product_bundle_identifier_setting.value}.$${xcode_product_bundle_target}"
QMAKE_MAC_XCODE_SETTINGS += xcode_product_bundle_identifier_setting
!macx-xcode {
generate_xcode_project.commands = @$(QMAKE) -spec macx-xcode \"$(EXPORT__PRO_FILE_)\" $$QMAKE_ARGS
generate_xcode_project.target = xcodeproj
QMAKE_EXTRA_VARIABLES += _PRO_FILE_
QMAKE_EXTRA_TARGETS += generate_xcode_project
}

View File

@ -0,0 +1,60 @@
CONFIG = asset_catalogs rez $$CONFIG
load(default_pre)
isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
# Get path of Xcode's Developer directory
QMAKE_XCODE_DEVELOPER_PATH = $$system("/usr/bin/xcode-select --print-path 2>/dev/null")
isEmpty(QMAKE_XCODE_DEVELOPER_PATH): \
error("Xcode path is not set. Please use xcode-select to choose Xcode installation path.")
# Make sure Xcode path is valid
!exists($$QMAKE_XCODE_DEVELOPER_PATH): \
error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.")
}
isEmpty(QMAKE_XCODEBUILD_PATH): \
QMAKE_XCODEBUILD_PATH = $$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null")
!isEmpty(QMAKE_XCODEBUILD_PATH) {
# Make sure Xcode is set up properly
!system("/usr/bin/xcrun xcodebuild -license check 2>/dev/null"): \
error("Xcode not set up properly. You need to confirm the license agreement by running 'sudo xcrun xcodebuild -license accept'.")
isEmpty(QMAKE_XCODE_VERSION) {
# Extract Xcode version using xcodebuild
xcode_version = $$system("/usr/bin/xcrun xcodebuild -version")
QMAKE_XCODE_VERSION = $$member(xcode_version, 1)
isEmpty(QMAKE_XCODE_VERSION): error("Could not resolve Xcode version.")
unset(xcode_version)
}
}
isEmpty(QMAKE_TARGET_BUNDLE_PREFIX) {
QMAKE_XCODE_PREFERENCES_FILE = $$(HOME)/Library/Preferences/com.apple.dt.Xcode.plist
exists($$QMAKE_XCODE_PREFERENCES_FILE): \
QMAKE_TARGET_BUNDLE_PREFIX = $$system("/usr/libexec/PlistBuddy -c 'print IDETemplateOptions:bundleIdentifierPrefix' $$QMAKE_XCODE_PREFERENCES_FILE 2>/dev/null")
!isEmpty(_QMAKE_CACHE_):!isEmpty(QMAKE_TARGET_BUNDLE_PREFIX): \
cache(QMAKE_TARGET_BUNDLE_PREFIX)
}
QMAKE_ASSET_CATALOGS_APP_ICON = AppIcon
# Make the default debug info format for static debug builds
# DWARF instead of DWARF with dSYM. This cuts down build times
# for application debug builds significantly, as Xcode doesn't
# have to pull out all the DWARF info from the Qt static libs
# and put it into a dSYM file. We don't need that dSYM file in
# the first place, since the information is available in the
# object files inside the archives (static libraries).
macx-xcode:qtConfig(static): \
QMAKE_XCODE_DEBUG_INFORMATION_FORMAT = dwarf
# This variable is used by the xcode_dynamic_library_suffix
# feature, which allows Xcode to choose the Qt libraries to link to
# at build time, depending on the current Xcode SDK and configuration.
QMAKE_XCODE_LIBRARY_SUFFIX_SETTING = QT_LIBRARY_SUFFIX
xcode_copy_phase_strip_setting.name = COPY_PHASE_STRIP
xcode_copy_phase_strip_setting.value = NO
QMAKE_MAC_XCODE_SETTINGS += xcode_copy_phase_strip_setting

View File

@ -0,0 +1,18 @@
# Embed plist file via linker if we're not building a bundle
!isEmpty(QMAKE_INFO_PLIST) {
add_plist = false
equals(TEMPLATE, lib) {
plugin:!plugin_bundle: \
add_plist = true
else: !plugin:!lib_bundle: \
add_plist = true
} else: equals(TEMPLATE, app) {
!app_bundle: \
add_plist = true
}
$$add_plist: \
QMAKE_LFLAGS += -Wl,-sectcreate,__TEXT,__info_plist,$$shell_quote( \
$$relative_path($$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_), $$OUT_PWD))
}

View File

@ -0,0 +1,7 @@
# Prevent warnings about object files without any symbols. This is a common
# thing in Qt as we tend to build files unconditionally, and then use ifdefs
# to compile out parts that are not relevant.
QMAKE_RANLIB += -no_warning_for_no_symbols
# We have to tell 'ar' to not run ranlib by itself
QMAKE_AR += -S

View File

@ -0,0 +1,12 @@
# Objective-C/C++ sources go in SOURCES, like all other sources
SOURCES += $$OBJECTIVE_SOURCES
unset(OBJECTIVE_SOURCES)
# Strip C/C++ flags from QMAKE_OBJECTIVE_CFLAGS just in case
QMAKE_OBJECTIVE_CFLAGS -= $$QMAKE_CFLAGS $$QMAKE_CXXFLAGS
# Add Objective-C/C++ flags to C/C++ flags, the compiler can handle it
QMAKE_CFLAGS += $$QMAKE_OBJECTIVE_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_OBJECTIVE_CFLAGS
unset(QMAKE_OBJECTIVE_CFLAGS)

View File

@ -0,0 +1,16 @@
#global defaults
isEmpty(QMAKE_REZ) {
QMAKE_REZ = /Developer/Tools/Rez
}
isEmpty(REZ_DIR):REZ_DIR = .
isEmpty(QMAKE_EXT_REZ):QMAKE_EXT_REZ = .rsrc
rez_source.CONFIG += no_link
rez_source.dependency_type = TYPE_C
rez_source.commands = $$QMAKE_REZ ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} -useDF
rez_source.output = $$REZ_DIR/${QMAKE_FILE_BASE}$${first(QMAKE_EXT_REZ)}
rez_source.input = REZ_FILES
rez_source.name = REZ ${QMAKE_FILE_IN}
silent:rez_source.commands = @echo rez ${QMAKE_FILE_IN} && $$rez_source.commands
QMAKE_EXTRA_COMPILERS += rez_source

View File

@ -0,0 +1,27 @@
ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),)
CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>/dev/null
CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND))
ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION))
# We don't want to complain about out of date SDK unless the target needs to be remade.
# This covers use-cases such as running 'make check' after moving the build to a
# computer without Xcode or with a different Xcode version.
TARGET_UP_TO_DATE := $(shell QT_MAC_SDK_NO_VERSION_CHECK=1 $(MAKE) --question $(QMAKE_TARGET) && echo 1 || echo 0)
ifeq ($(TARGET_UP_TO_DATE),0)
ifneq ($(findstring missing DEVELOPER_DIR path,$(CURRENT_MAC_SDK_VERSION)),)
$(info The developer dir $(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) is no longer valid.)
else ifneq ($(findstring SDK "$(EXPORT_QMAKE_MAC_SDK)" cannot be located,$(CURRENT_MAC_SDK_VERSION)),)
$(info The developer dir $(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) no longer contains the $(EXPORT_QMAKE_MAC_SDK_VERSION) platform SDK.)
else ifneq ($(CURRENT_MAC_SDK_VERSION),)
$(info The $(EXPORT_QMAKE_MAC_SDK) platform SDK has been changed from version $(EXPORT_QMAKE_MAC_SDK_VERSION) to version $(CURRENT_MAC_SDK_VERSION).)
else
$(info Unknown error resolving current platform SDK version.)
endif
$(info This requires a fresh build of your project. Please wipe the build directory)
ifneq ($(EXPORT__QMAKE_STASH_),)
$(info including the qmake cache in $(EXPORT__QMAKE_STASH_))
endif
$(error ^)
endif
endif
endif

View File

@ -0,0 +1,61 @@
isEmpty(QMAKE_MAC_SDK): \
error("QMAKE_MAC_SDK must be set when using CONFIG += sdk.")
contains(QMAKE_MAC_SDK, .*/.*): \
error("QMAKE_MAC_SDK can only contain short-form SDK names (eg. macosx, iphoneos)")
defineReplace(xcodeSDKInfo) {
info = $$1
equals(info, "Path"): \
infoarg = --show-sdk-path
equals(info, "PlatformPath"): \
infoarg = --show-sdk-platform-path
equals(info, "SDKVersion"): \
infoarg = --show-sdk-version
sdk = $$2
isEmpty(sdk): \
sdk = $$QMAKE_MAC_SDK
isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) {
QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$infoarg 2>/dev/null")
# --show-sdk-platform-path won't work for Command Line Tools; this is fine
# only used by the XCTest backend to testlib
isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(infoarg, "--show-sdk-platform-path")): \
error("Could not resolve SDK $$info for \'$$sdk\' using $$infoarg")
cache(QMAKE_MAC_SDK.$${sdk}.$${info}, set stash, QMAKE_MAC_SDK.$${sdk}.$${info})
}
return($$eval(QMAKE_MAC_SDK.$${sdk}.$${info}))
}
QMAKE_MAC_SDK_PATH = $$xcodeSDKInfo(Path)
QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath)
QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion)
isEmpty(QMAKE_EXPORT_INCDIR_OPENGL) {
QMAKE_EXPORT_INCDIR_OPENGL = $$QMAKE_INCDIR_OPENGL
sysrootified =
for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val
QMAKE_INCDIR_OPENGL = $$sysrootified
}
QMAKESPEC_NAME = $$basename(QMAKESPEC)
# Resolve SDK version of various tools
for(tool, $$list(QMAKE_CC QMAKE_CXX QMAKE_FIX_RPATH QMAKE_AR QMAKE_RANLIB QMAKE_LINK QMAKE_LINK_SHLIB QMAKE_ACTOOL QMAKE_LINK_C QMAKE_LINK_C_SHLIB)) {
tool_variable = QMAKE_MAC_SDK.$${QMAKESPEC_NAME}.$${QMAKE_MAC_SDK}.$${tool}
!isEmpty($$tool_variable) {
$$tool = $$eval($$tool_variable)
next()
}
value = $$eval($$tool)
isEmpty(value): next()
sysrooted = $$system("/usr/bin/xcrun -sdk $$QMAKE_MAC_SDK -find $$first(value) 2>/dev/null")
isEmpty(sysrooted): next()
$$tool = $$sysrooted $$member(value, 1, -1)
cache($$tool_variable, set stash, $$tool)
}

View File

@ -0,0 +1,5 @@
# Ensure that we process sdk.prf first, as it will update QMAKE_CXX,
# which the default path determination uses.
sdk: load(sdk)
load(toolchain)

View File

@ -0,0 +1,50 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
# The Objective-C runtime will complain when loading a binary that
# introduces as class name that already exists in the global namespace.
# This may happen when linking Qt statically into a plugin, and then
# loading more than two plugins into the same host, both using Qt.
#
# We work around this by doing a bit of post-processing on the final
# binary, adding new suffixed class name entries to the __objc_classname
# section of the __TEXT segment, and then patching the class_ro_t
# entries to point to the newly added class names.
#
# By linking the binary between these two steps we avoid having to
# manually remap all the offsets in the Mach-O binary due to the
# added class names, instead relying on the linker to do this
# for us by linking in an assembly file with the added names.
objc_namespace_script = $$clean_path($$PWD/../../data/mac/objc_namespace.sh)
isEmpty(QMAKE_OBJC_NAMESPACE_SUFFIX) {
QMAKE_OBJC_NAMESPACE_SUFFIX = $$TARGET
!isEmpty(QMAKE_TARGET_BUNDLE_PREFIX): \
QMAKE_OBJC_NAMESPACE_SUFFIX = $${QMAKE_TARGET_BUNDLE_PREFIX}.$${QMAKE_OBJC_NAMESPACE_SUFFIX}
}
QMAKE_LFLAGS += \
-Wobjc_namespace,--target=$$shell_quote($$TARGET) \
-Wobjc_namespace,--suffix=$$shell_quote($$QMAKE_OBJC_NAMESPACE_SUFFIX) \
-Wobjc_namespace,--original_ld=$$shell_quote($$QMAKE_LINK)
!isEmpty(QMAKE_OBJC_NAMESPACE_EXCLUDE): \
QMAKE_LFLAGS += -Wobjc_namespace,--exclude_list=$$shell_quote($$QMAKE_OBJC_NAMESPACE_EXCLUDE)
!isEmpty(QMAKE_OBJC_NAMESPACE_EXCLUDE_REGEX) {
equals(MAKEFILE_GENERATOR, UNIX): \
QMAKE_OBJC_NAMESPACE_EXCLUDE_REGEX ~= s/\\$/\$\$/
QMAKE_LFLAGS += -Wobjc_namespace,--exclude_regex=$$shell_quote($$QMAKE_OBJC_NAMESPACE_EXCLUDE_REGEX)
}
slient: QMAKE_LFLAGS += -Wobjc_namespace,--silent=1
QMAKE_LINK = $$objc_namespace_script

View File

@ -0,0 +1,64 @@
qtPrepareLibExecTool(MOC_COLLECT_JSON, moc)
QMAKE_MOC_OPTIONS += --output-json
MOC_JSON_H_BASE = $${QMAKE_H_MOD_MOC}
MOC_JSON_CPP_BASE = $${QMAKE_CPP_MOD_MOC}
!isEmpty(MOC_DIR) {
MOC_JSON_H_BASE = $$MOC_DIR/$${MOC_JSON_H_BASE}
MOC_JSON_CPP_BASE = $$MOC_DIR/$${MOC_JSON_CPP_BASE}
}
moc_json_header.input = HEADERS
moc_json_header.output = $${MOC_JSON_H_BASE}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}.json
moc_json_header.CONFIG = no_link moc_verify
moc_json_header.depends = $${MOC_JSON_H_BASE}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}
moc_json_header.commands = $$escape_expand(\\n) # force creation of rule
moc_json_header.variable_out = MOC_JSON_FILES
moc_json_source.input = SOURCES
moc_json_source.output = $${MOC_JSON_CPP_BASE}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC}.json
moc_json_source.CONFIG = no_link moc_verify
moc_json_source.depends = $${MOC_JSON_CPP_BASE}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC}
moc_json_source.commands = $$escape_expand(\\n) # force creation of rule
moc_json_source.variable_out = MOC_JSON_FILES
# Add an empty JSON file so that the moc_collect_json rule is executed even if there are no files
# to run moc on.
!build_pass {
MOC_EMPTY_JSON = "[]"
MOC_EMPTY_JSON_FILE = $$OUT_PWD/$${MOC_JSON_H_BASE}$${first(QMAKE_EXT_CPP)}.json
write_file($${MOC_EMPTY_JSON_FILE}, MOC_EMPTY_JSON)
MOC_JSON_FILES += $${MOC_EMPTY_JSON_FILE}
}
TARGET_BASENAME = $$lower($$basename(TARGET))
TARGET_BASENAME ~= s/\s/_/g
MOC_COLLECT_JSON_OUTPUT = $${TARGET_BASENAME}_metatypes.json
moc_collect_json.CONFIG += no_link combine target_predeps
moc_collect_json.commands = $$MOC_COLLECT_JSON --collect-json -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
moc_collect_json.input = MOC_JSON_FILES
moc_collect_json.output = $$MOC_COLLECT_JSON_OUTPUT
moc_collect_json.name = Collect moc JSON output into central file
install_metatypes {
do_install_metatypes.CONFIG += no_check_exist
do_install_metatypes.path = $$[QT_INSTALL_ARCHDATA]/metatypes
do_install_metatypes.files = $$OUT_PWD/$$MOC_COLLECT_JSON_OUTPUT
prefix_build {
load(qt_build_paths)
!isEmpty(MODULE_BASE_OUTDIR) {
metatypes_to_builddir.files = $$do_install_metatypes.files
metatypes_to_builddir.path = $$MODULE_BASE_OUTDIR/lib/metatypes
COPIES += metatypes_to_builddir
}
INSTALLS += do_install_metatypes
} else {
COPIES += do_install_metatypes
}
}
QMAKE_EXTRA_COMPILERS += moc_collect_json moc_json_header moc_json_source

124
mkspecs/features/moc.prf Normal file
View File

@ -0,0 +1,124 @@
#global defaults
qtPrepareLibExecTool(QMAKE_MOC, moc)
isEmpty(MOC_DIR):MOC_DIR = .
isEmpty(QMAKE_H_MOD_MOC):QMAKE_H_MOD_MOC = moc_
isEmpty(QMAKE_EXT_CPP_MOC):QMAKE_EXT_CPP_MOC = .moc
MOC_INCLUDEPATH =
for (inc, INCLUDEPATH): \
MOC_INCLUDEPATH += $$absolute_path($$inc, $$_PRO_FILE_PWD_)
!no_include_pwd:!isEqual(OUT_PWD, $$_PRO_FILE_PWD_): \
MOC_INCLUDEPATH += .
MOC_INCLUDEPATH = $$QMAKESPEC $$_PRO_FILE_PWD_ $$MOC_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS
# On Windows, put the includes into a .inc file which moc will read, if the project
# has too many includes. We do this to overcome a command-line limit on Win < XP
WIN_INCLUDETEMP=
win32:count(MOC_INCLUDEPATH, 40, >) {
WIN_INCLUDETEMP = $$MOC_DIR/mocinclude.opt
WIN_INCLUDETEMP_CONT =
for (inc, MOC_INCLUDEPATH): \
WIN_INCLUDETEMP_CONT += -I$$inc
write_file($$absolute_path($$WIN_INCLUDETEMP, $$OUT_PWD), WIN_INCLUDETEMP_CONT)|error()
}
# QNX's compiler sets "gcc" config, but does not support the -dM option;
# UIKit builds are always multi-arch due to simulator_and_device (unless
# -sdk is used) so this feature cannot possibly work.
if(gcc|intel_icl|msvc):!rim_qcc:!uikit:!no_moc_predefs:if(!macos|count(QMAKE_APPLE_DEVICE_ARCHS, 1)) {
moc_predefs.name = "Generate moc_predefs.h"
moc_predefs.CONFIG = no_link
gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
else:msvc {
moc_predefs.commands += $$QMAKE_CXX -Bx$$shell_quote($$shell_path($$QMAKE_QMAKE)) $$QMAKE_CXXFLAGS \
-E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT}
} else: error("Oops, I messed up")
moc_predefs.output = $$MOC_DIR/moc_predefs.h
moc_predefs.input = MOC_PREDEF_FILE
silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\\n\\t)@$$moc_predefs.commands
QMAKE_EXTRA_COMPILERS += moc_predefs
MOC_PREDEF_FILE = $$[QT_HOST_DATA/src]/mkspecs/features/data/dummy.cpp
}
defineReplace(mocCmdBase) {
!isEmpty(WIN_INCLUDETEMP) {
incvar = @$$shell_quote($$WIN_INCLUDETEMP)
} else {
incvar =
for (inc, MOC_INCLUDEPATH): \
incvar += -I$$shell_quote($$inc)
incvar += $$QMAKE_FRAMEWORKPATH_FLAGS
}
RET = $$QMAKE_MOC $(DEFINES)
msvc: RET += --compiler-flavor=msvc
isEmpty(MOC_PREDEF_FILE): RET += $$join(QMAKE_COMPILER_DEFINES, " -D", -D)
else: RET += --include $$shell_quote($$absolute_path($$moc_predefs.output, $$OUT_PWD))
RET += $$incvar $$QMAKE_MOC_OPTIONS
return($$RET)
}
#moc headers
moc_header.CONFIG = moc_verify
moc_header.dependency_type = TYPE_C
moc_header.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}
moc_header.input = HEADERS
moc_header.variable_out = SOURCES
moc_header.name = MOC ${QMAKE_FILE_IN}
moc_header.depends += $$WIN_INCLUDETEMP $$moc_predefs.output
silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands
QMAKE_EXTRA_COMPILERS += moc_header
INCREDIBUILD_XGE += moc_header
#moc objc headers
moc_objc_header.CONFIG = moc_verify
moc_objc_header.dependency_type = TYPE_C
moc_objc_header.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
moc_objc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJCXX)}
moc_objc_header.input = OBJECTIVE_HEADERS
moc_objc_header.variable_out = SOURCES
moc_objc_header.name = MOC ${QMAKE_FILE_IN}
moc_objc_header.depends += $$WIN_INCLUDETEMP $$moc_predefs.output
silent:moc_objc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_objc_header.commands
QMAKE_EXTRA_COMPILERS += moc_objc_header
INCREDIBUILD_XGE += moc_objc_header
#moc sources
moc_sources = $$SOURCES
precompile_header: moc_sources += $$NO_PCH_SOURCES
moc_source.CONFIG = no_link moc_verify
moc_source.dependency_type = TYPE_C
moc_source.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC}
moc_source.input = moc_sources
moc_source.name = MOC ${QMAKE_FILE_IN}
moc_source.depends += $$WIN_INCLUDETEMP $$moc_predefs.output
silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands
QMAKE_EXTRA_COMPILERS += moc_source
INCREDIBUILD_XGE += moc_source
#make sure we can include these files
INCLUDEPATH += $$absolute_path($$MOC_DIR, $$OUT_PWD)
#auto depend on moc
!no_mocdepend {
moc_source.depends += $$QMAKE_MOC_EXE
moc_header.depends += $$QMAKE_MOC_EXE
moc_objc_header.depends += $$QMAKE_MOC_EXE
}
#generate a mocclean
build_pass|isEmpty(BUILDS):mocclean.depends = compiler_moc_header_clean compiler_moc_objc_header_clean compiler_moc_source_clean
else:mocclean.CONFIG += recursive
QMAKE_EXTRA_TARGETS += mocclean
#generate a mocables
build_pass|isEmpty(BUILDS):mocables.depends = compiler_moc_header_make_all compiler_moc_objc_header_make_all compiler_moc_source_make_all
else:mocables.CONFIG += recursive
QMAKE_EXTRA_TARGETS += mocables

View File

@ -0,0 +1,13 @@
msvc {
QMAKE_CFLAGS -= -Zi
QMAKE_CFLAGS_DEBUG -= -Zi
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO -= -Zi
QMAKE_CXXFLAGS -= -Zi
QMAKE_CXXFLAGS_DEBUG -= -Zi
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO -= -Zi
} else {
QMAKE_CFLAGS -= -g -ggdb3 -gstabs
QMAKE_CXXFLAGS -= -g -ggdb3 -gstabs
QMAKE_LFLAGS -= -g -ggdb3 -gstabs
QMAKE_LIBFLAGS -= -g -ggdb3 -gstabs
}

View File

@ -0,0 +1,40 @@
isEmpty(QMAKE_INFO_PLIST): \
return()
plist_path = $$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_)
!exists($$plist_path): \
return()
for(plugin, QT_PLUGINS) {
!equals(QT_PLUGIN.$${plugin}.TYPE, permissions): \
next()
usage_descriptions = $$eval(QT_PLUGIN.$${plugin}.usage_descriptions)
found_usage_description = false
for(usage_description_key, usage_descriptions) {
usage_description = $$system("/usr/libexec/PlistBuddy" \
"-c 'print $$usage_description_key' $$plist_path 2>/dev/null", \
singleLine, exit_code)
!equals(exit_code, 0): \
next()
!isEmpty(usage_description) {
found_usage_description = true
break()
}
}
!$$found_usage_description: \
next()
request_flag = $$eval(QT_PLUGIN.$${plugin}.request_flag)
QTPLUGIN += $$plugin
QMAKE_LFLAGS += $$request_flag
QMAKE_INTERNAL_INCLUDED_FILES *= $$QMAKE_INFO_PLIST
}

View File

@ -0,0 +1,2 @@
# Override mkspec default which creates a shared library
mac: QMAKE_LFLAGS_PLUGIN = -bundle

View File

@ -0,0 +1,24 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
#
# Set up extra compiler for PCH disabled sources
#
no_pch_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN}
msvc: no_pch_compiler.commands += -Fo${QMAKE_FILE_OUT}
else: no_pch_compiler.commands += -o ${QMAKE_FILE_OUT}
no_pch_compiler.dependency_type = TYPE_C
no_pch_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
no_pch_compiler.input = NO_PCH_SOURCES
no_pch_compiler.variable_out = OBJECTS
no_pch_compiler.name = compiling[no_pch] ${QMAKE_FILE_IN}
silent: no_pch_compiler.commands = @echo compiling[no_pch] ${QMAKE_FILE_IN} && $$no_pch_compiler.commands
QMAKE_EXTRA_COMPILERS += no_pch_compiler

View File

@ -0,0 +1,12 @@
qtPrepareTool(QMAKE_QGLTF, qgltf)
isEmpty(QGLTF_DIR): QGLTF_DIR = .
qgltf.input = QT3D_MODELS
qgltf.output = $$QGLTF_DIR/${QMAKE_FILE_BASE}.qrc
qgltf.variable_out += RESOURCES
qgltf.depends += $$QMAKE_QGLTF_EXE
qgltf.commands = $$QMAKE_QGLTF -d $$QGLTF_DIR $$QGLTF_PARAMS ${QMAKE_FILE_NAME}
silent: qgltf.commands = @echo qgltf ${QMAKE_FILE_IN} && $$qgltf.commands -s
qgltf.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += qgltf

View File

@ -0,0 +1,50 @@
qtPrepareLibExecTool(QMAKE_QLALR, qlalr)
isEmpty(QLALR_DIR): QLALR_DIR = .
!isEmpty(QLALRSOURCES) {
INCLUDEPATH += $$absolute_path($$QLALR_DIR, $$OUT_PWD)
}
for (s, QLALRSOURCES) {
sf = $$absolute_path($$s, $$_PRO_FILE_PWD_)
QMAKE_INTERNAL_INCLUDED_FILES += $$sf
sfl = $$cat($$sf, lines)
parser = $$lower($$member($$list($$find(sfl, "^%parser\\s")), 1))
isEmpty(parser): error("Could not extract %parser from $$sf")
decl = $$member($$list($$find(sfl, "^%decl\\s")), 1)
isEmpty(decl): error("Could not extract %decl from $$sf")
impl = $$member($$list($$find(sfl, "^%impl\\s")), 1)
isEmpty(impl): error("Could not extract %impl from $$sf")
base = qlalr_$$replace(sf, ^.*/([^./]+)[^/]*$, \\1)
invar = $$upper($$base)_SOURCES
$$invar = $$sf
$${base}.input = $$invar
$${base}.output = $$QLALR_DIR/$${parser}.cpp
$${base}.variable_out = GENERATED_SOURCES
$${base}.depends += $$QMAKE_QLALR_EXE
$${base}.commands = $$QMAKE_QLALR $$QMAKE_QLALRFLAGS ${QMAKE_FILE_IN}
silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $$eval($${base}.commands)
$${base}.name = QLALR ${QMAKE_FILE_IN}
$${base}_h.input = $$invar
$${base}_h.output = $$QLALR_DIR/$${parser}_p.h
$${base}_h.CONFIG = no_link
$${base}_h.depends += $$QLALR_DIR/$${parser}.cpp
$${base}_h.commands = $$escape_expand(\\n) # force creation of rule
$${base}_decl.input = $$invar
$${base}_decl.output = $$QLALR_DIR/$${decl}
$${base}_decl.CONFIG = no_link
$${base}_decl.depends += $$QLALR_DIR/$${parser}.cpp
$${base}_decl.commands = $$escape_expand(\\n) # force creation of rule
$${base}_impl.input = $$invar
$${base}_impl.output = $$QLALR_DIR/$${impl}
$${base}_impl.variable_out = GENERATED_SOURCES
$${base}_impl.depends += $$QLALR_DIR/$${parser}.cpp
$${base}_impl.commands = $$escape_expand(\\n) # force creation of rule
QMAKE_EXTRA_COMPILERS += $$base $${base}_h $${base}_decl $${base}_impl
}

View File

@ -0,0 +1,38 @@
suffix =
for(ever) {
CC_USES =
LD_USES =
for (use, QMAKE_USE$${suffix}) {
use = $$split(use, /)
name = $$take_first(use)
nu = $$upper($$replace(name, -, _))
!contains(use, linkonly): CC_USES += $$nu
!contains(use, nolink): LD_USES += $$nu
}
CC_USES = $$resolve_depends(CC_USES, QMAKE_DEPENDS_, _CC)
for (nu, CC_USES) {
!defined(QMAKE_LIBS_$$nu, var): \
error("Library '$$lower($$replace(nu, _, -))' is not defined.")
DEFINES += $$eval(QMAKE_DEFINES_$${nu})
INCLUDEPATH += $$eval(QMAKE_INCDIR_$${nu})
}
LD_USES = $$resolve_depends(LD_USES, QMAKE_DEPENDS_, _LD)
for (nu, LD_USES) {
!defined(QMAKE_LIBS_$$nu, var): \
error("Library '$$lower($$replace(nu, _, -))' is not defined.")
QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu)
android {
ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH})
isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu})
LIBS$${suffix} += $$ABI_LIBS
} else: debug: \
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu)
else: \
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_RELEASE) $$eval(QMAKE_LIBS_$$nu)
}
!isEmpty(suffix): break()
suffix = "_PRIVATE"
}

View File

@ -0,0 +1 @@
DEFINES += QT_QML_DEBUG

View File

@ -0,0 +1,84 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
equals(TEMPLATE, app): TEMPLATE = aux
isEmpty(TARGETPATH): error("Must set TARGETPATH (QML import name)")
!isEmpty(DYNAMIC_QMLDIR) {
qmldir_path = $$OUT_PWD
write_file($${qmldir_path}/qmldir, DYNAMIC_QMLDIR)|error("Aborting.")
} else {
qmldir_path = $$_PRO_FILE_PWD_
}
qmldir_file = $${qmldir_path}/qmldir
fq_qml_files =
for(qmlf, QML_FILES): fq_qml_files += $$absolute_path($$qmlf, $$_PRO_FILE_PWD_)
fq_aux_qml_files =
for(qmlf, AUX_QML_FILES): fq_aux_qml_files += $$absolute_path($$qmlf, $$_PRO_FILE_PWD_)
load(qt_build_paths)
DESTDIR = $$MODULE_BASE_OUTDIR/qml/$$TARGETPATH
static: \
CONFIG += builtin_resources
else: \
CONFIG += install_qml_files
builtin_resources {
URITARGET = $$replace(URI, "\\.", "_")
# In static builds, the QML engine reads also the qmldir file from the resources.
static: $${URITARGET}.files = $$qmldir_file
# Ensure the QML files are included in the resources.
$${URITARGET}.files += $$fq_qml_files
# qt-project.org/imports is the path used for locating imports inside the resources
$${URITARGET}.prefix = /qt-project.org/imports/$$TARGETPATH
RESOURCES += $${URITARGET}
}
# Install rules
qmldir.base = $$qmldir_path
qmldir.files = $$qmldir_file
qmldir.path = $$[QT_INSTALL_QML]/$$TARGETPATH
qmlfiles.base = $$_PRO_FILE_PWD_
qmlfiles.files = $$fq_aux_qml_files
install_qml_files: qmlfiles.files += $$fq_qml_files
qmlfiles.path = $${qmldir.path}
INSTALL_QML_FILES = false
android {
single_android_abi|build_pass {
isEmpty(ANDROID_ABIS): ANDROID_ABIS = $$ALL_ANDROID_ABIS
ABI = $$first(ANDROID_ABIS)
equals(ABI, $$QT_ARCH): INSTALL_QML_FILES = true
}
} else: !debug_and_release|!build_all|CONFIG(release, debug|release): INSTALL_QML_FILES = true
equals(INSTALL_QML_FILES, true) {
INSTALLS += qmldir
INSTALLS += qmlfiles
!prefix_build {
COPIES += qmldir qmlfiles
} else {
# For non-installed static builds, tools need qmldir and plugins.qmltypes
# files in the build dir
qml2build.files = $$qmldir_file $$fq_aux_qml_files
qml2build.path = $$DESTDIR
COPIES += qml2build
}
}

View File

@ -0,0 +1,119 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
load(qt_build_config)
TEMPLATE = lib
CONFIG += plugin
if(win32|mac):!macx-xcode {
qtConfig(debug_and_release): CONFIG += debug_and_release
qtConfig(build_all): CONFIG += build_all
}
CONFIG += relative_qt_rpath # Qt's QML plugins should be relocatable
# Qt libraries should only use Application Extension safe APIs
darwin:!no_app_extension_api_only: CONFIG += app_extension_api_only
!no_cxx_module:isEmpty(CXX_MODULE) {
CXX_MODULE = $$TARGET
TARGET = declarative_$${TARGET}
}
isEmpty(TARGETPATH): TARGETPATH = $$eval(QT.$${CXX_MODULE}.name)
win32:CONFIG(shared, static|shared) {
# Embed a VERSIONINFO resource into the plugin's DLL.
isEmpty(VERSION): VERSION = $$MODULE_VERSION
CONFIG += skip_target_version_ext
}
# Insert the plugins URI into its meta data to enable usage
# of static plugins in QtDeclarative:
URI = $$replace(TARGETPATH, "/", ".")
QMAKE_MOC_OPTIONS += -Muri=$$URI
QMLTYPEFILE = $$_PRO_FILE_PWD_/plugins.qmltypes
exists($$QMLTYPEFILE): AUX_QML_FILES += $$QMLTYPEFILE
# Install rules
load(qt_build_paths)
DESTDIR = $$MODULE_BASE_OUTDIR/qml/$$TARGETPATH
target.path = $$[QT_INSTALL_QML]/$$TARGETPATH
INSTALLS += target
# Some final setup
TARGET = $$qt5LibraryTarget($$TARGET, "qml/$$TARGETPATH/")
load(qt_targets)
load(qt_common)
# plugins.qmltypes is used by Qt Creator for syntax highlighting and the QML code model. It needs
# to be regenerated whenever the QML elements exported by the plugin change. This cannot be done
# automatically at compile time because qmlplugindump does not support some QML features and it may
# not be possible when cross-compiling.
#
# To regenerate run 'make qmltypes' which will update the plugins.qmltypes file in the source
# directory. Then review and commit the changes made to plugins.qmltypes.
#
# Due to the above mentioned drawbacks, there is a better mechanism available now: qmltyperegistrar
# can generate the .qmltypes files at compile time. It will do this when CONFIG += qmltypes is set.
# Therefore, don't try to generate the qmltypes files via qmlplugindump in that case.
!cross_compile:!qmltypes {
qmlplugindump = qmlplugindump
importpath.name = QML2_IMPORT_PATH
importpath.value =
for(qmod, QTREPOS) {
exists($$qmod/qml): importpath.value += $$shell_path($$qmod/qml)
}
importpath.value = $$unique(importpath.value)
QT_TOOL_ENV = importpath
qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump)
QT_TOOL_ENV =
# qtPrepareTool() must be called outside a build pass, as it protects
# against concurrent wrapper creation by omitting it during build passes.
# However, creating the actual targets is reserved to the build passes.
build_pass|!debug_and_release {
isEmpty(QML_IMPORT_VERSION):!isEmpty(IMPORT_VERSION): QML_IMPORT_VERSION = $$IMPORT_VERSION
isEmpty(QML_IMPORT_VERSION) {
no_cxx_module {
QML_IMPORT_VERSION = $$section(MODULE_VERSION, ., 0, 1)
isEmpty(QML_IMPORT_VERSION): error("Must set QML_IMPORT_VERSION")
} else {
QML_IMPORT_VERSION = $$section(QT.$${CXX_MODULE}.VERSION, ., 0, 1)
}
}
load(resolve_target)
isEmpty(IMPORT_NAME): IMPORT_NAME = $$replace(TARGETPATH, \\.\\d+\$, )
!qml1_target {
isEmpty(QMAKE_PLUGINDUMP_DEPENDENCIES_FILE):exists($$_PRO_FILE_PWD_/dependencies.json): \
QMAKE_PLUGINDUMP_DEPENDENCIES_FILE = $$_PRO_FILE_PWD_/dependencies.json
!isEmpty(QMAKE_PLUGINDUMP_DEPENDENCIES_FILE): \
QMAKE_QMLPLUGINDUMP_FLAGS += -dependencies $$shell_quote($$QMAKE_PLUGINDUMP_DEPENDENCIES_FILE)
}
qmltypes.target = qmltypes
qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$QMAKE_QMLPLUGINDUMP_FLAGS $$replace(IMPORT_NAME, /, .) $$QML_IMPORT_VERSION > $$QMLTYPEFILE
qmltypes.depends = $$QMAKE_RESOLVED_TARGET
} else {
qmltypes.CONFIG += recursive
}
QMAKE_EXTRA_TARGETS += qmltypes
}
load(qml_module)

View File

@ -0,0 +1,29 @@
!isEmpty(SOURCES) {
QT += qml qmltest
load(testcase)
!android {
contains(TEMPLATE, vc.*): DEFINES += QUICK_TEST_SOURCE_DIR=\"$$_PRO_FILE_PWD_\"
else: DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\"$$_PRO_FILE_PWD_\")
} else {
isEmpty(RESOURCES) {
ANDROID_EXTRA_PLUGINS *= $$_PRO_FILE_PWD_
DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\"assets:/$$basename(_PRO_FILE_PWD_)\")
} else {
DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\":/\")
}
}
} else {
# Allow a project to run tests without a CPP stub
TEMPLATE = aux
QMAKE_EXTRA_TARGETS += check
qtPrepareTool(QMAKE_QMLTESTRUNNER, qmltestrunner)
check.commands = $$QMAKE_QMLTESTRUNNER
}
# If the .pro file specified an IMPORTPATH, then add that to
# the command-line when the test is run.
!isEmpty(IMPORTPATH) {
for(import, IMPORTPATH): check.commands += -import \"$$import\"
}

390
mkspecs/features/qt.prf Normal file
View File

@ -0,0 +1,390 @@
# This avoids spurious errors when a project is explicitly disabled
# due to required Qt modules being missing.
!isEmpty(QMAKE_FAILED_REQUIREMENTS): return()
qtConfig(thread): CONFIG *= thread
#handle defines
win32 {
qtConfig(shared) {
# this variable is read by qmake in qmake/generators/win32/msvc_vcproj.cpp
# function VcprojGenerator::initDeploymentTool()
QMAKE_DLL_PATHS += $$[QT_INSTALL_BINS/get]
}
}
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG
no_keywords:DEFINES += QT_NO_KEYWORDS
plugin { #Qt plugins
static:DEFINES += QT_STATICPLUGIN
DEFINES += QT_PLUGIN
}
qtestlib {
warning("CONFIG+=qtestlib is deprecated. Use QT+=testlib instead.")
QT += testlib
}
qdbus {
warning("CONFIG+=qdbus is deprecated. Use QT+=dbus instead.")
QT += dbus
}
help {
warning("CONFIG+=help is deprecated. Use QT+=help instead.")
QT += help-private # sic!
}
designer {
warning("CONFIG+=designer is deprecated. Use QT+=designer instead.")
QT += designer
}
uitools {
warning("CONFIG+=uitools is deprecated. Use QT+=uitools instead.")
QT += uitools
}
qaxcontainer {
warning("CONFIG+=qaxcontainer is deprecated. Use QT+=axcontainer instead.")
QT += axcontainer
}
qaxserver {
warning("CONFIG+=qaxserver is deprecated. Use QT+=axserver instead.")
QT += axserver
}
!import_qpa_plugin {
warning("CONFIG-=import_qpa_plugin is deprecated. Use QTPLUGIN.platforms=- instead.")
QTPLUGIN.platforms = -
} else: qpa_minimal_plugin {
warning("CONFIG+=qpa_minimal_plugin is deprecated. Use QTPLUGIN.platforms=qminimal instead.")
QTPLUGIN.platforms = qminimal
}
!force_import_plugins:!contains(TEMPLATE, ".*app"):!if(contains(TEMPLATE, ".*lib"):dll): \
CONFIG -= import_plugins
unix {
contains(QT_CONFIG, no_direct_extern_access): CONFIG += no_direct_extern_access
else:contains(QT_CONFIG, reduce_relocations):!contains(TEMPLATE, .*lib): {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_PIC
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_PIC
}
}
# Will automatically add plugins, so run first
contains(QT_CONFIG, permissions): load(permissions)
# qmake variables cannot contain dashes, so normalize the names first
CLEAN_QT = $$replace(QT, -private$, _private)
CLEAN_QT_PRIVATE = $$replace(QT_PRIVATE, -private$, _private)
qt_module_deps = $$CLEAN_QT $$CLEAN_QT_PRIVATE
all_qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depends")
QTPLUGIN = $$unique($$list($$lower($$QTPLUGIN)))
# Sanitize requested plugins, and add any default plugins
import_plugins {
manualplugs = $$QTPLUGIN # User may specify plugins. Mostly legacy.
autoplugs = # Auto-added plugins.
# First round: explicitly specified modules.
all_plugin_deps = $$all_qt_module_deps
plugin_deps = $$all_plugin_deps
for(ever) {
# Automatically add the default plugins for the linked Qt modules.
for (qtmod, plugin_deps) {
for (ptype, QT.$${qtmod}.plugin_types) {
nptype = $$replace(ptype, [-/], _)
isEmpty(QTPLUGIN.$$nptype) {
for (plug, QT_PLUGINS) {
equals(QT_PLUGIN.$${plug}.TYPE, $$ptype) {
for (dep, QT_PLUGIN.$${plug}.EXTENDS) {
!contains(all_plugin_deps, $$dep) {
plug =
break()
}
}
autoplugs += $$plug
}
}
} else {
plug = $$eval(QTPLUGIN.$$nptype)
!equals(plug, -): \
autoplugs += $$plug
}
}
}
QTPLUGIN = $$manualplugs $$autoplugs
QTPLUGIN = $$unique(QTPLUGIN)
# Obtain the plugins' Qt dependencies ...
plugin_deps =
for (plug, QTPLUGIN): \
plugin_deps += $$eval(QT_PLUGIN.$${plug}.DEPENDS)
plugin_deps = $$resolve_depends(plugin_deps, "QT.", ".depends" ".run_depends")
plugin_deps -= $$all_plugin_deps
isEmpty(plugin_deps): \
break()
# ... and start over if any new Qt modules appeared,
# as these may want to load plugins in turn.
all_plugin_deps += $$plugin_deps
}
extraplugs = $$manualplugs
manualplugs -= $$autoplugs
extraplugs -= $$manualplugs
!isEmpty(extraplugs): \
warning("Redundant entries in QTPLUGIN: $$extraplugs")
}
# Link static plugins
!isEmpty(QTPLUGIN) {
for (plug, QTPLUGIN) {
module_config = $$eval(QT_PLUGIN.$${plug}.module_config)
isEmpty(module_config):!qtConfig(static): \
next() # Compatibility with older modules
!contains(module_config, staticlib): \
next()
plug_class = $$eval(QT_PLUGIN.$${plug}.CLASS_NAME)
!isEmpty(plug_class): \
IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$plug_class)"
else: \
warning("Plugin class name could not be determined for plugin '$$plug'.")
plugin_deps = $$eval(QT_PLUGIN.$${plug}.DEPENDS)
plugin_deps = $$resolve_depends(plugin_deps, "QT.", ".depends" ".run_depends")
all_qt_module_deps *= $$plugin_deps
# Check if the plugin is known to Qt. We can use this to determine
# the plugin path. Unknown plugins must rely on the default link path.
plug_type = $$eval(QT_PLUGIN.$${plug}.TYPE)
!isEmpty(plug_type) {
# Respect target config if Qt provides both debug and release versions
# of each plugin. Otherwise, respect what Qt was configured with.
qtConfig(debug_and_release): config_variable = CONFIG
else: config_variable = QT_CONFIG
plug_name = $$QMAKE_PREFIX_STATICLIB$${plug}$$qtPlatformTargetSuffix($$config_variable).$$QMAKE_EXTENSION_STATICLIB
plug_path = $$eval(QT_PLUGIN.$${plug}.PATH)
isEmpty(plug_path): \
plug_path = $$[QT_INSTALL_PLUGINS/get]
LIBS += $$plug_path/$$plug_type/$$plug_name
} else {
LIBS += -l$${plug}$$qtPlatformTargetSuffix(CONFIG)
}
}
!isEmpty(IMPORT_FILE_CONT) {
IMPORT_FILE_CONT = \
"// This file is autogenerated by qmake. It imports static plugin classes for" \
"// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS.<plugin> variables." \
"$${LITERAL_HASH}include <QtPlugin>" \
"$$IMPORT_FILE_CONT"
TARGET_BASENAME = $$lower($$basename(TARGET))
TARGET_BASENAME ~= s/\s/_/g
IMPORT_CPP = $$OUT_PWD/$${TARGET_BASENAME}_plugin_import.cpp
write_file($$IMPORT_CPP, IMPORT_FILE_CONT)|error()
GENERATED_SOURCES += $$IMPORT_CPP
QMAKE_DISTCLEAN += $$IMPORT_CPP
}
}
# target variable, flag source variable
defineTest(qtProcessModuleFlags) {
for(flag, $$2) {
contains(flag, ^-.*): \
$$1 -= $$replace(flag, ^-, )
else: \
$$1 += $$flag
}
export($$1)
}
unset(using_private_headers)
var_sfx =
for(ever) {
# Topological resolution of modules based on their QT.<module>.depends variable
FULL_QT$$var_sfx = $$resolve_depends(CLEAN_QT$$var_sfx, "QT.")
# Finally actually add the modules
unset(BAD_QT)
for(QTLIB, FULL_QT$$var_sfx) {
MODULE_NAME = $$eval(QT.$${QTLIB}.name)
MODULE_MODULE = $$eval(QT.$${QTLIB}.module)
MODULE_INCLUDES = $$eval(QT.$${QTLIB}.includes)
MODULE_LDFLAGS = $$eval(QT.$${QTLIB}.ldflags)
MODULE_LIBS = $$eval(QT.$${QTLIB}.libs)
MODULE_FRAMEWORKS = $$eval(QT.$${QTLIB}.frameworks)
MODULE_USES = $$eval(QT.$${QTLIB}.uses)
MODULE_CONFIG = $$eval(QT.$${QTLIB}.module_config)
isEmpty(MODULE_NAME) {
BAD_QT += $$QTLIB
next()
}
contains(MODULE_CONFIG, internal_module):!isEmpty(MODULE_INCLUDES): \
using_private_headers = true
contains(MODULE_CONFIG, ltcg): \
CONFIG += link_ltcg
qtProcessModuleFlags(CONFIG, QT.$${QTLIB}.CONFIG)
qtProcessModuleFlags(DEFINES, QT.$${QTLIB}.DEFINES)
MODULE_INCLUDES -= $$QMAKE_DEFAULT_INCDIRS
# Add linker flags before lib
LIBS$$var_sfx += $$MODULE_LDFLAGS
# Frameworks shouldn't need include paths, but much code does not use
# module-qualified #includes, so by default we add paths which point
# directly into the frameworks. Private modules have somewhat convoluted
# header paths, so adding them is necessary in every case.
!if(contains(MODULE_CONFIG, lib_bundle):qt_no_framework_direct_includes) \
|contains(MODULE_CONFIG, internal_module): \
INCLUDEPATH *= $$MODULE_INCLUDES
QMAKE_FRAMEWORKPATH *= $$MODULE_FRAMEWORKS
!isEmpty(MODULE_MODULE) {
contains(MODULE_CONFIG, lib_bundle) {
framework = $$MODULE_MODULE
# Linking frameworks by absolute path does not work.
LIBS$$var_sfx += -framework $$framework
} else {
lib_bases = $$MODULE_MODULE$$qtPlatformTargetSuffix()
darwin: lib_bases *= $$MODULE_MODULE
win32|contains(MODULE_CONFIG, staticlib) {
lib_prefix = $$MODULE_LIBS/$$QMAKE_PREFIX_STATICLIB
lib_suffixes = $$QMAKE_EXTENSION_STATICLIB
lib_suffixes *= $$QMAKE_LIB_EXTENSIONS
add_lib_to_pretargetdeps = true
} else {
lib_prefix = $$MODULE_LIBS/$$QMAKE_PREFIX_SHLIB
lib_suffixes = $$QMAKE_EXTENSION_SHLIB
add_lib_to_pretargetdeps = false
}
candidates =
for(lib_base, lib_bases) {
for(lib_suffix, lib_suffixes) {
candidates += $${lib_prefix}$${lib_base}.$${lib_suffix}
}
}
lib =
for(candidate, candidates) {
exists("$$candidate") {
lib = "$$candidate"
break()
}
}
isEmpty(lib): \
lib = $$first(candidates)
$$add_lib_to_pretargetdeps: \
PRE_TARGETDEPS += $$lib
LIBS$$var_sfx += $$lib
}
}
QMAKE_USE$$var_sfx += $$MODULE_USES
}
!isEmpty(BAD_QT):error("Unknown module(s) in QT$$var_sfx: $$replace(BAD_QT, _private$, -private)")
!isEmpty(var_sfx): break()
var_sfx = _PRIVATE
}
!isEmpty(using_private_headers):!no_private_qt_headers_warning:!build_pass {
message("This project is using private headers and will therefore be tied to this specific Qt module build version.")
message("Running this project against other versions of the Qt modules may crash at any arbitrary point.")
message("This is not a bug, but a result of using Qt internals. You have been warned!")
}
!no_qt_rpath:!static:qtConfig(rpath):!qtConfig(static):\
contains(all_qt_module_deps, core) {
relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\
isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) {
# NOT the /dev property, as INSTALLS use host paths
QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase())
} else {
QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev]
}
}
!isEmpty(QMAKE_LFLAGS_RPATHLINK):!qtConfig(static) {
# -rpath-link is used by the linker to find dependencies of dynamic
# libraries which were NOT specified on the command line.
# This means that paths of direct dependencies (QT & QT_PRIVATE)
# don't need to be listed, unlike their private dependencies' paths.
privdep = $$all_qt_module_deps
privdep -= $$resolve_depends(qt_module_deps, "QT.")
rpaths =
for(dep, privdep): \
rpaths += $$eval(QT.$${dep}.libs)
QMAKE_RPATHLINKDIR *= $$unique(rpaths)
}
# static builds: link qml import plugins into the target.
contains(all_qt_module_deps, qml): \
qtConfig(static):import_plugins:!host_build:!no_import_scan {
exists($$[QT_INSTALL_QML/get]): \
QMLPATHS *= $$[QT_INSTALL_QML/get]
# run qmlimportscanner
qtPrepareLibExecTool(QMLIMPORTSCANNER, qmlimportscanner, , system)
for (QMLPATH, QMLPATHS): \
IMPORTPATHS += -importPath $$system_quote($$QMLPATH)
# add resources to qmlimportscanner
for (RESOURCE, RESOURCES) {
defined($${RESOURCE}.files, var) {
# in case of a "struct", add the struct's files
base = $$RESOURCE.base
for (f, $$RESOURCE.files): SCANNERRESOURCES += "$$base/$$f"
} else {
# if the resource is a file, just add it
SCANNERRESOURCES += $$RESOURCE
}
}
!isEmpty(SCANNERRESOURCES) {
IMPORTPATHS += -qrcFiles
for (RESOURCE, SCANNERRESOURCES): \
IMPORTPATHS += $$absolute_path($$system_quote($$RESOURCE), $$_PRO_FILE_PWD_)
}
# message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS)
JSON = $$system($$QMLIMPORTSCANNER $$system_quote($$_PRO_FILE_PWD_) $$IMPORTPATHS)
parseJson(JSON, IMPORTS)| error("Failed to parse qmlimportscanner output.")
!isEmpty(IMPORTS._KEYS_) {
# add import plugins to LIBS line
for (key, IMPORTS._KEYS_) {
PATH = $$eval(IMPORTS.$${key}.path)
PLUGIN = $$eval(IMPORTS.$${key}.plugin)
!isEmpty(PATH):!isEmpty(PLUGIN): \
LIBS += $$PATH/$$QMAKE_PREFIX_STATICLIB$${PLUGIN}$$qtPlatformTargetSuffix().$$QMAKE_EXTENSION_STATICLIB
}
# create qml_plugin_import.cpp
IMPORT_FILE_CONT = \
"// This file is autogenerated by qmake. It imports static plugin classes for" \
"// static plugins used by QML imports." \
"$${LITERAL_HASH}include <QtPlugin>"
for (key, IMPORTS._KEYS_) {
PLUGIN = $$eval(IMPORTS.$${key}.plugin)
CLASSNAME = $$eval(IMPORTS.$${key}.classname)
!isEmpty(PLUGIN) {
!isEmpty(CLASSNAME) {
!contains(ADDED_IMPORTS, $$PLUGIN) {
ADDED_IMPORTS += $$PLUGIN
IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$CLASSNAME)"
}
} else {
error("Plugin $$PLUGIN is missing a classname entry, please add one to the qmldir file.")
}
}
}
TARGET_BASENAME = $$lower($$basename(TARGET))
TARGET_BASENAME ~= s/\s/_/g
QML_IMPORT_CPP = $$OUT_PWD/$${TARGET_BASENAME}_qml_plugin_import.cpp
write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error()
GENERATED_SOURCES += $$QML_IMPORT_CPP
QMAKE_DISTCLEAN += $$QML_IMPORT_CPP
}
}

View File

@ -0,0 +1,43 @@
# This file is loaded as one of the last things by all qmakespecs.
QMAKE_QT_CONFIG = $$[QT_HOST_DATA/get]/mkspecs/qconfig.pri
!exists($$QMAKE_QT_CONFIG)|!include($$QMAKE_QT_CONFIG, "", true) {
debug(1, "Cannot load qconfig.pri!")
} else {
debug(1, "Loaded .qconfig.pri from ($$QMAKE_QT_CONFIG)")
dirs = $$(QMAKEMODULES)
QMAKE_MODULE_PATH = $$split(dirs, $$DIRLIST_SEPARATOR)
QMAKE_MODULE_PATH += $$QMAKEMODULES
dirs = $$[QMAKEMODULES]
QMAKE_MODULE_PATH += $$split(dirs, $$DIRLIST_SEPARATOR)
dirs = $$[QMAKE_MKSPECS]
dirs = $$split(dirs, $$DIRLIST_SEPARATOR)
QMAKE_MODULE_PATH += $$replace(dirs, \$, /modules)
unset(dirs)
QMAKE_MODULE_PATH = $$unique(QMAKE_MODULE_PATH)
QMAKE_MODULE_PATH = $$reverse(QMAKE_MODULE_PATH)
for(dir, QMAKE_MODULE_PATH) {
debug(1, "Loading modules from $${dir}")
mods = $$files($$dir/qt_*.pri)
for (mod, mods) {
# For installed Qt these paths will be common for all modules.
# For uninstalled prefix builds these will vary per module, via the
# forwarding module pri files. Keep qt_module_pris.prf in sync with this!
QT_MODULE_INCLUDE_BASE = $$[QT_INSTALL_HEADERS]
QT_MODULE_LIB_BASE = $$[QT_INSTALL_LIBS]
QT_MODULE_HOST_LIB_BASE = $$[QT_HOST_LIBS]
QT_MODULE_HOST_LIBEXEC_BASE = $$[QT_HOST_LIBEXECS]
QT_MODULE_BIN_BASE = $$[QT_INSTALL_BINS]
include($$mod)
}
unset(mods)
}
QT_MODULES = $$unique(QT_MODULES) # In case modules appear in multiple places
unset(QT_MODULE_INCLUDE_BASE)
unset(QT_MODULE_LIB_BASE)
unset(QT_MODULE_HOST_LIB_BASE)
unset(QT_MODULE_HOST_LIBEXEC_BASE)
unset(QT_MODULE_BIN_BASE)
}
load(qt_functions)

View File

@ -0,0 +1,395 @@
defineReplace(qtPlatformTargetSuffix) {
config_variable = $$1
isEmpty(config_variable): \
config_variable = CONFIG
suffix =
android: return($${suffix}_$${QT_ARCH})
win32 {
contains($$config_variable, debug, debug|release) {
mingw {
qtConfig(debug_and_release):build_pass: \
return($${suffix}d)
} else {
!debug_and_release|build_pass: \
return($${suffix}d)
}
}
}
darwin {
contains($$config_variable, debug, debug|release) {
!debug_and_release|build_pass: \
return($${suffix}_debug)
}
}
return($$suffix)
}
defineReplace(qtLibraryTarget) {
LIBRARY_NAME = $$1
CONFIG(shared, static|shared):qtConfig(framework) {
QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME
export(QMAKE_FRAMEWORK_BUNDLE_NAME)
}
return($$LIBRARY_NAME$$qtPlatformTargetSuffix())
}
defineReplace(qt5LibraryTarget) {
android {
LIBRARY_NAME_PREFIX = $$2
LIBRARY_NAME_PREFIX = $$replace(LIBRARY_NAME_PREFIX, "//", "/")
LIBRARY_NAME_PREFIX = $$replace(LIBRARY_NAME_PREFIX, "/", "_")
LIBRARY_NAME = $$LIBRARY_NAME_PREFIX$$qtLibraryTarget($$1)
unset(LIBRARY_NAME_PREFIX)
} else: LIBRARY_NAME = $$qtLibraryTarget($$1)
isEmpty(QMAKE_FRAMEWORK_BUNDLE_NAME) {
# Insert the major version of Qt in the library name
# unless it's a framework build.
LIBRARY_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
}
return($$LIBRARY_NAME)
}
defineReplace(qtRelativeRPathBase) {
darwin {
if(equals(TEMPLATE, app):app_bundle)|\
if(equals(TEMPLATE, lib):plugin:plugin_bundle) {
shallow_bundle: return($$target.path/$${TARGET}.app)
return($$target.path/$${TARGET}.app/Contents/MacOS)
}
equals(TEMPLATE, lib):!plugin:lib_bundle {
shallow_bundle: return($$target.path/$${TARGET}.framework)
return($$target.path/$${TARGET}.framework/Versions/Current)
}
}
return($$target.path)
}
defineTest(qtAddLibrary) {
warning("qtAddLibrary() is deprecated. Use QT+= instead.")
# Reverse-engineer the module name from the library name.
for(var, QT_MODULES) {
isEqual(QT.$${var}.name, $$1) {
QT += $$var
export(QT)
return(true)
}
}
error("No module matching library '$$1' found.")
}
# qt module
defineTest(qtHaveModule) {
!isEmpty(QT.$$replace(1, -, _).name): \
return(true)
return(false)
}
# Arguments:
# variable, default, [suffix for variable for system() use],
# [prepare primary variable for system() use],
# [installation location; default: $$[QT_HOST_BINS]]
defineTest(qtPrepareTool) {
cmd = $$eval(QT_TOOL.$${2}.binary)
isEmpty(cmd) {
isEmpty(5) {
instloc = $$[QT_HOST_BINS]
} else {
instloc = $$5
}
cmd = $$instloc/$$2
exists($${cmd}.pl) {
$${1}_EXE = $${cmd}.pl
cmd = perl -w $$system_path($${cmd}.pl)
} else: contains(QMAKE_HOST.os, Windows) {
$${1}_EXE = $${cmd}.exe
cmd = $$system_path($${cmd}.exe)
} else:contains(QMAKE_HOST.os, Darwin) {
BUNDLENAME = $${cmd}.app/Contents/MacOS/$$2
exists($$BUNDLENAME) {
cmd = $$BUNDLENAME
}
$${1}_EXE = $$cmd
} else {
$${1}_EXE = $$cmd
}
} else {
$${1}_EXE = $$last(cmd)
}
export($${1}_EXE)
QT_TOOL_ENV += $$eval(QT_TOOL.$${2}.envvars)
QT_TOOL_NAME = $$2
!isEmpty(3)|!isEmpty(4) {
$$1$$3 =
for (arg, cmd): \
$$1$$3 += $$system_quote($$arg)
qtAddTargetEnv($$1$$3, QT_TOOL.$${2}.depends, system)
}
isEmpty(4) {
$$1 =
for (arg, cmd): \
$$1 += $$shell_quote($$arg)
qtAddTargetEnv($$1, QT_TOOL.$${2}.depends, )
}
}
# Prepare a tool that's not supposed to be called manually by users but by the build system.
#
# Forwards its arguments to qtPrepareTool but defaults the installation location to
# $$[QT_HOST_LIBEXECS]
defineTest(qtPrepareLibExecTool) {
isEmpty(instloc): instloc = "$$[QT_HOST_LIBEXECS]"
qtPrepareTool($$1, $$2, $$3, $$4, $$instloc)
}
# target variable, list of env var names, [non-empty: prepare for system(), not make]
defineTest(qtAddToolEnv) {
isEmpty(3): \
ds = $$QMAKE_DIR_SEP
else: \
ds = $$DIR_SEPARATOR
batch_sets =
for(env, 2) {
value = $$eval($${env}.value)
!isEmpty(value) {
name = $$eval($${env}.name)
config = $$eval($${env}.CONFIG)
equals(ds, /) {
contains(config, prepend): infix = \${$$name:+:\$$$name}
else: contains(config, always_prepend): infix = :\$$$name
else: infix =
# Under msys, this path is taken only in the non-system()
# case, so using shell_quote() always works.
batch_sets += \
"$$name=$$shell_quote($$join(value, :))$$infix" \
"export $$name"
} else {
value ~= s,\\^,^^^^,g
value ~= s,!,^^!,g
value ~= s,\\),^),g
contains(config, prepend) {
batch_sets += \
"if defined $$name (" \
" set $$name=$$join(value, ;);!$$name!" \
") else (" \
" set $$name=$$join(value, ;)" \
")"
} else: contains(config, always_prepend) {
batch_sets += "(set $$name=$$join(value, ;);!$$name!)"
} else {
batch_sets += "(set $$name=$$join(value, ;))"
}
}
}
}
!isEmpty(batch_sets) {
batch_name = wrapper
!isEmpty(QT_TOOL_NAME): batch_name = $${QT_TOOL_NAME}_wrapper
cmd = $$eval($$1)
!isEmpty(cmd): cmd = "$$cmd "
equals(ds, /) {
batch_name = $${batch_name}.sh
equals(QMAKE_HOST.os, Darwin):exists(/bin/bash): \
shell = /bin/bash
else: \
shell = /bin/sh
batch_cont = \
"$$LITERAL_HASH!$$shell" \
$$batch_sets \
"exec $$cmd\"$@\""
# It would be nicer to use the '.' command (without 'exec' above),
# but that doesn't set the positional arguments under (d)ash.
$$1 =
} else {
batch_name = $${batch_name}.bat
batch_cont = \
"@echo off" \
"SetLocal EnableDelayedExpansion" \
$$batch_sets \
"$$cmd%*" \
"EndLocal"
$$1 = call
}
!build_pass:!write_file($$OUT_PWD/$$batch_name, batch_cont, exe): error()
isEmpty(3): \
$$1 += $$shell_quote($$shell_path($$OUT_PWD/$$batch_name))
else: \
$$1 += $$system_quote($$system_path($$OUT_PWD/$$batch_name))
QMAKE_DISTCLEAN += $$OUT_PWD/$$batch_name
}
export($$1)
export(QMAKE_DISTCLEAN)
}
# target variable, dependency var name, [non-empty: prepare for system(), not make]
defineTest(qtAddTargetEnv) {
deps = $$replace($$2, -private$, _private)
deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends")
!isEmpty(deps) {
libs = libs
deppath.CONFIG = prepend
equals(QMAKE_HOST.os, Windows) {
libs = bins
deppath.CONFIG = always_prepend
deppath.name = PATH
} else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) {
deppath.name = LD_LIBRARY_PATH
} else:contains(QMAKE_HOST.os, Haiku) {
deppath.name = LIBRARY_PATH
} else:equals(QMAKE_HOST.os, Darwin) {
qtConfig(framework): \
deppath.name = DYLD_FRAMEWORK_PATH
else: \
deppath.name = DYLD_LIBRARY_PATH
} else:equals(QMAKE_HOST.os, AIX) {
deppath.name = LIBPATH
} else {
error("Operating system not supported.")
}
ptypes =
for(dep, deps) {
isEmpty(3): \
deppath += $$shell_path($$eval(QT.$${dep}.$$libs))
else: \
deppath += $$system_path($$eval(QT.$${dep}.$$libs))
ptypes += $$eval(QT.$${dep}.plugin_types)
}
deppath.value = $$unique(deppath)
pluginpath.value =
ppaths = $$[QT_INSTALL_PLUGINS/get]
for(qplug, QT_PLUGINS): \
contains(ptypes, $$eval(QT_PLUGIN.$${qplug}.TYPE)): \
ppaths += $$eval(QT_PLUGIN.$${qplug}.PATH)
ppaths = $$unique(ppaths)
for(qplug, ppaths) {
isEmpty(3): \
pluginpath.value += $$shell_path($$qplug)
else: \
pluginpath.value += $$system_path($$qplug)
}
pluginpath.name = QT_PLUGIN_PATH
pluginpath.CONFIG = prepend
QT_TOOL_ENV += deppath pluginpath
}
qtAddToolEnv($$1, $$QT_TOOL_ENV, $$3)
}
defineReplace(pkgConfigExecutable) {
isEmpty(PKG_CONFIG) {
!isEmpty(QMAKE_PKG_CONFIG) {
# Assumed to be properly sysrootified.
PKG_CONFIG = $$QMAKE_PKG_CONFIG
export(PKG_CONFIG)
} else {
PKG_CONFIG = pkg-config
!cross_compile {
export(PKG_CONFIG)
} else {
# Cross compiling, ensure that pkg-config is set up sanely.
sysroot = $$[QT_SYSROOT]
pkgConfigLibdir = $$(PKG_CONFIG_LIBDIR)
isEmpty(pkgConfigLibdir) {
isEmpty(sysroot) {
warning("Cross compiling without sysroot. Disabling pkg-config.")
return()
}
!exists("$$sysroot/usr/lib/pkgconfig") {
warning("Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and the")
warning("host's .pc files would be used (even if you set PKG_CONFIG_PATH).")
warning("Set this variable to the directory that contains target .pc files")
warning("for pkg-config to function correctly when cross-compiling.")
return()
}
pkgConfigLibdir = $$system_path($$sysroot/usr/lib/pkgconfig)$$QMAKE_DIRLIST_SEP$$system_path($$sysroot/usr/share/pkgconfig)
!isEmpty(GCC_MACHINE_DUMP): \
pkgConfigLibdir = "$$pkgConfigLibdir$$QMAKE_DIRLIST_SEP$$system_path($$sysroot/usr/lib/$$GCC_MACHINE_DUMP/pkgconfig)"
message("PKG_CONFIG_LIBDIR automatically set to $$pkgConfigLibdir")
}
pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR)
isEmpty(pkgConfigSysrootDir) {
isEmpty(sysroot) {
warning("Disabling pkg-config since PKG_CONFIG_SYSROOT_DIR is not set.")
warning("Set this variable to your sysroot for pkg-config to function")
warning("correctly when cross-compiling.")
return()
}
pkgConfigSysrootDir = $$sysroot
message("PKG_CONFIG_SYSROOT_DIR automatically set to $$pkgConfigSysrootDir")
}
sysroot.name = PKG_CONFIG_SYSROOT_DIR
sysroot.value = $$pkgConfigSysrootDir
libdir.name = PKG_CONFIG_LIBDIR
libdir.value = $$pkgConfigLibdir
QT_TOOL_NAME = pkg-config
qtAddToolEnv(PKG_CONFIG, sysroot libdir, SYS)
}
}
}
PKG_CONFIG += 2> $$QMAKE_SYSTEM_NULL_DEVICE
return($$PKG_CONFIG)
}
defineTest(packagesExist) {
# this can't be done in global scope here because qt_functions is loaded
# before the .pro is parsed, so if the .pro set PKG_CONFIG, we wouldn't know it
# yet. oops.
pkg_config = $$pkgConfigExecutable()
for(package, ARGS) {
!system($$pkg_config --exists $$package):return(false)
}
return(true)
}
# Prepares target that will iterate through all subdirs (except those
# with no_default_target or no_{name_of_target}_target. The prepared
# target must still be manually added to QMAKE_EXTRA_TARGETS.
defineTest(prepareRecursiveTarget) {
target = $$1
no_$${target}_target: return()
for(subdir, SUBDIRS) {
subdir_config = $$eval($${subdir}.CONFIG)
contains(subdir_config, no_default_target): next()
contains(subdir_config, no_$${target}_target): next()
$${target}.recurse += $$subdir
}
# Set up the recurse target only when there
# is something to recurse into.
isEmpty($${target}.recurse): return()
$${target}.CONFIG = recursive
$${target}.recurse_target = $${target}
export($${target}.recurse)
export($${target}.CONFIG)
export($${target}.recurse_target)
}
defineTest(qtConfig) {
modules = $$QT $$QT_PRIVATE $$QT_FOR_CONFIG
modules ~= s,-private$,_private,g
modules = $$resolve_depends(modules, "QT.", ".depends")
modules += global global_private
modules = $$reverse(modules)
for (module, modules) {
contains(QT.$${module}.enabled_features, $$1): \
return(true)
contains(QT.$${module}.disabled_features, $$1): \
return(false)
}
error("Could not find feature $${1}.")
}

View File

@ -0,0 +1,59 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
staticlib: \
CONFIG += static
else: dll: \
CONFIG += shared
CONFIG(static, static|shared) {
CONFIG -= shared dll
contains(TEMPLATE, ".*lib"): CONFIG += staticlib
} else {
CONFIG -= static staticlib
contains(TEMPLATE, ".*lib"): CONFIG += dll
}
!macx-xcode: \
addExclusiveBuilds(shared, static)
CONFIG(debug, debug|release) {
CONFIG -= release
!force_debug_plist:debug_and_release: \
CONFIG += no_plist
} else {
CONFIG -= debug
}
!macx-xcode {
addExclusiveBuilds(debug, release)
} else {
# The Xcode generator always generates project files with
# debug and release configurations, regardless of whether
# or not debug_and_release is active.
for(build, $$list(debug release)) {
suffix =
qtConfig(debug_and_release) {
equals(build, debug): \
suffix = _debug
} else {
contains(QT_CONFIG, debug): \
suffix = _debug
}
library_suffix_$${build}.name = $$QMAKE_XCODE_LIBRARY_SUFFIX_SETTING
library_suffix_$${build}.value = $$suffix
library_suffix_$${build}.build = $$build
QMAKE_MAC_XCODE_SETTINGS += library_suffix_$${build}
CONFIG *= xcode_dynamic_library_suffix
}
}

View File

@ -0,0 +1,111 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
load(resolve_config)
exclusive_builds: load(exclusive_builds_post)
QMAKE_RESOLVED_TARGET = $$absolute_path($$DESTDIR, $$OUT_PWD)/
win32 {
contains(TEMPLATE, .*lib) {
!skip_target_version_ext:isEmpty(TARGET_VERSION_EXT):!isEmpty(VERSION) {
TARGET_VERSION_EXT = $$section(VERSION, ., 0, 0)
}
static:TARGET_EXT = .lib
else:TARGET_EXT = .dll
} else {
TARGET_EXT = .exe
}
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${TARGET}$${TARGET_VERSION_EXT}$${TARGET_EXT}
} else {
contains(TEMPLATE, .*lib):!if(plugin:no_plugin_name_prefix): LIBPREFIX = lib
mac {
equals(TEMPLATE, lib) {
plugin:plugin_bundle {
!isEmpty(QMAKE_PLUGIN_BUNDLE_NAME): \
plugin_target = $$QMAKE_PLUGIN_BUNDLE_NAME
else: \
plugin_target = $$TARGET
isEmpty(QMAKE_BUNDLE_EXTENSION): \
plugin_ext = .plugin
else: \
plugin_ext = $$QMAKE_BUNDLE_EXTENSION
QMAKE_RESOLVED_BUNDLE = $${QMAKE_RESOLVED_TARGET}$${plugin_target}$${plugin_ext}
!shallow_bundle: \
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/Contents/MacOS/$${TARGET}
else: \
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}$${TARGET}
} else: !plugin:lib_bundle {
!isEmpty(QMAKE_FRAMEWORK_BUNDLE_NAME): \
framework_target = $$QMAKE_FRAMEWORK_BUNDLE_NAME
else: \
framework_target = $$TARGET
isEmpty(QMAKE_BUNDLE_EXTENSION): \
framework_ext = .framework
else: \
framework_ext = $$QMAKE_BUNDLE_EXTENSION
QMAKE_RESOLVED_BUNDLE = $${QMAKE_RESOLVED_TARGET}$${framework_target}$${framework_ext}
!shallow_bundle {
framework_version = $$QMAKE_FRAMEWORK_VERSION
isEmpty(framework_version):framework_version = $$section(VERSION, ., 0, 0)
isEmpty(framework_version):framework_version = A
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/Versions/$${framework_version}/$${TARGET}
} else {
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/$${TARGET}
}
} else {
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${LIBPREFIX}$${TARGET}
!plugin {
TEMP_VERSION = $$section(VERSION, ., 0, 0)
isEmpty(TEMP_VERSION):TEMP_VERSION = 1
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}.$${TEMP_VERSION}
}
static:QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}.$${QMAKE_EXTENSION_STATICLIB}
else:QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}.$${QMAKE_EXTENSION_SHLIB}
}
} else {
app_bundle {
!isEmpty(QMAKE_APPLICATION_BUNDLE_NAME): \
app_target = $$QMAKE_APPLICATION_BUNDLE_NAME
else: \
app_target = $$TARGET
QMAKE_RESOLVED_BUNDLE = $${QMAKE_RESOLVED_TARGET}$${app_target}.app
!shallow_bundle: \
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/Contents/MacOS/$${TARGET}
else: \
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/$${TARGET}
} else {
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${TARGET}
}
}
} else {
equals(TEMPLATE, lib) {
static {
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${LIBPREFIX}$${TARGET}.$${QMAKE_EXTENSION_STATICLIB}
} else: plugin|unversioned_libname {
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${LIBPREFIX}$${TARGET}.$${QMAKE_EXTENSION_SHLIB}
} else {
TEMP_VERSION = $$VERSION
isEmpty(TEMP_VERSION):TEMP_VERSION = 1.0.0
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${LIBPREFIX}$${TARGET}.$${QMAKE_EXTENSION_SHLIB}.$${TEMP_VERSION}
}
} else {
QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${TARGET}
}
}
}
unset(TARGET_EXT)
unset(LIBPREFIX)
unset(TEMP_VERSION)

View File

@ -0,0 +1,47 @@
qtPrepareLibExecTool(QMAKE_RCC, rcc, _DEP)
isEmpty(QMAKE_MOD_RCC):QMAKE_MOD_RCC = qrc
!contains(QMAKE_RESOURCE_FLAGS, -root):!isEmpty(QMAKE_RESOURCE_ROOT):QMAKE_RESOURCE_FLAGS += -root $$QMAKE_RESOURCE_ROOT
!contains(QMAKE_RESOURCE_FLAGS, -name): QMAKE_RESOURCE_FLAGS += -name ${QMAKE_FILE_BASE}
!qtConfig(zstd): QMAKE_RESOURCE_FLAGS += --no-zstd
load(resources_functions)
qtFlattenResources()
qtEnsurePluginResourcesCpp()
rcc.input = RESOURCES
rcc.name = RCC ${QMAKE_FILE_IN}
rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
rcc.CONFIG += add_inputs_as_makefile_deps dep_lines remove_no_exist
!resources_big|ltcg|macx-xcode|wasm|contains(TEMPLATE, "vc.*") {
rcc.output = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}
rcc.commands = $$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
rcc.variable_out = SOURCES
} else {
isEmpty(RCC_CXX):RCC_CXX = $$QMAKE_CXX $(CXXFLAGS)
RCC_OUT_BASE = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}
RCC_CPP = $$RCC_OUT_BASE$${first(QMAKE_EXT_CPP)}
RCC_TMP = $${RCC_OUT_BASE}.tmp$${first(QMAKE_EXT_OBJ)}
RCC_OBJ = $$RCC_OUT_BASE$${first(QMAKE_EXT_OBJ)}
msvc: RCC_CXX_O_FLAG = "-Fo"
else: RCC_CXX_O_FLAG = "-o "
rcc.output = $$RCC_OBJ
rcc.commands = \
$$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -pass 1 -o $$RCC_CPP && \
$$RCC_CXX -c $$RCC_CPP $$RCC_CXX_O_FLAG$$RCC_TMP && \
$$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -pass 2 -temp $$RCC_TMP -o ${QMAKE_FILE_OUT}
rcc.clean += $$RCC_CPP $$RCC_TMP
}
rcc.depends += $$QMAKE_RCC_EXE
silent:rcc.commands = @echo rcc ${QMAKE_FILE_IN} && $$rcc.commands
else:rcc.commands ~= s/&&/$$escape_expand(\\n\\t)/g
QMAKE_EXTRA_COMPILERS += rcc

View File

@ -0,0 +1,139 @@
# http://www.w3.org/TR/xml/#syntax
defineReplace(xml_escape) {
1 ~= s,&,&amp;,
1 ~= s,\',&apos;,
1 ~= s,\",&quot;,
1 ~= s,<,&lt;,
1 ~= s,>,&gt;,
return($$1)
}
defineTest(qtFlattenResources) {
isEmpty(RCC_DIR):RCC_DIR = .
immediate = qmake_immediate$$QMAKE_RESOURCES_IMMEDIATE_NR
defined(QMAKE_RESOURCES_IMMEDIATE_NR, var): \
QMAKE_RESOURCES_IMMEDIATE_NR = $$num_add($$QMAKE_RESOURCES_IMMEDIATE_NR, 1)
else: \
QMAKE_RESOURCES_IMMEDIATE_NR = 1
RESOURCES += $$immediate
for(resource, RESOURCES) {
# Regular case of user qrc file
contains(resource, ".*\\.qrc$"): \
next()
# Fallback for stand-alone files/directories
!defined($${resource}.files, var) {
!equals(resource, $$immediate) {
!exists($$absolute_path($$resource, $$_PRO_FILE_PWD_)): \
warning("Failure to find: $$resource")
$${immediate}.files += $$resource
OTHER_FILES *= $$resource
}
RESOURCES -= $$resource
next()
}
RESOURCES -= $$resource
isEmpty(BUILDS)|build_pass {
resource_file = $$absolute_path($$RCC_DIR/qmake_$${resource}.qrc, $$OUT_PWD)
RESOURCES += $$resource_file
} else: android {
# Android will need a resource file for each architecture make sure it is placed
# correctly for other functions that need the right paths for these files
for (arch, ANDROID_ABIS) {
resource_file = $$absolute_path($$RCC_DIR/$$arch/qmake_$${resource}.qrc, $$OUT_PWD)
RESOURCES += $$resource_file
}
}
isEmpty(BUILDS)|build_pass {
# Collection of files, generate qrc file
prefix = $$eval($${resource}.prefix)
isEmpty(prefix): \
prefix = "/"
resource_file_content = \
"<!DOCTYPE RCC><RCC version=\"1.0\">" \
"<qresource prefix=\"$$xml_escape($$prefix)\">"
abs_base = $$absolute_path($$eval($${resource}.base), $$_PRO_FILE_PWD_)
for(file, $${resource}.files) {
abs_path = $$absolute_path($$file, $$_PRO_FILE_PWD_)
files = $$files($$abs_path/*, true)
isEmpty(files): \
files = $$abs_path
for (file, files) {
exists($$file/*): next() # exclude directories
alias = $$relative_path($$file, $$abs_base)
# If a resource is added by the build system from outside of $$_PRO_FILE_PWD_
# everything except the filename needs to be discarded.
subdir = $$find(alias, ^../)
if (!isEmpty(subdir)): alias = $$basename(file)
resource_file_content += \
"<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$file)</file>"
OTHER_FILES *= $$file
}
}
resource_file_content += \
"</qresource>" \
"</RCC>"
!write_file($$resource_file, resource_file_content): \
error()
}
}
export(RCC_DIR)
export(QMAKE_RESOURCES_IMMEDIATE_NR)
export(RESOURCES)
export(OTHER_FILES)
export($${immediate}.files)
return(true)
}
defineTest(qtEnsurePluginResourcesCpp) {
contains(DEFINES, QT_PLUGIN_RESOURCE_INIT_FUNCTION=.*): \
return(true)
!isEmpty(RESOURCES):contains(TEMPLATE, .*lib):plugin:static {
pluginBaseName = $$basename(TARGET)
pluginName = $$lower($$replace(pluginBaseName, [-], _))
resource_init_function = $${pluginName}_plugin_resource_init
DEFINES += "QT_PLUGIN_RESOURCE_INIT_FUNCTION=$$resource_init_function"
RESOURCE_INIT_CPP = $$OUT_PWD/$${pluginName}_plugin_resources.cpp
GENERATED_SOURCES += $$RESOURCE_INIT_CPP
QMAKE_DISTCLEAN += $$RESOURCE_INIT_CPP
isEmpty(BUILDS)|build_pass {
RESOURCE_INIT_CONT = \
"// This file is autogenerated by qmake. It contains a function that" \
"// references all resources the plugin includes and the function is" \
"// referenced by QT_(MOC_)EXPORT_PLUGIN to ensure the inclusion in" \
"// the statically linked plugin." \
"$${LITERAL_HASH}include <QtCore/qglobal.h>" \
"void $${resource_init_function}() " \
"{" \
for (resource, RESOURCES) {
resource_name = $$replace($$list($$basename(resource)),\.qrc$, )
resource_name = $$replace(resource_name, [^a-zA-Z0-9_], _)
RESOURCE_INIT_CONT += " Q_INIT_RESOURCE($$resource_name);"
}
RESOURCE_INIT_CONT += \
"}"
write_file($$RESOURCE_INIT_CPP, RESOURCE_INIT_CONT)|error()
}
export(DEFINES)
export(GENERATED_SOURCES)
export(QMAKE_DISTCLEAN)
}
return(true)
}

View File

@ -0,0 +1,3 @@
CONFIG -= rtti_off
QMAKE_CFLAGS += $$QMAKE_CFLAGS_RTTI_ON
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_RTTI_ON

View File

@ -0,0 +1,4 @@
CONFIG -= rtti
QMAKE_CFLAGS += $$QMAKE_CFLAGS_RTTI_OFF
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_RTTI_OFF
DEFINES += QT_NO_DYNAMIC_CAST

View File

@ -0,0 +1,59 @@
# Sanitizer flags
sanitize_address {
QMAKE_CFLAGS += $$QMAKE_SANITIZE_ADDRESS_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_ADDRESS_CXXFLAGS
QMAKE_LFLAGS += $$QMAKE_SANITIZE_ADDRESS_LFLAGS
android {
# ARM 32 (armeabi-v7a & arm5) are not supported because Qt must be rebuilt with -marm
equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_LIBCLANG_RT_FILE = "libclang_rt.asan-aarch64-android.so"
else: equals(ANDROID_TARGET_ARCH, x86): ANDROID_LIBCLANG_RT_FILE = "libclang_rt.asan-i686-android.so"
else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_LIBCLANG_RT_FILE = "libclang_rt.asan-x86_64-android.so"
else: error("ASAN: Unsupported platform $${ANDROID_TARGET_ARCH}")
ANDROID_LIBCLANG_RT_PATH = $${NDK_LLVM_PATH}/lib64/clang
ANDROID_CLANG_RT_VERSIONS = $$files($$ANDROID_LIBCLANG_RT_PATH/*)
for (VERSION, ANDROID_CLANG_RT_VERSIONS) {
greaterThan(VERSION, $$ANDROID_LIBCLANG_RT_PATH): ANDROID_LIBCLANG_RT_PATH = $$VERSION
}
ANDROID_LIBCLANG_RT_PATH = "$${ANDROID_LIBCLANG_RT_PATH}/lib/linux/"
ANDROID_WRAP_SH_CONTENT = "$$LITERAL_HASH!/system/bin/sh"
ANDROID_WRAP_SH_CONTENT += "HERE=\"$(cd \"$(dirname \"$0\")\" && pwd)\""
isEmpty(ANDROID_ASAN_OPTIONS): ANDROID_ASAN_OPTIONS = "log_to_syslog=false,allow_user_segv_handler=1"
ANDROID_WRAP_SH_CONTENT += "export ASAN_OPTIONS=$${ANDROID_ASAN_OPTIONS}"
ANDROID_WRAP_SH_CONTENT += "export LD_PRELOAD=$HERE/$${ANDROID_LIBCLANG_RT_FILE}"
ANDROID_WRAP_SH_CONTENT += "exec \"$@\""
write_file($$OUT_PWD/android-build/resources/lib/$${ANDROID_TARGET_ARCH}/wrap.sh, ANDROID_WRAP_SH_CONTENT) | error()
libclang_rt.path = /libs/$$ANDROID_TARGET_ARCH/
libclang_rt.files = "$${ANDROID_LIBCLANG_RT_PATH}/$${ANDROID_LIBCLANG_RT_FILE}"
INSTALLS += libclang_rt
}
}
sanitize_memory {
QMAKE_CFLAGS += $$QMAKE_SANITIZE_MEMORY_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_MEMORY_CXXFLAGS
QMAKE_LFLAGS += $$QMAKE_SANITIZE_MEMORY_LFLAGS
}
sanitize_thread {
QMAKE_CFLAGS += $$QMAKE_SANITIZE_THREAD_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_THREAD_CXXFLAGS
QMAKE_LFLAGS += $$QMAKE_SANITIZE_THREAD_LFLAGS
}
sanitize_fuzzer_no_link {
QMAKE_CFLAGS += $$QMAKE_SANITIZE_FUZZERNL_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_FUZZERNL_CXXFLAGS
QMAKE_LFLAGS += $$QMAKE_SANITIZE_FUZZERNL_LFLAGS
}
sanitize_undefined {
QMAKE_CFLAGS += $$QMAKE_SANITIZE_UNDEFINED_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_UNDEFINED_CXXFLAGS
QMAKE_LFLAGS += $$QMAKE_SANITIZE_UNDEFINED_LFLAGS
}
QMAKE_CFLAGS += $$QMAKE_COMMON_SANITIZE_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_COMMON_SANITIZE_CXXFLAGS

View File

@ -0,0 +1,11 @@
!macx-xcode {
msvc {
QMAKE_CC = @$$QMAKE_CC
QMAKE_CXX = @$$QMAKE_CXX
} else {
QMAKE_CC = @echo compiling $< && $$QMAKE_CC
QMAKE_CXX = @echo compiling $< && $$QMAKE_CXX
}
!contains(QMAKE_LINK, "@:"):QMAKE_LINK = @echo linking $@ && $$QMAKE_LINK
QMAKE_LINK_SHLIB = @echo linking $@ && $$QMAKE_LINK_SHLIB
}

199
mkspecs/features/simd.prf Normal file
View File

@ -0,0 +1,199 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
# Get the SIMD flags
load(qt_build_config)
# Set QT_CPU_FEATURES for convenience
QT_CPU_FEATURES = $$eval(QT_CPU_FEATURES.$$QT_ARCH)
#
# Set up compilers for SIMD (SSE/AVX, NEON etc)
#
defineTest(addSimdCompiler) {
name = $$1
upname = $$upper($$name)
headers_var = $${upname}_HEADERS
sources_var = $${upname}_SOURCES
csources_var = $${upname}_C_SOURCES
asm_var = $${upname}_ASM
CONFIG($$1) {
cflags = $$eval(QMAKE_CFLAGS_$${upname})
ltcg: cflags += $$QMAKE_CFLAGS_DISABLE_LTCG
contains(QT_CPU_FEATURES, $$name) {
# Default compiler settings include this feature, so just add to SOURCES
SOURCES += $$eval($$sources_var)
export(SOURCES)
} else {
# We need special compiler flags
# Split C and C++ sources
$$csources_var = $$find($$sources_var, ".*\\.c$")
$$sources_var -= $$eval($$csources_var)
export($$csources_var)
export($$sources_var)
# Add C++ compiler
$${name}_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $$cflags $(INCPATH) ${QMAKE_FILE_IN}
msvc: $${name}_compiler.commands += -Fo${QMAKE_FILE_OUT}
else: $${name}_compiler.commands += -o ${QMAKE_FILE_OUT}
$${name}_compiler.dependency_type = TYPE_C
$${name}_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
$${name}_compiler.input = $$sources_var
$${name}_compiler.variable_out = OBJECTS
$${name}_compiler.name = compiling[$${name}] ${QMAKE_FILE_IN}
silent: $${name}_compiler.commands = @echo compiling[$${name}] ${QMAKE_FILE_IN} && $$eval($${name}_compiler.commands)
QMAKE_EXTRA_COMPILERS += $${name}_compiler
export($${name}_compiler.commands)
export($${name}_compiler.dependency_type)
export($${name}_compiler.output)
export($${name}_compiler.input)
export($${name}_compiler.variable_out)
export($${name}_compiler.name)
# Add a C compiler
$${name}_c_compiler.commands = $$QMAKE_CC -c $(CFLAGS) $$cflags $(INCPATH) ${QMAKE_FILE_IN}
msvc: $${name}_c_compiler.commands += -Fo${QMAKE_FILE_OUT}
else: $${name}_c_compiler.commands += -o ${QMAKE_FILE_OUT}
$${name}_c_compiler.dependency_type = TYPE_C
$${name}_c_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
$${name}_c_compiler.input = $$csources_var
$${name}_c_compiler.variable_out = OBJECTS
$${name}_c_compiler.name = compiling[$${name}] ${QMAKE_FILE_IN}
silent: $${name}_c_compiler.commands = @echo compiling[$${name}] ${QMAKE_FILE_IN} && $$eval($${name}_c_compiler.commands)
QMAKE_EXTRA_COMPILERS += $${name}_c_compiler
export($${name}_c_compiler.commands)
export($${name}_c_compiler.dependency_type)
export($${name}_c_compiler.output)
export($${name}_c_compiler.input)
export($${name}_c_compiler.variable_out)
export($${name}_c_compiler.name)
}
# We always need an assembler (need to run the C compiler and without precompiled headers)
msvc {
# Don't know how to run MSVC's assembler...
!isEmpty($$asm_var): error("Sorry, not implemented: assembling $$upname for MSVC.")
} else: false {
# This is just for the IDE
SOURCES += $$eval($$asm_var)
export(SOURCES)
} else {
$${name}_assembler.commands = $$QMAKE_CC -c $(CFLAGS)
!contains(QT_CPU_FEATURES, $${name}): $${name}_assembler.commands += $$cflags
clang:no_clang_integrated_as: $${name}_assembler.commands += -fno-integrated-as
$${name}_assembler.commands += $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
$${name}_assembler.dependency_type = TYPE_C
$${name}_assembler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
$${name}_assembler.input = $$asm_var
$${name}_assembler.variable_out = OBJECTS
$${name}_assembler.name = assembling[$${name}] ${QMAKE_FILE_IN}
silent: $${name}_assembler.commands = @echo assembling[$${name}] ${QMAKE_FILE_IN} && $$eval($${name}_assembler.commands)
QMAKE_EXTRA_COMPILERS += $${name}_assembler
export($${name}_assembler.commands)
export($${name}_assembler.dependency_type)
export($${name}_assembler.output)
export($${name}_assembler.input)
export($${name}_assembler.variable_out)
export($${name}_assembler.name)
}
HEADERS += $$eval($$headers_var)
export(HEADERS)
export(QMAKE_EXTRA_COMPILERS)
}
}
addSimdCompiler(sse2)
addSimdCompiler(sse3)
addSimdCompiler(ssse3)
addSimdCompiler(sse4_1)
addSimdCompiler(sse4_2)
addSimdCompiler(aesni)
addSimdCompiler(shani)
addSimdCompiler(vaes)
addSimdCompiler(avx)
addSimdCompiler(avx2)
addSimdCompiler(avx512f)
addSimdCompiler(avx512cd)
addSimdCompiler(avx512er)
addSimdCompiler(avx512pf)
addSimdCompiler(avx512dq)
addSimdCompiler(avx512bw)
addSimdCompiler(avx512vl)
addSimdCompiler(avx512vnni)
addSimdCompiler(avx512ifma)
addSimdCompiler(avx512vbmi)
addSimdCompiler(avx512vbmi2)
addSimdCompiler(avx512bitalg)
addSimdCompiler(avx512vpopcntd)
addSimdCompiler(f16c)
addSimdCompiler(rdrnd)
addSimdCompiler(rdseed)
addSimdCompiler(neon)
addSimdCompiler(mips_dsp)
addSimdCompiler(mips_dspr2)
# Haswell sub-architecture
defineTest(addSimdArch) {
name = arch_$$1
dependencies = $$2
upname = $$upper($$name)
cpu_features_missing =
for(part, dependencies) {
!contains(QT_CPU_FEATURES, $$part): cpu_features_missing = 1
}
CONFIG += $$name
isEmpty(cpu_features_missing): QT_CPU_FEATURES += $$name
export(QT_CPU_FEATURES)
export(CONFIG)
addSimdCompiler($$name)
}
isEmpty(QMAKE_CFLAGS_ARCH_HASWELL): QMAKE_CFLAGS_ARCH_HASWELL = $$QMAKE_CFLAGS_AVX2
avx2: addSimdArch(haswell, avx2 bmi bmi2 f16c fma lzcnt popcnt)
# Follow the Intel compiler's lead and define profiles of AVX512 instructions
defineTest(addAvx512Profile) {
name = $$1
dependencies = $$2
upname = $$upper($$name)
varname = QMAKE_CFLAGS_$$upname
cpu_features_missing =
cflags = $$QMAKE_CFLAGS_ARCH_HASWELL $$QMAKE_CFLAGS_AVX512F
for(part, dependencies) {
!CONFIG($$part): return() # Profile isn't supported by the compiler
uppart = $$upper($$part)
cflags *= $$eval(QMAKE_CFLAGS_$${uppart})
!contains(QT_CPU_FEATURES, $$uppart): cpu_features_missing += $$uppart
}
CONFIG += $$name
isEmpty(cpu_features_missing): QT_CPU_FEATURES += $$name
$$varname = $$cflags
export(QT_CPU_FEATURES)
export(CONFIG)
export($$varname)
addSimdCompiler($$name)
}
addAvx512Profile(avx512common, avx512cd)
addAvx512Profile(avx512core, avx512cd avx512bw avx512dq avx512vl)

View File

@ -0,0 +1,130 @@
# This file is loaded by qmake right after loading the qmakespec.
# Afterwards, the project's .qmake.conf and .qmake.cache are loaded
# (if present).
# Note that up to this point, nothing specific to a particular SUBDIRS
# project or build pass can be done.
isEmpty(MAKEFILE_GENERATOR):error("Qmake spec does not set MAKEFILE_GENERATOR.")
isEmpty(QMAKE_PLATFORM) {
isEmpty(TARGET_PLATFORM) {
equals(MAKEFILE_GENERATOR, UNIX) {
equals(QMAKE_HOST.os, Darwin): \
TARGET_PLATFORM = macx # backwards compatibility; cannot change
else: \
TARGET_PLATFORM = unix
} else:if(equals(MAKEFILE_GENERATOR, MSVC.NET) \
|equals(MAKEFILE_GENERATOR, MSBUILD) \
|equals(MAKEFILE_GENERATOR, MINGW)) {
TARGET_PLATFORM = win32
} else:if(equals(MAKEFILE_GENERATOR, PROJECTBUILDER) \
|equals(MAKEFILE_GENERATOR, XCODE)) {
TARGET_PLATFORM = macx
} else {
error("Qmake spec sets an invalid MAKEFILE_GENERATOR.")
}
}
equals(TARGET_PLATFORM, unix): \
QMAKE_PLATFORM = unix
else:equals(TARGET_PLATFORM, macx): \
QMAKE_PLATFORM = macos osx macx mac darwin unix
else:equals(TARGET_PLATFORM, win32): \
QMAKE_PLATFORM = win32
else: \
error("Qmake spec sets an invalid TARGET_PLATFORM.")
}
contains(QMAKE_PLATFORM, macx) {
!contains(QMAKE_PLATFORM, osx) {
warning("qmake spec specified platform macx, but not osx.");
QMAKE_PLATFORM = osx $$QMAKE_PLATFORM
}
!contains(QMAKE_PLATFORM, macos) {
warning("qmake spec specifies platform macx, but not macos.")
QMAKE_PLATFORM = macos $$QMAKE_PLATFORM
}
}
CONFIG += $$QMAKE_PLATFORM
isEmpty(QMAKE_COMPILER) {
*-g++*: \
QMAKE_COMPILER = gcc
else:*-llvm*: \
QMAKE_COMPILER = gcc llvm
else:*-clang*: \
QMAKE_COMPILER = gcc clang llvm
else:*-msvc*: \
QMAKE_COMPILER = msvc
else: \
error("qmake spec does not announce the compiler family, and it cannot be guessed.")
warning("qmake spec does not announce the compiler family. Guessed $${QMAKE_COMPILER}.")
}
CONFIG += $$QMAKE_COMPILER
equals(MAKEFILE_GENERATOR, MSBUILD) \
|equals(MAKEFILE_GENERATOR, MSVC.NET) \
|isEmpty(QMAKE_SH) {
QMAKE_ZIP = zip -r -9
QMAKE_CD = cd /d
QMAKE_COPY = copy /y
QMAKE_COPY_FILE = $$QMAKE_COPY
QMAKE_COPY_DIR = xcopy /s /q /y /i
# xcopy copies the contained files if source is a directory. Deal with it.
CONFIG += copy_dir_files
QMAKE_MOVE = move
QMAKE_DEL_FILE = del
QMAKE_DEL_DIR = rmdir
QMAKE_DEL_TREE = rmdir /s /q
QMAKE_CHK_EXISTS = if not exist %1
QMAKE_CHK_DIR_EXISTS = if not exist # legacy
QMAKE_MKDIR = mkdir # legacy
QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1
QMAKE_STREAM_EDITOR = $(QMAKE) -install sed
QMAKE_SHELL_NULL_DEVICE = NUL
QMAKE_INSTALL_FILE = copy /y
QMAKE_INSTALL_PROGRAM = copy /y
} else {
QMAKE_TAR = tar -cf
QMAKE_GZIP = gzip -9f
QMAKE_CD = cd
QMAKE_COPY = cp -f
QMAKE_COPY_FILE = $$QMAKE_COPY
QMAKE_COPY_DIR = $$QMAKE_COPY -R
QMAKE_MOVE = mv -f
QMAKE_DEL_FILE = rm -f
QMAKE_DEL_DIR = rmdir
QMAKE_DEL_TREE = rm -rf
QMAKE_CHK_EXISTS = test -e %1 ||
QMAKE_CHK_DIR_EXISTS = test -d # legacy
QMAKE_MKDIR = mkdir -p # legacy
QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1
QMAKE_STREAM_EDITOR = sed
QMAKE_SHELL_NULL_DEVICE = /dev/null
equals(QMAKE_HOST.os, Windows) {
MINGW_IN_SHELL = 1 # legacy
# Override built-ins.
QMAKE_DIR_SEP = /
QMAKE_DIRLIST_SEP = :
# Because install's ability to set permissions is not relevant on Windows,
# and git's msys does not provide it to start with.
QMAKE_INSTALL_FILE = cp -f
QMAKE_INSTALL_PROGRAM = cp -f
} else {
QMAKE_INSTALL_FILE = install -m 644 -p
QMAKE_INSTALL_PROGRAM = install -m 755 -p
}
}
QMAKE_INSTALL_DIR = $$QMAKE_COPY_DIR
equals(QMAKE_HOST.os, Windows) {
QMAKE_SYMBOLIC_LINK = $(QMAKE) -install ln -f -s
QMAKE_LN_SHLIB = $(QMAKE) -install ln -s
QMAKE_SYSTEM_NULL_DEVICE = NUL
} else {
QMAKE_SYMBOLIC_LINK = ln -f -s
QMAKE_LN_SHLIB = ln -s
QMAKE_SYSTEM_NULL_DEVICE = /dev/null
}

View File

@ -0,0 +1,55 @@
# This file is loaded by qmake right before loading the qmakespec.
# At this point, the built-in variables have been set up and the project's
# .qmake.super was read (if present).
QMAKE_DIR_SEP = $$DIR_SEPARATOR
QMAKE_DIRLIST_SEP = $$DIRLIST_SEPARATOR
QMAKE_EXT_C = .c
QMAKE_EXT_CPP = .cpp .cc .cxx
QMAKE_EXT_OBJC = .m
QMAKE_EXT_OBJCXX = .mm
QMAKE_EXT_CPP_MOC = .moc
QMAKE_EXT_H = .h .hpp .hh .hxx
QMAKE_EXT_H_MOC = .cpp
QMAKE_EXT_JS = .js
QMAKE_EXT_LEX = .l
QMAKE_EXT_LIBTOOL = .la
QMAKE_EXT_PKGCONFIG = .pc
QMAKE_EXT_PRL = .prl
QMAKE_EXT_UI = .ui
QMAKE_EXT_YACC = .y
QMAKE_CPP_MOD_MOC =
QMAKE_H_MOD_MOC = moc_
QMAKE_MOD_LEX = _lex
QMAKE_MOD_YACC = _yacc
defineTest(ensurePathEnv) {
isEmpty(QMAKE_PATH_ENV) {
QMAKE_PATH_ENV = $$(PATH)
QMAKE_PATH_ENV = $$split(QMAKE_PATH_ENV, $$QMAKE_DIRLIST_SEP)
export(QMAKE_PATH_ENV)
}
}
equals(QMAKE_HOST.os, Windows) {
QMAKE_EXT_OBJ = .obj
QMAKE_EXT_RES = .res
QMAKE_SH =
ensurePathEnv()
for(dir, QMAKE_PATH_ENV) {
exists($$dir/sh.exe) {
QMAKE_SH = $$dir/sh.exe
break()
}
}
} else {
QMAKE_EXT_CPP += .C
QMAKE_EXT_H += .H
QMAKE_EXT_OBJ = .o
QMAKE_SH = sh
}
CONFIG = file_copies qmake_use qt warn_on release link_prl
QT = core gui

View File

@ -0,0 +1,7 @@
msvc {
# -MD becomes -MT, -MDd becomes -MTd
QMAKE_CFLAGS ~= s,^-MD(d?)$,-MT\\1,g
QMAKE_CXXFLAGS ~= s,^-MD(d?)$,-MT\\1,g
} else: mingw {
QMAKE_LFLAGS += -static
}

View File

@ -0,0 +1,262 @@
!have_target: return()
# qt_build_config.prf disables execptions for all Qt modules which don't
# explicitly turn it on again, while the qmake default is to build with
# exceptions. As we want tests to be built like 3rd party applications,
# qt_build_config tells us to re-enable exceptions here.
testcase_exceptions: CONFIG += exceptions
# Set in qt_build_config.prf
testcase_no_bundle: CONFIG -= app_bundle
# cmdline may have been specified and not processed yet
cmdline: CONFIG -= app_bundle
# Allow testcases to mark themselves as not supporting high-DPI
testcase_lowdpi {
macos {
!isEmpty(QMAKE_INFO_PLIST): \
error("QMAKE_INFO_PLIST already set, can't apply testcase_lowdpi")
QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.disable_highdpi
# Needs to be bundle so that Launch Services will pick
# up and apply the NSHighResolutionCapable=NO state.
CONFIG += app_bundle
} else {
# TODO: Add support for other platforms if possible
}
DEFINES += TESTCASE_LOWDPI
}
benchmark: type = benchmark
else: type = check
$${type}.files =
$${type}.path = .
# Make sure we explicitly load the debug version of the Qt libraries if needed
macos {
dyld_image_suffix.name = DYLD_IMAGE_SUFFIX
dyld_image_suffix.value = $$qtPlatformTargetSuffix()
QT_TOOL_ENV += dyld_image_suffix
}
# Add environment for non-installed builds. Do this first, so the
# 'make' variable expansions don't end up in a batch file/script.
QT_TOOL_NAME = target
qtAddTargetEnv($${type}.commands, QT)
# If the test ends up in a different directory, we should cd to that directory.
TESTRUN_CWD = $$DESTDIR
debug_and_release:debug_and_release_target {
# But in debug-and-release-target mode we don't want to cd into the debug/release
# directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do
# 'cd foo && release/tst_thing.exe', not 'cd foo/release && tst_thing.exe').
TESTRUN_CWD ~= s/(release|debug)$//
TEST_TARGET_DIR = $$relative_path($$absolute_path($$DESTDIR, $$OUT_PWD), $$absolute_path($$TESTRUN_CWD, $$OUT_PWD))
}
# Allow for a custom test runner script
android: isEmpty($(TESTRUNNER)) {
build_pass|single_android_abi {
APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
qtPrepareTool(ANDROIDTESTRUNNER, androidtestrunner)
qtPrepareTool(ANDROIDDEPLOYQT, androiddeployqt)
isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET-deployment-settings.json
contains(QMAKE_HOST.os, Windows): extension = .exe
$${type}.commands = $$ANDROIDTESTRUNNER --path \"$$OUT_PWD/android-build\"
$${type}.commands += --adb \"$$shell_path($${ANDROID_SDK_ROOT}$${QMAKE_DIR_SEP}platform-tools$${QMAKE_DIR_SEP}adb$${extension})\"
$${type}.commands += --make \"$(MAKE) apk\"
$${type}.commands += --apk $$APK_PATH
# Allow for custom arguments to tests
!catch: $${type}.commands += $(TESTARGS)
$${type}.commands += "--"
for(import, IMPORTPATH): $${type}.commands *= -import \"assets:/$$basename(_PRO_FILE_PWD_)/$$import\"
} else {
$${type}.commands = "echo \"Pass\""
}
} else {
$${type}.commands += $(TESTRUNNER)
unix {
isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = .
app_bundle: \
$${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
else: !android: \
$${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
} else {
# Windows
!isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $$shell_path($$TEST_TARGET_DIR)$${QMAKE_DIR_SEP}
$${type}.commands += $${TEST_TARGET_DIR}$(TARGET)
}
# Allow for custom arguments to tests
!catch: $${type}.commands += $(TESTARGS)
}
!isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD, ^\\./?): \
$${type}.commands = $$QMAKE_CD $$shell_path($$TESTRUN_CWD) && $$eval($${type}.commands)
# If the test is marked as insignificant, discard the exit code
insignificant_test: $${type}.commands = -$$eval($${type}.commands)
QMAKE_EXTRA_TARGETS *= $${type}
isEmpty(BUILDS)|build_pass {
$${type}.depends = first
} else {
# For exclusive builds, only run the test once.
$${type}.CONFIG = recursive
$${type}.target = $${type}_all
$${type}.recurse_target = $${type}
$${type}.commands =
$${type}_first.depends = $$eval($$first(BUILDS).target)-$${type}
$${type}_first.target = $${type}
QMAKE_EXTRA_TARGETS += $${type}_first
}
!no_testcase_installs:!contains(INSTALLS, target) {
# Install tests unless no_testcase_installs is set, or there is already
# a `target' in INSTALLS.
#
# Tests are installed under a directory named after their source folder
# so that each test has its own directory for testdata etc.
#
TEST_FOLDER = $$basename(_PRO_FILE_PWD_)
target.path = $$[QT_INSTALL_TESTS]/$$TEST_FOLDER
INSTALLS += target
}
!builtin_testdata:contains(INSTALLS, target) {
# Install testdata and helpers as well, but only if we're actually installing the test.
#
# Testdata is installed relative to the directory containing the testcase
# binary itself, e.g. this:
#
# CONFIG += testcase
# TARGET = tst_qxmlreader
#
# TESTDATA += testdata/test1.xml testdata/test2.xml
#
# ... will result in:
#
# /usr/lib/qt5/tests/tst_qxmlreader/tst_qxmlreader
# /usr/lib/qt5/tests/tst_qxmlreader/testdata/test1.xml
# /usr/lib/qt5/tests/tst_qxmlreader/testdata/test2.xml
# ...
#
for(file, TESTDATA) {
tnam = $$file
tnam ~= s,\\.\\.,dotdot,
tnam ~= s,[?*],wildcard,
tnam ~= s,[^A-Za-z0-9],_,
tdi = testdata_$$tnam
# TESTDATA consists of the files to install (source)...
$${tdi}.files = $$file
# ... and the destination preserves the relative path.
# Strip any leading ../ from the testdata, so that installation does not escape
# the test's directory in the case of e.g.
#
# TARGET = ../tst_qprocess
# TESTDATA = ../thing1 ../thing2
#
# The testdata should end up at $$[QT_INSTALL_TESTS]/tst_qprocess/thing1,
# rather than $$[QT_INSTALL_TESTS]/tst_qprocess/../thing1.
#
# Note that this does not guarantee the same relative path between test binary
# and testdata in the build and install tree, but should cover most cases.
#
file = $$replace(file, ^(\\.\\./)+, )
$${tdi}.path = $${target.path}/$$dirname(file)
INSTALLS += $$tdi
}
# Install GENERATED_TESTDATA.
# Logic is copied from the TESTDATA installation, only difference being that
# INSTALL target is added with CONFIG = no_check_exist
for(file, GENERATED_TESTDATA) {
tnam = $$file
tnam ~= s,\\.\\.,dotdot,
tnam ~= s,[?*],wildcard,
tnam ~= s,[^A-Za-z0-9],_,
tdi = testdata_$$tnam
$${tdi}.files = $$file
$${tdi}.CONFIG = no_check_exist
file = $$replace(file, ^(\\.\\./)+, )
$${tdi}.path = $${target.path}/$$dirname(file)
INSTALLS += $$tdi
}
# TEST_HELPER_INSTALLS specifies additional test helper executables for installation.
#
# Typical usage is:
#
# TEST_HELPER_INSTALLS += ../some/helper1 ../some/helper2
#
# Resulting in the test helpers being installed to:
#
# $$[QT_INSTALL_TESTS]/$$TARGET/some/helper1
# $$[QT_INSTALL_TESTS]/$$TARGET/some/helper2
#
win32: extension = .exe
for(test_helper, TEST_HELPER_INSTALLS) {
test_helper_dir = $$dirname(test_helper)
output = $$basename(test_helper_dir)
target = $$basename(test_helper)
targetName = $$replace(target, ' ', '_') # handle spaces in name
subTarget = $${targetName}.target
subInstall = $${targetName}_install
subConfig = $${subInstall}.CONFIG
subFiles = $${subInstall}.files
subPath = $${subInstall}.path
$$subTarget = $${output}/$${target}$${extension}
$$subFiles = $${OUT_PWD}/$${test_helper}$${extension}
$$subPath = $${target.path}/$${output}
$$subConfig += no_check_exist executable
INSTALLS += $${subInstall}
}
}
builtin_testdata {
# RESOURCES does not support wildcards (for good reasons)
for (td, TESTDATA): \
testdata.files += $$files($$absolute_path($$td, $$_PRO_FILE_PWD_))
# BLACKLIST needs to be added to the testdata
BLACKLISTPATH = $$_PRO_FILE_PWD_/BLACKLIST
exists($$BLACKLISTPATH): \
testdata.files *= $$BLACKLISTPATH
!isEmpty(testdata.files) {
testdata.base = $$_PRO_FILE_PWD_
RESOURCES += testdata
}
# Extra compilers don't create wildcards to start with.
for (td, GENERATED_TESTDATA): \
gentestdata.files += $$absolute_path($$td, $$OUT_PWD)
!isEmpty(gentestdata.files) {
gentestdata.base = $$OUT_PWD
RESOURCES += gentestdata
}
!isEmpty(TEST_HELPER_INSTALLS): \
error("This platform does not support tests which require helpers.")
}
macx-xcode:bundle:isEmpty(QMAKE_BUNDLE_EXTENSION) {
QMAKE_PBX_PRODUCT_TYPE = com.apple.product-type.bundle.unit-test
QMAKE_PBX_BUNDLE_TYPE = wrapper.cfbundle
QMAKE_BUNDLE_EXTENSION = .xctest
}

View File

@ -0,0 +1,19 @@
# Let every project have a standard GNU `check' target
!contains(QMAKE_EXTRA_TARGETS, check) {
contains(TEMPLATE, subdirs): \
prepareRecursiveTarget(check)
else: \
check.depends = first # `make check' implies build
QMAKE_EXTRA_TARGETS += check
}
# ... and the same for benchmarks, too.
!contains(QMAKE_EXTRA_TARGETS, benchmark) {
contains(TEMPLATE, subdirs): \
prepareRecursiveTarget(benchmark)
else: \
benchmark.depends = first # `make benchmark' implies build
QMAKE_EXTRA_TARGETS += benchmark
}

View File

@ -0,0 +1,57 @@
#
# Tested with TestCocoon 1.6.14
#
load(resolve_target)
# Retrieve the target basename
TARGET_BASENAME = $$basename(QMAKE_RESOLVED_TARGET)
# Configure testcocoon for a full instrumentation - excluding the moc, ui and qrc files from the instrumentation
# --cs-output defines the name to give to the execution report (.csexe).
TESTCOCOON_COVERAGE_OPTIONS = \
--cs-qt4 \
--cs-exclude-file-regex=\'(^|[/\\\\])(qrc|moc)_.*\\.cpp\$\$\' \
--cs-exclude-file-regex=\'.*\\.moc\$\$\' \
--cs-exclude-file-regex=\'.*\\.g\$\$\' \
--cs-exclude-file-regex=\'.*\\.h\$\$\' \
--cs-output=\'$$TARGET_BASENAME\' # name of the csexe file (execution report)
# The .csmes file should be placed alongside the .so or binary.
# Unfortunately, testcocoon has no option to specify the output directory,
# so we must move it into place if a custom destdir was used.
# We don't move applications' csmes because some qt applications (tools, examples)
# are using DESTDIR in some cases but always alongside target.path, so the binary
# is built directly in target.path and there is no need to move the csmes.
!isEmpty(DESTDIR):contains(TEMPLATE, lib) {
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK
QMAKE_POST_LINK = -$(MOVE) $${TARGET_BASENAME}.csmes $$shell_path($${QMAKE_RESOLVED_TARGET}.csmes)$$QMAKE_POST_LINK
}
QMAKE_CLEAN += *.csexe *.csmes
# The compiler/linker is replaced by the coveragescanner which is named after the name of the
# compiler/linker preceded by cs (ie gcc is replaced by csgcc).
# Testcocoon options defined in TESTCOCOON_COVERAGE_OPTIONS are added as argument to the coveragescanner (ie csgcc).
# In practice they are added as compiler/linker flags.
*-g++* {
QMAKE_CXX ~= s/(\\S*g\\+\\+)/cs\\1/
QMAKE_CC ~= s/(\\S*gcc)/cs\\1/
QMAKE_LINK ~= s/(\\S*g\\+\\+|\\S*gcc)/cs\\1/
QMAKE_AR ~= s/(\\S*ar)/cs\\1/
QMAKE_AR += $$TESTCOCOON_COVERAGE_OPTIONS
} else {
error("Non-gcc qmake specs not supported by TestCocoon integration yet")
}
QMAKE_CFLAGS += $$TESTCOCOON_COVERAGE_OPTIONS
QMAKE_CXXFLAGS += $$TESTCOCOON_COVERAGE_OPTIONS
QMAKE_LFLAGS += $$TESTCOCOON_COVERAGE_OPTIONS
unix {
QMAKE_LFLAGS += --cs-libgen=-fPIC
}
unset(TARGET_BASENAME)
unset(TESTCOCOON_COVERAGE_OPTIONS)

View File

@ -0,0 +1,2 @@
contains(TEMPLATE, vc.*): DEFINES += QT_TESTCASE_BUILDDIR=\"$$OUT_PWD\"
else: DEFINES += QT_TESTCASE_BUILDDIR=$$shell_quote(\"$$OUT_PWD\")

View File

@ -0,0 +1,442 @@
defineTest(qtToolchainError) {
msg = \
$$1 \
"===================" \
$$2 \
"===================" \
$$3
error($$join(msg, $$escape_expand(\\n)))
}
defineTest(qtCompilerError) {
!cross_compile: \
what =
else: host_build: \
what = " host"
else: \
what = " target"
qtToolchainError("Cannot run$$what compiler '$$1'. Output:", $$2, \
"Maybe you forgot to setup the environment?")
}
cross_compile:host_build: \
target_prefix = QMAKE_HOST_CXX
else: \
target_prefix = QMAKE_CXX
#
# Determine and cache the compiler version
#
defineReplace(qtVariablesFromMSVC) {
ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec)
!equals(ec, 0): qtCompilerError($$1, $$ret)
return($$ret)
}
defineReplace(qtVariablesFromGCC) {
ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \
2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec)
!equals(ec, 0): qtCompilerError($$1, $$ret)
return($$ret)
}
isEmpty($${target_prefix}.COMPILER_MACROS) {
msvc {
clang_cl {
# We need to obtain the cl.exe version first
vars = $$qtVariablesFromMSVC(cl)
for (v, vars) {
isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next()
eval($$v)
}
isEmpty(QMAKE_MSC_FULL_VER): error("Could not determine the Visual Studio version")
QMAKE_CFLAGS_MSVC_COMPAT = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", \
"-fms-compatibility-version=\\1.\\2.\\3")
cache($${target_prefix}.QMAKE_CFLAGS_MSVC_COMPAT, set stash, QMAKE_CFLAGS_MSVC_COMPAT)
$${target_prefix}.COMPILER_MACROS += QMAKE_CFLAGS_MSVC_COMPAT
vars = $$qtVariablesFromMSVC($$QMAKE_CXX, $$QMAKE_CFLAGS_MSVC_COMPAT)
} else {
vars = $$qtVariablesFromMSVC($$QMAKE_CXX)
}
} else: gcc|ghs {
vars = $$qtVariablesFromGCC($$QMAKE_CXX)
}
for (v, vars) {
!contains(v, "[A-Z_]+ = .*"): next()
# Set both <varname> for the outer scope ...
eval($$v)
v ~= s/ .*//
isEmpty($$v): error("Compiler produced empty value for $${v}.")
# ... and save QMAKE_(HOST_)?CXX.<varname> in the cache.
cache($${target_prefix}.$$v, set stash, $$v)
$${target_prefix}.COMPILER_MACROS += $$v
}
cache($${target_prefix}.COMPILER_MACROS, set stash)
} else {
# load from the cache
for (i, $${target_prefix}.COMPILER_MACROS): \
$$i = $$eval($${target_prefix}.$$i)
}
# Populate QMAKE_COMPILER_DEFINES and some compatibility variables.
# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal.
QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX
!isEmpty(QMAKE_MSC_VER): \
QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER
!isEmpty(QMAKE_ICC_VER): \
QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER
!isEmpty(QMAKE_APPLE_CC): \
QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC
!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION): \
QMAKE_COMPILER_DEFINES += __clang__ \
__clang_major__=$$QMAKE_APPLE_CLANG_MAJOR_VERSION \
__clang_minor__=$$QMAKE_APPLE_CLANG_MINOR_VERSION \
__clang_patchlevel__=$$QMAKE_APPLE_CLANG_PATCH_VERSION
!isEmpty(QMAKE_CLANG_MAJOR_VERSION): \
QMAKE_COMPILER_DEFINES += __clang__ \
__clang_major__=$$QMAKE_CLANG_MAJOR_VERSION \
__clang_minor__=$$QMAKE_CLANG_MINOR_VERSION \
__clang_patchlevel__=$$QMAKE_CLANG_PATCH_VERSION
!isEmpty(QMAKE_GCC_MAJOR_VERSION): \
QMAKE_COMPILER_DEFINES += \
__GNUC__=$$QMAKE_GCC_MAJOR_VERSION \
__GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \
__GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION
!isEmpty(QMAKE_GHS_VERSION): \
QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION
QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
clang_cl|intel_icl {
include(../common/msvc-based-version.conf)
} else: msvc {
include(../common/msvc-version.conf)
}
#
# Determine and cache the default search paths
#
defineReplace(qtMakeExpand) {
out = "$$1"
for(ever) {
m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1)
equals(m, $$out): \
return($$out)
out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m))
}
}
defineReplace(qtSplitPathList) {
paths = $$split(1, $$QMAKE_DIRLIST_SEP)
ret =
for (p, paths): \
ret += $$clean_path($$p)
return($$ret)
}
defineReplace(qtNmakePathList) {
paths =
for (p, 1): \
paths += $$shell_path($$p)
paths ~= s,$${LITERAL_HASH},^$${LITERAL_HASH},g
paths ~= s,\\$,\$\$,g
return($$join(paths, $$QMAKE_DIRLIST_SEP))
}
msvc {
arch = $$lower($$VCPROJ_ARCH)
equals(arch, x64): \ # may be "win32" or undefined
arch = amd64
else: !equals(arch, arm):!equals(arch, arm64): \ # may be "win32" or undefined
arch = x86
# Consider only ARM64 desktop builds to be cross-builds -
# the host is assumed to be Intel and capable of running the target
# executables (so building for x64 on x86 will break).
equals(arch, arm64): \
CONFIG += msvc_cross
}
isEmpty($${target_prefix}.INCDIRS) {
#
# Get default include and library paths from compiler
#
wasm {
# wasm compiler does not work here, just use defaults
} else: gcc {
cmd_suffix = "<$$QMAKE_SYSTEM_NULL_DEVICE >$$QMAKE_SYSTEM_NULL_DEVICE"
equals(QMAKE_HOST.os, Windows): \
cmd_prefix = "set LC_ALL=C&"
else: \
cmd_prefix = "LC_ALL=C"
cxx_flags = $$QMAKE_CXXFLAGS
# Manually inject the sysroot for Apple Platforms because its resolution
# normally does not happen until default_post.prf. This is especially
# important for moc to gain the correct default include directory list.
# While technically incorrect but without any likely practical effect,
# UIKit simulator platforms will see the device SDK's sysroot in
# QMAKE_DEFAULT_*DIRS, because they're handled in a single build pass.
darwin {
uikit {
# Clang doesn't automatically pick up the architecture, just because
# we're passing the iOS sysroot below, and we will end up building the
# test for the host architecture, resulting in linker errors when
# linking against the iOS libraries. We work around this by passing
# the architecture explicitly.
cxx_flags += -arch $$first(QMAKE_APPLE_DEVICE_ARCHS)
}
uikit:macx-xcode: \
cxx_flags += -isysroot $$sdk_path_device.value
else: \
cxx_flags += -isysroot $$QMAKE_MAC_SDK_PATH
}
rim_qcc: \
# Need the cc1plus and ld command lines to pick up the paths
cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$QMAKE_SYSTEM_NULL_DEVICE -v
else: darwin:clang: \
# Need to link to pick up library paths
cxx_flags += -g0 $$QMAKE_LFLAGS_SHLIB -o /dev/null -v -Wl,-v
else: \
# Just preprocess, might not pick up library paths
cxx_flags += -E -v
output = $$system("$$cmd_prefix $$QMAKE_CXX $$qtMakeExpand($$cxx_flags) -xc++ - 2>&1 $$cmd_suffix", lines, ec)
!equals(ec, 0): qtCompilerError($$QMAKE_CXX, $$output)
rim_qcc {
for (line, output) {
contains(line, "^[^ ]*cc1plus .*") {
take_next = false
for (parameter, $$list($$line)) {
$$take_next {
QMAKE_DEFAULT_INCDIRS += $$clean_path($$parameter)
take_next = false
} else: equals(parameter, "-isystem") {
take_next = true
}
}
} else: contains(line, "^[^ ]*-ld .*") {
for (parameter, $$list($$line)) {
contains(parameter, "^-L.*") {
parameter ~= s/^-L//
QMAKE_DEFAULT_LIBDIRS += $$clean_path($$parameter)
}
}
}
}
} else {
add_includes = false
add_libraries = false
for (line, output) {
line ~= s/^[ \\t]*// # remove leading spaces
contains(line, "LIBRARY_PATH=.*") {
line ~= s/^LIBRARY_PATH=// # remove leading LIBRARY_PATH=
equals(QMAKE_HOST.os, Windows): \
paths = $$split(line, ;)
else: \
paths = $$split(line, $$QMAKE_DIRLIST_SEP)
for (path, paths): \
QMAKE_DEFAULT_LIBDIRS += $$clean_path($$path)
} else: contains(line, "Library search paths:") {
add_libraries = true
} else: contains(line, "$${LITERAL_HASH}include <.*") { # #include <...> search starts here:
add_includes = true
} else: contains(line, "End of search.*") {
add_includes = false
} else: $$add_libraries {
# We assume all library search paths are absolute
!contains(line, "^/.*") {
add_libraries = false
next()
}
QMAKE_DEFAULT_LIBDIRS += $$clean_path($$line)
} else: $$add_includes {
!contains(line, ".* \\(framework directory\\)"): \
QMAKE_DEFAULT_INCDIRS += $$clean_path($$line)
}
}
}
if(!darwin:clang)|intel_icc {
# Clang on a non-Apple system (that is, a system without ld64 -- say, with GNU ld
# or gold under Linux) will not print any library search path. Need to use another
# invocation with different options (which in turn doesn't print include search
# paths, so it can't just be used in place of the above code).
# What's more, -print-search-dirs can't be used on clang on Apple because it
# won't print all the library paths (only the clang-internal ones).
output = $$system("$$cmd_prefix $$QMAKE_LINK $$QMAKE_LFLAGS -print-search-dirs", lines, ec)
!equals(ec, 0): qtCompilerError($$QMAKE_LINK, $$output)
for (line, output) {
contains(line, "^libraries: .*") {
line ~= s,^libraries: ,,
equals(QMAKE_HOST.os, Windows) {
# clang (7.x) on Windows uses the wrong path list separator ...
line ~= s,:(?![/\\\\]),;,
paths = $$split(line, ;)
} else {
paths = $$split(line, $$QMAKE_DIRLIST_SEP)
}
for (path, paths): \
QMAKE_DEFAULT_LIBDIRS += $$clean_path($$replace(path, ^=, $$[SYSROOT]))
}
}
}
isEmpty(QMAKE_DEFAULT_LIBDIRS)|isEmpty(QMAKE_DEFAULT_INCDIRS): \
!integrity: \
error("failed to parse default search paths from compiler output")
QMAKE_DEFAULT_LIBDIRS = $$unique(QMAKE_DEFAULT_LIBDIRS)
} else: ghs {
cmd = $$QMAKE_CXX $$QMAKE_CXXFLAGS -$${LITERAL_HASH} -o /tmp/fake_output /tmp/fake_input.cpp
output = $$system("$$cmd", blob, ec)
!equals(ec, 0): qtCompilerError($$QMAKE_CXX, $$output)
output ~= s/\\\\\\n {8}//g
output = $$split(output, $$escape_expand(\\n))
for (line, output) {
contains(line, "^[^ ]+/ecom[^ ]+ .* /tmp/fake_input\\.cpp") {
for (parameter, $$list($$line)) {
contains(parameter, "^(-I|--include_no_mmd=|--sys_include=).*") {
parameter ~= s/^(-I|--include_no_mmd=|--sys_include=)//
QMAKE_DEFAULT_INCDIRS += $$clean_path($$parameter)
}
}
} else: contains(line, "^[^ ]+/elxr .*") {
for (parameter, $$list($$line)) {
contains(parameter, "^-L.*") {
parameter ~= s/^-L//
QMAKE_DEFAULT_LIBDIRS += $$clean_path($$parameter)
}
}
}
}
} else: msvc_cross {
# Use a batch file, because %VAR% in the system() call expands to
# the pre-script-call value, and !VAR! cannot be enabled outside
# a batch file without invoking another shell instance.
cmd = $$system_quote($$system_path($$PWD/data/dumpvcvars.bat))
hostArch = $$QMAKE_HOST.arch
equals(hostArch, x86_64): \
hostArch = amd64
!equals(arch, $$hostArch): \
arch = $${hostArch}_$$arch
isEmpty(MSVC_VER): \
error("Mkspec does not specify MSVC_VER. Cannot continue.")
versionAtLeast(MSVC_VER, 15.0) {
dir = $$(VSINSTALLDIR)
isEmpty(dir) {
version_parts = $$split(MSVC_VER, .)
MSVC_NEXT_MAJOR = $$num_add($$first(version_parts), 1)
vswhere = "$$getenv(ProgramFiles\(x86\))/Microsoft Visual Studio/Installer/vswhere.exe"
!exists($$vswhere): \
error("Could not find $$vswhere")
vswhere = $$system_quote($$system_path($$vswhere))
# -version parameter: A version range for instances to find. 15.0 will get all versions >= 15.0
# Example: [15.0,16.0) will find versions 15.*.
dir = $$system("$$vswhere -latest -version [$$MSVC_VER,$${MSVC_NEXT_MAJOR}.0] -property installationPath")
}
isEmpty(dir): \
error("Failed to find the Visual Studio installation directory.")
cmd += $$system_quote($$dir\\VC\\Auxiliary\\Build\\vcvarsall.bat) $$arch
} else {
dir = $$(VCINSTALLDIR)
isEmpty(dir): \
dir = $$read_registry(HKLM, \
"Software\\Microsoft\\VisualStudio\\$$MSVC_VER\\Setup\\VC\\ProductDir", 32)
isEmpty(dir): \
error("Failed to find the Visual C installation directory.")
cmd += $$system_quote($$dir\\vcvarsall.bat) $$arch
}
isEmpty(WINSDK_VER): \
error("Mkspec does not specify WINSDK_VER. Cannot continue.")
# We prefer the environment variable, because that may work around
# a broken registry entry after uninstalling a newer SDK.
# However, we do that only if the major+minor SDK version matches
# the one requested by the mkspec, as we might be building for a
# newer target than the host.
winsdk_ver = $$(WindowsSDKVersion)
!isEmpty(winsdk_ver) {
winsdk_ver ~= s,\\\\$,, # Work around SDK breakage.
!equals(WINSDK_VER, $$replace(winsdk_ver, ^(\\d+\\.\\d+).*$, \\1)): \
winsdk_ver =
}
!isEmpty(winsdk_ver) {
cmd += $$winsdk_ver
} else {
winsdk_ver = $$read_registry(HKLM, \
"Software\\Microsoft\\Microsoft SDKs\\Windows\\v$$WINSDK_VER\\ProductVersion", 32)
isEmpty(winsdk_ver): \
error("Windows SDK $$WINSDK_VER requested by mkspec is not installed. Cannot continue.")
cmd += $${winsdk_ver}.0
}
output = $$system("$$cmd 2>&1", lines, ec)
!equals(ec, 0): \
qtToolchainError("SDK setup script failed. Output:", $$output, \
"Command was: $$cmd")
lines = $$output
for(ever) {
isEmpty(lines): \
break()
line = $$take_first(lines)
equals(line, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+="): \
break()
}
!count(lines, 3): \
qtToolchainError("SDK setup script returned unexpected output:", $$output, \
"Command was: $$cmd")
# These contain only paths for the target.
QMAKE_DEFAULT_INCDIRS = $$qtSplitPathList($$member(lines, 0))
QMAKE_DEFAULT_LIBDIRS = $$qtSplitPathList($$member(lines, 1))
# PATH is inherently for the host, and paths that are not shadowed
# by vcvarsall.bat are assumed to contain only tools that work for
# both host and target builds.
QMAKE_DEFAULT_PATH = $$qtSplitPathList($$member(lines, 2))
# We de-duplicate, because the script just prepends to the paths for
# the host, some of which are identical to the ones for the target.
QMAKE_DEFAULT_PATH = $$unique(QMAKE_DEFAULT_PATH)
} else: msvc {
LIB = $$getenv("LIB")
QMAKE_DEFAULT_LIBDIRS = $$split(LIB, $$QMAKE_DIRLIST_SEP)
INCLUDE = $$getenv("INCLUDE")
QMAKE_DEFAULT_INCDIRS = $$split(INCLUDE, $$QMAKE_DIRLIST_SEP)
}
unix:if(!cross_compile|host_build) {
isEmpty(QMAKE_DEFAULT_INCDIRS): QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include
isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib
}
# cache() complains about undefined variables and doesn't persist empty ones.
!isEmpty(QMAKE_DEFAULT_INCDIRS): \
cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS)
!isEmpty(QMAKE_DEFAULT_LIBDIRS): \
cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS)
!isEmpty(QMAKE_DEFAULT_PATH): \
cache($${target_prefix}.PATH, set stash, QMAKE_DEFAULT_PATH)
} else {
QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS)
QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS)
QMAKE_DEFAULT_PATH = $$eval($${target_prefix}.PATH)
}
msvc_cross {
qmake_inc_exp.name = INCLUDE
qmake_inc_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_INCDIRS)
qmake_lib_exp.name = LIB
qmake_lib_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_LIBDIRS)
qmake_path_exp.name = PATH
qmake_path_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_PATH)
QMAKE_EXPORTED_VARIABLES += qmake_inc_exp qmake_lib_exp qmake_path_exp
}
unset(target_prefix)

20
mkspecs/features/uic.prf Normal file
View File

@ -0,0 +1,20 @@
qtPrepareLibExecTool(QMAKE_UIC, uic, _DEP)
isEmpty(UI_DIR):UI_DIR = .
isEmpty(QMAKE_MOD_UIC):QMAKE_MOD_UIC = ui_
uic.depends += $$QMAKE_UIC_EXE
uic.commands = $$QMAKE_UIC $$QMAKE_UIC_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
uic.depend_command = $$QMAKE_UIC_DEP -d ${QMAKE_FILE_IN}
uic.output = $$UI_DIR/$${QMAKE_MOD_UIC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
uic.input = FORMS
uic.variable_out = GENERATED_FILES
uic.CONFIG += no_link target_predeps dep_lines dep_existing_only
uic.name = UIC ${QMAKE_FILE_IN}
silent:uic.commands = @echo uic ${QMAKE_FILE_IN} && $$uic.commands
QMAKE_EXTRA_COMPILERS += uic
INCREDIBUILD_XGE += uic
!isEmpty(FORMS) {
INCLUDEPATH += $$absolute_path($$UI_DIR, $$OUT_PWD)
}

View File

@ -0,0 +1,21 @@
!versionAtLeast(QMAKE_XCODE_VERSION, 7.0) {
warning("You need to update Xcode to version 7 or newer to support bitcode")
} else: !macx-xcode {
# Simulator builds and all debug builds SHOULD use -fembed-bitcode-marker,
# but unfortunately the -fembed-bitcode and -fembed-bitcode-marker driver
# flags do not work in conjunction with -Xarch, so we'll have to let it use
# the "wrong" flags for now (note that this issue affects only the Makefile
# generator). We also don't want the flags to be passed in Xcode builds, as
# the Xcode ENABLE_BITCODE setting will take care of that for us.
release {
QMAKE_CFLAGS += -fembed-bitcode
QMAKE_CXXFLAGS += -fembed-bitcode
QMAKE_OBJECTIVE_CFLAGS += -fembed-bitcode
QMAKE_LFLAGS += -fembed-bitcode
} else {
QMAKE_CFLAGS += -fembed-bitcode-marker
QMAKE_CXXFLAGS += -fembed-bitcode-marker
QMAKE_OBJECTIVE_CFLAGS += -fembed-bitcode-marker
QMAKE_LFLAGS += -fembed-bitcode-marker
}
}

View File

@ -0,0 +1,51 @@
equals(TEMPLATE, app):qt {
# If the application uses Qt, it needs to be an application bundle
# to be able to deploy and run on iOS. The only exception to this
# is if you're working with a jailbroken device and can run the
# resulting binary from the console/over SSH, but that's not a
# use-case we care about, so no need to complicate the logic.
CONFIG *= app_bundle
# For Qt applications we want Xcode project files as the generated output,
# but since qmake doesn't handle the transition between makefiles and Xcode
# project files (which happens when using subdirs), we can't just override
# MAKEFILE_GENERATOR. Instead, we generate the Xcode project by spawning a
# child qmake process with -spec macx-xcode and let the top level qmake
# process generate a wrapper makefile that forwards everything to xcodebuild.
equals(MAKEFILE_GENERATOR, UNIX): \
CONFIG = xcodebuild $$CONFIG
}
load(default_post)
macx-xcode {
ios:!isEmpty(QMAKE_IOS_TARGETED_DEVICE_FAMILY) {
warning("QMAKE_IOS_TARGETED_DEVICE_FAMILY is deprecated; use QMAKE_APPLE_TARGETED_DEVICE_FAMILY")
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY
}
device_family.name = TARGETED_DEVICE_FAMILY
device_family.value = $$QMAKE_APPLE_TARGETED_DEVICE_FAMILY
QMAKE_MAC_XCODE_SETTINGS += device_family
equals(TEMPLATE, app):ios {
isEmpty(QMAKE_IOS_LAUNCH_SCREEN) {
qmake_launch_screen = LaunchScreen.storyboard
qmake_copy_launch_screen.input = $$QMAKESPEC/$$qmake_launch_screen
qmake_copy_launch_screen.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$qmake_launch_screen
QMAKE_SUBSTITUTES += qmake_copy_launch_screen
qmake_launch_screens.files = $$qmake_copy_launch_screen.output
} else {
qmake_launch_screens.files = $$QMAKE_IOS_LAUNCH_SCREEN
}
QMAKE_BUNDLE_DATA += qmake_launch_screens
}
}
!xcodebuild:equals(TEMPLATE, app):!isEmpty(QMAKE_INFO_PLIST) {
# Only link in photo library support if Info.plist contains
# NSPhotoLibraryUsageDescription. Otherwise it will be rejected from AppStore.
plist_path = $$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_)
system("/usr/libexec/PlistBuddy -c 'Print NSPhotoLibraryUsageDescription' $$system_quote($$plist_path) &>/dev/null"): \
QTPLUGIN += qiosnsphotolibrarysupport
}

View File

@ -0,0 +1,19 @@
sim_and_dev = false
!isEmpty(QT_VERSION):qtConfig(simulator_and_device): \
sim_and_dev = true
$$sim_and_dev|contains(QMAKE_MAC_SDK, ^$${device.sdk}.*): \
CONFIG += device $${device.sdk}
$$sim_and_dev|contains(QMAKE_MAC_SDK, ^$${simulator.sdk}.*): \
CONFIG += simulator $${simulator.sdk}
CONFIG += entrypoint
unset(sim_and_dev)
load(default_pre)
# Check for supported Xcode versions
!versionAtLeast(QMAKE_XCODE_VERSION, 4.3): \
error("This mkspec requires Xcode 4.3 or later")

View File

@ -0,0 +1,37 @@
#!/bin/bash
# Copyright (C) 2016 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
scheme=$1
shift
booted_simulator=$($DIR/devices.py --state booted $@ | tail -n 1)
echo "SIMULATOR_DEVICES = $booted_simulator"
xcodebuild test -scheme $scheme -destination 'id=0' -destination-timeout 1 2>&1| sed -n 's/{ \(platform:.*\) }/\1/p' | while read destination; do
id=$(echo $destination | sed -n -E 's/.*id:([^ ,]+).*/\1/p')
[[ $id == *"placeholder"* ]] && continue
echo $destination | tr ',' '\n' | while read keyval; do
key=$(echo $keyval | cut -d ':' -f 1 | tr '[:lower:]' '[:upper:]')
val=$(echo $keyval | cut -d ':' -f 2)
echo "%_$id: DESTINATION_${key} = $val"
if [ $key = 'PLATFORM' ]; then
if [ "$val" = "iOS" ]; then
echo "HARDWARE_DEVICES += $id"
elif [ "$val" = "iOS Simulator" -a "$id" != "$booted_simulator" ]; then
echo "SIMULATOR_DEVICES += $id"
elif [ "$val" = "tvOS" ]; then
echo "HARDWARE_DEVICES += $id"
elif [ "$val" = "tvOS Simulator" -a "$id" != "$booted_simulator" ]; then
echo "SIMULATOR_DEVICES += $id"
elif [ "$val" = "watchOS" ]; then
echo "HARDWARE_DEVICES += $id"
elif [ "$val" = "watchOS Simulator" -a "$id" != "$booted_simulator" ]; then
echo "SIMULATOR_DEVICES += $id"
fi
fi
done
echo
done

View File

@ -0,0 +1,51 @@
#!/usr/bin/env python3
# Copyright (C) 2017 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
from __future__ import print_function
import argparse
import json
import subprocess
from distutils.version import StrictVersion
def is_available(object):
if "isAvailable" in object:
return object["isAvailable"] # introduced in Xcode 11
else:
return "unavailable" not in object["availability"]
def is_suitable_runtime(runtimes, runtime_name, platform, min_version):
for runtime in runtimes:
identifier = runtime["identifier"]
if (runtime["name"] == runtime_name or identifier == runtime_name) \
and is_available(runtime) \
and identifier.startswith("com.apple.CoreSimulator.SimRuntime.{}".format(platform)) \
and StrictVersion(runtime["version"]) >= min_version:
return True
return False
def simctl_runtimes():
return json.loads(subprocess.check_output(
["/usr/bin/xcrun", "simctl", "list", "runtimes", "--json"]))["runtimes"]
def simctl_devices():
return json.loads(subprocess.check_output(
["/usr/bin/xcrun", "simctl", "list", "devices", "--json"]))["devices"]
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--platform', choices=['iOS', 'tvOS', 'watchOS'], required=True)
parser.add_argument('--minimum-deployment-target', type=StrictVersion, default='0.0')
parser.add_argument('--state',
choices=['booted', 'shutdown', 'creating', 'booting', 'shutting-down'], action='append')
args = parser.parse_args()
runtimes = simctl_runtimes()
device_dict = simctl_devices()
for runtime_name in device_dict:
if is_suitable_runtime(runtimes, runtime_name, args.platform, args.minimum_deployment_target):
for device in device_dict[runtime_name]:
if is_available(device) \
and (args.state is None or device["state"].lower() in args.state):
print(device["udid"])

Some files were not shown because too many files have changed in this diff Show More