diff options
author | Brad King <brad.king@kitware.com> | 2022-11-21 15:03:28 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2022-11-21 15:03:35 (GMT) |
commit | 55e3168dc493ed88a7519a92a7cfbd3506b5797e (patch) | |
tree | 58dde89186f91dbfb8e9cc506bfc72b656566fbc | |
parent | 973d88c25f0f7870c33bd46b58b496bbf39cdb60 (diff) | |
parent | a1c20b08b4b1b913a205607dad7240d5c63f4a62 (diff) | |
download | CMake-55e3168dc493ed88a7519a92a7cfbd3506b5797e.zip CMake-55e3168dc493ed88a7519a92a7cfbd3506b5797e.tar.gz CMake-55e3168dc493ed88a7519a92a7cfbd3506b5797e.tar.bz2 |
Merge topic 'lang-std-flag-order'
a1c20b08b4 cmLocalGenerator: Inline AddCompilerRequirementFlag in only call site
914571a042 Place language standard flags just after CMAKE_<LANG>_FLAGS
ad16ae5c70 VS: Recognize -std: flag in CMAKE_C_FLAGS in target with C++ sources
Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !7931
-rw-r--r-- | Help/manual/cmake-compile-features.7.rst | 22 | ||||
-rw-r--r-- | Help/release/dev/lang-std-flag-order.rst | 7 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 58 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 2 | ||||
-rw-r--r-- | Tests/CompileFeatures/CMakeLists.txt | 13 | ||||
-rw-r--r-- | Tests/CompileFeatures/msvc_permissive.cxx | 9 |
7 files changed, 77 insertions, 38 deletions
diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst index 8073511..1e87ec6 100644 --- a/Help/manual/cmake-compile-features.7.rst +++ b/Help/manual/cmake-compile-features.7.rst @@ -282,3 +282,25 @@ versions specified for each: * ``Clang``: Clang compiler 5.0+. * ``NVIDIA``: NVIDIA nvcc compiler 7.5+. + +.. _`Language Standard Flags`: + +Language Standard Flags +======================= + +In order to satisfy requirements specified by the +:command:`target_compile_features` command or the +:variable:`CMAKE_<LANG>_STANDARD` variable, CMake may pass a +language standard flag to the compiler, such as ``-std=c++11``. + +For :ref:`Visual Studio Generators`, CMake cannot precisely control +the placement of the language standard flag on the compiler command line. +For :ref:`Ninja Generators`, :ref:`Makefile Generators`, and +:generator:`Xcode`, CMake places the language standard flag just after +the language-wide flags from :variable:`CMAKE_<LANG>_FLAGS` +and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`. + +.. versionchanged:: 3.26 + The language standard flag is placed before flags specified by other + abstractions such as the :command:`target_compile_options` command. + Prior to CMake 3.26, the language standard flag was placed after them. diff --git a/Help/release/dev/lang-std-flag-order.rst b/Help/release/dev/lang-std-flag-order.rst new file mode 100644 index 0000000..4ef4123 --- /dev/null +++ b/Help/release/dev/lang-std-flag-order.rst @@ -0,0 +1,7 @@ +lang-std-flag-order +------------------- + +* :ref:`Language Standard Flags`, such as ``-std=c++11``, when generated due + to :command:`target_compile_features` or :variable:`CMAKE_<LANG>_STANDARD`, + are now placed before flags added by :command:`target_compile_options`, + rather than after them. diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9745142..4d5371f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1021,12 +1021,6 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, } } - std::string compReqFlag; - this->AddCompilerRequirementFlag(compReqFlag, target, lang, config); - if (!compReqFlag.empty()) { - flags.emplace_back(std::move(compReqFlag)); - } - // Add Warning as errors flags if (!this->GetCMakeInstance()->GetIgnoreWarningAsError()) { const cmValue wError = target->GetProperty("COMPILE_WARNING_AS_ERROR"); @@ -1932,6 +1926,30 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"), config); + // Add the language standard flag for compiling, and sometimes linking. + if (compileOrLink == cmBuildStep::Compile || + (compileOrLink == cmBuildStep::Link && + // Some toolchains require use of the language standard flag + // when linking in order to use the matching standard library. + // FIXME: If CMake gains an abstraction for standard library + // selection, this will have to be reconciled with it. + this->Makefile->IsOn( + cmStrCat("CMAKE_", lang, "_LINK_WITH_STANDARD_COMPILE_OPTION")))) { + cmStandardLevelResolver standardResolver(this->Makefile); + std::string const& optionFlagDef = + standardResolver.GetCompileOptionDef(target, lang, config); + if (!optionFlagDef.empty()) { + cmValue opt = + target->Target->GetMakefile()->GetDefinition(optionFlagDef); + if (opt) { + std::vector<std::string> optVec = cmExpandedList(*opt); + for (std::string const& i : optVec) { + this->AppendFlagEscape(flags, i); + } + } + } + } + std::string compiler = this->Makefile->GetSafeDefinition( cmStrCat("CMAKE_", lang, "_COMPILER_ID")); @@ -2076,15 +2094,6 @@ void cmLocalGenerator::AddLanguageFlagsForLinking( std::string& flags, cmGeneratorTarget const* target, const std::string& lang, const std::string& config) { - if (this->Makefile->IsOn("CMAKE_" + lang + - "_LINK_WITH_STANDARD_COMPILE_OPTION")) { - // This toolchain requires use of the language standard flag - // when linking in order to use the matching standard library. - // FIXME: If CMake gains an abstraction for standard library - // selection, this will have to be reconciled with it. - this->AddCompilerRequirementFlag(flags, target, lang, config); - } - this->AddLanguageFlags(flags, target, cmBuildStep::Link, lang, config); if (target->IsIPOEnabled(lang, config)) { @@ -2224,25 +2233,6 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags, } } -void cmLocalGenerator::AddCompilerRequirementFlag( - std::string& flags, cmGeneratorTarget const* target, const std::string& lang, - const std::string& config) -{ - cmStandardLevelResolver standardResolver(this->Makefile); - - std::string const& optionFlagDef = - standardResolver.GetCompileOptionDef(target, lang, config); - if (!optionFlagDef.empty()) { - cmValue opt = target->Target->GetMakefile()->GetDefinition(optionFlagDef); - if (opt) { - std::vector<std::string> optVec = cmExpandedList(*opt); - for (std::string const& i : optVec) { - this->AppendFlagEscape(flags, i); - } - } - } -} - static void AddVisibilityCompileOption(std::string& flags, cmGeneratorTarget const* target, cmLocalGenerator* lg, diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 765441c..20f23de 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -164,10 +164,6 @@ public: const std::string& lang); void AddConfigVariableFlags(std::string& flags, const std::string& var, const std::string& config); - void AddCompilerRequirementFlag(std::string& flags, - cmGeneratorTarget const* target, - const std::string& lang, - const std::string& config); void AddColorDiagnosticsFlags(std::string& flags, const std::string& lang); //! Append flags to a string. virtual void AppendFlags(std::string& flags, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 7e43bee..cd73551 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3293,6 +3293,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( this->GeneratorTarget->GetLanguages(languages, configName); if (languages.count("C")) { std::string flagsC; + this->LocalGenerator->AddLanguageFlags( + flagsC, this->GeneratorTarget, cmBuildStep::Compile, "C", configName); this->LocalGenerator->AddCompileOptions(flagsC, this->GeneratorTarget, "C", configName); Options optC(this->LocalGenerator, Options::Compiler, diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt index f3d3a73..17f4408 100644 --- a/Tests/CompileFeatures/CMakeLists.txt +++ b/Tests/CompileFeatures/CMakeLists.txt @@ -374,3 +374,16 @@ else() target_link_libraries(CompileFeaturesGenex3 PRIVATE std_11_iface) target_compile_definitions(CompileFeaturesGenex3 PRIVATE ${genex_test_defs} ALLOW_LATER_STANDARDS=1) endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" + AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.30 + # The MSVC 14.29.30133 toolset supports C++20, + # but MSBuild puts the flags in the wrong order. + OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30129 AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") + ) + ) + add_library(msvc_permissive msvc_permissive.cxx) + target_compile_features(msvc_permissive PRIVATE cxx_std_20) + # The `-std:c++20` flag implies `-permissive-`. Test passing `-permissive` afterward. + target_compile_options(msvc_permissive PRIVATE -permissive) +endif() diff --git a/Tests/CompileFeatures/msvc_permissive.cxx b/Tests/CompileFeatures/msvc_permissive.cxx new file mode 100644 index 0000000..a8f2ff3 --- /dev/null +++ b/Tests/CompileFeatures/msvc_permissive.cxx @@ -0,0 +1,9 @@ +#if !defined(_MSVC_LANG) || _MSVC_LANG < 202002L +# error "This source must be compiled with MSVC as C++20 or later." +#endif +// Test a construct that is allowed by MSVC only with 'cl -permissive'. +enum class X +{ + Y = 1 +}; +int array[X::Y]; |