1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-20 21:40:15 +08:00

try_compile: Add PROJECT keyword-dispatched signature

Introduce a new signature for the project flavor of try_compile (and
try_run) which removes the `bindir` argument and adds a required PROJECT
tag. This is similar to the SOURCES flavor added by commit aa9220d3
(try_compile: Add keyword-dispatched signature, 2022-09-02).
This commit is contained in:
Matthew Woehlke
2022-09-14 16:35:50 -04:00
parent c3e68020d6
commit 56ae40cc59
22 changed files with 147 additions and 33 deletions

View File

@@ -14,10 +14,15 @@ Try Compiling Whole Projects
.. code-block:: cmake .. code-block:: cmake
try_compile(<resultVar> <bindir> <srcdir> try_compile(<resultVar> PROJECT <projectName>
<projectName> [<targetName>] [CMAKE_FLAGS <flags>...] SOURCE_DIR <srcdir>
[BINARY_DIR <bindir>]
[TARGET <targetName>]
[CMAKE_FLAGS <flags>...]
[OUTPUT_VARIABLE <var>]) [OUTPUT_VARIABLE <var>])
.. versionadded:: 3.25
Try building a project. The success or failure of the ``try_compile``, Try building a project. The success or failure of the ``try_compile``,
i.e. ``TRUE`` or ``FALSE`` respectively, is returned in ``<resultVar>``. i.e. ``TRUE`` or ``FALSE`` respectively, is returned in ``<resultVar>``.
@@ -34,6 +39,15 @@ below for the meaning of other options.
Previously this was only done by the Previously this was only done by the
:ref:`source file <Try Compiling Source Files>` signature. :ref:`source file <Try Compiling Source Files>` signature.
This command also supports an alternate signature
which was present in older versions of CMake:
.. code-block:: cmake
try_compile(<resultVar> <bindir> <srcdir>
<projectName> [<targetName>] [CMAKE_FLAGS <flags>...]
[OUTPUT_VARIABLE <var>])
.. _`Try Compiling Source Files`: .. _`Try Compiling Source Files`:
Try Compiling Source Files Try Compiling Source Files

View File

