This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, next has been updated via bd86df676c8b19c0f5a4e5d87c0074caf3ebcbe3 (commit) via 9e1689413fd1e54e8056b7d369cd508636987072 (commit) via b734fa44719a780683e2eb0dfaabd38d64daa3f6 (commit) via 0b945ea9a6a38d1b3ee27cc32afb4268bd571600 (commit) via 5c559f11137dcb14113a3c5df99ff896c65c7596 (commit) from 60fd5e0a216879aca4f18e840a73e26ad95239d0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd86df676c8b19c0f5a4e5d87c0074caf3ebcbe3 commit bd86df676c8b19c0f5a4e5d87c0074caf3ebcbe3 Merge: 60fd5e0 9e16894 Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Mon Mar 9 16:08:11 2015 -0400 Commit: CMake Topic Stage <kwro...@kitware.com> CommitDate: Mon Mar 9 16:08:11 2015 -0400 Merge topic 'target-language-genex' into next 9e168941 File(GENERATE): Process genex evaluation files for each language. b734fa44 Genex: Allow COMPILE_LANGUAGE when processing include directories. 0b945ea9 Genex: Allow COMPILE_LANGUAGE when processing compile definitions. 5c559f11 Genex: Enable use of COMPILE_LANGUAGE for compile options. http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9e1689413fd1e54e8056b7d369cd508636987072 commit 9e1689413fd1e54e8056b7d369cd508636987072 Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Sun Feb 22 17:44:59 2015 +0100 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Mon Mar 9 20:49:17 2015 +0100 File(GENERATE): Process genex evaluation files for each language. diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index 4e2a868..fa00283 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -38,13 +38,15 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile( //---------------------------------------------------------------------------- void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, + const std::string& lang, cmCompiledGeneratorExpression* inputExpression, std::map<std::string, std::string> &outputFiles, mode_t perm) { std::string rawCondition = this->Condition->GetInput(); if (!rawCondition.empty()) { - std::string condResult = this->Condition->Evaluate(this->Makefile, config); + std::string condResult = this->Condition->Evaluate(this->Makefile, config, + false, 0, 0, 0, lang); if (condResult == "0") { return; @@ -60,9 +62,11 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, } const std::string outputFileName - = this->OutputFileExpr->Evaluate(this->Makefile, config); + = this->OutputFileExpr->Evaluate(this->Makefile, config, + false, 0, 0, 0, lang); const std::string outputContent - = inputExpression->Evaluate(this->Makefile, config); + = inputExpression->Evaluate(this->Makefile, config, + false, 0, 0, 0, lang); std::map<std::string, std::string>::iterator it = outputFiles.find(outputFileName); @@ -75,7 +79,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, } std::ostringstream e; e << "Evaluation file to be written multiple times for different " - "configurations with different content:\n " << outputFileName; + "configurations or languages with different content:\n " + << outputFileName; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } @@ -97,14 +102,22 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, void cmGeneratorExpressionEvaluationFile::CreateOutputFile( std::string const& config) { - std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config); - cmSourceFile* sf = this->Makefile->GetOrCreateSource(name); - sf->SetProperty("GENERATED", "1"); - + std::vector<std::string> enabledLanguages; cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator()->GetGlobalGenerator(); - gg->SetFilenameTargetDepends(sf, + gg->GetEnabledLanguages(enabledLanguages); + + for(std::vector<std::string>::const_iterator le = enabledLanguages.begin(); + le != enabledLanguages.end(); ++le) + { + std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config, + false, 0, 0, 0, *le); + cmSourceFile* sf = this->Makefile->GetOrCreateSource(name); + sf->SetProperty("GENERATED", "1"); + + gg->SetFilenameTargetDepends(sf, this->OutputFileExpr->GetSourceSensitiveTargets()); + } } //---------------------------------------------------------------------------- @@ -153,13 +166,23 @@ void cmGeneratorExpressionEvaluationFile::Generate() { allConfigs.push_back(""); } - for(std::vector<std::string>::const_iterator li = allConfigs.begin(); - li != allConfigs.end(); ++li) + + std::vector<std::string> enabledLanguages; + cmGlobalGenerator *gg + = this->Makefile->GetLocalGenerator()->GetGlobalGenerator(); + gg->GetEnabledLanguages(enabledLanguages); + + for(std::vector<std::string>::const_iterator le = enabledLanguages.begin(); + le != enabledLanguages.end(); ++le) { - this->Generate(*li, inputExpression.get(), outputFiles, perm); - if(cmSystemTools::GetFatalErrorOccured()) + for(std::vector<std::string>::const_iterator li = allConfigs.begin(); + li != allConfigs.end(); ++li) { - return; + this->Generate(*li, *le, inputExpression.get(), outputFiles, perm); + if(cmSystemTools::GetFatalErrorOccured()) + { + return; + } } } } diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h index 3394ade..4424bec 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.h +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -34,7 +34,7 @@ public: void CreateOutputFile(std::string const& config); private: - void Generate(const std::string& config, + void Generate(const std::string& config, const std::string& lang, cmCompiledGeneratorExpression* inputExpression, std::map<std::string, std::string> &outputFiles, mode_t perm); diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake new file mode 100644 index 0000000..e2b081d --- /dev/null +++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake @@ -0,0 +1,12 @@ + +enable_language(CXX C) + +add_library(empty empty.cpp empty.c) +target_compile_options(empty + PRIVATE LANG_IS_$<COMPILE_LANGUAGE> +) + +file(GENERATE + OUTPUT opts-$<COMPILE_LANGUAGE>.txt + CONTENT "$<TARGET_PROPERTY:empty,COMPILE_OPTIONS>\n" +) diff --git a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt index dbd39de..0abb7df 100644 --- a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt +++ b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt @@ -1,5 +1,5 @@ CMake Error in CMakeLists.txt: Evaluation file to be written multiple times for different configurations - with different content: + or languages with different content: .*output.txt diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake index 97f93d5..db344ef 100644 --- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake @@ -17,6 +17,16 @@ if (NOT file_contents MATCHES "generated.cpp.rule") message(SEND_ERROR "Rule file not in target sources! ${file_contents}") endif() +if (NOT RunCMake_GENERATOR MATCHES "Visual Studio") + run_cmake(COMPILE_LANGUAGE-genex) + foreach(l CXX C) + file(READ "${RunCMake_BINARY_DIR}/COMPILE_LANGUAGE-genex-build/opts-${l}.txt" l_defs) + if (NOT l_defs STREQUAL "LANG_IS_${l}\n") + message(FATAL_ERROR "File content does not match: ${l_defs}") + endif() + endforeach() +endif() + set(timeformat "%Y%j%H%M%S") file(REMOVE "${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt") diff --git a/Tests/RunCMake/File_Generate/empty.c b/Tests/RunCMake/File_Generate/empty.c new file mode 100644 index 0000000..563eef0 --- /dev/null +++ b/Tests/RunCMake/File_Generate/empty.c @@ -0,0 +1,8 @@ + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty_c() +{ + return 0; +} http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b734fa44719a780683e2eb0dfaabd38d64daa3f6 commit b734fa44719a780683e2eb0dfaabd38d64daa3f6 Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Wed Mar 4 21:53:15 2015 +0100 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Mon Mar 9 20:49:17 2015 +0100 Genex: Allow COMPILE_LANGUAGE when processing include directories. Issue an error if this is encountered by an IDE generator. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index b6d97d1..d38cf7e 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -121,7 +121,8 @@ Available logical expressions are: target_link_libraries(myapp myapp_c myapp_cxx) The ``Makefile`` and ``Ninja`` based generators can also use this - expression to specify compile-language specific compile definitions: + expression to specify compile-language specific compile definitions + and include directories: .. code-block:: cmake @@ -129,6 +130,9 @@ Available logical expressions are: target_compile_definitions(myapp PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX> ) + target_include_directories(myapp + PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers> + ) Informational Expressions ========================= diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 3ec8595..756d932 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -851,7 +851,8 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode } else if (genName.find("Xcode") != std::string::npos) { - if (dagChecker && dagChecker->EvaluatingCompileDefinitions()) + if (dagChecker && (dagChecker->EvaluatingCompileDefinitions() + || dagChecker->EvaluatingIncludeDirectories())) { reportError(context, content->GetOriginalExpression(), "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS " diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 44c9e9a..b7b2eff 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -960,9 +960,10 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang, //---------------------------------------------------------------------------- std::vector<std::string> -cmGeneratorTarget::GetIncludeDirectories(const std::string& config) const +cmGeneratorTarget::GetIncludeDirectories(const std::string& config, + const std::string& lang) const { - return this->Target->GetIncludeDirectories(config); + return this->Target->GetIncludeDirectories(config, lang); } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 2083b88..c329cf5 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -85,7 +85,7 @@ public: /** Get the include directories for this target. */ std::vector<std::string> GetIncludeDirectories( - const std::string& config) const; + const std::string& config, const std::string& lang) const; bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config) const; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 735dfa9..37cc2c6 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1600,7 +1600,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, // Get the target-specific include directories. std::vector<std::string> includes; - includes = target->GetIncludeDirectories(config); + includes = target->GetIncludeDirectories(config, lang); // Support putting all the in-project include directories first if // it is requested by the project. diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 9ecb029..50491af 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -2114,6 +2114,32 @@ void cmLocalUnixMakefileGenerator3 cmakefileStream << " )\n"; } + + // Target-specific include directories: + cmakefileStream + << "\n" + << "# The include file search paths:\n"; + cmakefileStream + << "set(CMAKE_" << l->first << "_TARGET_INCLUDE_PATH\n"; + std::vector<std::string> includes; + + cmGeneratorTarget* gt = this->GetGlobalGenerator() + ->GetGeneratorTarget(&target); + + const std::string& config = + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); + this->GetIncludeDirectories(includes, gt, + l->first, config); + for(std::vector<std::string>::iterator i = includes.begin(); + i != includes.end(); ++i) + { + cmakefileStream + << " \"" + << this->Convert(*i, cmLocalGenerator::HOME_OUTPUT) + << "\"\n"; + } + cmakefileStream + << " )\n"; } // Store include transform rule properties. Write the directory diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 57c49f1..c7a7110 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1056,40 +1056,6 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n"; } - // Target-specific include directories: - *this->InfoFileStream - << "\n" - << "# The include file search paths:\n"; - *this->InfoFileStream - << "set(CMAKE_C_TARGET_INCLUDE_PATH\n"; - std::vector<std::string> includes; - - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - this->LocalGenerator->GetIncludeDirectories(includes, - this->GeneratorTarget, - "C", config); - for(std::vector<std::string>::iterator i = includes.begin(); - i != includes.end(); ++i) - { - *this->InfoFileStream - << " \"" - << this->LocalGenerator->Convert(*i, - cmLocalGenerator::HOME_OUTPUT) - << "\"\n"; - } - *this->InfoFileStream - << " )\n"; - *this->InfoFileStream - << "set(CMAKE_CXX_TARGET_INCLUDE_PATH " - << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; - *this->InfoFileStream - << "set(CMAKE_Fortran_TARGET_INCLUDE_PATH " - << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; - *this->InfoFileStream - << "set(CMAKE_ASM_TARGET_INCLUDE_PATH " - << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; - // and now write the rule to use it std::vector<std::string> depends; std::vector<std::string> commands; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 87dcc99..7a6ad8b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1979,7 +1979,8 @@ static void processIncludeDirectories(cmTarget const* tgt, std::vector<std::string> &includes, UNORDERED_SET<std::string> &uniqueIncludes, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugIncludes) + const std::string& config, bool debugIncludes, + const std::string& language) { cmMakefile *mf = tgt->GetMakefile(); @@ -1995,7 +1996,7 @@ static void processIncludeDirectories(cmTarget const* tgt, config, false, tgt, - dagChecker), + dagChecker, language), entryIncludes); std::string usedIncludes; @@ -2106,7 +2107,8 @@ static void processIncludeDirectories(cmTarget const* tgt, //---------------------------------------------------------------------------- std::vector<std::string> -cmTarget::GetIncludeDirectories(const std::string& config) const +cmTarget::GetIncludeDirectories(const std::string& config, + const std::string& language) const { std::vector<std::string> includes; UNORDERED_SET<std::string> uniqueIncludes; @@ -2139,7 +2141,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const uniqueIncludes, &dagChecker, config, - debugIncludes); + debugIncludes, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceIncludeDirectoriesEntries; @@ -2179,7 +2182,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const uniqueIncludes, &dagChecker, config, - debugIncludes); + debugIncludes, + language); deleteAndClear(linkInterfaceIncludeDirectoriesEntries); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 0356c1e..5170b31 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -568,7 +568,8 @@ public: bool contentOnly) const; std::vector<std::string> GetIncludeDirectories( - const std::string& config) const; + const std::string& config, + const std::string& language) const; void InsertInclude(const cmValueWithOrigin &entry, bool before = false); void InsertCompileOption(const cmValueWithOrigin &entry, diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt index 661bbaa..d57556a 100644 --- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt +++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt @@ -42,6 +42,20 @@ add_executable(consumer "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" ) +if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") + target_sources(consumer PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c" + ) + target_include_directories(consumer + PRIVATE + $<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only> + $<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}/c_only> + ) + target_compile_definitions(consumer + PRIVATE -DTEST_LANG_DEFINES + ) +endif() + target_include_directories(consumer PRIVATE $<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES> diff --git a/Tests/CMakeCommands/target_include_directories/c_only/c_only.h b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h new file mode 100644 index 0000000..29f68ee --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h @@ -0,0 +1,2 @@ + +#define C_ONLY_DEFINE diff --git a/Tests/CMakeCommands/target_include_directories/consumer.c b/Tests/CMakeCommands/target_include_directories/consumer.c new file mode 100644 index 0000000..8821f5b --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/consumer.c @@ -0,0 +1,10 @@ + +#ifdef TEST_LANG_DEFINES + #include "c_only.h" + + #ifndef C_ONLY_DEFINE + #error Expected C_ONLY_DEFINE + #endif +#endif + +int consumer_c() { return 0; } diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp index 7e3443e..649510c 100644 --- a/Tests/CMakeCommands/target_include_directories/consumer.cpp +++ b/Tests/CMakeCommands/target_include_directories/consumer.cpp @@ -4,6 +4,9 @@ #include "interfaceinclude.h" #include "relative_dir.h" #include "consumer.h" +#ifdef TEST_LANG_DEFINES + #include "cxx_only.h" +#endif #ifdef PRIVATEINCLUDE_DEFINE #error Unexpected PRIVATEINCLUDE_DEFINE @@ -29,4 +32,10 @@ #error Expected CONSUMER_DEFINE #endif +#ifdef TEST_LANG_DEFINES + #ifndef CXX_ONLY_DEFINE + #error Expected CXX_ONLY_DEFINE + #endif +#endif + int main() { return 0; } diff --git a/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h new file mode 100644 index 0000000..67289a4 --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h @@ -0,0 +1,2 @@ + +#define CXX_ONLY_DEFINE diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt new file mode 100644 index 0000000..ec15068 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt @@ -0,0 +1,8 @@ +CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt new file mode 100644 index 0000000..fdf92b2 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt @@ -0,0 +1,9 @@ +CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the + Xcode generator. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake new file mode 100644 index 0000000..31771f6 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_executable(main main.cpp) +target_include_directories(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:anydir>) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake index 8a32aef..5e0a5f5 100644 --- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake @@ -11,3 +11,10 @@ elseif (RunCMake_GENERATOR MATCHES "Visual Studio") set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt) run_cmake(CompileDefinitions) endif() +if (RunCMake_GENERATOR STREQUAL "Xcode") + set(RunCMake-stderr-file IncludeDirectories-stderr-Xcode.txt) + run_cmake(IncludeDirectories) +elseif (RunCMake_GENERATOR MATCHES "Visual Studio") + set(RunCMake-stderr-file IncludeDirectories-stderr-VS.txt) + run_cmake(IncludeDirectories) +endif() http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0b945ea9a6a38d1b3ee27cc32afb4268bd571600 commit 0b945ea9a6a38d1b3ee27cc32afb4268bd571600 Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Wed Mar 4 21:46:42 2015 +0100 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Mon Mar 9 20:49:16 2015 +0100 Genex: Allow COMPILE_LANGUAGE when processing compile definitions. Issue an error if this is encountered by an IDE generator. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index b1b1102..b6d97d1 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -120,6 +120,16 @@ Available logical expressions are: add_executable(myapp main.cpp) target_link_libraries(myapp myapp_c myapp_cxx) + The ``Makefile`` and ``Ninja`` based generators can also use this + expression to specify compile-language specific compile definitions: + + .. code-block:: cmake + + add_executable(myapp main.cpp foo.c bar.cpp) + target_compile_definitions(myapp + PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX> + ) + Informational Expressions ========================= diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 69857ef..614e7d9 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -599,7 +599,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, // the compilerdefines for this target std::vector<std::string> cdefs; - target->GetCompileDefinitions(cdefs, buildType); + target->GetCompileDefinitions(cdefs, buildType, "C"); // Expand the list. for(std::vector<std::string>::const_iterator di = cdefs.begin(); diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 5fff0fb..25f9005 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -436,7 +436,7 @@ ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target, } // Add preprocessor definitions for this target and configuration. - lg->AddCompileDefinitions(defines, target, config); + lg->AddCompileDefinitions(defines, target, config, language); lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS")); { std::string defPropName = "COMPILE_DEFINITIONS_"; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 6a9f251..3ec8595 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -817,7 +817,7 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode std::string Evaluate(const std::vector<std::string> ¶meters, cmGeneratorExpressionContext *context, const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const + cmGeneratorExpressionDAGChecker *dagChecker) const { if(context->Language.empty()) { @@ -849,12 +849,21 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode "generators."); return std::string(); } + else if (genName.find("Xcode") != std::string::npos) + { + if (dagChecker && dagChecker->EvaluatingCompileDefinitions()) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS " + "with the Xcode generator."); + return std::string(); + } + } else { if(genName.find("Makefiles") == std::string::npos && genName.find("Ninja") == std::string::npos && - genName.find("Watcom WMake") == std::string::npos && - genName.find("Xcode") == std::string::npos) + genName.find("Watcom WMake") == std::string::npos) { reportError(context, content->GetOriginalExpression(), "$<COMPILE_LANGUAGE:...> not supported for this generator."); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index e89161d..bd8a1f5 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1803,7 +1803,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, } cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); std::vector<std::string> targetDefines; - target.GetCompileDefinitions(targetDefines, configName); + target.GetCompileDefinitions(targetDefines, configName, "C"); this->AppendDefines(ppDefs, targetDefines); buildSettings->AddAttribute ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList()); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index be82085..735dfa9 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1428,11 +1428,11 @@ std::string cmLocalGenerator::GetIncludeFlags( //---------------------------------------------------------------------------- void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines, cmTarget const* target, - const std::string& config) + const std::string& config, + const std::string& lang) { std::vector<std::string> targetDefines; - target->GetCompileDefinitions(targetDefines, - config); + target->GetCompileDefinitions(targetDefines, config, lang); this->AppendDefines(defines, targetDefines); } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 3a9d5be..f1f0da1 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -239,7 +239,8 @@ public: const std::string& lang, const std::string& config); void AddCompileDefinitions(std::set<std::string>& defines, cmTarget const* target, - const std::string& config); + const std::string& config, + const std::string& lang); /** Compute the language used to compile the given source file. */ std::string GetSourceFileLanguage(const cmSourceFile& source); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 432cb3a..9ecb029 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -2094,26 +2094,26 @@ void cmLocalUnixMakefileGenerator3 << "set(CMAKE_" << l->first << "_COMPILER_ID \"" << cid << "\")\n"; } - } - // Build a list of preprocessor definitions for the target. - std::set<std::string> defines; - this->AddCompileDefinitions(defines, &target, - this->ConfigurationName); - if(!defines.empty()) - { - cmakefileStream - << "\n" - << "# Preprocessor definitions for this target.\n" - << "set(CMAKE_TARGET_DEFINITIONS\n"; - for(std::set<std::string>::const_iterator di = defines.begin(); - di != defines.end(); ++di) + // Build a list of preprocessor definitions for the target. + std::set<std::string> defines; + this->AddCompileDefinitions(defines, &target, + this->ConfigurationName, l->first); + if(!defines.empty()) { cmakefileStream - << " " << this->EscapeForCMake(*di) << "\n"; + << "\n" + << "# Preprocessor definitions for this target.\n" + << "set(CMAKE_TARGET_DEFINITIONS_" << l->first << "\n"; + for(std::set<std::string>::const_iterator di = defines.begin(); + di != defines.end(); ++di) + { + cmakefileStream + << " " << this->EscapeForCMake(*di) << "\n"; + } + cmakefileStream + << " )\n"; } - cmakefileStream - << " )\n"; } // Store include transform rule properties. Write the directory diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 0848b03..2b999eb 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1778,15 +1778,15 @@ void cmLocalVisualStudio6Generator std::set<std::string> minsizeDefinesSet; std::set<std::string> debugrelDefinesSet; - this->AddCompileDefinitions(definesSet, &target, ""); + this->AddCompileDefinitions(definesSet, &target, "", linkLanguage); this->AddCompileDefinitions(debugDefinesSet, &target, - "DEBUG"); + "DEBUG", linkLanguage); this->AddCompileDefinitions(releaseDefinesSet, &target, - "RELEASE"); + "RELEASE", linkLanguage); this->AddCompileDefinitions(minsizeDefinesSet, &target, - "MINSIZEREL"); + "MINSIZEREL", linkLanguage); this->AddCompileDefinitions(debugrelDefinesSet, &target, - "RELWITHDEBINFO"); + "RELWITHDEBINFO", linkLanguage); std::string defines = " "; std::string debugDefines = " "; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index ed560aa..f53f825 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -775,7 +775,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(&target); std::vector<std::string> targetDefines; - target.GetCompileDefinitions(targetDefines, configName); + target.GetCompileDefinitions(targetDefines, configName, "CXX"); targetOptions.AddDefines(targetDefines); targetOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 20207f5..57c49f1 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -329,7 +329,7 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AddCompileDefinitions(defines, this->Target, - this->LocalGenerator->ConfigurationName); + this->LocalGenerator->ConfigurationName, l); std::string definesString; this->LocalGenerator->JoinDefines(defines, definesString, lang); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index cfd8937..92fccd3 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -231,7 +231,7 @@ ComputeDefines(cmSourceFile const* source, const std::string& language) // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AddCompileDefinitions(defines, this->Target, - this->GetConfigName()); + this->GetConfigName(), language); this->LocalGenerator->AppendDefines (defines, source->GetProperty("COMPILE_DEFINITIONS")); diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index e18e757..844d708 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -507,7 +507,7 @@ static void GetCompileDefinitionsAndDirectories(cmTarget const* target, incs = cmJoin(includeDirs, ";"); std::set<std::string> defines; - localGen->AddCompileDefinitions(defines, target, config); + localGen->AddCompileDefinitions(defines, target, config, "CXX"); defs += cmJoin(defines, ";"); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c54d694..87dcc99 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2336,16 +2336,18 @@ static void processCompileDefinitions(cmTarget const* tgt, std::vector<std::string> &options, UNORDERED_SET<std::string> &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions) + const std::string& config, bool debugOptions, + std::string const& language) { processCompileOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, config, debugOptions, - "definitions", std::string()); + "definitions", language); } //---------------------------------------------------------------------------- void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, - const std::string& config) const + const std::string& config, + const std::string& language) const { UNORDERED_SET<std::string> uniqueOptions; @@ -2377,7 +2379,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, uniqueOptions, &dagChecker, config, - debugDefines); + debugDefines, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceCompileDefinitionsEntries; @@ -2424,7 +2427,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, uniqueOptions, &dagChecker, config, - debugDefines); + debugDefines, + language); deleteAndClear(linkInterfaceCompileDefinitionsEntries); } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 56db22e..0356c1e 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -496,7 +496,8 @@ public: const char* GetExportMacro() const; void GetCompileDefinitions(std::vector<std::string> &result, - const std::string& config) const; + const std::string& config, + const std::string& language) const; // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 04d1487..19444ed 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1876,7 +1876,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.Parse(flags.c_str()); clOptions.Parse(defineFlags.c_str()); std::vector<std::string> targetDefines; - this->Target->GetCompileDefinitions(targetDefines, configName.c_str()); + this->Target->GetCompileDefinitions(targetDefines, + configName.c_str(), "CXX"); clOptions.AddDefines(targetDefines); if(this->MSTools) { diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt index 14d40aa..f96283d 100644 --- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt @@ -26,6 +26,21 @@ target_compile_definitions(consumer PRIVATE ) +if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") + target_sources(consumer PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c" + ) + target_compile_definitions(consumer + PRIVATE + CONSUMER_LANG_$<COMPILE_LANGUAGE> + LANG_IS_CXX=$<COMPILE_LANGUAGE:CXX> + LANG_IS_C=$<COMPILE_LANGUAGE:C> + ) + target_compile_definitions(consumer + PRIVATE -DTEST_LANG_DEFINES + ) +endif() + add_definitions(-DSOME_DEF) add_library(imp UNKNOWN IMPORTED) get_target_property(_res imp COMPILE_DEFINITIONS) diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.c b/Tests/CMakeCommands/target_compile_definitions/consumer.c new file mode 100644 index 0000000..5796d96 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_definitions/consumer.c @@ -0,0 +1,23 @@ + +#ifdef TEST_LANG_DEFINES + #ifdef CONSUMER_LANG_CXX + #error Unexpected CONSUMER_LANG_CXX + #endif + + #ifndef CONSUMER_LANG_C + #error Expected CONSUMER_LANG_C + #endif + + #if !LANG_IS_C + #error Expected LANG_IS_C + #endif + + #if LANG_IS_CXX + #error Unexpected LANG_IS_CXX + #endif +#endif + +void consumer_c() +{ + +} diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp index a391114..778f57e 100644 --- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp +++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp @@ -15,4 +15,22 @@ #error Expected DASH_D_DEFINE #endif +#ifdef TEST_LANG_DEFINES + #ifndef CONSUMER_LANG_CXX + #error Expected CONSUMER_LANG_CXX + #endif + + #ifdef CONSUMER_LANG_C + #error Unexpected CONSUMER_LANG_C + #endif + + #if !LANG_IS_CXX + #error Expected LANG_IS_CXX + #endif + + #if LANG_IS_C + #error Unexpected LANG_IS_C + #endif +#endif + int main() { return 0; } diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt new file mode 100644 index 0000000..73b66ac --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt @@ -0,0 +1,8 @@ +CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt new file mode 100644 index 0000000..a1ed633 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt @@ -0,0 +1,9 @@ +CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the + Xcode generator. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake new file mode 100644 index 0000000..7935d88 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_executable(main main.cpp) +target_compile_definitions(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake index 2c5d9ae..8a32aef 100644 --- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake @@ -4,3 +4,10 @@ if (RunCMake_GENERATOR MATCHES "Visual Studio") set(RunCMake-stderr-file CompileOptions-stderr-VS.txt) run_cmake(CompileOptions) endif() +if (RunCMake_GENERATOR STREQUAL "Xcode") + set(RunCMake-stderr-file CompileDefinitions-stderr-Xcode.txt) + run_cmake(CompileDefinitions) +elseif (RunCMake_GENERATOR MATCHES "Visual Studio") + set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt) + run_cmake(CompileDefinitions) +endif() http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5c559f11137dcb14113a3c5df99ff896c65c7596 commit 5c559f11137dcb14113a3c5df99ff896c65c7596 Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Tue Nov 25 22:47:44 2014 +0100 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Mon Mar 9 20:48:57 2015 +0100 Genex: Enable use of COMPILE_LANGUAGE for compile options. Follow-ups will allow the use of the generator expression for compile definitions and include directories for non-IDE generators. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index c47a7c4..b1b1102 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -93,6 +93,32 @@ Available logical expressions are: for the 'head' target, an error is reported. See the :manual:`cmake-compile-features(7)` manual for information on compile features. +``$<COMPILE_LANGUAGE:lang>`` + ``1`` when the language used for compilation unit matches ``lang``, + otherwise ``0``. This expression used to specify compile options for + source files of a particular language in a target. For example, to specify + the use of the ``-fno-exceptions`` compile option (compiler id checks + elided): + + .. code-block:: cmake + + add_executable(myapp main.cpp foo.c bar.cpp) + target_compile_options(myapp + PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions> + ) + + This generator expression has limited use because it is not possible to + use it with the Visual Studio generators. Portable buildsystems would + not use this expression, and would create separate libraries for each + source file language instead: + + .. code-block:: cmake + + add_library(myapp_c foo.c) + add_library(myapp_cxx foo.c) + target_compile_options(myapp_cxx PUBLIC -fno-exceptions) + add_executable(myapp main.cpp) + target_link_libraries(myapp myapp_c myapp_cxx) Informational Expressions ========================= @@ -174,6 +200,10 @@ Available informational expressions are: ``$<INSTALL_PREFIX>`` Content of the install prefix when the target is exported via :command:`install(EXPORT)` and empty otherwise. +``$<COMPILE_LANGUAGE>`` + The compile language of source files when evaluating compile options. See + the unary version for notes about portability of this generator + expression. Output Expressions ================== diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 63a46f2..6a9f251 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -827,6 +827,40 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode "components of the file(GENERATE) command."); return std::string(); } + + std::vector<std::string> enabledLanguages; + cmGlobalGenerator* gg + = context->Makefile->GetLocalGenerator()->GetGlobalGenerator(); + gg->GetEnabledLanguages(enabledLanguages); + if (!parameters.empty() && + std::find(enabledLanguages.begin(), enabledLanguages.end(), + parameters.front()) == enabledLanguages.end()) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> Unknown language."); + return std::string(); + } + + std::string genName = gg->GetName(); + if (genName.find("Visual Studio") != std::string::npos) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> may not be used with Visual Studio " + "generators."); + return std::string(); + } + else + { + if(genName.find("Makefiles") == std::string::npos && + genName.find("Ninja") == std::string::npos && + genName.find("Watcom WMake") == std::string::npos && + genName.find("Xcode") == std::string::npos) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> not supported for this generator."); + return std::string(); + } + } if (parameters.empty()) { return context->Language; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7c83f27..be82085 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1453,7 +1453,7 @@ void cmLocalGenerator::AddCompileOptions( { cmSystemTools::ParseWindowsCommandLine(targetFlags, opts); } - target->GetCompileOptions(opts, config); + target->GetCompileOptions(opts, config, lang); for(std::vector<std::string>::const_iterator i = opts.begin(); i != opts.end(); ++i) { @@ -1474,7 +1474,7 @@ void cmLocalGenerator::AddCompileOptions( this->AppendFlags(flags, targetFlags); } std::vector<std::string> opts; - target->GetCompileOptions(opts, config); + target->GetCompileOptions(opts, config, lang); for(std::vector<std::string>::const_iterator i = opts.begin(); i != opts.end(); ++i) { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index e046bef..c54d694 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2192,7 +2192,8 @@ static void processCompileOptionsInternal(cmTarget const* tgt, std::vector<std::string> &options, UNORDERED_SET<std::string> &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions, const char *logName) + const std::string& config, bool debugOptions, const char *logName, + std::string const& language) { cmMakefile *mf = tgt->GetMakefile(); @@ -2204,7 +2205,8 @@ static void processCompileOptionsInternal(cmTarget const* tgt, config, false, tgt, - dagChecker), + dagChecker, + language), entryOptions); std::string usedOptions; for(std::vector<std::string>::iterator @@ -2238,10 +2240,12 @@ static void processCompileOptions(cmTarget const* tgt, std::vector<std::string> &options, UNORDERED_SET<std::string> &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions) + const std::string& config, bool debugOptions, + std::string const& language) { processCompileOptionsInternal(tgt, entries, options, uniqueOptions, - dagChecker, config, debugOptions, "options"); + dagChecker, config, debugOptions, "options", + language); } //---------------------------------------------------------------------------- @@ -2271,7 +2275,8 @@ void cmTarget::GetAutoUicOptions(std::vector<std::string> &result, //---------------------------------------------------------------------------- void cmTarget::GetCompileOptions(std::vector<std::string> &result, - const std::string& config) const + const std::string& config, + const std::string& language) const { UNORDERED_SET<std::string> uniqueOptions; @@ -2303,7 +2308,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, uniqueOptions, &dagChecker, config, - debugOptions); + debugOptions, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceCompileOptionsEntries; @@ -2318,7 +2324,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, uniqueOptions, &dagChecker, config, - debugOptions); + debugOptions, + language); deleteAndClear(linkInterfaceCompileOptionsEntries); } @@ -2333,7 +2340,7 @@ static void processCompileDefinitions(cmTarget const* tgt, { processCompileOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, config, debugOptions, - "definitions"); + "definitions", std::string()); } //---------------------------------------------------------------------------- @@ -2431,7 +2438,8 @@ static void processCompileFeatures(cmTarget const* tgt, const std::string& config, bool debugOptions) { processCompileOptionsInternal(tgt, entries, options, uniqueOptions, - dagChecker, config, debugOptions, "features"); + dagChecker, config, debugOptions, "features", + std::string()); } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index ddd9859..56db22e 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -577,7 +577,8 @@ public: void AppendBuildInterfaceIncludes(); void GetCompileOptions(std::vector<std::string> &result, - const std::string& config) const; + const std::string& config, + const std::string& language) const; void GetAutoUicOptions(std::vector<std::string> &result, const std::string& config) const; void GetCompileFeatures(std::vector<std::string> &features, diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt index 1d04639..35dd276 100644 --- a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt @@ -23,6 +23,21 @@ add_executable(consumer "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" ) +if (NOT CMAKE_GENERATOR MATCHES "Visual Studio") + target_sources(consumer PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c" + ) + target_compile_options(consumer + PRIVATE + -DCONSUMER_LANG_$<COMPILE_LANGUAGE> + -DLANG_IS_CXX=$<COMPILE_LANGUAGE:CXX> + -DLANG_IS_C=$<COMPILE_LANGUAGE:C> + ) + target_compile_definitions(consumer + PRIVATE -DTEST_LANG_DEFINES + ) +endif() + target_compile_options(consumer PRIVATE $<$<CXX_COMPILER_ID:GNU>:$<TARGET_PROPERTY:target_compile_options,INTERFACE_COMPILE_OPTIONS>> ) diff --git a/Tests/CMakeCommands/target_compile_options/consumer.c b/Tests/CMakeCommands/target_compile_options/consumer.c new file mode 100644 index 0000000..5796d96 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_options/consumer.c @@ -0,0 +1,23 @@ + +#ifdef TEST_LANG_DEFINES + #ifdef CONSUMER_LANG_CXX + #error Unexpected CONSUMER_LANG_CXX + #endif + + #ifndef CONSUMER_LANG_C + #error Expected CONSUMER_LANG_C + #endif + + #if !LANG_IS_C + #error Expected LANG_IS_C + #endif + + #if LANG_IS_CXX + #error Unexpected LANG_IS_CXX + #endif +#endif + +void consumer_c() +{ + +} diff --git a/Tests/CMakeCommands/target_compile_options/consumer.cpp b/Tests/CMakeCommands/target_compile_options/consumer.cpp index 1299606..c5882a5 100644 --- a/Tests/CMakeCommands/target_compile_options/consumer.cpp +++ b/Tests/CMakeCommands/target_compile_options/consumer.cpp @@ -15,4 +15,22 @@ #endif +#ifdef TEST_LANG_DEFINES + #ifndef CONSUMER_LANG_CXX + #error Expected CONSUMER_LANG_CXX + #endif + + #ifdef CONSUMER_LANG_C + #error Unexpected CONSUMER_LANG_C + #endif + + #if !LANG_IS_CXX + #error Expected LANG_IS_CXX + #endif + + #if LANG_IS_C + #error Unexpected LANG_IS_C + #endif +#endif + int main() { return 0; } diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index eb42057..9f1256e 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -208,3 +208,5 @@ add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths) if(RPMBUILD_EXECUTABLE) add_RunCMake_test(CPackRPM) endif() + +add_RunCMake_test(COMPILE_LANGUAGE-genex) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt new file mode 100644 index 0000000..e9e8e9f --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt @@ -0,0 +1,8 @@ +CMake Error at CompileOptions.cmake:5 \(target_compile_options\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake new file mode 100644 index 0000000..6c92abc --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_executable(main main.cpp) +target_compile_options(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake new file mode 100644 index 0000000..2c5d9ae --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake @@ -0,0 +1,6 @@ +include(RunCMake) + +if (RunCMake_GENERATOR MATCHES "Visual Studio") + set(RunCMake-stderr-file CompileOptions-stderr-VS.txt) + run_cmake(CompileOptions) +endif() diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp new file mode 100644 index 0000000..31a1337 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp @@ -0,0 +1,5 @@ + +int main() +{ + return 0; +} diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt new file mode 100644 index 0000000..444da45 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at COMPILE_LANGUAGE-unknown-lang.cmake:4 \(target_compile_options\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> Unknown language. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake new file mode 100644 index 0000000..cec12a3 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake @@ -0,0 +1,4 @@ + +enable_language(C) +add_executable(empty empty.c) +target_compile_options(empty PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall>) diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index f591c3d..542b7fc 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -23,6 +23,7 @@ run_cmake(COMPILE_LANGUAGE-target_sources) run_cmake(COMPILE_LANGUAGE-add_executable) run_cmake(COMPILE_LANGUAGE-add_library) run_cmake(COMPILE_LANGUAGE-add_test) +run_cmake(COMPILE_LANGUAGE-unknown-lang) if(LINKER_SUPPORTS_PDB) run_cmake(NonValidTarget-TARGET_PDB_FILE) ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org http://public.kitware.com/mailman/listinfo/cmake-commits