Merge topic 'try_compile-custom-variables'

d256ba07 try_compile: Optionally forward custom platform variables to test project
fb4791b3 cmCoreTryCompile: Refactor forwarding of variables to test project
This commit is contained in:
Brad King 2016-05-26 09:52:12 -04:00 committed by CMake Topic Stage
commit 36d9a01a31
7 changed files with 118 additions and 74 deletions

View File

@ -115,3 +115,7 @@ a build configuration.
Set the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable to specify Set the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable to specify
the type of target used for the source file signature. the type of target used for the source file signature.
Set the :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable to specify
variables that must be propagated into the test project. This variable is
meant for use only in toolchain files.

View File

@ -298,6 +298,7 @@ Variables that Control the Build
/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG
/variable/CMAKE_STATIC_LINKER_FLAGS /variable/CMAKE_STATIC_LINKER_FLAGS
/variable/CMAKE_TRY_COMPILE_CONFIGURATION /variable/CMAKE_TRY_COMPILE_CONFIGURATION
/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
/variable/CMAKE_TRY_COMPILE_TARGET_TYPE /variable/CMAKE_TRY_COMPILE_TARGET_TYPE
/variable/CMAKE_USE_RELATIVE_PATHS /variable/CMAKE_USE_RELATIVE_PATHS
/variable/CMAKE_VISIBILITY_INLINES_HIDDEN /variable/CMAKE_VISIBILITY_INLINES_HIDDEN

View File

@ -0,0 +1,7 @@
try_compile-custom-variables
----------------------------
* A :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable was
added for use by toolchain files to specify platform-specific
variables that must be propagated by the :command:`try_compile`
command into test projects.

View File

@ -0,0 +1,10 @@
CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
------------------------------------
List of variables that the :command:`try_compile` command source file signature
must propagate into the test project in order to target the same platform as
the host project.
This variable should not be set by project code. It is meant to be set by
CMake's platform information modules for the current toolchain, or by a
toolchain file when used with :variable:`CMAKE_TOOLCHAIN_FILE`.

View File

