summaryrefslogtreecommitdiffstats
path: root/mkspecs/features/qt_module_headers.prf
blob: 7acca41d472224e0f3ffccc7c71d04a181fc0633 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#
#  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_paths)

!build_pass:git_build {
    qtPrepareTool(QMAKE_SYNCQT, syncqt, , system)
    minimal_syncqt {
        QMAKE_SYNCQT += -minimal $$QMAKE_SYNCQT_OPTIONS
    } else {
        contains(QT_CONFIG, private_tests): \   # -developer-build
            QMAKE_SYNCQT += -check-includes
    }
    for(mod, MODULE_INCNAME): \
        QMAKE_SYNCQT += -module $$mod
    QMAKE_SYNCQT += \
        -version $$VERSION -outdir $$system_quote($$MODULE_BASE_OUTDIR) $$MODULE_SYNCQT_DIR
    !silent: message($$QMAKE_SYNCQT)
    system($$QMAKE_SYNCQT)|error("Failed to run: $$QMAKE_SYNCQT")

    !minimal_syncqt {
        include-distclean.commands = \
            $$QMAKE_DEL_TREE $$shell_quote($$shell_path($$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME))
        QMAKE_EXTRA_TARGETS += include-distclean
        DISTCLEAN_DEPS += include-distclean
    }
}

# Pre-generated headers in the source tree (tar-ball) and
# - shadow build or
# - non-shadow non-prefix build of a module which is not qtbase
#   (because the build-time generated headers all end up in qtbase).
!git_build: \
        if(!equals(_PRO_FILE_PWD_, $$OUT_PWD) \
           |if(!prefix_build:!equals(MODULE_BASE_INDIR, $$[QT_HOST_PREFIX]))): \
    CONFIG += split_incpath

# To avoid stuffing the code with repetetive conditionals,
# we parametrize the names of the variables we assign to.

# Internal modules have no private part - they *are* private.
!internal_module: \
    prv = _PRIVATE

# When doing a framework build with a prefix, the module needs to point
# into the frameworks' Headers dirs directly, as no shared include/ dir
# is installed.
# However, during the build, it needs to point into the shared include/
# dir, as the framework doesn't even exist yet. For bootstrapped modules
# which borrow headers from "proper" modules, this situation persists
# even beyond the module's own build. The implication of this is that
# qmake might never use a framework's headers in a non-prefix build,
# as there is no separate set of .pri files for users outside Qt.
prefix_build:lib_bundle: \
    fwd = _FWD
# When using a split include path during the build, the installed module's
# include path is also structurally different from that in the build dir.
prefix_build:split_incpath: \
    sfwd = _FWD

ibase = \$\$QT_MODULE_INCLUDE_BASE
MODULE$${fwd}_INCLUDES = $$ibase
split_incpath {
    bibase = $$val_escape(MODULE_BASE_OUTDIR)/include
    MODULE$${sfwd}_INCLUDES += $$bibase
}
for(mod, MODULE_INCNAME) {
    mibase = $$ibase/$$mod
    MODULE$${fwd}_INCLUDES += $$mibase
    MODULE$${fwd}$${prv}_INCLUDES += $$mibase/$$VERSION $$mibase/$$VERSION/$$mod
    split_incpath {
        mbibase = $$bibase/$$mod
        MODULE$${sfwd}_INCLUDES += $$mbibase
        generated_privates: \
            MODULE$${sfwd}$${prv}_INCLUDES += $$mbibase/$$VERSION $$mbibase/$$VERSION/$$mod
    }
    prefix_build:lib_bundle {
        mfbase = \$\$QT_MODULE_LIB_BASE/$${mod}.framework/Headers
        MODULE_INCLUDES += $$mfbase
        MODULE$${prv}_INCLUDES += $$mfbase/$$VERSION $$mfbase/$$VERSION/$$mod
    }
}
MODULE_INCLUDES += $$MODULE_AUX_INCLUDES
MODULE_PRIVATE_INCLUDES += $$MODULE_PRIVATE_AUX_INCLUDES

