1# 2# W A R N I N G 3# ------------- 4# 5# This file is not part of the Qt API. It exists purely as an 6# implementation detail. It may change from version to version 7# without notice, or even be removed. 8# 9# We mean it. 10# 11 12load(qt_build_paths) 13 14!build_pass:git_build { 15 qtPrepareTool(QMAKE_SYNCQT, syncqt, , system) 16 minimal_syncqt { 17 QMAKE_SYNCQT += -minimal $$QMAKE_SYNCQT_OPTIONS 18 } else { 19 qtConfig(private_tests): \ # -developer-build 20 QMAKE_SYNCQT += -check-includes 21 } 22 for(mod, MODULE_INCNAME): \ 23 QMAKE_SYNCQT += -module $$mod 24 QMAKE_SYNCQT += \ 25 -version $$VERSION -outdir $$system_quote($$MODULE_BASE_OUTDIR) \ 26 -builddir $$system_quote($$REAL_MODULE_BASE_OUTDIR) $$MODULE_SYNCQT_DIR 27 !silent: message($$QMAKE_SYNCQT) 28 system($$QMAKE_SYNCQT)|error("Failed to run: $$QMAKE_SYNCQT") 29 30 !minimal_syncqt { 31 include-distclean.commands = \ 32 $$QMAKE_DEL_TREE $$shell_quote($$shell_path($$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME)) 33 QMAKE_EXTRA_TARGETS += include-distclean 34 DISTCLEAN_DEPS += include-distclean 35 } 36} 37 38# Pre-generated headers in the source tree (tar-ball) and 39# - shadow build or 40# - non-shadow non-prefix build of a module which is not qtbase 41# (because the build-time generated headers all end up in qtbase). 42!git_build: \ 43 if(!equals(_PRO_FILE_PWD_, $$OUT_PWD) \ 44 |if(!prefix_build:!equals(MODULE_BASE_INDIR, $$[QT_HOST_PREFIX]))): \ 45 CONFIG += split_incpath 46 47# To avoid stuffing the code with repetetive conditionals, 48# we parametrize the names of the variables we assign to. 49 50# Internal modules have no private part - they *are* private. 51!internal_module: \ 52 prv = _PRIVATE 53 54# When doing a framework build with a prefix, the module needs to point 55# into the frameworks' Headers dirs directly, as no shared include/ dir 56# is installed. 57# However, during the build, it needs to point into the shared include/ 58# dir, as the framework doesn't even exist yet. For bootstrapped modules 59# which borrow headers from "proper" modules, this situation persists 60# even beyond the module's own build. The implication of this is that 61# qmake might never use a framework's headers in a non-prefix build, 62# as there is no separate set of .pri files for users outside Qt. 63# Borrowing is assumed to happen from modules which, in a framework build, 64# actually are frameworks. 65prefix_build:module_frameworks: \ 66 fwd = _FWD 67# When using a split include path during the build, the installed module's 68# include path is also structurally different from that in the build dir. 69prefix_build:split_incpath: \ 70 sfwd = _FWD 71 72ibase = \$\$QT_MODULE_INCLUDE_BASE 73MODULE$${fwd}_INCLUDES = $$ibase 74split_incpath { 75 bibase = $$val_escape(MODULE_BASE_OUTDIR)/include 76 MODULE$${sfwd}_INCLUDES += $$bibase 77} 78for(mod, MODULE_INCNAME) { 79 mibase = $$ibase/$$mod 80 MODULE$${fwd}_INCLUDES += $$mibase 81 MODULE$${fwd}$${prv}_INCLUDES += $$mibase/$$VERSION $$mibase/$$VERSION/$$mod 82 split_incpath { 83 mbibase = $$bibase/$$mod 84 MODULE$${sfwd}_INCLUDES += $$mbibase 85 generated_privates: \ 86 MODULE$${sfwd}$${prv}_INCLUDES += $$mbibase/$$VERSION $$mbibase/$$VERSION/$$mod 87 } 88 prefix_build:module_frameworks { 89 mfbase = \$\$QT_MODULE_LIB_BASE/$${mod}$${QT_LIBINFIX}.framework/Headers 90 MODULE_INCLUDES += $$mfbase 91 MODULE$${prv}_INCLUDES += $$mfbase/$$VERSION $$mfbase/$$VERSION/$$mod 92 } 93} 94MODULE_INCLUDES += $$MODULE_AUX_INCLUDES 95MODULE_PRIVATE_INCLUDES += $$MODULE_PRIVATE_AUX_INCLUDES 96 97minimal_syncqt: return() 98 99defineTest(syncQtResolve) { 100 out = 101 for (f, SYNCQT.$$1): \ 102 out += $$absolute_path($$f, $$2) 103 SYNCQT.$$1 = $$out 104 export(SYNCQT.$$1) 105} 106 107#load up the headers info 108git_build: \ 109 INC_PATH = $$MODULE_BASE_OUTDIR 110else: \ 111 INC_PATH = $$MODULE_BASE_INDIR 112include($$INC_PATH/include/$$MODULE_INCNAME/headers.pri, "", true) 113syncQtResolve(HEADER_FILES, $$_PRO_FILE_PWD_) 114syncQtResolve(PRIVATE_HEADER_FILES, $$_PRO_FILE_PWD_) 115syncQtResolve(QPA_HEADER_FILES, $$_PRO_FILE_PWD_) 116syncQtResolve(GENERATED_HEADER_FILES, $$INC_PATH/include/$$MODULE_INCNAME) 117!lib_bundle: \ # Headers are embedded into the bundle, so don't install them separately. 118 CONFIG += qt_install_headers 119 120alien_syncqt: return() 121 122MODULE_INC_OUTDIR = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME 123 124isEmpty(MODULE_CFG_FILE): MODULE_CFG_FILE = qt$${MODULE}-config 125exists($$OUT_PWD/$${MODULE_CFG_FILE}.h) { 126 fwd_rel = $$relative_path($$OUT_PWD, $$REAL_MODULE_BASE_OUTDIR) 127 SYNCQT.INJECTIONS += \ 128 $$fwd_rel/$${MODULE_CFG_FILE}.h:$${MODULE_CFG_FILE}.h \ 129 $$fwd_rel/$${MODULE_CFG_FILE}_p.h:$$MODULE_VERSION/$$MODULE_INCNAME/private/$${MODULE_CFG_FILE}_p.h 130} 131 132for (injection, SYNCQT.INJECTIONS) { 133 injects = $$split(injection, :) 134 dst_hdr = $$absolute_path($$member(injects, 0), $$REAL_MODULE_BASE_OUTDIR) 135 ofwd_hdr = $$member(injects, 1) 136 fwd_hdr = $$replace(ofwd_hdr, ^\\^, ) 137 MAIN_FWD = $$MODULE_INC_OUTDIR/$$fwd_hdr 138 MAIN_FWD_CONT = '$${LITERAL_HASH}include "$$relative_path($$dst_hdr, $$dirname(MAIN_FWD))"' 139 write_file($$MAIN_FWD, MAIN_FWD_CONT)|error() 140 equals(fwd_hdr, ofwd_hdr): touch($$MAIN_FWD, $$dst_hdr) 141 !git_build: QMAKE_DISTCLEAN += $$MAIN_FWD 142 !contains(ofwd_hdr, .*/private/.*): \ 143 SYNCQT.INJECTED_HEADER_FILES += $$dst_hdr 144 else: \ 145 SYNCQT.INJECTED_PRIVATE_HEADER_FILES += $$dst_hdr 146 injects = $$member(injects, 2, -1) 147 for (inject, injects) { 148 CLASS_FWD = $$MODULE_INC_OUTDIR/$$inject 149 CLASS_FWD_CONT = '$${LITERAL_HASH}include "$$fwd_hdr"' 150 write_file($$CLASS_FWD, CLASS_FWD_CONT)|error() 151 touch($$CLASS_FWD, $$MAIN_FWD) 152 !git_build: QMAKE_DISTCLEAN += $$CLASS_FWD 153 SYNCQT.INJECTED_HEADER_FILES += $$CLASS_FWD 154 } 155} 156 157autogen_warning = \ 158 "/* This file was generated by qmake with the info from <root>/$$relative_path($$_PRO_FILE_, $$MODULE_BASE_INDIR). */" 159 160# Create a module master depends header 161MODULE_MASTER_DEPS_HEADER = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME/$${MODULE_INCNAME}Depends 162!build_pass { 163 MODULE_MASTER_DEPS_HEADER_CONT = $$autogen_warning 164 MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}ifdef __cplusplus /* create empty PCH in C mode */" 165 for(dep, MODULE_DEPENDS) { 166 depname = $$eval(QT.$${dep}.master_header) 167 isEmpty(depname): \ 168 depname = $$eval(QT.$${dep}.name) 169 MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}include <$$depname/$$depname>" 170 } 171 MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}endif" 172 write_file($$MODULE_MASTER_DEPS_HEADER, MODULE_MASTER_DEPS_HEADER_CONT)|error() 173 !git_build: QMAKE_DISTCLEAN += $$MODULE_MASTER_DEPS_HEADER 174} 175SYNCQT.HEADER_FILES += $$MODULE_MASTER_DEPS_HEADER 176 177# Automatically enable precompiled headers for Qt modules with more than 2 sources 178combined_SOURCES = $$SOURCES $$OBJECTIVE_SOURCES 179count(combined_SOURCES, 2, >) { 180 # except for Gcc/Windows: Larger precompiled headers crash cc1plus.exe 181 # (e.g. with i686-4.8.2-release-posix-dwarf-rt_v3-rev3) 182 !if(gcc:equals(QMAKE_HOST.os, Windows)):!equals(TEMPLATE, aux) { 183 !defined(PRECOMPILED_HEADER, "var"): PRECOMPILED_HEADER = $$MODULE_MASTER_DEPS_HEADER 184 } 185} else { 186 CONFIG -= precompile_header 187} 188unset(combined_SOURCES) 189 190headersclean:!internal_module { 191 # Make sure that the header compiles with our strict options 192 hcleanDEFS = -DQT_NO_CAST_TO_ASCII=1 \ 193 -DQT_NO_CAST_FROM_ASCII=1 \ 194 -UQT_RESTRICTED_CAST_FROM_ASCII \ 195 -DQT_STRICT_ITERATORS \ 196 -DQT_NO_URL_CAST_FROM_STRING=1 \ 197 -DQT_NO_CAST_FROM_BYTEARRAY=1 \ 198 -DQT_NO_KEYWORDS=1 \ 199 -DQT_USE_QSTRINGBUILDER \ 200 -DQT_USE_FAST_OPERATOR_PLUS \ 201 -Dsignals=int \ 202 -Dslots=int \ 203 -Demit=public: \ 204 -Dforeach=public: \ 205 -Dforever=public: 206 207 gcc:!rim_qcc { 208 # Turn on some extra warnings not found in -Wall -Wextra. 209 # Common to GCC, Clang and ICC (and other compilers that masquerade as GCC): 210 hcleanFLAGS = -Wall -Wextra -Werror \ 211 -Woverloaded-virtual -Wshadow -Wundef -Wfloat-equal \ 212 -Wnon-virtual-dtor -Wpointer-arith -Wformat-security \ 213 -Wno-long-long -Wno-variadic-macros -pedantic-errors 214 215 intel_icc { 216 # these warnings are disabled because explicit constructors with zero or 217 # multiple arguments are permitted in C++11: 218 # 2304: non-explicit constructor with single argument may cause implicit type conversion 219 # 2305: declaration of 'explicit' constructor without a single argument is redundant 220 hcleanFLAGS += -wd2304,2305 221 greaterThan(QT_ICC_MAJOR_VERSION, 13) { 222 # ICC 14+ has a bug with -Wshadow, emitting it for cases where there's no shadowing 223 # (issue ID 0000698329, task DPD200245740) 224 hcleanFLAGS -= -Wshadow 225 } 226 } else { 227 # options accepted by GCC and Clang 228 hcleanFLAGS += -Wchar-subscripts -Wold-style-cast 229 230 !contains(QT_ARCH, arm):!contains(QT_ARCH, mips): \ 231 hcleanFLAGS += -Wcast-align 232 233 clang_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION} 234 versionAtLeast(clang_ver, 3.8): hcleanFLAGS += -Wdouble-promotion 235 236 !clang { 237 # options accepted only by GCC 238 239 gcc_ver = $${QT_GCC_MAJOR_VERSION}.$${QT_GCC_MINOR_VERSION} 240 versionAtLeast(gcc_ver, 4.5): hcleanFLAGS += -Wdouble-promotion 241 versionAtLeast(gcc_ver, 4.9): hcleanFLAGS += -Wfloat-conversion 242 # GCC 9 has a lot of false positives relating to this, so disable completely 243 greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-deprecated-copy 244 # GCC 9 introduced this 245 greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-redundant-move 246 # GCC 9 introduced this 247 greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-format-overflow 248 # GCC 9 introduced this 249 greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-init-list-lifetime 250 251 c++11 { 252 # only enabled for actual c++11 builds due to 253 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52806 254 hcleanFLAGS += -Wzero-as-null-pointer-constant 255 } 256 } 257 } 258 259 # Use strict mode C++11 or C++98, with no GNU extensions (see -pedantic-errors above). 260 # The module might set CONFIG += c++11, but it might also change QMAKE_CXXFLAGS_CXX11 261 # or the module (or the mkspec) can set the C++11 flag on QMAKE_CXXFLAGS 262 # (or QMAKE_CXXFLAGS_{RELEASE,DEBUG} but that's unlikely). 263 c++11:contains(QMAKE_CXXFLAGS_CXX11, -std=gnu++11) { 264 hcleanFLAGS += -std=c++11 265 } else: contains(QMAKE_CXXFLAGS, -std=gnu++11) { 266 hcleanFLAGS += -std=c++11 267 } else: c++11:contains(QMAKE_CXXFLAGS_CXX11, -std=gnu++0x) { 268 hcleanFLAGS += -std=c++0x 269 } else: contains(QMAKE_CXXFLAGS, -std=gnu++0x) { 270 hcleanFLAGS += -std=c++0x 271 } else: !c++11:!contains(QMAKE_CXXFLAGS, -std=c++0x):!contains(QMAKE_CXXFLAGS, -std=c++11) { 272 hcleanFLAGS += -std=c++98 273 } 274 275 hcleanCOMMAND = $(CXX) -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -xc++ ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} 276 } else: msvc:!intel_icl { 277 # 4180: qualifier applied to function type has no meaning; ignored 278 # 4458: declaration of 'identifier' hides class member 279 # -Za enables strict standards behavior, but we can't add it because 280 # <windows.h> and <GL.h> violate the standards. 281 hcleanFLAGS = -WX -W3 -wd4180 -wd4458 282 283 # MSVC 2015 (compiler version 19.0): 284 # 4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc 285 greaterThan(QMAKE_MSC_VER, 18): hcleanFLAGS += -wd4577 286 287 hcleanCOMMAND = $(CXX) -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -FI${QMAKE_FILE_IN} -Fo${QMAKE_FILE_OUT} \ 288 $$[QT_INSTALL_DATA/src]/mkspecs/features/data/dummy.cpp 289 } 290 291 !isEmpty(hcleanCOMMAND):if(!qtConfig(debug_and_release)|CONFIG(release, debug|release)) { 292 CLEAN_HEADERS = 293 for (h, SYNCQT.CLEAN_HEADER_FILES) { 294 hh = $$split(h, :) 295 hr = $$member(hh, 1) 296 isEmpty(hr)|qtConfig($$hr): \ 297 CLEAN_HEADERS += $$member(hh, 0) 298 } 299 CLEAN_HEADERS -= $$HEADERSCLEAN_EXCLUDE 300 header_check.dependency_type = TYPE_C 301 header_check.CONFIG += no_link 302 header_check.output = ${QMAKE_VAR_OBJECTS_DIR}header_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} 303 header_check.input = CLEAN_HEADERS 304 header_check.variable_out = PRE_TARGETDEPS 305 header_check.name = headercheck ${QMAKE_FILE_IN} 306 header_check.commands = $$hcleanCOMMAND 307 QMAKE_EXTRA_COMPILERS += header_check 308 } 309 unset(hcleanCOMMAND) 310 unset(hcleanFLAGS) 311 unset(hcleanDEFS) 312} 313