summaryrefslogtreecommitdiffstats
path: root/mkspecs/features
diff options
context:
space:
mode:
Diffstat (limited to 'mkspecs/features')
-rw-r--r--mkspecs/features/android/android.prf18
-rw-r--r--mkspecs/features/data/testserver/Dockerfile29
-rw-r--r--mkspecs/features/data/testserver/docker-compose-common.yml38
-rw-r--r--mkspecs/features/exclusive_builds.prf4
-rw-r--r--mkspecs/features/lex.prf50
-rw-r--r--mkspecs/features/ltcg.prf2
-rw-r--r--mkspecs/features/qmltestcase.prf10
-rw-r--r--mkspecs/features/qt_common.prf4
-rw-r--r--mkspecs/features/qt_configure.prf7
-rw-r--r--mkspecs/features/qt_module.prf9
-rw-r--r--mkspecs/features/qt_plugin.prf1
-rw-r--r--mkspecs/features/sanitizer.prf25
-rw-r--r--mkspecs/features/testcase.prf16
-rw-r--r--mkspecs/features/unsupported/testserver.prf231
-rw-r--r--mkspecs/features/win32/dumpcpp.prf16
-rw-r--r--mkspecs/features/yacc.prf59
16 files changed, 459 insertions, 60 deletions
diff --git a/mkspecs/features/android/android.prf b/mkspecs/features/android/android.prf
index 1dc8f87313..0e6f4a4592 100644
--- a/mkspecs/features/android/android.prf
+++ b/mkspecs/features/android/android.prf
@@ -1,3 +1,21 @@
+APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
+!contains(TEMPLATE, subdirs): {
+ apk_install_target.target = apk_install_target
+ apk_install_target.depends = first
+ apk_install_target.commands = $(MAKE) -f $(MAKEFILE) INSTALL_ROOT=$$OUT_PWD/android-build install
+
+ apk.target = apk
+ apk.depends = apk_install_target
+ 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.commands = $$ANDROIDDEPLOYQT --input $$ANDROID_DEPLOYMENT_SETTINGS_FILE --output $$OUT_PWD/android-build --apk $$APK_PATH
+} else {
+ prepareRecursiveTarget(apk)
+ prepareRecursiveTarget(apk_install_target)
+}
+QMAKE_EXTRA_TARGETS *= apk apk_install_target
+
contains(TEMPLATE, ".*app") {
!android_app {
!contains(TARGET, ".so"): TARGET = lib$${TARGET}.so
diff --git a/mkspecs/features/data/testserver/Dockerfile b/mkspecs/features/data/testserver/Dockerfile
new file mode 100644
index 0000000000..a20d289d3f
--- /dev/null
+++ b/mkspecs/features/data/testserver/Dockerfile
@@ -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
diff --git a/mkspecs/features/data/testserver/docker-compose-common.yml b/mkspecs/features/data/testserver/docker-compose-common.yml
new file mode 100644
index 0000000000..58282c1273
--- /dev/null
+++ b/mkspecs/features/data/testserver/docker-compose-common.yml
@@ -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}"
diff --git a/mkspecs/features/exclusive_builds.prf b/mkspecs/features/exclusive_builds.prf
index 1ff9a04d42..b28e74146a 100644
--- a/mkspecs/features/exclusive_builds.prf
+++ b/mkspecs/features/exclusive_builds.prf
@@ -38,5 +38,5 @@ defineTest(addExclusiveBuilds) {
}
# Default directories to process
-QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR
-QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR
+QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR LEX_DIR YACC_DIR
+QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR DESTDIR $$QMAKE_DIR_REPLACE_SANE
diff --git a/mkspecs/features/lex.prf b/mkspecs/features/lex.prf
index 7d8325bedb..ee06215103 100644
--- a/mkspecs/features/lex.prf
+++ b/mkspecs/features/lex.prf
@@ -2,37 +2,49 @@
# Lex extra-compiler for handling files specified in the LEXSOURCES variable
#
-{
- 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
- }
+isEmpty(LEX_DIR): LEX_DIR = .
- isEmpty(QMAKE_LEXFLAGS_MANGLE):QMAKE_LEXFLAGS_MANGLE = -P${QMAKE_FILE_BASE}
+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
+ !yacc_no_name_mangle: QMAKE_LEXEXTRAFLAGS += $$QMAKE_LEXFLAGS_MANGLE
contains(QMAKE_LEX, .*flex) {
# GNU flex, we can use -o outfile
- lex.commands = $$QMAKE_LEX $$QMAKE_LEXEXTRAFLAGS --nounistd -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
+ 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
- lex.commands = \
- -$(DEL_FILE) ${QMAKE_FILE_OUT}$$escape_expand(\\n\\t) \
- $$QMAKE_LEX $$QMAKE_LEXEXTRAFLAGS ${QMAKE_FILE_IN}$$escape_expand(\\n\\t) \
- $(MOVE) $$intermediate_file ${QMAKE_FILE_OUT} $$escape_expand(\\n\\t)
- unset(intermediate_file)
+ 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.output = $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_LEX}$${first(QMAKE_EXT_CPP)}
- silent:lex.commands = @echo Lex ${QMAKE_FILE_IN} && $$lex.commands
+ 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
}
diff --git a/mkspecs/features/ltcg.prf b/mkspecs/features/ltcg.prf
index a94f6d0eeb..10d14dfe85 100644
--- a/mkspecs/features/ltcg.prf
+++ b/mkspecs/features/ltcg.prf
@@ -4,7 +4,7 @@ static:no-static-ltcg {
# 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
+ # tables so the linker will know better. For other compilers, we disable LTCG
# for static libraries.
msvc {
# Nothing to do
diff --git a/mkspecs/features/qmltestcase.prf b/mkspecs/features/qmltestcase.prf
index b4b1224781..ae4ebef513 100644
--- a/mkspecs/features/qmltestcase.prf
+++ b/mkspecs/features/qmltestcase.prf
@@ -1,8 +1,14 @@
!isEmpty(SOURCES) {
QT += qml qmltest
load(testcase)
- contains(TEMPLATE, vc.*): DEFINES += QUICK_TEST_SOURCE_DIR=\"$$_PRO_FILE_PWD_\"
- else: DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\"$$_PRO_FILE_PWD_\")
+ !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): warning("The RESOURCES qmake variable is empty, the test will probably fail to run")
+ DEFINES += QUICK_TEST_SOURCE_DIR=\":/\"
+ }
+
} else {
# Allow a project to run tests without a CPP stub
TEMPLATE = aux
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf
index e64dfa98c2..c24f2c6062 100644
--- a/mkspecs/features/qt_common.prf
+++ b/mkspecs/features/qt_common.prf
@@ -152,8 +152,8 @@ warnings_are_errors:warning_clean {
android: QMAKE_CXXFLAGS_WARN_ON += -Wno-error=literal-suffix
}
} else:msvc:!intel_icl {
- # enable for MSVC 2012, MSVC 2013, MSVC 2015
- contains(MSVC_VER, "1[124].0"): QMAKE_CXXFLAGS_WARN_ON += -WX
+ # enable for MSVC 2015, MSVC 2017
+ contains(MSVC_VER, "1[45].0"): QMAKE_CXXFLAGS_WARN_ON += -WX
}
unset(ver)
}
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf
index 9be4fb6f1f..2ac9de266f 100644
--- a/mkspecs/features/qt_configure.prf
+++ b/mkspecs/features/qt_configure.prf
@@ -61,6 +61,13 @@ defineTest(qtConfCommandlineSetInput) {
val = $${2}
!isEmpty($${currentConfig}.commandline.options.$${arg}.name): \
arg = $$eval($${currentConfig}.commandline.options.$${arg}.name)
+ !isEmpty(config.input.$$arg) {
+ oldval = $$eval(config.input.$$arg)
+ equals(oldval, $$val): \
+ qtConfAddNote("Option '$$arg' with value '$$val' was specified twice")
+ else: \
+ qtConfAddNote("Overriding option '$$arg' with '$$val' (was: '$$oldval')")
+ }
config.input.$$arg = $$val
export(config.input.$$arg)
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index 46687f262e..169d91c746 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -269,7 +269,7 @@ load(qt_installs)
load(qt_targets)
# this builds on top of qt_common
-!internal_module:if(unix|mingw) {
+!internal_module:if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) {
CONFIG += create_pc
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
host_build: \
@@ -282,11 +282,13 @@ load(qt_targets)
} else {
QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw]
QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME
+ for(inc, MODULE_AUX_INCLUDES): \
+ QMAKE_PKGCONFIG_CFLAGS += -I${includedir}/$$section(inc, /, 1, 1)
}
QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ")
- QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)
+ QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)$$qtPlatformTargetSuffix()
for(i, MODULE_DEPENDS): \
- QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))
+ QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))$$qtPlatformTargetSuffix()
isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \
QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module
!isEmpty(lib_replace0.match) {
@@ -334,5 +336,6 @@ win32 {
# On other platforms, Qt's own compilation goes needs to compile the Qt 5.0 API
DEFINES *= QT_DISABLE_DEPRECATED_BEFORE=0x050000
}
+DEFINES *= QT_DEPRECATED_WARNINGS_SINCE=0x060000
TARGET = $$qt5LibraryTarget($$TARGET$$QT_LIBINFIX) # Do this towards the end
diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf
index 40528a65e2..6e7388c352 100644
--- a/mkspecs/features/qt_plugin.prf
+++ b/mkspecs/features/qt_plugin.prf
@@ -91,6 +91,7 @@ CONFIG(static, static|shared)|prefix_build {
target.path = $$[QT_INSTALL_PLUGINS]/$$PLUGIN_TYPE
INSTALLS += target
+qt_libinfix_plugins: TARGET = $$TARGET$$QT_LIBINFIX
TARGET = $$qt5LibraryTarget($$TARGET)
CONFIG += create_cmake
diff --git a/mkspecs/features/sanitizer.prf b/mkspecs/features/sanitizer.prf
index 9e7ff0218a..c7d72aec80 100644
--- a/mkspecs/features/sanitizer.prf
+++ b/mkspecs/features/sanitizer.prf
@@ -1,10 +1,33 @@
# 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 {
diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf
index b8102c26b5..d4f08835f1 100644
--- a/mkspecs/features/testcase.prf
+++ b/mkspecs/features/testcase.prf
@@ -52,14 +52,26 @@ debug_and_release:debug_and_release_target {
}
# Allow for a custom test runner script
-$${type}.commands += $(TESTRUNNER)
+
+android: isEmpty($(TESTRUNNER)) {
+ 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 --androiddeployqt \"$$ANDROIDDEPLOYQT --input $$ANDROID_DEPLOYMENT_SETTINGS_FILE\"
+ $${type}.commands += --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) -f $(MAKEFILE)\"
+ $${type}.commands += --apk $$APK_PATH
+} 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: \
+ else: !android: \
$${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
} else {
# Windows
diff --git a/mkspecs/features/unsupported/testserver.prf b/mkspecs/features/unsupported/testserver.prf
new file mode 100644
index 0000000000..bca88ea2d8
--- /dev/null
+++ b/mkspecs/features/unsupported/testserver.prf
@@ -0,0 +1,231 @@
+# Integrating docker-based test servers into Qt Test framework
+#
+# This file adds support for docker-based test servers built by testcase
+# projects that need them. To enable this feature, any automated test can
+# include testserver.pri in its project file. This instructs qmake to insert
+# additional targets into the generated Makefile. The 'check' target then brings
+# up test servers before running the testcase, and shuts them down afterwards.
+#
+# TESTSERVER_COMPOSE_FILE
+# - Contains the path of docker-compose file
+# This configuration file defines the services used for autotests. It tells the
+# docker engine how to build up the docker images and containers. In qtbase, a
+# shared docker-compose file is located in the tests folder.
+# Example: TESTSERVER_COMPOSE_FILE = \
+# $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
+#
+# The user must run the provisioning scripts in advance before attempting to
+# build the test servers. The docker_testserver.sh script is used to build up
+# the docker images into the docker-cache. It handles the immutable parts of the
+# server installation that rarely need adjustment, such as downloading packages.
+# Example: qt5/coin/provisioning/.../testserver/docker_testserver.sh
+#
+# QT_TEST_SERVER_LIST
+# - A list of test servers to bring up for this testcase
+# These test servers should be defined in $$TESTSERVER_COMPOSE_FILE. Each
+# testcase can define the test servers it depends on.
+# Example: QT_TEST_SERVER_LIST = apache2 squid vsftpd ftp-proxy danted
+#
+# Pre-processor defines needed for the application:
+# QT_TEST_SERVER
+# - A preprocessor macro used for testcase to change testing parameters at
+# compile time
+# This macro is predefined for docker-based test servers and is passed as a
+# compiler option (-DQT_TEST_SERVER). The testcase can then check whether
+# docker-based servers are in use and change the testing parameters, such as
+# host name or port number, at compile time. An example can be found in
+# network-settings.h.
+#
+# Example:
+# #if defined(QT_TEST_SERVER)
+# Change the testing parameters at compile time
+# #endif
+#
+# QT_TEST_SERVER_DOMAIN
+# - A preprocessor macro that holds the server domain name
+# Provided for the helper functions in network-settings.h. Use function
+# serverDomainName() in your application instead.
+#
+# Additional make targets:
+# 1. check_network - A renamed target from the check target of testcase feature.
+# 2. testserver_clean - Clean up server containers/images and tidy away related
+# files.
+
+# The docker test server should only be integrated in the leaf Makefile.
+# If debug_and_release option is in use, skip the meta-Makefile except for
+# Makefile.Debug and Makefile.Release.
+debug_and_release:!build_pass: return()
+
+DOCKER_ENABLED = 1
+
+equals(QMAKE_HOST.os, Darwin) {
+ DOCKER_ENABLED = 0
+ message("Not using docker network test server on macOS, see QTQAINFRA-2717 and QTQAINFRA-2750")
+}
+
+TESTSERVER_VERSION = ""
+
+equals(DOCKER_ENABLED, 1) {
+ TESTSERVER_VERSION = $$system(docker-compose --version)
+}
+
+isEmpty(TESTSERVER_VERSION) {
+ # Make check with server "qt-test-server.qt-test-net" as a fallback
+} else {
+ # Make check with docker test servers
+ equals(QMAKE_HOST.os, Linux) {
+ # For the platform supporting docker bridge network, each container is
+ # assigned a unique hostname and connected to the same network domain
+ # to communicate with the others.
+ DEFINES += QT_TEST_SERVER_NAME
+ DNSDOMAIN = test-net.qt.local
+ } else {
+ # For the others, the containers are deployed into a virtual machine
+ # using the host network. All the containers share the same hostname of
+ # the virtual machine, and they are connected to the same network domain.
+ # NOTE: In Windows, Apple Bonjour only works within a single local domain.
+ DNSDOMAIN = local
+ }
+
+ equals(QMAKE_HOST.os, Darwin) {
+ # There is no docker bridge on macOS. It is impossible to ping a container.
+ # Docker docs recommends using port mapping to connect to a container;
+ # but it causes a port conflict if the user is running a service that
+ # binds the same port on the host. An alternative solution is to deploy
+ # the docker environment into VirtualBox using docker-machine.
+ isEmpty(TESTSERVER_COMPOSE_FILE): TESTSERVER_COMPOSE_FILE = \
+ $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose-host-network.yml
+
+ # The connection configuration for the target machine
+ MACHINE_CONFIG = $(shell docker-machine config qt-test-server)
+
+ # The environment variables passed to the docker-compose file
+ TEST_ENV = 'MACHINE_IP=$(shell docker-machine ip qt-test-server)'
+ TEST_ENV += 'HOST_NAME=qt-test-server'
+ TEST_ENV += 'TEST_DOMAIN=$$DNSDOMAIN'
+ TEST_ENV += 'SHARED_DATA=$$PWD/../data/testserver'
+ TEST_ENV += 'SHARED_SERVICE=host-network'
+ TEST_CMD = env
+ } else:equals(QMAKE_HOST.os, Windows) {
+ # There is no docker bridge on Windows. It is impossible to ping a container.
+ # Use docker-machine to deploy the docker environment into VirtualBox.
+ isEmpty(TESTSERVER_COMPOSE_FILE): TESTSERVER_COMPOSE_FILE = \
+ $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose-host-network.yml
+
+ # The connection configuration for the target machine
+ MACHINE_CONFIG = (docker-machine config qt-test-server)
+
+ # The environment variables passed to the docker-compose file
+ TEST_ENV = '\$\$env:MACHINE_IP = docker-machine ip qt-test-server;'
+ TEST_ENV += '\$\$env:HOST_NAME = $$shell_quote(\"qt-test-server\");'
+ TEST_ENV += '\$\$env:TEST_DOMAIN = $$shell_quote(\"$$DNSDOMAIN\");'
+ TEST_ENV += '\$\$env:SHARED_DATA = $$shell_quote(\"$$PWD/../data/testserver\");'
+ TEST_ENV += '\$\$env:SHARED_SERVICE = $$shell_quote(\"host-network\");'
+
+ # Docker-compose CLI environment variables:
+ # Enable path conversion from Windows-style to Unix-style in volume definitions.
+ TEST_ENV += '\$\$env:COMPOSE_CONVERT_WINDOWS_PATHS = $$shell_quote(\"true\");'
+
+ TEST_CMD = 'PowerShell -noprofile'
+ CONFIG += PowerShell
+ } else {
+ isEmpty(TESTSERVER_COMPOSE_FILE): TESTSERVER_COMPOSE_FILE = \
+ $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose-bridge-network.yml
+ # The environment variables passed to the docker-compose file
+ TEST_ENV = 'TEST_DOMAIN=$$DNSDOMAIN'
+ TEST_ENV += 'SHARED_DATA=$$PWD/../data/testserver'
+ TEST_ENV += 'SHARED_SERVICE=bridge-network'
+ TEST_CMD = env
+ }
+
+ # If $$TESTSERVER_COMPOSE_FILE defined by platform doesn't exist, the default
+ # docker-compose.yml is used as a fallback.
+ !exists($$TESTSERVER_COMPOSE_FILE): TESTSERVER_COMPOSE_FILE = \
+ $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
+ !exists($$TESTSERVER_COMPOSE_FILE): error("Invalid TESTSERVER_COMPOSE_FILE specified")
+
+
+ # The domain name is relevant to https keycert (qnetworkreply/crts/qt-test-net-cacert.pem).
+ DEFINES += QT_TEST_SERVER QT_TEST_SERVER_DOMAIN=$$shell_quote(\"$${DNSDOMAIN}\")
+
+ # Ensure that the docker-compose file is provided. It is a configuration
+ # file which is mandatory for all docker-compose commands. You can get more
+ # detail from the description of TESTSERVER_COMPOSE_FILE above. There is
+ # also an example showing how to configure it manually.
+ FILE_PRETEST_MSG = "Project variable 'TESTSERVER_COMPOSE_FILE' is not set"
+ PowerShell {
+ testserver_pretest.commands = echo $$TESTSERVER_VERSION &&
+ testserver_pretest.commands += \
+ $$TEST_CMD if ([String]::IsNullOrEmpty($$shell_quote(\"$$TESTSERVER_COMPOSE_FILE\"))) \
+ {Write-Error $$shell_quote(\"$$FILE_PRETEST_MSG\")} &&
+ } else {
+ testserver_pretest.commands = $(info "testserver:" $$TESTSERVER_VERSION)
+ testserver_pretest.commands += $(if $$TESTSERVER_COMPOSE_FILE,,$(error $$FILE_PRETEST_MSG))
+ }
+
+ # Make sure docker-machine is both created and running. The docker_machine
+ # script is used to deploy the docker environment into VirtualBox.
+ # Example: qt5/coin/provisioning/common/shared/testserver/docker_machine.sh
+ !isEmpty(MACHINE_CONFIG) {
+ MACHINE_LIST_CMD = docker-machine ls -q --filter "Name=^qt-test-server\$\$"
+ MACHINE_LIST_MSG = "Docker machine qt-test-server not found"
+ PowerShell {
+ testserver_pretest.commands += $$TEST_CMD if (!($$MACHINE_LIST_CMD)) \
+ {Write-Error $$shell_quote(\"$$MACHINE_LIST_MSG\")} &&
+ } else {
+ testserver_pretest.commands += \
+ $(if $(shell $$MACHINE_LIST_CMD),,$(error $$MACHINE_LIST_MSG))
+ }
+
+ MACHINE_STATE_CMD = \
+ docker-machine ls -q --filter "State=Running" --filter "Name=^qt-test-server\$\$"
+ MACHINE_START_CMD = docker-machine start qt-test-server
+ MACHINE_RECERT = docker-machine regenerate-certs -f qt-test-server
+ PowerShell {
+ testserver_pretest.commands += \
+ $$TEST_CMD if (!($$MACHINE_STATE_CMD)) {$$MACHINE_START_CMD; $$MACHINE_RECERT} &&
+ } else {
+ testserver_pretest.commands += \
+ $(if $(shell $$MACHINE_STATE_CMD),,\
+ $(shell $$MACHINE_START_CMD > /dev/null && $$MACHINE_RECERT > /dev/null))
+ }
+ }
+
+ # Before starting the test servers, it requires the user to run the setup
+ # script (coin/provisioning/.../testserver/docker_testserver.sh) in advance.
+ IMAGE_PRETEST_CMD = docker $$MACHINE_CONFIG images -aq "qt-test-server-*"
+ IMAGE_PRETEST_MSG = "Docker image qt-test-server-* not found"
+ PowerShell {
+ testserver_pretest.commands += $$TEST_CMD if (!($$IMAGE_PRETEST_CMD)) \
+ {Write-Error $$shell_quote(\"$$IMAGE_PRETEST_MSG\")}
+ } else {
+ testserver_pretest.commands += \
+ $(if $(shell $$IMAGE_PRETEST_CMD),,$(error $$IMAGE_PRETEST_MSG))
+ }
+
+ # Rename the check target of testcase feature
+ check.target = check_network
+ testserver_test.target = check
+
+ # Pretesting test servers environment
+ testserver_test.depends = testserver_pretest
+
+ # Bring up test servers and make sure the services are ready.
+ !isEmpty(TEST_CMD): testserver_test.commands = $$TEST_CMD $$TEST_ENV
+ testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE up \
+ --build -d --force-recreate --timeout 1 $${QT_TEST_SERVER_LIST} &&
+
+ # Check test cases with docker-based test servers.
+ testserver_test.commands += $(MAKE) -f $(MAKEFILE) check_network &&
+
+ # Stop and remove test servers after testing.
+ !isEmpty(TEST_CMD): testserver_test.commands += $$TEST_CMD $$TEST_ENV
+ testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \
+ --timeout 1
+
+ # Destroy test servers and tidy away related files.
+ testserver_clean.commands = docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \
+ --rmi all
+
+ QMAKE_EXTRA_TARGETS += testserver_pretest testserver_test testserver_clean
+}
diff --git a/mkspecs/features/win32/dumpcpp.prf b/mkspecs/features/win32/dumpcpp.prf
index c8cb0dd24b..d19da3d077 100644
--- a/mkspecs/features/win32/dumpcpp.prf
+++ b/mkspecs/features/win32/dumpcpp.prf
@@ -22,15 +22,15 @@ dumpcpp_impl.depends += ${QMAKE_FILE_BASE}.h
QMAKE_EXTRA_COMPILERS += dumpcpp_impl
-# Create dependencies from every object file to our generated header files.
-if(isEmpty(BUILDS)|build_pass):have_target:!contains(TEMPLATE, vc.*) {
+# Call dumpcpp the first time if the files do not exist to help find dependencies
+!build_pass:have_target:!contains(TEMPLATE, vc.*) {
for(tlb, TYPELIBS) {
+ tlbCopy = $$replace(tlb, \", )
hdr = $$basename(tlb)
- hdr = $$section(hdr, ., 0, -2).h
- TYPELIB_HEADERS += $$hdr
+ hdr = $$section(hdr, ., 0, -2)
+ tmp_command = $$QMAKE_DUMPCPP $$system_quote($$absolute_path($$tlb, $$_PRO_FILE_PWD_)) \
+ -o $$system_quote($$OUT_PWD/$$hdr)
+ qaxcontainer_compat: tmp_command += -compat
+ !exists($$OUT_PWD/$${hdr}.h): system($$tmp_command)
}
-
- objtgt.target = $(OBJECTS)
- objtgt.depends += $$TYPELIB_HEADERS
- QMAKE_EXTRA_TARGETS += objtgt
}
diff --git a/mkspecs/features/yacc.prf b/mkspecs/features/yacc.prf
index 618f0668c2..0c7ff7321e 100644
--- a/mkspecs/features/yacc.prf
+++ b/mkspecs/features/yacc.prf
@@ -2,32 +2,49 @@
# Yacc extra-compiler for handling files specified in the YACCSOURCES variable
#
-{
- yacc_decl.name = Yacc header
- yacc_decl.input = YACCSOURCES
- yacc_decl.variable_out = GENERATED_FILES
+isEmpty(YACC_DIR): YACC_DIR = .
+defineReplace(yaccCommands) {
+ input = $$relative_path($$absolute_path($$1, $$OUT_PWD), $$OUT_PWD/$$YACC_DIR)
+ input_base = $$basename(1)
+ input_base ~= s/\.[^.]*$//
+ hpp_output = $$2
+ cpp_output = $$hpp_output
+ cpp_output ~= s/$$re_escape($$first(QMAKE_EXT_H))$/$$first(QMAKE_EXT_CPP)/
isEmpty(QMAKE_YACCFLAGS_MANGLE) {
- QMAKE_YACCFLAGS_MANGLE = -p ${QMAKE_FILE_BASE} -b ${QMAKE_FILE_BASE}
- QMAKE_YACC_HEADER = ${QMAKE_FILE_BASE}.tab.h
- QMAKE_YACC_SOURCE = ${QMAKE_FILE_BASE}.tab.c
+ QMAKE_YACCFLAGS_MANGLE = -p $${input_base} -b $${input_base}
+ QMAKE_YACC_HEADER = $${input_base}.tab.h
+ QMAKE_YACC_SOURCE = $${input_base}.tab.c
} else {
- QMAKE_YACCFLAGS_MANGLE ~= s/\\$base/${QMAKE_FILE_BASE}/g #backwards compat
- QMAKE_YACC_HEADER ~= s/\\$base/${QMAKE_FILE_BASE}/g
- QMAKE_YACC_SOURCE ~= s/\\$base/${QMAKE_FILE_BASE}/g
+ QMAKE_YACCFLAGS_MANGLE ~= s/\\$base/$${input_base}/g #backwards compat
+ QMAKE_YACC_HEADER ~= s/\\$base/$${input_base}/g
+ QMAKE_YACC_SOURCE ~= s/\\$base/$${input_base}/g
}
QMAKE_YACCDECLFLAGS = $$QMAKE_YACCFLAGS
- !yacc_no_name_mangle:QMAKE_YACCDECLFLAGS += $$QMAKE_YACCFLAGS_MANGLE
+ !yacc_no_name_mangle: QMAKE_YACCDECLFLAGS += $$QMAKE_YACCFLAGS_MANGLE
- yacc_decl.commands = \
- -$(DEL_FILE) $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_H)} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t) \
- $$QMAKE_YACC $$QMAKE_YACCDECLFLAGS ${QMAKE_FILE_IN}$$escape_expand(\\n\\t) \
- $(MOVE) $${QMAKE_YACC_HEADER} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_H)}$$escape_expand(\\n\\t) \
- $(MOVE) $${QMAKE_YACC_SOURCE} $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_CPP)}$$escape_expand(\\n\\t)
- yacc_decl.output = $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_H)}
+ !equals(YACC_DIR, .): yacc_call = cd $$YACC_DIR &&
+ yacc_call += $$QMAKE_YACC $$QMAKE_YACCDECLFLAGS $${input}
+
+ commands = \
+ -$(DEL_FILE) $${hpp_output} $${cpp_output}$$escape_expand(\\n\\t) \
+ $${yacc_call}$$escape_expand(\\n\\t) \
+ $(MOVE) $${YACC_DIR}/$${QMAKE_YACC_HEADER} $${hpp_output}$$escape_expand(\\n\\t) \
+ $(MOVE) $${YACC_DIR}/$${QMAKE_YACC_SOURCE} $${cpp_output}$$escape_expand(\\n\\t)
+
+ silent: commands = @echo Yacc $$1 && $$commands
+ return($$commands)
+}
- silent:yacc_decl.commands = @echo Yacc ${QMAKE_FILE_IN} && $$yacc_decl.commands
+yacc_output_base = $${YACC_DIR}/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}
+
+{
+ yacc_decl.name = Yacc header
+ yacc_decl.input = YACCSOURCES
+ yacc_decl.variable_out = GENERATED_FILES
+ yacc_decl.commands = ${QMAKE_FUNC_yaccCommands}
+ yacc_decl.output = $${yacc_output_base}$$first(QMAKE_EXT_H)
QMAKE_EXTRA_COMPILERS += yacc_decl
}
@@ -37,7 +54,9 @@
yacc_impl.variable_out = GENERATED_SOURCES
yacc_impl.dependency_type = TYPE_C
yacc_impl.commands = $$escape_expand(\\n) # We don't want any commands where, but if command is empty no rules are created
- yacc_impl.depends += $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_H)} # Make sure we depend on the step above
- yacc_impl.output = $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_CPP)} # Faked output from this step, output really created in step above
+ yacc_impl.depends += $${yacc_output_base}$$first(QMAKE_EXT_H) # Make sure we depend on the step above
+ yacc_impl.output = $${yacc_output_base}$$first(QMAKE_EXT_CPP) # Faked output from this step, output really created in step above
QMAKE_EXTRA_COMPILERS += yacc_impl
}
+
+unset(yacc_output_base)