diff options
author | Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com> | 2015-10-02 13:54:33 +0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-10-09 15:15:17 +0000 |
commit | 9ff1310af51814e521572fa3de4e086907633a90 (patch) | |
tree | d3b1902b99174adee2f04e92bdc50613bba0c138 /qmake/generators/unix/unixmake.cpp | |
parent | a3a7d485fa2d572225c7050badf28784316aec37 (diff) |
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
Diffstat (limited to 'qmake/generators/unix/unixmake.cpp')
-rw-r--r-- | qmake/generators/unix/unixmake.cpp | 122 |
1 files changed, 53 insertions, 69 deletions
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index b44d7f032a..1d9ebb35e3 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -145,14 +145,16 @@ UnixMakefileGenerator::init() MakefileGenerator::init(); - QString comps[] = { "C", "CXX", "OBJC", "OBJCXX", QString() }; - for(int i = 0; !comps[i].isNull(); i++) { + if (project->isActiveConfig("objective_c")) + project->values("QMAKE_BUILTIN_COMPILERS") << "OBJC" << "OBJCXX"; + + foreach (const ProString &compiler, project->values("QMAKE_BUILTIN_COMPILERS")) { QString compile_flag = var("QMAKE_COMPILE_FLAG"); if(compile_flag.isEmpty()) compile_flag = "-c"; if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { - QString pchFlags = var(ProKey("QMAKE_" + comps[i] + "FLAGS_USE_PRECOMPILE")); + QString pchFlags = var(ProKey("QMAKE_" + compiler + "FLAGS_USE_PRECOMPILE")); QString pchBaseName; if(!project->isEmpty("PRECOMPILED_DIR")) { @@ -179,22 +181,11 @@ UnixMakefileGenerator::init() pchBaseName += project->first("QMAKE_PCH_OUTPUT_EXT").toQString(); pchBaseName += Option::dir_sep; - QString pchOutputFile; - - if(comps[i] == "C") { - pchOutputFile = "c"; - } else if(comps[i] == "CXX") { - pchOutputFile = "c++"; - } else if(project->isActiveConfig("objective_c")) { - if(comps[i] == "OBJC") - pchOutputFile = "objective-c"; - else if(comps[i] == "OBJCXX") - pchOutputFile = "objective-c++"; - } - if(!pchOutputFile.isEmpty()) { + ProString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)); + if (!language.isEmpty()) { pchFlags.replace("${QMAKE_PCH_OUTPUT}", - escapeFilePath(pchBaseName + pchOutputFile + headerSuffix)); + escapeFilePath(pchBaseName + language + headerSuffix)); } } @@ -202,23 +193,27 @@ UnixMakefileGenerator::init() compile_flag += " " + pchFlags; } - QString cflags; - if(comps[i] == "OBJC" || comps[i] == "OBJCXX") - cflags += " $(CFLAGS)"; - else - cflags += " $(" + comps[i] + "FLAGS)"; - compile_flag += cflags + " $(INCPATH)"; + QString compilerExecutable; + if (compiler == "C" || compiler == "OBJC") { + compilerExecutable = "$(CC)"; + compile_flag += " $(CFLAGS)"; + } else { + compilerExecutable = "$(CXX)"; + compile_flag += " $(CXXFLAGS)"; + } - QString compiler = comps[i]; - if (compiler == "C") - compiler = "CC"; + compile_flag += " $(INCPATH)"; - const ProKey runComp("QMAKE_RUN_" + compiler); + ProString compilerVariable = compiler; + if (compilerVariable == "C") + compilerVariable = ProString("CC"); + + const ProKey runComp("QMAKE_RUN_" + compilerVariable); if(project->isEmpty(runComp)) - project->values(runComp).append("$(" + compiler + ") " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "$obj $src"); - const ProKey runCompImp("QMAKE_RUN_" + compiler + "_IMP"); + project->values(runComp).append(compilerExecutable + " " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "$obj $src"); + const ProKey runCompImp("QMAKE_RUN_" + compilerVariable + "_IMP"); if(project->isEmpty(runCompImp)) - project->values(runCompImp).append("$(" + compiler + ") " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "\"$@\" \"$<\""); + project->values(runCompImp).append(compilerExecutable + " " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "\"$@\" \"$<\""); } if (project->isActiveConfig("mac") && !project->isEmpty("TARGET") && @@ -306,10 +301,11 @@ UnixMakefileGenerator::init() } QStringList -&UnixMakefileGenerator::findDependencies(const QString &file) +&UnixMakefileGenerator::findDependencies(const QString &f) { - QStringList &ret = MakefileGenerator::findDependencies(file); + QStringList &ret = MakefileGenerator::findDependencies(f); if (doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { + ProString file = f; QString header_prefix; if(!project->isEmpty("PRECOMPILED_DIR")) header_prefix = project->first("PRECOMPILED_DIR").toQString(); @@ -329,45 +325,33 @@ QStringList QString header_suffix = project->isActiveConfig("clang_pch_style") ? project->first("QMAKE_PCH_OUTPUT_EXT").toQString() : ""; header_prefix += Option::dir_sep + project->first("QMAKE_PRECOMP_PREFIX"); - for(QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { - if(file.endsWith(*it)) { - if(!project->isEmpty("QMAKE_CFLAGS_PRECOMPILE")) { - QString precomp_c_h = header_prefix + "c" + header_suffix; - if(!ret.contains(precomp_c_h)) - ret += precomp_c_h; - } - if(project->isActiveConfig("objective_c")) { - if(!project->isEmpty("QMAKE_OBJCFLAGS_PRECOMPILE")) { - QString precomp_objc_h = header_prefix + "objective-c" + header_suffix; - if(!ret.contains(precomp_objc_h)) - ret += precomp_objc_h; - } - if(!project->isEmpty("QMAKE_OBJCXXFLAGS_PRECOMPILE")) { - QString precomp_objcpp_h = header_prefix + "objective-c++" + header_suffix; - if(!ret.contains(precomp_objcpp_h)) - ret += precomp_objcpp_h; - } - } - break; - } - } - for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { - if(file.endsWith(*it)) { - if(!project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE")) { - QString precomp_cpp_h = header_prefix + "c++" + header_suffix; - if(!ret.contains(precomp_cpp_h)) - ret += precomp_cpp_h; - } - if(project->isActiveConfig("objective_c")) { - if(!project->isEmpty("QMAKE_OBJCXXFLAGS_PRECOMPILE")) { - QString precomp_objcpp_h = header_prefix + "objective-c++" + header_suffix; - if(!ret.contains(precomp_objcpp_h)) - ret += precomp_objcpp_h; - } - } - break; + + foreach (const ProString &compiler, project->values("QMAKE_BUILTIN_COMPILERS")) { + if (project->isEmpty(ProKey("QMAKE_" + compiler + "FLAGS_PRECOMPILE"))) + continue; + + ProString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)); + if (language.isEmpty()) + continue; + + // Unfortunately we were not consistent about the C++ naming + ProString extensionSuffix = compiler; + if (extensionSuffix == "CXX") + extensionSuffix = ProString("CPP"); + + foreach (const ProString &extension, project->values(ProKey("QMAKE_EXT_" + extensionSuffix))) { + if (!file.endsWith(extension.toQString())) + continue; + + QString precompiledHeader = header_prefix + language + header_suffix; + if (!ret.contains(precompiledHeader)) + ret += precompiledHeader; + + goto foundPrecompiledDependency; } } + foundPrecompiledDependency: + ; // Hurray!! } } return ret; |