diff options
author | Brad King <brad.king@kitware.com> | 2014-12-03 11:02:31 -0500 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2014-12-03 15:30:22 -0500 |
commit | 88eb5824da12940e78d57fe254f17f64cdacd659 (patch) | |
tree | 24d535cb4d88f076e69c9a85870aaaff3d1204e8 | |
parent | a4f9b6f0ca9248530b9749b7fa9628053a3f8f98 (diff) | |
download | cmake-88eb5824da12940e78d57fe254f17f64cdacd659.tar.gz |
try_compile: Pass linker flags into test project (#14066)
Copy CMAKE_EXE_LINKER_FLAGS into the test project generated by
try_compile, just like we already copy CMAKE_<LANG>_FLAGS.
Add CMake Policy CMP0056 to activate this behavior in a compatible way,
but do not warn by default when the policy is not set since it will
affect all try_compile calls.
Extend the RunCMake.try_compile test with a case covering this behavior
for each policy setting.
-rw-r--r-- | Help/manual/cmake-policies.7.rst | 1 | ||||
-rw-r--r-- | Help/policy/CMP0056.rst | 32 | ||||
-rw-r--r-- | Help/release/dev/try_compile-link-flags.rst | 6 | ||||
-rw-r--r-- | Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst | 2 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.cxx | 34 | ||||
-rw-r--r-- | Source/cmPolicies.cxx | 5 | ||||
-rw-r--r-- | Source/cmPolicies.h | 1 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/CMP0056-stderr.txt | 13 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/CMP0056-stdout.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/CMP0056.cmake | 67 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/RunCMakeTest.cmake | 2 |
11 files changed, 167 insertions, 0 deletions
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 742fd6362a..96f39e66ed 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -113,3 +113,4 @@ All Policies /policy/CMP0053 /policy/CMP0054 /policy/CMP0055 + /policy/CMP0056 diff --git a/Help/policy/CMP0056.rst b/Help/policy/CMP0056.rst new file mode 100644 index 0000000000..3c75ff451e --- /dev/null +++ b/Help/policy/CMP0056.rst @@ -0,0 +1,32 @@ +CMP0056 +------- + +Honor link flags in :command:`try_compile` source-file signature. + +The :command:`try_compile` command source-file signature generates a +``CMakeLists.txt`` file to build the source file into an executable. +In order to compile the source the same way as it might be compiled +by the calling project, the generated project sets the value of the +:variable:`CMAKE_<LANG>_FLAGS` variable to that in the calling project. +The value of the :variable:`CMAKE_EXE_LINKER_FLAGS` variable may be +needed in some cases too, but CMake 3.1 and lower did not set it in +the generated project. CMake 3.2 and above prefer to set it so that +linker flags are honored as well as compiler flags. This policy +provides compatibility with the pre-3.2 behavior. + +The OLD behavior for this policy is to not set the value of the +:variable:`CMAKE_EXE_LINKER_FLAGS` variable in the generated test +project. The NEW behavior for this policy is to set the value of +the :variable:`CMAKE_EXE_LINKER_FLAGS` variable in the test project +to the same as it is in the calling project. + +If the project code does not set the policy explicitly, users may +set it on the command line by defining the +:variable:`CMAKE_POLICY_DEFAULT_CMP0056 <CMAKE_POLICY_DEFAULT_CMP<NNNN>>` +variable in the cache. + +This policy was introduced in CMake version 3.2. Unlike most policies, +CMake version |release| does *not* warn by default when this policy +is not set and simply uses OLD behavior. See documentation of the +:variable:`CMAKE_POLICY_WARNING_CMP0056 <CMAKE_POLICY_WARNING_CMP<NNNN>>` +variable to control the warning. diff --git a/Help/release/dev/try_compile-link-flags.rst b/Help/release/dev/try_compile-link-flags.rst new file mode 100644 index 0000000000..d995e0b92a --- /dev/null +++ b/Help/release/dev/try_compile-link-flags.rst @@ -0,0 +1,6 @@ +try_compile-link-flags +---------------------- + +* The :command:`try_compile` command source file signature now honors + link flags (e.g. :variable:`CMAKE_EXE_LINKER_FLAGS`) in the generated + test project. See policy :policy:`CMP0056`. diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst index b563aeaec0..a83c80756d 100644 --- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst +++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst @@ -9,6 +9,8 @@ warn by default: policy :policy:`CMP0025`. * ``CMAKE_POLICY_WARNING_CMP0047`` controls the warning for policy :policy:`CMP0047`. +* ``CMAKE_POLICY_WARNING_CMP0056`` controls the warning for + policy :policy:`CMP0056`. This variable should not be set by a project in CMake code. Project developers running CMake may set this variable in their cache to diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 350632376e..0030b841e2 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -331,6 +331,40 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}" " ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str()); } + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0056)) + { + case cmPolicies::WARN: + if(this->Makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0056")) + { + cmOStringStream w; + w << (this->Makefile->GetCMakeInstance()->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0056)) << "\n" + "For compatibility with older versions of CMake, try_compile " + "is not honoring caller link flags (e.g. CMAKE_EXE_LINKER_FLAGS) " + "in the test project." + ; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + } + case cmPolicies::OLD: + // OLD behavior is to do nothing. + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + this->Makefile->GetCMakeInstance()->GetPolicies() + ->GetRequiredPolicyError(cmPolicies::CMP0056) + ); + case cmPolicies::NEW: + // NEW behavior is to pass linker flags. + { + const char* exeLinkFlags = + this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS"); + fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n", + lg->EscapeForCMake(exeLinkFlags?exeLinkFlags:"").c_str()); + } break; + } fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS}" " ${EXE_LINKER_FLAGS}\")\n"); fprintf(fout, "include_directories(${INCLUDE_DIRECTORIES})\n"); diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 64b87b7306..1a27a25f5f 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -369,6 +369,11 @@ cmPolicies::cmPolicies() CMP0055, "CMP0055", "Strict checking for break() command.", 3,2,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0056, "CMP0056", + "Honor link flags in try_compile() source-file signature.", + 3,2,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 46ecc22ad7..c393c2f70f 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -112,6 +112,7 @@ public: CMP0054, ///< Only interpret if() arguments as variables /// or keywords when unquoted. CMP0055, ///< Strict checking for break() command. + CMP0056, ///< Honor link flags in try_compile() source-file signature. /** \brief Always the last entry. * diff --git a/Tests/RunCMake/try_compile/CMP0056-stderr.txt b/Tests/RunCMake/try_compile/CMP0056-stderr.txt new file mode 100644 index 0000000000..5c1f0e4cf9 --- /dev/null +++ b/Tests/RunCMake/try_compile/CMP0056-stderr.txt @@ -0,0 +1,13 @@ +before try_compile with CMP0056 WARN-default +after try_compile with CMP0056 WARN-default +* +CMake Warning \(dev\) at CMP0056.cmake:[0-9]+ \(try_compile\): + Policy CMP0056 is not set: Honor link flags in try_compile\(\) source-file + signature. Run "cmake --help-policy CMP0056" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + For compatibility with older versions of CMake, try_compile is not honoring + caller link flags \(e.g. CMAKE_EXE_LINKER_FLAGS\) in the test project. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/try_compile/CMP0056-stdout.txt b/Tests/RunCMake/try_compile/CMP0056-stdout.txt new file mode 100644 index 0000000000..89e7c437b0 --- /dev/null +++ b/Tests/RunCMake/try_compile/CMP0056-stdout.txt @@ -0,0 +1,4 @@ +-- try_compile with CMP0056 WARN-default worked as expected +-- try_compile with CMP0056 WARN-enabled worked as expected +-- try_compile with CMP0056 OLD worked as expected +-- try_compile with CMP0056 NEW worked as expected diff --git a/Tests/RunCMake/try_compile/CMP0056.cmake b/Tests/RunCMake/try_compile/CMP0056.cmake new file mode 100644 index 0000000000..e8d3d4a3bd --- /dev/null +++ b/Tests/RunCMake/try_compile/CMP0056.cmake @@ -0,0 +1,67 @@ +enable_language(C) +set(obj "${CMAKE_C_OUTPUT_EXTENSION}") +if(BORLAND) + set(pre -) +endif() +set(CMAKE_EXE_LINKER_FLAGS ${pre}BADFLAG${obj}) + +#----------------------------------------------------------------------------- +message("before try_compile with CMP0056 WARN-default") +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(NOT RESULT) + message(FATAL_ERROR "try_compile failed but should have passed:\n${out}") +elseif("x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 WARN-default worked as expected") +endif() +message("after try_compile with CMP0056 WARN-default") + +#----------------------------------------------------------------------------- +set(CMAKE_POLICY_WARNING_CMP0056 ON) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(NOT RESULT) + message(FATAL_ERROR "try_compile failed but should have passed:\n${out}") +elseif("x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 WARN-enabled worked as expected") +endif() + +#----------------------------------------------------------------------------- +cmake_policy(SET CMP0056 OLD) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(NOT RESULT) + message(FATAL_ERROR "try_compile failed but should have passed:\n${out}") +elseif("x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 OLD worked as expected") +endif() + +#----------------------------------------------------------------------------- +cmake_policy(SET CMP0056 NEW) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(RESULT) + message(FATAL_ERROR "try_compile passed but should have failed:\n${out}") +elseif(NOT "x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile did not fail with BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 NEW worked as expected") +endif() diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake index c93445876e..06096b2390 100644 --- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake +++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake @@ -15,3 +15,5 @@ run_cmake(BadSources1) run_cmake(BadSources2) run_cmake(NonSourceCopyFile) run_cmake(NonSourceCompileDefinitions) + +run_cmake(CMP0056) |