diff options
author | Brad King <brad.king@kitware.com> | 2020-10-29 14:14:11 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-10-29 14:14:20 (GMT) |
commit | 32d369aa7049c4921d3c35ca8097bc0485866be6 (patch) | |
tree | 039ec9fb81b3c6848067d34fd3d61039bc02a011 | |
parent | 1d3603a1706d122f6d22b47a365ec5023e58579a (diff) | |
parent | ea03f508420845fef72fef06ba4c9a7dacbca5fe (diff) | |
download | CMake-32d369aa7049c4921d3c35ca8097bc0485866be6.zip CMake-32d369aa7049c4921d3c35ca8097bc0485866be6.tar.gz CMake-32d369aa7049c4921d3c35ca8097bc0485866be6.tar.bz2 |
Merge topic 'llvm-rc-CMAKE_RC_FLAGS'
ea03f50842 llvm_rc: add llvm_rc option filter to correctly pick up all options
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5412
-rw-r--r-- | Modules/Platform/Windows-Clang.cmake | 4 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 46 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CommandLine/RunCMakeTest.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/pseudo_llvm-rc.c | 30 |
5 files changed, 79 insertions, 6 deletions
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index 2261c90..6275043 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -112,7 +112,9 @@ macro(__enable_llvm_rc_preprocessing clang_option_prefix) endif() if(DEFINED CMAKE_RC_PREPROCESSOR) set(CMAKE_DEPFILE_FLAGS_RC "${clang_option_prefix}-MD ${clang_option_prefix}-MF ${clang_option_prefix}<DEPFILE>") - set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp") + # The <FLAGS> are passed to the preprocess and the resource compiler to pick + # up the eventual -D / -C options passed through the CMAKE_RC_FLAGS. + set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> <FLAGS> /fo <OBJECT> <OBJECT>.pp") if(CMAKE_GENERATOR MATCHES "Ninja") set(CMAKE_NINJA_CMCLDEPS_RC 0) set(CMAKE_NINJA_DEP_TYPE_RC gcc) diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index ea1f968..f094085 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -58,6 +58,7 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" #include "cmsys/Process.h" +#include "cmsys/RegularExpression.hxx" #include "cmsys/Terminal.h" int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, @@ -1711,7 +1712,6 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name) int cmcmd::RunPreprocessor(const std::vector<std::string>& command, const std::string& intermediate_file) { - cmUVProcessChainBuilder builder; uv_fs_t fs_req; @@ -1743,7 +1743,6 @@ int cmcmd::RunPreprocessor(const std::vector<std::string>& command, return 1; } - return 0; } @@ -1761,19 +1760,56 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args) std::cerr << "Invalid cmake_llvm_rc arguments"; return 1; } + const std::string& intermediate_file = args[3]; const std::string& source_file = args[2]; std::vector<std::string> preprocess; std::vector<std::string> resource_compile; std::vector<std::string>* pArgTgt = &preprocess; + + static const cmsys::RegularExpression llvm_rc_only_single_arg("^[-/](N|Y)"); + static const cmsys::RegularExpression llvm_rc_only_double_arg( + "^[-/](C|LN|L)(.)?"); + static const cmsys::RegularExpression common_double_arg( + "^[-/](D|U|I|FO|fo|Fo)(.)?"); + bool acceptNextArg = false; + bool skipNextArg = false; for (std::string const& arg : cmMakeRange(args).advance(4)) { + if (skipNextArg) { + skipNextArg = false; + continue; + } // We use ++ as seperator between the preprocessing step definition and the // rc compilation step becase we need to prepend a -- to seperate the // source file properly from other options when using clang-cl for // preprocessing. if (arg == "++") { pArgTgt = &resource_compile; + skipNextArg = false; + acceptNextArg = true; } else { + cmsys::RegularExpressionMatch match; + if (!acceptNextArg) { + if (common_double_arg.find(arg.c_str(), match)) { + acceptNextArg = match.match(2).empty(); + } else { + if (llvm_rc_only_single_arg.find(arg.c_str(), match)) { + if (pArgTgt == &preprocess) { + continue; + } + } else if (llvm_rc_only_double_arg.find(arg.c_str(), match)) { + if (pArgTgt == &preprocess) { + skipNextArg = match.match(2).empty(); + continue; + } + acceptNextArg = match.match(2).empty(); + } else if (pArgTgt == &resource_compile) { + continue; + } + } + } else { + acceptNextArg = false; + } if (arg.find("SOURCE_DIR") != std::string::npos) { std::string sourceDirArg = arg; cmSystemTools::ReplaceString( @@ -1793,10 +1829,14 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args) std::cerr << "Empty resource compilation command"; return 1; } + // Since we might have skipped the last argument to llvm-rc + // we need to make sure the llvm-rc source file is present in the commandline + if (resource_compile.back() != intermediate_file) { + resource_compile.push_back(intermediate_file); + } auto result = RunPreprocessor(preprocess, intermediate_file); if (result != 0) { - cmSystemTools::RemoveFile(intermediate_file); return result; } diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 38ab553..9fc5b69 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -565,7 +565,8 @@ if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)" endif() -add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}) +add_executable(pseudo_llvm-rc pseudo_llvm-rc.c) +add_RunCMake_test(CommandLine -DLLVM_RC=$<TARGET_FILE:pseudo_llvm-rc> -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}) add_RunCMake_test(CommandLineTar) if(CMAKE_PLATFORM_NO_VERSIONED_SONAME OR (NOT CMAKE_SHARED_LIBRARY_SONAME_FLAG AND NOT CMAKE_SHARED_LIBRARY_SONAME_C_FLAG)) diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index b9c5aa2..c438860 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -789,7 +789,7 @@ function(run_llvm_rc) "test.tmp was not deleted") endif() file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir") - run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result ) + run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${LLVM_RC} -bad /FO SOURCE_DIR/llvmrc.result test.tmp ) if(EXISTS ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/test.tmp) message(SEND_ERROR "${test} - FAILED:\n" "test.tmp was not deleted") diff --git a/Tests/RunCMake/pseudo_llvm-rc.c b/Tests/RunCMake/pseudo_llvm-rc.c new file mode 100644 index 0000000..7acb2a3 --- /dev/null +++ b/Tests/RunCMake/pseudo_llvm-rc.c @@ -0,0 +1,30 @@ +#include <stdio.h> +#include <string.h> + +int main(int argc, char* argv[]) +{ + FILE* source; + FILE* target; + int i; + for (i = 1; i < argc; ++i) { + if (strcmp(argv[i], "-bad") == 0) { + fprintf(stdout, "stdout from bad command line arg '-bad'\n"); + fprintf(stderr, "stderr from bad command line arg '-bad'\n"); + return 1; + } + } + source = fopen(argv[argc - 1], "rb"); + if (source == NULL) { + return 1; + } + target = fopen(argv[argc - 2], "wb"); + if (target != NULL) { + char buffer[500]; + size_t n = fread(buffer, 1, sizeof(buffer), source); + fwrite(buffer, 1, n, target); + fclose(source); + fclose(target); + return 0; + } + return 1; +} |