try_compile: Add SOURCE_FROM_FILE
Add ability to copy try_compile (and try_run) source files from arbitrary locations into the operation directory. This is included for the sake of completion and consolidation, although use cases which actually require this may be rare.
This commit is contained in:
parent
a04eaf6742
commit
611d801790
@ -58,7 +58,8 @@ Try Compiling Source Files
|
||||
try_compile(<resultVar>
|
||||
<SOURCES <srcfile...>] |
|
||||
SOURCE_FROM_ARG <name> <content>] |
|
||||
SOURCE_FROM_VAR <name> <var>] >...
|
||||
SOURCE_FROM_VAR <name> <var>] |
|
||||
SOURCE_FROM_FILE <name> <path> >...
|
||||
[CMAKE_FLAGS <flags>...]
|
||||
[COMPILE_DEFINITIONS <defs>...]
|
||||
[LINK_OPTIONS <options>...]
|
||||
@ -178,6 +179,16 @@ The options are:
|
||||
|
||||
``SOURCE_FROM_ARG`` may be specified multiple times.
|
||||
|
||||
``SOURCE_FROM_FILE <name> <path>``
|
||||
.. versionadded:: 3.25
|
||||
|
||||
Copy ``<path>`` to a file named ``<name>`` in the operation directory. This
|
||||
can be used to consolidate files into the operation directory, which may be
|
||||
useful if a source which already exists (i.e. as a stand-alone file in a
|
||||
project's source repository) needs to refer to other file(s) created by
|
||||
``SOURCE_FROM_*``. (Otherwise, ``SOURCES`` is usually more convenient.) The
|
||||
specified ``<name>`` is not allowed to contain path components.
|
||||
|
||||
``SOURCE_FROM_VAR <name> <content>``
|
||||
.. versionadded:: 3.25
|
||||
|
||||
|
@ -15,7 +15,8 @@ Try Compiling and Running Source Files
|
||||
try_run(<runResultVar> <compileResultVar>
|
||||
<SOURCES <srcfile...>] |
|
||||
SOURCE_FROM_ARG <name> <content>] |
|
||||
SOURCE_FROM_VAR <name> <var>] >...
|
||||
SOURCE_FROM_VAR <name> <var>] |
|
||||
SOURCE_FROM_FILE <name> <path> >...
|
||||
[CMAKE_FLAGS <flags>...]
|
||||
[COMPILE_DEFINITIONS <defs>...]
|
||||
[LINK_OPTIONS <options>...]
|
||||
|
@ -174,6 +174,7 @@ auto const TryCompileBaseNewSourcesArgParser =
|
||||
cmArgumentParser<Arguments>{ TryCompileBaseSourcesArgParser }
|
||||
.Bind("SOURCE_FROM_ARG"_s, &Arguments::SourceFromArg)
|
||||
.Bind("SOURCE_FROM_VAR"_s, &Arguments::SourceFromVar)
|
||||
.Bind("SOURCE_FROM_FILE"_s, &Arguments::SourceFromFile)
|
||||
/* keep semicolon on own line */;
|
||||
|
||||
auto const TryCompileBaseProjectArgParser =
|
||||
@ -416,6 +417,12 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
|
||||
"SOURCE_FROM_VAR requires exactly two arguments");
|
||||
return false;
|
||||
}
|
||||
if (arguments.SourceFromFile && arguments.SourceFromFile->size() % 2) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
"SOURCE_FROM_FILE requires exactly two arguments");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// only valid for srcfile signatures
|
||||
if (!arguments.LangProps.empty()) {
|
||||
@ -497,6 +504,31 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
|
||||
sources.emplace_back(std::move(out));
|
||||
}
|
||||
}
|
||||
if (arguments.SourceFromFile) {
|
||||
auto const k = arguments.SourceFromFile->size();
|
||||
for (auto i = decltype(k){ 0 }; i < k; i += 2) {
|
||||
const auto& dst = (*arguments.SourceFromFile)[i + 0];
|
||||
const auto& src = (*arguments.SourceFromFile)[i + 1];
|
||||
|
||||
if (!cmSystemTools::GetFilenamePath(dst).empty()) {
|
||||
const auto& msg =
|
||||
cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, "\"");
|
||||
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto dstPath = cmStrCat(this->BinaryDirectory, "/", dst);
|
||||
auto const result = cmSystemTools::CopyFileAlways(src, dstPath);
|
||||
if (!result.IsSuccess()) {
|
||||
const auto& msg = cmStrCat("SOURCE_FROM_FILE failed to copy \"", src,
|
||||
"\": ", result.GetString());
|
||||
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
sources.emplace_back(std::move(dstPath));
|
||||
}
|
||||
}
|
||||
// TODO: ensure sources is not empty
|
||||
|
||||
// Detect languages to enable.
|
||||
|
@ -44,6 +44,8 @@ public:
|
||||
SourceFromArg;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
|
||||
SourceFromVar;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
|
||||
SourceFromFile;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> CMakeFlags{
|
||||
1, "CMAKE_FLAGS"
|
||||
}; // fake argv[0]
|
||||
|
@ -23,6 +23,7 @@ unset(RunCMake_TEST_OPTIONS)
|
||||
run_cmake(SourceFromOneArg)
|
||||
run_cmake(SourceFromThreeArgs)
|
||||
run_cmake(SourceFromBadName)
|
||||
run_cmake(SourceFromBadFile)
|
||||
|
||||
run_cmake(ProjectCopyFile)
|
||||
run_cmake(NonSourceCopyFile)
|
||||
|
1
Tests/RunCMake/try_compile/SourceFromBadFile-result.txt
Normal file
1
Tests/RunCMake/try_compile/SourceFromBadFile-result.txt
Normal file
@ -0,0 +1 @@
|
||||
1
|
4
Tests/RunCMake/try_compile/SourceFromBadFile-stderr.txt
Normal file
4
Tests/RunCMake/try_compile/SourceFromBadFile-stderr.txt
Normal file
@ -0,0 +1,4 @@
|
||||
CMake Error at SourceFromBadFile.cmake:[0-9]+ \(try_compile\):
|
||||
SOURCE_FROM_FILE failed to copy "bad#source.c": No such file or directory
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
1
Tests/RunCMake/try_compile/SourceFromBadFile.cmake
Normal file
1
Tests/RunCMake/try_compile/SourceFromBadFile.cmake
Normal file
@ -0,0 +1 @@
|
||||
try_compile(RESULT SOURCE_FROM_FILE bad.c "bad#source.c")
|
@ -89,6 +89,12 @@ if(SHOULD_FAIL_DUE_TO_EMPTY_SOURCE)
|
||||
message(SEND_ERROR "Trying to compile an empty source succeeded?")
|
||||
endif()
|
||||
|
||||
# try to compile a copied source
|
||||
try_compile(SHOULD_PASS
|
||||
SOURCE_FROM_FILE pass.c ${TryCompile_SOURCE_DIR}/pass.c
|
||||
OUTPUT_VARIABLE TRY_OUT)
|
||||
EXPECT_COMPILED("SOURCE_FROM_FILE" SHOULD_PASS "${TRY_OUT}")
|
||||
|
||||
# try to run a source specified directly
|
||||
set(TRY_RUN_MAIN_CODE
|
||||
"extern int answer(); \n"
|
||||
|
Loading…
Reference in New Issue
Block a user