minimal_syncqt: return()

#load up the headers info
git_build: \
    INC_PATH = $$MODULE_BASE_OUTDIR
else: \
    INC_PATH = $$MODULE_BASE_INDIR
include($$INC_PATH/include/$$MODULE_INCNAME/headers.pri, "", true)
!lib_bundle: \  # Headers are embedded into the bundle, so don't install them separately.
    CONFIG += qt_install_headers

alien_syncqt: return()

for (injection, SYNCQT.INJECTIONS) {
    injects = $$split(injection, :)
    fwd_hdr = $$member(injects, 1)
    MAIN_FWD = $$INC_PATH/include/$$MODULE_INCNAME/$$fwd_hdr
    MAIN_FWD_CONT = '$${LITERAL_HASH}include "$$member(injects, 0)"'
    write_file($$MAIN_FWD, MAIN_FWD_CONT)|error("Aborting.")
    !git_build: QMAKE_DISTCLEAN += $$MAIN_FWD
    injects = $$member(injects, 2, -1)
    for (inject, injects) {
        CLASS_FWD = $$INC_PATH/include/$$MODULE_INCNAME/$$inject
        CLASS_FWD_CONT = '$${LITERAL_HASH}include "$$fwd_hdr"'
        write_file($$CLASS_FWD, CLASS_FWD_CONT)|error("Aborting.")
        !git_build: QMAKE_DISTCLEAN += $$CLASS_FWD
    }
}

autogen_warning = \
    "/* This file was generated by qmake with the info from <root>/$$relative_path($$_PRO_FILE_, $$MODULE_BASE_INDIR). */"

# Create a module master depends header
MODULE_MASTER_DEPS_HEADER = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME/$${MODULE_INCNAME}Depends
!build_pass {
    MODULE_MASTER_DEPS_HEADER_CONT = $$autogen_warning
    MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}ifdef __cplusplus /* create empty PCH in C mode */"
    for(dep, MODULE_DEPENDS) {
        depname = $$eval(QT.$${dep}.master_header)
        isEmpty(depname): \
            depname = $$eval(QT.$${dep}.name)
        MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}include <$$depname/$$depname>"
    }
    MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}endif"
    write_file($$MODULE_MASTER_DEPS_HEADER, MODULE_MASTER_DEPS_HEADER_CONT)|error("Aborting.")
    !git_build: QMAKE_DISTCLEAN += $$MODULE_MASTER_DEPS_HEADER
}
SYNCQT.HEADER_FILES += $$MODULE_MASTER_DEPS_HEADER

# Automatically enable precompiled headers for Qt modules,
# except for Gcc/Windows: Larger precompiled headers crash cc1plus.exe
# (e.g. with i686-4.8.2-release-posix-dwarf-rt_v3-rev3)
!if(gcc:equals(QMAKE_HOST.os, Windows)):!equals(TEMPLATE, aux) {
    isEmpty(PRECOMPILED_HEADER): PRECOMPILED_HEADER = $$MODULE_MASTER_DEPS_HEADER
}

