summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-02-19 18:23:48 (GMT)
committerBrad King <brad.king@kitware.com>2016-02-19 19:07:38 (GMT)
commit7f1bd9fe6910f7633d98dec018cc01331a46b87e (patch)
treed7f1e58c327d7aecd6ce861b6cd6b3c65c8bff71
parent509b1f08ea3ee1d8063efc81fee851ee075b3c97 (diff)
downloadCMake-7f1bd9fe6910f7633d98dec018cc01331a46b87e.zip
CMake-7f1bd9fe6910f7633d98dec018cc01331a46b87e.tar.gz
CMake-7f1bd9fe6910f7633d98dec018cc01331a46b87e.tar.bz2
try_compile: Add option to control type of target
Create a `CMAKE_TRY_COMPILE_TARGET_TYPE` option to specify use of `add_library(... STATIC ...)` for the generated test project. This will be useful for cross-compiling toolchains that cannot link a binary without custom flags or scripts.
-rw-r--r--Help/command/try_compile.rst3
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/release/dev/try_compile-target-type.rst8
-rw-r--r--Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst15
-rw-r--r--Source/cmCoreTryCompile.cxx73
-rw-r--r--Source/cmCoreTryCompile.h6
-rw-r--r--Source/cmTryCompileCommand.cxx2
-rw-r--r--Source/cmTryRunCommand.cxx2
-rw-r--r--Tests/RunCMake/try_compile/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeExe.cmake14
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeInvalid-result.txt1
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt5
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeInvalid.cmake2
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeStatic.cmake14
-rw-r--r--Tests/RunCMake/try_compile/other.c1
15 files changed, 136 insertions, 15 deletions
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 28dae80..78b1bc7 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -112,3 +112,6 @@ The current setting of :policy:`CMP0065` is set in the generated project.
Set the :variable:`CMAKE_TRY_COMPILE_CONFIGURATION` variable to choose
a build configuration.
+
+Set the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable to specify
+the type of target used for the source file signature.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 15eaece..444a706 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -292,6 +292,7 @@ Variables that Control the Build
/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG
/variable/CMAKE_STATIC_LINKER_FLAGS
/variable/CMAKE_TRY_COMPILE_CONFIGURATION
+ /variable/CMAKE_TRY_COMPILE_TARGET_TYPE
/variable/CMAKE_USE_RELATIVE_PATHS
/variable/CMAKE_VISIBILITY_INLINES_HIDDEN
/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
diff --git a/Help/release/dev/try_compile-target-type.rst b/Help/release/dev/try_compile-target-type.rst
new file mode 100644
index 0000000..cc41bf3
--- /dev/null
+++ b/Help/release/dev/try_compile-target-type.rst
@@ -0,0 +1,8 @@
+try_compile-target-type
+-----------------------
+
+* The :command:`try_compile` command learned to check a new
+ :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable to optionally
+ build a static library instead of an executable. This is useful
+ for cross-compiling toolchains that cannot link binaries without
+ custom flags or scripts.
diff --git a/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst b/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
new file mode 100644
index 0000000..5fa8dfc
--- /dev/null
+++ b/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
@@ -0,0 +1,15 @@
+CMAKE_TRY_COMPILE_TARGET_TYPE
+-----------------------------
+
+Type of target generated for :command:`try_compile` calls using the
+source file signature. Valid values are:
+
+``EXECUTABLE``
+ Use :command:`add_executable` to name the source file in the
+ generated project. This is the default if no value is given.
+
+``STATIC_LIBRARY``
+ Use :command:`add_library` with the ``STATIC`` option to name the
+ source file in the generated project. This avoids running the
+ linker and is intended for use with cross-compiling toolchains
+ that cannot link without custom flags or linker scripts.
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 4a1f770..b639c15 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -19,13 +19,42 @@
#include <assert.h>
-int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
+int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
+ bool isTryRun)
{
this->BinaryDirectory = argv[1].c_str();
this->OutputFile = "";
// which signature were we called with ?
this->SrcFileSignature = true;
+ cmState::TargetType targetType = cmState::EXECUTABLE;
+ const char* tt =
+ this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE");
+ if (!isTryRun && tt && *tt)
+ {
+ if (strcmp(tt, cmState::GetTargetTypeName(cmState::EXECUTABLE)) == 0)
+ {
+ targetType = cmState::EXECUTABLE;
+ }
+ else if (strcmp(tt,
+ cmState::GetTargetTypeName(cmState::STATIC_LIBRARY)) == 0)
+ {
+ targetType = cmState::STATIC_LIBRARY;
+ }
+ else
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ std::string("Invalid value '") + tt + "' for "
+ "CMAKE_TRY_COMPILE_TARGET_TYPE. Only "
+ "'" + cmState::GetTargetTypeName(cmState::EXECUTABLE) + "' and "
+ "'" + cmState::GetTargetTypeName(cmState::STATIC_LIBRARY) + "' "
+ "are allowed."
+ );
+ return -1;
+ }
+ }
+
const char* sourceDirectory = argv[2].c_str();
const char* projectName = 0;
std::string targetName;
@@ -486,11 +515,22 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
fprintf(fout, "set(CMAKE_ENABLE_EXPORTS %s)\n", ee);
}
- /* Put the executable at a known location (for COPY_FILE). */
- fprintf(fout, "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
- this->BinaryDirectory.c_str());
- /* Create the actual executable. */
- fprintf(fout, "add_executable(%s", targetName.c_str());
+ if (targetType == cmState::EXECUTABLE)
+ {
+ /* Put the executable at a known location (for COPY_FILE). */
+ fprintf(fout, "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
+ this->BinaryDirectory.c_str());
+ /* Create the actual executable. */
+ fprintf(fout, "add_executable(%s", targetName.c_str());
+ }
+ else // if (targetType == cmState::STATIC_LIBRARY)
+ {
+ /* Put the static library at a known location (for COPY_FILE). */
+ fprintf(fout, "set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \"%s\")\n",
+ this->BinaryDirectory.c_str());
+ /* Create the actual static library. */
+ fprintf(fout, "add_library(%s STATIC", targetName.c_str());
+ }
for(std::vector<std::string>::iterator si = sources.begin();
si != sources.end(); ++si)
{
@@ -549,7 +589,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
if (this->SrcFileSignature)
{
std::string copyFileErrorMessage;
- this->FindOutputFile(targetName);
+ this->FindOutputFile(targetName, targetType);
if ((res==0) && !copyFile.empty())
{
@@ -651,13 +691,26 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
}
}
-void cmCoreTryCompile::FindOutputFile(const std::string& targetName)
+void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
+ cmState::TargetType targetType)
{
this->FindErrorMessage = "";
this->OutputFile = "";
std::string tmpOutputFile = "/";
- tmpOutputFile += targetName;
- tmpOutputFile +=this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
+ if (targetType == cmState::EXECUTABLE)
+ {
+ tmpOutputFile += targetName;
+ tmpOutputFile +=
+ this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
+ }
+ else // if (targetType == cmState::STATIC_LIBRARY)
+ {
+ tmpOutputFile +=
+ this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX");
+ tmpOutputFile += targetName;
+ tmpOutputFile +=
+ this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
+ }
// a list of directories where to search for the compilation result
// at first directly in the binary dir
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 3272462..c2beea8 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -30,7 +30,7 @@ public:
* commands, such as TryRun can access the same logic without
* duplication.
*/
- int TryCompileCode(std::vector<std::string> const& argv);
+ int TryCompileCode(std::vector<std::string> const& argv, bool isTryRun);
/**
* This deletes all the files created by TryCompileCode.
@@ -44,8 +44,8 @@ public:
TryCompileCode. The result is stored in OutputFile. If nothing is found,
the error message is stored in FindErrorMessage.
*/
- void FindOutputFile(const std::string& targetName);
-
+ void FindOutputFile(const std::string& targetName,
+ cmState::TargetType targetType);
cmTypeMacro(cmCoreTryCompile, cmCommand);
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
index 12ce015..87fbbdf 100644
--- a/Source/cmTryCompileCommand.cxx
+++ b/Source/cmTryCompileCommand.cxx
@@ -28,7 +28,7 @@ bool cmTryCompileCommand
return false;
}
- this->TryCompileCode(argv);
+ this->TryCompileCode(argv, false);
// if They specified clean then we clean up what we can
if (this->SrcFileSignature)
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index b9ffe5e..d4a36c9 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -135,7 +135,7 @@ bool cmTryRunCommand
this->CompileResultVariable = argv[1];
// do the try compile
- int res = this->TryCompileCode(tryCompile);
+ int res = this->TryCompileCode(tryCompile, true);
// now try running the command if it compiled
if (!res)
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index 6cdbafa..43ce998 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -16,6 +16,10 @@ run_cmake(BadSources2)
run_cmake(NonSourceCopyFile)
run_cmake(NonSourceCompileDefinitions)
+run_cmake(TargetTypeExe)
+run_cmake(TargetTypeInvalid)
+run_cmake(TargetTypeStatic)
+
run_cmake(CMP0056)
if(RunCMake_GENERATOR MATCHES "Make|Ninja")
diff --git a/Tests/RunCMake/try_compile/TargetTypeExe.cmake b/Tests/RunCMake/try_compile/TargetTypeExe.cmake
new file mode 100644
index 0000000..9b6e727
--- /dev/null
+++ b/Tests/RunCMake/try_compile/TargetTypeExe.cmake
@@ -0,0 +1,14 @@
+enable_language(C)
+set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+ SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ OUTPUT_VARIABLE out
+ COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/copy
+ COPY_FILE_ERROR copy_err
+ )
+if(NOT result)
+ message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
+if(copy_err)
+ message(FATAL_ERROR "try_compile COPY_FILE failed:\n${copy_err}")
+endif()
diff --git a/Tests/RunCMake/try_compile/TargetTypeInvalid-result.txt b/Tests/RunCMake/try_compile/TargetTypeInvalid-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/TargetTypeInvalid-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt b/Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt
new file mode 100644
index 0000000..08b281a
--- /dev/null
+++ b/Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TargetTypeInvalid.cmake:2 \(try_compile\):
+ Invalid value 'INVALID' for CMAKE_TRY_COMPILE_TARGET_TYPE. Only
+ 'EXECUTABLE' and 'STATIC_LIBRARY' are allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/TargetTypeInvalid.cmake b/Tests/RunCMake/try_compile/TargetTypeInvalid.cmake
new file mode 100644
index 0000000..0bbc4ac
--- /dev/null
+++ b/Tests/RunCMake/try_compile/TargetTypeInvalid.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_TRY_COMPILE_TARGET_TYPE INVALID)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
diff --git a/Tests/RunCMake/try_compile/TargetTypeStatic.cmake b/Tests/RunCMake/try_compile/TargetTypeStatic.cmake
new file mode 100644
index 0000000..006b8b8
--- /dev/null
+++ b/Tests/RunCMake/try_compile/TargetTypeStatic.cmake
@@ -0,0 +1,14 @@
+enable_language(C)
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+ SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/other.c
+ OUTPUT_VARIABLE out
+ COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/copy
+ COPY_FILE_ERROR copy_err
+ )
+if(NOT result)
+ message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
+if(copy_err)
+ message(FATAL_ERROR "try_compile COPY_FILE failed:\n${copy_err}")
+endif()
diff --git a/Tests/RunCMake/try_compile/other.c b/Tests/RunCMake/try_compile/other.c
new file mode 100644
index 0000000..6c24f10
--- /dev/null
+++ b/Tests/RunCMake/try_compile/other.c
@@ -0,0 +1 @@
+int other(void) { return 0; }