@ -20,6 +20,30 @@
#include <assert.h> #include <assert.h>
static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN =
"CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN";
static std::string const kCMAKE_C_COMPILER_TARGET = "CMAKE_C_COMPILER_TARGET";
static std::string const kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN =
"CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN";
static std::string const kCMAKE_CXX_COMPILER_TARGET =
"CMAKE_CXX_COMPILER_TARGET";
static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
"CMAKE_LINK_SEARCH_END_STATIC";
static std::string const kCMAKE_LINK_SEARCH_START_STATIC =
"CMAKE_LINK_SEARCH_START_STATIC";
static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET =
"CMAKE_OSX_DEPLOYMENT_TARGET";
static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
"CMAKE_POSITION_INDEPENDENT_CODE";
static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
"CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool isTryRun) bool isTryRun)
{ {
@ -383,76 +407,51 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
fname.c_str()); fname.c_str());
} }
/* for the TRY_COMPILEs we want to be able to specify the architecture. // Forward a set of variables to the inner project cache.
So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set {
CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to std::set<std::string> vars;
have the tests run for each specific architecture. Since vars.insert(kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN);
cmLocalGenerator doesn't allow building for "the other" vars.insert(kCMAKE_C_COMPILER_TARGET);
architecture only via CMAKE_OSX_ARCHITECTURES. vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
*/ vars.insert(kCMAKE_CXX_COMPILER_TARGET);
if (this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_OSX_ARCHITECTURES") != vars.insert(kCMAKE_ENABLE_EXPORTS);
0) { vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
std::string flag = "-DCMAKE_OSX_ARCHITECTURES="; vars.insert(kCMAKE_LINK_SEARCH_START_STATIC);
flag += this->Makefile->GetSafeDefinition( vars.insert(kCMAKE_OSX_ARCHITECTURES);
"CMAKE_TRY_COMPILE_OSX_ARCHITECTURES"); vars.insert(kCMAKE_OSX_DEPLOYMENT_TARGET);
cmakeFlags.push_back(flag); vars.insert(kCMAKE_OSX_SYSROOT);
} else if (this->Makefile->GetDefinition("CMAKE_OSX_ARCHITECTURES") != 0) { vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE);
std::string flag = "-DCMAKE_OSX_ARCHITECTURES="; vars.insert(kCMAKE_SYSROOT);
flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
cmakeFlags.push_back(flag); if (const char* varListStr = this->Makefile->GetDefinition(
} kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
/* on APPLE also pass CMAKE_OSX_SYSROOT to the try_compile */ std::vector<std::string> varList;
if (this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT") != 0) { cmSystemTools::ExpandListArgument(varListStr, varList);
std::string flag = "-DCMAKE_OSX_SYSROOT="; vars.insert(varList.begin(), varList.end());
flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_SYSROOT"); }
cmakeFlags.push_back(flag);
} /* for the TRY_COMPILEs we want to be able to specify the architecture.
/* on APPLE also pass CMAKE_OSX_DEPLOYMENT_TARGET to the try_compile */ So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set
if (this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET") != 0) { CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to
std::string flag = "-DCMAKE_OSX_DEPLOYMENT_TARGET="; have the tests run for each specific architecture. Since
flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); cmLocalGenerator doesn't allow building for "the other"
cmakeFlags.push_back(flag); architecture only via CMAKE_OSX_ARCHITECTURES.
} */
if (const char* cxxDef = if (const char* tcArchs = this->Makefile->GetDefinition(
this->Makefile->GetDefinition("CMAKE_CXX_COMPILER_TARGET")) { kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES)) {
std::string flag = "-DCMAKE_CXX_COMPILER_TARGET="; vars.erase(kCMAKE_OSX_ARCHITECTURES);
flag += cxxDef; std::string flag = "-DCMAKE_OSX_ARCHITECTURES=" + std::string(tcArchs);
cmakeFlags.push_back(flag); cmakeFlags.push_back(flag);
} }
if (const char* cDef =
this->Makefile->GetDefinition("CMAKE_C_COMPILER_TARGET")) { for (std::set<std::string>::iterator vi = vars.begin(); vi != vars.end();
std::string flag = "-DCMAKE_C_COMPILER_TARGET="; ++vi) {
flag += cDef; std::string const& var = *vi;
cmakeFlags.push_back(flag); if (const char* val = this->Makefile->GetDefinition(var)) {
} std::string flag = "-D" + var + "=" + val;
if (const char* tcxxDef = this->Makefile->GetDefinition( cmakeFlags.push_back(flag);
"CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN")) { }
std::string flag = "-DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN="; }
flag += tcxxDef;
cmakeFlags.push_back(flag);
}
if (const char* tcDef = this->Makefile->GetDefinition(
"CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN")) {
std::string flag = "-DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=";
flag += tcDef;
cmakeFlags.push_back(flag);
}
if (const char* rootDef = this->Makefile->GetDefinition("CMAKE_SYSROOT")) {
std::string flag = "-DCMAKE_SYSROOT=";
flag += rootDef;
cmakeFlags.push_back(flag);
}
if (this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE") !=
0) {
fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
}
if (const char* lssDef =
this->Makefile->GetDefinition("CMAKE_LINK_SEARCH_START_STATIC")) {
fprintf(fout, "set(CMAKE_LINK_SEARCH_START_STATIC \"%s\")\n", lssDef);
}
if (const char* lssDef =
this->Makefile->GetDefinition("CMAKE_LINK_SEARCH_END_STATIC")) {
fprintf(fout, "set(CMAKE_LINK_SEARCH_END_STATIC \"%s\")\n", lssDef);
} }
/* Set the appropriate policy information for ENABLE_EXPORTS */ /* Set the appropriate policy information for ENABLE_EXPORTS */
@ -461,10 +460,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
cmPolicies::NEW cmPolicies::NEW
? "NEW" ? "NEW"
: "OLD"); : "OLD");
if (const char* ee =
this->Makefile->GetDefinition("CMAKE_ENABLE_EXPORTS")) {
fprintf(fout, "set(CMAKE_ENABLE_EXPORTS %s)\n", ee);
}
if (targetType == cmState::EXECUTABLE) { if (targetType == cmState::EXECUTABLE) {
/* Put the executable at a known location (for COPY_FILE). */ /* Put the executable at a known location (for COPY_FILE). */

View File

@ -0,0 +1,23 @@
enable_language(C)
# Normally this variable should be set by a platform information module or
# a toolchain file, but for purposes of this test we simply set it here.
set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES MY_CUSTOM_VARIABLE)
set(MY_CUSTOM_VARIABLE SOME_VALUE)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
OUTPUT_VARIABLE out
)
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
# Check that the cache was populated with our custom variable.
file(STRINGS ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CMakeCache.txt entries
REGEX MY_CUSTOM_VARIABLE:UNINITIALIZED=${MY_CUSTOM_VARIABLE}
)
if(NOT entries)
message(FATAL_ERROR "try_compile did not populate cache as expected")
endif()

View File

@ -16,6 +16,10 @@ run_cmake(BadSources2)
run_cmake(NonSourceCopyFile) run_cmake(NonSourceCopyFile)
run_cmake(NonSourceCompileDefinitions) run_cmake(NonSourceCompileDefinitions)
set(RunCMake_TEST_OPTIONS --debug-trycompile)
run_cmake(PlatformVariables)
unset(RunCMake_TEST_OPTIONS)
run_cmake(TargetTypeExe) run_cmake(TargetTypeExe)
run_cmake(TargetTypeInvalid) run_cmake(TargetTypeInvalid)
run_cmake(TargetTypeStatic) run_cmake(TargetTypeStatic)