headersclean:!internal_module {
    # Make sure that the header compiles with our strict options
    hcleanDEFS = -DQT_NO_CAST_TO_ASCII=1 \
                 -DQT_NO_CAST_FROM_ASCII=1 \
                 -DQT_STRICT_ITERATORS \
                 -DQT_NO_URL_CAST_FROM_STRING=1 \
                 -DQT_NO_CAST_FROM_BYTEARRAY=1 \
                 -DQT_NO_KEYWORDS=1 \
                 -DQT_USE_QSTRINGBUILDER \
                 -DQT_USE_FAST_OPERATOR_PLUS \
                 -Dsignals=int \
                 -Dslots=int \
                 -Demit=public: \
                 -Dforeach=public: \
                 -Dforever=public:

    gcc {
        # Turn on some extra warnings not found in -Wall -Wextra.
        # Common to GCC, Clang and ICC (and other compilers that masquerade as GCC):
        hcleanFLAGS = -Wall -Wextra -Werror \
                      -Woverloaded-virtual -Wshadow -Wundef \
                      -Wnon-virtual-dtor -Wpointer-arith -Wformat-security \
                      -Wno-long-long -Wno-variadic-macros -pedantic-errors

        intel_icc {
            # these warnings are disabled because explicit constructors with zero or
            # multiple arguments are permitted in C++11:
            # 2304: non-explicit constructor with single argument may cause implicit type conversion
            # 2305: declaration of 'explicit' constructor without a single argument is redundant
            hcleanFLAGS += -wd2304,2305
            greaterThan(QT_ICC_MAJOR_VERSION, 13) {
                # ICC 14+ has a bug with -Wshadow, emitting it for cases where there's no shadowing
                # (issue ID 0000698329, task DPD200245740)
                hcleanFLAGS -= -Wshadow
            }
        } else {
            # options accepted by GCC and Clang
            hcleanFLAGS += -Wchar-subscripts -Wold-style-cast

            !contains(QT_ARCH, arm):!contains(QT_ARCH, mips): \
                hcleanFLAGS += -Wcast-align
        }

        # Use strict mode C++11 or C++98, with no GNU extensions (see -pedantic-errors above).
        # The module might set CONFIG += c++11, but it might also change QMAKE_CXXFLAGS_CXX11
        # or the module (or the mkspec) can set the C++11 flag on QMAKE_CXXFLAGS
        # (or QMAKE_CXXFLAGS_{RELEASE,DEBUG} but that's unlikely).
        c++11:contains(QMAKE_CXXFLAGS_CXX11, -std=gnu++11) {
            hcleanFLAGS += -std=c++11
        } else: contains(QMAKE_CXXFLAGS, -std=gnu++11) {
            hcleanFLAGS += -std=c++11
        } else: c++11:contains(QMAKE_CXXFLAGS_CXX11, -std=gnu++0x) {
            hcleanFLAGS += -std=c++0x
        } else: contains(QMAKE_CXXFLAGS, -std=gnu++0x) {
            hcleanFLAGS += -std=c++0x
        } else: !c++11:!contains(QMAKE_CXXFLAGS, -std=c++0x):!contains(QMAKE_CXXFLAGS, -std=c++11) {
            hcleanFLAGS += -std=c++98
        }

        hcleanCOMMAND = $$QMAKE_CXX -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -xc++ ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
    } else: win32-msvc2013 {
        # 4180: qualifier applied to function type has no meaning; ignored
        # 4458: declaration of 'identifier' hides class member
        # -Za enables strict standards behavior, but we can't add it because
        # <windows.h> and <GL.h> violate the standards.
        hcleanFLAGS = -WX -W3 -wd4180 -wd4458
        hcleanCOMMAND = $$QMAKE_CXX -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -FI${QMAKE_FILE_IN} -Fo${QMAKE_FILE_OUT} \
                        $$[QT_INSTALL_DATA/src]/mkspecs/features/data/dummy.cpp
    }

    !isEmpty(hcleanCOMMAND):if(!contains(QT_CONFIG, debug_and_release)|CONFIG(release, debug|release)) {
        header_check.dependency_type = TYPE_C
        header_check.CONFIG += no_link
        header_check.output = ${QMAKE_VAR_OBJECTS_DIR}header_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
        header_check.input = SYNCQT.CLEAN_HEADER_FILES
        header_check.variable_out = PRE_TARGETDEPS
        header_check.name = headercheck ${QMAKE_FILE_IN}
        header_check.commands = $$hcleanCOMMAND
        silent:header_check.commands = @echo compiling[header] ${QMAKE_FILE_IN} && $$hcleanCOMMAND
        QMAKE_EXTRA_COMPILERS += header_check
        SYNCQT.CLEAN_HEADER_FILES -= $$HEADERSCLEAN_EXCLUDE
    }
    unset(hcleanCOMMAND)
    unset(hcleanFLAGS)
    unset(hcleanDEFS)
}