try_compile: Escape CMAKE_<lang>_FLAGS in test projects (#14268)

If CMAKE_<lang>_FLAGS contains quotes or other CMake language characters
they must be escaped when written into the generated CMakeLists.txt file
so that the test project parses them properly.

Teach the TryCompile test to cover this case by adding a flag with
quotes into CMAKE_C_FLAGS during a C language try_compile.
This commit is contained in:
Brad King 2013-07-03 15:57:02 -04:00
parent 99a814e5b9
commit 290857bb03
3 changed files with 30 additions and 8 deletions

View File

@ -12,6 +12,7 @@
#include "cmCoreTryCompile.h" #include "cmCoreTryCompile.h"
#include "cmake.h" #include "cmake.h"
#include "cmCacheManager.h" #include "cmCacheManager.h"
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmExportTryCompileFileGenerator.h" #include "cmExportTryCompileFileGenerator.h"
#include <cmsys/Directory.hxx> #include <cmsys/Directory.hxx>
@ -214,8 +215,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
} }
// Detect languages to enable. // Detect languages to enable.
cmGlobalGenerator* gg = cmLocalGenerator* lg = this->Makefile->GetLocalGenerator();
this->Makefile->GetCMakeInstance()->GetGlobalGenerator(); cmGlobalGenerator* gg = lg->GetGlobalGenerator();
std::set<std::string> testLangs; std::set<std::string> testLangs;
for(std::vector<std::string>::iterator si = sources.begin(); for(std::vector<std::string>::iterator si = sources.begin();
si != sources.end(); ++si) si != sources.end(); ++si)
@ -295,13 +296,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
for(std::set<std::string>::iterator li = testLangs.begin(); for(std::set<std::string>::iterator li = testLangs.begin();
li != testLangs.end(); ++li) li != testLangs.end(); ++li)
{ {
fprintf(fout, "SET(CMAKE_%s_FLAGS \"", li->c_str());
std::string langFlags = "CMAKE_" + *li + "_FLAGS"; std::string langFlags = "CMAKE_" + *li + "_FLAGS";
if(const char* flags = this->Makefile->GetDefinition(langFlags.c_str())) const char* flags = this->Makefile->GetDefinition(langFlags.c_str());
{ fprintf(fout, "SET(CMAKE_%s_FLAGS %s)\n", li->c_str(),
fprintf(fout, " %s ", flags); lg->EscapeForCMake(flags?flags:"").c_str());
} fprintf(fout, "SET(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}"
fprintf(fout, " ${COMPILE_DEFINITIONS}\")\n"); " ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str());
} }
fprintf(fout, "INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})\n"); fprintf(fout, "INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})\n");
fprintf(fout, "SET(CMAKE_SUPPRESS_REGENERATION 1)\n"); fprintf(fout, "SET(CMAKE_SUPPRESS_REGENERATION 1)\n");

View File

@ -89,6 +89,24 @@ if(SHOULD_FAIL)
message(SEND_ERROR "Should fail passed ${TRY_OUT}") message(SEND_ERROR "Should fail passed ${TRY_OUT}")
endif() endif()
# try to compile a file that should compile
set(_c_flags "${CMAKE_C_FLAGS}")
if(CMAKE_GENERATOR STREQUAL "Visual Studio 6")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D \"TESTDEF\"")
elseif(WATCOM)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -dTESTDEF")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \"-DTESTDEF\"")
endif()
try_compile(SHOULD_PASS
${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
${TryCompile_SOURCE_DIR}/testdef.c
OUTPUT_VARIABLE TRY_OUT)
if(NOT SHOULD_PASS)
message(SEND_ERROR "should pass failed ${TRY_OUT}")
endif()
set(CMAKE_C_FLAGS "${_c_flags}")
if(NOT SHOULD_FAIL) if(NOT SHOULD_FAIL)
if(SHOULD_PASS) if(SHOULD_PASS)
message("All Tests passed, ignore all previous output.") message("All Tests passed, ignore all previous output.")

View File

@ -0,0 +1,4 @@
#ifndef TESTDEF
# error "TESTDEF should be defined!"
#endif
int main(void) { return 0; }