
# 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"
        }

        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: cxx_flags += -isysroot $$QMAKE_MAC_SDK_PATH

        clang: \
            # Need to link to pick up library paths
            cxx_flags += $$QMAKE_LFLAGS_SHLIB -o /dev/null -v -Wl,-v
        else: \
            # gcc is fine with just preprocessing
            cxx_flags += -E -v

        output = $$system("$$cmd_prefix $$QMAKE_CXX $$qtMakeExpand($$cxx_flags) -xc++ - 2>&1 $$cmd_suffix", lines, ec)
        !equals(ec, 0): \
            error("Cannot run compiler '$$QMAKE_CXX'. Maybe you forgot to setup the environment?")
        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=
                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)
            }
        }
        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) {
    ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) <NUL 2>NUL", lines, ec)
    !equals(ec, 0): \
        error("Cannot run compiler '$$1'. Maybe you forgot to setup the environment?")
    return($$ret)
}

defineReplace(qtVariablesFromGCC) {
    null_device = /dev/null
    equals(QMAKE_HOST.os, Windows): null_device = NUL
    ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$null_device 2>$$null_device", lines, ec)
    !equals(ec, 0): \
        error("Cannot run compiler '$$1'. Maybe you forgot to setup the environment?")
    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 {
        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.
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(QT_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(QT_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(QT_GCC_MAJOR_VERSION): \
    QMAKE_COMPILER_DEFINES += \
        __GNUC__=$$QMAKE_GCC_MAJOR_VERSION \
        __GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \
        __GNUC_PATCHLEVEL__=$$QMAKE_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)