@@ -121,6 +121,26 @@ ArgumentParser::Continue TryCompileCompileDefs(Arguments& args,
return ArgumentParser::Continue::Yes; return ArgumentParser::Continue::Yes;
} }
cmArgumentParser<Arguments> makeTryCompileParser(
const cmArgumentParser<Arguments>& base)
{
return cmArgumentParser<Arguments>{ base }.Bind("OUTPUT_VARIABLE"_s,
&Arguments::OutputVariable);
}
cmArgumentParser<Arguments> makeTryRunParser(
const cmArgumentParser<Arguments>& base)
{
return cmArgumentParser<Arguments>{ base }
.Bind("COMPILE_OUTPUT_VARIABLE"_s, &Arguments::CompileOutputVariable)
.Bind("RUN_OUTPUT_VARIABLE"_s, &Arguments::RunOutputVariable)
.Bind("RUN_OUTPUT_STDOUT_VARIABLE"_s, &Arguments::RunOutputStdOutVariable)
.Bind("RUN_OUTPUT_STDERR_VARIABLE"_s, &Arguments::RunOutputStdErrVariable)
.Bind("WORKING_DIRECTORY"_s, &Arguments::RunWorkingDirectory)
.Bind("ARGS"_s, &Arguments::RunArgs)
/* keep semicolon on own line */;
}
#define BIND_LANG_PROPS(lang) \ #define BIND_LANG_PROPS(lang) \
Bind(#lang "_STANDARD"_s, TryCompileLangProp) \ Bind(#lang "_STANDARD"_s, TryCompileLangProp) \
.Bind(#lang "_STANDARD_REQUIRED"_s, TryCompileLangProp) \ .Bind(#lang "_STANDARD_REQUIRED"_s, TryCompileLangProp) \
@@ -129,13 +149,17 @@ ArgumentParser::Continue TryCompileCompileDefs(Arguments& args,
auto const TryCompileBaseArgParser = auto const TryCompileBaseArgParser =
cmArgumentParser<Arguments>{} cmArgumentParser<Arguments>{}
.Bind(0, &Arguments::CompileResultVariable) .Bind(0, &Arguments::CompileResultVariable)
.Bind("SOURCES"_s, &Arguments::Sources)
.Bind("CMAKE_FLAGS"_s, &Arguments::CMakeFlags) .Bind("CMAKE_FLAGS"_s, &Arguments::CMakeFlags)
.Bind("__CMAKE_INTERNAL"_s, &Arguments::CMakeInternal)
/* keep semicolon on own line */;
auto const TryCompileBaseNonProjectArgParser =
cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
.Bind("SOURCES"_s, &Arguments::Sources)
.Bind("COMPILE_DEFINITIONS"_s, TryCompileCompileDefs, .Bind("COMPILE_DEFINITIONS"_s, TryCompileCompileDefs,
ArgumentParser::ExpectAtLeast{ 0 }) ArgumentParser::ExpectAtLeast{ 0 })
.Bind("LINK_LIBRARIES"_s, &Arguments::LinkLibraries) .Bind("LINK_LIBRARIES"_s, &Arguments::LinkLibraries)
.Bind("LINK_OPTIONS"_s, &Arguments::LinkOptions) .Bind("LINK_OPTIONS"_s, &Arguments::LinkOptions)
.Bind("__CMAKE_INTERNAL"_s, &Arguments::CMakeInternal)
.Bind("COPY_FILE"_s, &Arguments::CopyFileTo) .Bind("COPY_FILE"_s, &Arguments::CopyFileTo)
.Bind("COPY_FILE_ERROR"_s, &Arguments::CopyFileError) .Bind("COPY_FILE_ERROR"_s, &Arguments::CopyFileError)
.BIND_LANG_PROPS(C) .BIND_LANG_PROPS(C)
@@ -146,38 +170,35 @@ auto const TryCompileBaseArgParser =
.BIND_LANG_PROPS(OBJCXX) .BIND_LANG_PROPS(OBJCXX)
/* keep semicolon on own line */; /* keep semicolon on own line */;
auto const TryCompileArgParser = auto const TryCompileBaseProjectArgParser =
cmArgumentParser<Arguments>{ TryCompileBaseArgParser }.Bind( cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
"OUTPUT_VARIABLE"_s, &Arguments::OutputVariable) .Bind("PROJECT"_s, &Arguments::ProjectName)
.Bind("SOURCE_DIR"_s, &Arguments::SourceDirectoryOrFile)
.Bind("BINARY_DIR"_s, &Arguments::BinaryDirectory)
.Bind("TARGET"_s, &Arguments::TargetName)
/* keep semicolon on own line */; /* keep semicolon on own line */;
auto const TryCompileProjectArgParser =
makeTryCompileParser(TryCompileBaseProjectArgParser);
auto const TryCompileSourcesArgParser =
makeTryCompileParser(TryCompileBaseNonProjectArgParser);
auto const TryCompileOldArgParser = auto const TryCompileOldArgParser =
cmArgumentParser<Arguments>{ TryCompileArgParser } makeTryCompileParser(TryCompileBaseNonProjectArgParser)
.Bind(1, &Arguments::BinaryDirectory) .Bind(1, &Arguments::BinaryDirectory)
.Bind(2, &Arguments::SourceDirectoryOrFile) .Bind(2, &Arguments::SourceDirectoryOrFile)
.Bind(3, &Arguments::ProjectName) .Bind(3, &Arguments::ProjectName)
.Bind(4, &Arguments::TargetName) .Bind(4, &Arguments::TargetName)
/* keep semicolon on own line */; /* keep semicolon on own line */;
auto const TryRunArgParser = auto const TryRunProjectArgParser =
cmArgumentParser<Arguments>{ TryCompileBaseArgParser } makeTryRunParser(TryCompileBaseProjectArgParser);
.Bind("COMPILE_OUTPUT_VARIABLE"_s, &Arguments::CompileOutputVariable)
.Bind("RUN_OUTPUT_VARIABLE"_s, &Arguments::RunOutputVariable)
.Bind("RUN_OUTPUT_STDOUT_VARIABLE"_s, &Arguments::RunOutputStdOutVariable)
.Bind("RUN_OUTPUT_STDERR_VARIABLE"_s, &Arguments::RunOutputStdErrVariable)
.Bind("WORKING_DIRECTORY"_s, &Arguments::RunWorkingDirectory)
.Bind("ARGS"_s, &Arguments::RunArgs)
/* keep semicolon on own line */;
auto const TryRunOldArgParser = auto const TryRunSourcesArgParser =
cmArgumentParser<Arguments>{ TryCompileOldArgParser } makeTryRunParser(TryCompileBaseNonProjectArgParser);
.Bind("COMPILE_OUTPUT_VARIABLE"_s, &Arguments::CompileOutputVariable)
.Bind("RUN_OUTPUT_VARIABLE"_s, &Arguments::RunOutputVariable) auto const TryRunOldArgParser = makeTryRunParser(TryCompileOldArgParser);
.Bind("RUN_OUTPUT_STDOUT_VARIABLE"_s, &Arguments::RunOutputStdOutVariable)
.Bind("RUN_OUTPUT_STDERR_VARIABLE"_s, &Arguments::RunOutputStdErrVariable)
.Bind("WORKING_DIRECTORY"_s, &Arguments::RunWorkingDirectory)
.Bind("ARGS"_s, &Arguments::RunArgs)
/* keep semicolon on own line */;
#undef BIND_LANG_PROPS #undef BIND_LANG_PROPS
} }
@@ -203,10 +224,23 @@ Arguments cmCoreTryCompile::ParseArgs(
cmRange<std::vector<std::string>::const_iterator> args, bool isTryRun) cmRange<std::vector<std::string>::const_iterator> args, bool isTryRun)
{ {
std::vector<std::string> unparsedArguments; std::vector<std::string> unparsedArguments;
if (cmHasLiteralPrefix(*(++args.begin()), "SOURCE")) { const auto& second = *(++args.begin());
// New signature.
auto arguments = if (second == "PROJECT") {
this->ParseArgs(args, isTryRun ? TryRunArgParser : TryCompileArgParser, // New PROJECT signature.
auto arguments = this->ParseArgs(
args, isTryRun ? TryRunProjectArgParser : TryCompileProjectArgParser,
unparsedArguments);
if (!arguments.BinaryDirectory) {
arguments.BinaryDirectory = unique_binary_directory;
}
return arguments;
}
if (cmHasLiteralPrefix(second, "SOURCE")) {
// New SOURCES signature.
auto arguments = this->ParseArgs(
args, isTryRun ? TryRunSourcesArgParser : TryCompileSourcesArgParser,
unparsedArguments); unparsedArguments);
arguments.BinaryDirectory = unique_binary_directory; arguments.BinaryDirectory = unique_binary_directory;
return arguments; return arguments;
@@ -256,8 +290,14 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
std::string sourceDirectory; std::string sourceDirectory;
std::string projectName; std::string projectName;
std::string targetName; std::string targetName;
if (arguments.SourceDirectoryOrFile && arguments.ProjectName) { if (arguments.ProjectName) {
this->SrcFileSignature = false; this->SrcFileSignature = false;
if (!arguments.SourceDirectoryOrFile ||
arguments.SourceDirectoryOrFile->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"No <srcdir> specified.");
return false;
}
sourceDirectory = *arguments.SourceDirectoryOrFile; sourceDirectory = *arguments.SourceDirectoryOrFile;
projectName = *arguments.ProjectName; projectName = *arguments.ProjectName;
if (arguments.TargetName) { if (arguments.TargetName) {

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
^CMake Error at OldProjectBinDirEmpty.cmake:[0-9]+ \(try_compile\):
No <bindir> specified.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$

View File

@@ -0,0 +1 @@
try_compile(RESULT "" ${CMAKE_CURRENT_SOURCE_DIR}/proj Foo)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at OldProjectSrcDirEmpty.cmake:[0-9]+ \(try_compile\):
No <srcdir> specified.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@@ -0,0 +1 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} "" Foo)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
^CMake Error at ProjectBinDirEmpty.cmake:[0-9]+ \(try_compile\):
No <bindir> specified.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$

View File

@@ -0,0 +1,4 @@
try_compile(RESULT PROJECT Foo
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/proj
BINARY_DIR ""
)

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1,7 @@
CMake Warning \(dev\) at ProjectCopyFile.cmake:[0-9]+ \(try_compile\):
Unknown arguments:
"COPY_FILE"
"result"
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@@ -0,0 +1,4 @@
try_compile(RESULT
PROJECT TestProject
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/proj
COPY_FILE result)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at ProjectSrcDirEmpty.cmake:[0-9]+ \(try_compile\):
No <srcdir> specified.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@@ -0,0 +1 @@
try_compile(RESULT PROJECT Foo SOURCE_DIR "")

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,4 @@
CMake Error at ProjectSrcDirMissing.cmake:[0-9]+ \(try_compile\):
No <srcdir> specified.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@@ -0,0 +1 @@
try_compile(RESULT PROJECT Foo)

View File

@@ -6,6 +6,11 @@ run_cmake(TwoArgs)
run_cmake(NoSources) run_cmake(NoSources)
run_cmake(BinDirEmpty) run_cmake(BinDirEmpty)
run_cmake(BinDirRelative) run_cmake(BinDirRelative)
run_cmake(ProjectSrcDirMissing)
run_cmake(ProjectSrcDirEmpty)
run_cmake(ProjectBinDirEmpty)
run_cmake(OldProjectSrcDirEmpty)
run_cmake(OldProjectBinDirEmpty)
set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=old_signature.cmake) set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=old_signature.cmake)
include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake) include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake)
@@ -15,6 +20,7 @@ set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=new_signature.cmake)
include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake) include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake)
unset(RunCMake_TEST_OPTIONS) unset(RunCMake_TEST_OPTIONS)
run_cmake(ProjectCopyFile)
run_cmake(NonSourceCopyFile) run_cmake(NonSourceCopyFile)
run_cmake(NonSourceCompileDefinitions) run_cmake(NonSourceCompileDefinitions)

