summaryrefslogtreecommitdiffstats
path: root/mkspecs/features/toolchain.prf
blob: 15b082923592632839fa52581dcd1f19e766190c (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

# In early configure setup; nothing useful to be done here.
isEmpty(QMAKE_CXX): return()

defineReplace(qtMakeExpand) {
    out = "$$1"
    for(ever) {
        m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1)
        equals(m, $$out): \
            return($$out)
        out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m))
    }
}

cross_compile:host_build: \
    target_prefix = QMAKE_HOST_CXX
else: \
    target_prefix = QMAKE_CXX

isEmpty($${target_prefix}.INCDIRS) {
    #
    # Get default include and library paths from compiler
    #
    gcc {
        !equals(QMAKE_HOST.os, Windows) {
            cmd_prefix = "LC_ALL=C"
            cmd_suffix = "</dev/null >/dev/null"
        } else {
            cmd_prefix = "set LC_ALL=C&"
            cmd_suffix = "<NUL >NUL"
        }
        output = $$system("$$cmd_prefix $$QMAKE_CXX $$qtMakeExpand($$QMAKE_CXXFLAGS) -xc++ -E -v - 2>&1 $$cmd_suffix", lines)
        add_includes = false
        for (line, output) {
            line ~= s/^ *//  # remove leading spaces
            contains(line, "LIBRARY_PATH=.*") {
                line ~= s/^LIBRARY_PATH=//  # remove leading LIBRARY_PATH=
                paths = $$split(line, $$QMAKE_DIRLIST_SEP)
                for (path, paths): \
                    QMAKE_DEFAULT_LIBDIRS += $$clean_path($$path)
            } else: contains(line, "$${LITERAL_HASH}include <.*") {  # #include <...> search starts here:
                add_includes = true
            } else: contains(line, "End of search.*") {
                add_includes = false
            } else: $$add_includes {
                !contains(line, ".* \\(framework directory\\)"): \
                    QMAKE_DEFAULT_INCDIRS += $$clean_path($$line)
            }
        }
        QMAKE_DEFAULT_LIBDIRS = $$unique(QMAKE_DEFAULT_LIBDIRS)
    } else: msvc {
        # This doesn't differentiate between host and target,
        # but neither do the compilers.
        LIB = $$getenv("LIB")
        QMAKE_DEFAULT_LIBDIRS = $$split(LIB, $$QMAKE_DIRLIST_SEP)
        INCLUDE = $$getenv("INCLUDE")
        QMAKE_DEFAULT_INCDIRS = $$split(INCLUDE, $$QMAKE_DIRLIST_SEP)
    }

    unix {
        isEmpty(QMAKE_DEFAULT_INCDIRS): QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include
        isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib
    }

    cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS)
    cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS)
} else {
    QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS)
    QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS)
}

#
# Determine and cache the compiler version
#

defineReplace(qtVariablesFromMSVC) {
    return($$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) <NUL 2>NUL", lines))
}

defineReplace(qtVariablesFromGCC) {
    null_device = /dev/null
    equals(QMAKE_HOST.os, Windows): null_device = NUL
    return($$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$null_device 2>$$null_device", lines))
}

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 {
        vars = $$qtVariablesFromGCC($$QMAKE_CXX)
    }
    for (v, vars) {
        isEmpty(v)|contains(v, $${LITERAL_HASH}.*): 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)
}

unset(target_prefix)

# Populate QMAKE_COMPILER_DEFINES and some compatibility variables.
# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal.
!isEmpty(QMAKE_MSC_VER) {
    QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER
    QT_MSVC_MAJOR_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\1")
    QT_MSVC_MINOR_VERSION = $$format_number($$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\2"))
    QT_MSVC_PATCH_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\3"))
}
!isEmpty(QMAKE_ICC_VER) {
    QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER
    QT_ICC_MAJOR_VERSION = $$replace(QMAKE_ICC_VER, "(..)(..)", "\\1")
    QT_ICC_MINOR_VERSION = $$format_number($$replace(QMAKE_ICC_VER, "(..)(..)", "\\2"))
    QT_ICC_PATCH_VERSION = $$QMAKE_ICC_UPDATE_VER
}
!isEmpty(QMAKE_APPLE_CC): \
    QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC
!isEmpty(QT_APPLE_CLANG_MAJOR_VERSION): \
    QMAKE_COMPILER_DEFINES += __clang__ \
        __clang_major__=$$QT_APPLE_CLANG_MAJOR_VERSION \
        __clang_minor__=$$QT_APPLE_CLANG_MINOR_VERSION \
        __clang_patchlevel__=$$QT_APPLE_CLANG_PATCH_VERSION
!isEmpty(QT_CLANG_MAJOR_VERSION): \
    QMAKE_COMPILER_DEFINES += __clang__ \
        __clang_major__=$$QT_CLANG_MAJOR_VERSION \
        __clang_minor__=$$QT_CLANG_MINOR_VERSION \
        __clang_patchlevel__=$$QT_CLANG_PATCH_VERSION
!isEmpty(QT_GCC_MAJOR_VERSION): \
    QMAKE_COMPILER_DEFINES += \
        __GNUC__=$$QT_GCC_MAJOR_VERSION \
        __GNUC_MINOR__=$$QT_GCC_MINOR_VERSION \
        __GNUC_PATCHLEVEL__=$$QT_GCC_PATCH_VERSION

QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT

msvc:!intel_icl:!clang_cl: include(../common/msvc-version.conf)