diff options
-rw-r--r-- | Help/command/try_compile.rst | 13 | ||||
-rw-r--r-- | Help/command/try_run.rst | 3 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.cxx | 32 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.h | 2 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/RunCMakeTest.cmake | 1 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/SourceFromBadFile-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/SourceFromBadFile-stderr.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/SourceFromBadFile.cmake | 1 | ||||
-rw-r--r-- | Tests/TryCompile/CMakeLists.txt | 6 |
9 files changed, 61 insertions, 2 deletions
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst index ed61a2f..4632cd9 100644 --- a/Help/command/try_compile.rst +++ b/Help/command/try_compile.rst @@ -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 diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst index 5498344..efc10ec 100644 --- a/Help/command/try_run.rst +++ b/Help/command/try_run.rst @@ -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>...] diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 0ef32c0..839cb7b 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -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. diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h index 75dcf6e..3f4a4dc 100644 --- a/Source/cmCoreTryCompile.h +++ b/Source/cmCoreTryCompile.h @@ -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] diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake index 0aa9039..d63624c 100644 --- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake +++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake @@ -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) diff --git a/Tests/RunCMake/try_compile/SourceFromBadFile-result.txt b/Tests/RunCMake/try_compile/SourceFromBadFile-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/SourceFromBadFile-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/SourceFromBadFile-stderr.txt b/Tests/RunCMake/try_compile/SourceFromBadFile-stderr.txt new file mode 100644 index 0000000..53a6d8d --- /dev/null +++ b/Tests/RunCMake/try_compile/SourceFromBadFile-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/try_compile/SourceFromBadFile.cmake b/Tests/RunCMake/try_compile/SourceFromBadFile.cmake new file mode 100644 index 0000000..0a37f11 --- /dev/null +++ b/Tests/RunCMake/try_compile/SourceFromBadFile.cmake @@ -0,0 +1 @@ +try_compile(RESULT SOURCE_FROM_FILE bad.c "bad#source.c") diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt index cca19bc..9396cfa 100644 --- a/Tests/TryCompile/CMakeLists.txt +++ b/Tests/TryCompile/CMakeLists.txt @@ -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" |