View File

@@ -65,7 +65,7 @@ set(try_compile_run_output_var RUN_OUTPUT)
include(old_and_new_signature_tests.cmake) include(old_and_new_signature_tests.cmake)
# try to compile a project (old signature) # try to compile a project (old signature)
message("Testing try_compile project mode") message("Testing try_compile project mode (old signature)")
try_compile(TEST_INNER try_compile(TEST_INNER
${TryCompile_BINARY_DIR}/CMakeFiles/Inner ${TryCompile_BINARY_DIR}/CMakeFiles/Inner
${TryCompile_SOURCE_DIR}/Inner ${TryCompile_SOURCE_DIR}/Inner
@@ -73,6 +73,15 @@ try_compile(TEST_INNER
OUTPUT_VARIABLE output) OUTPUT_VARIABLE output)
TEST_ASSERT(TEST_INNER "try_compile project mode failed:\n${output}") TEST_ASSERT(TEST_INNER "try_compile project mode failed:\n${output}")
# try to compile a project (new signature)
message("Testing try_compile project mode (new signature)")
try_compile(TEST_INNER
PROJECT TryCompileInner
SOURCE_DIR ${TryCompile_SOURCE_DIR}/Inner
TARGET innerexe
OUTPUT_VARIABLE output)
TEST_ASSERT(TEST_INNER "try_compile project mode failed:\n${output}")
add_executable(TryCompile pass.c) add_executable(TryCompile pass.c)
####################################################################### #######################################################################