diff options
author | Thomas Bernard <tbernard@go-engineering.de> | 2020-01-14 10:31:34 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-02-04 13:19:12 (GMT) |
commit | 1c2d031cbdbf28f99ef36e5db5e4d9de1b97fff9 (patch) | |
tree | b987d5cf32bdf9b094f830e0e7c91112709301c8 /Source | |
parent | 5f04dfe57ebf1abee29101228844ebaa721356a2 (diff) | |
download | CMake-1c2d031cbdbf28f99ef36e5db5e4d9de1b97fff9.zip CMake-1c2d031cbdbf28f99ef36e5db5e4d9de1b97fff9.tar.gz CMake-1c2d031cbdbf28f99ef36e5db5e4d9de1b97fff9.tar.bz2 |
Add -E cmake_llvm_rc to preprocess files for llvm-rc
llvm-rc requires preprocessed rc files. The CMake command line tool
cmake_llvm_rc enables channing the preprocessor call and the resource
compiler and make this appear as single compilation step.
When llvm-rc is detected as resource compiler, the RC compilation step
is set to use this command.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmcmd.cxx | 111 | ||||
-rw-r--r-- | Source/cmcmd.h | 3 |
2 files changed, 114 insertions, 0 deletions
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 67c776e..7eeb97f 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -4,6 +4,10 @@ #include <cmext/algorithm> +#include <fcntl.h> + +#include "cm_uv.h" + #include "cmAlgorithms.h" #include "cmDuration.h" #include "cmGlobalGenerator.h" @@ -17,6 +21,7 @@ #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmUVProcessChain.h" #include "cmUtils.hxx" #include "cmVersion.h" #include "cmake.h" @@ -1129,6 +1134,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return cmcmd::VisualStudioLink(args, 2); } + if (args[1] == "cmake_llvm_rc") { + return cmcmd::RunLLVMRC(args); + } + // Internal CMake color makefile support. if (args[1] == "cmake_echo_color") { return cmcmd::ExecuteEchoColor(args); @@ -1660,6 +1669,108 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name) return -1; } +int cmcmd::RunPreprocessor(const std::vector<std::string>& command, + const std::string& intermediate_file) +{ + + cmUVProcessChainBuilder builder; + + uv_fs_t fs_req; + int preprocessedFile = + uv_fs_open(nullptr, &fs_req, intermediate_file.c_str(), O_CREAT | O_RDWR, + 0644, nullptr); + uv_fs_req_cleanup(&fs_req); + + builder + .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, + preprocessedFile) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR) + .AddCommand(command); + auto process = builder.Start(); + if (!process.Valid()) { + std::cerr << "Failed to start preprocessor."; + return 1; + } + if (!process.Wait()) { + std::cerr << "Failed to wait for preprocessor"; + return 1; + } + auto status = process.GetStatus(); + if (!status[0] || status[0]->ExitStatus != 0) { + return 1; + } + + return 0; +} + +int cmcmd::RunLLVMRC(std::vector<std::string> const& args) +{ + // The arguments are + // args[0] == <cmake-executable> + // args[1] == cmake_llvm_rc + // args[2] == intermediate_file + // args[3..n] == preprocess+args + // args[n+1] == -- + // args[n+2...] == llvm-rc+args + if (args.size() < 3) { + std::cerr << "Invalid cmake_llvm_rc arguments"; + return 1; + } + const std::string& intermediate_file = args[2]; + std::vector<std::string> preprocess; + std::vector<std::string> resource_compile; + std::vector<std::string>* pArgTgt = &preprocess; + for (std::string const& arg : cmMakeRange(args).advance(3)) { + if (arg == "--") { + pArgTgt = &resource_compile; + } else { + pArgTgt->push_back(arg); + } + } + if (preprocess.empty()) { + std::cerr << "Empty preprocessing command"; + return 1; + } + if (resource_compile.empty()) { + std::cerr << "Empty resource compilation command"; + return 1; + } + + auto result = RunPreprocessor(preprocess, intermediate_file); + if (result != 0) { + + cmSystemTools::RemoveFile(intermediate_file); + return result; + } + cmUVProcessChainBuilder builder; + + builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) + .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR) + .AddCommand(resource_compile); + auto process = builder.Start(); + result = 0; + if (!process.Valid()) { + std::cerr << "Failed to start resource compiler."; + result = 1; + } else { + if (!process.Wait()) { + std::cerr << "Failed to wait for resource compiler"; + result = 1; + } + } + + cmSystemTools::RemoveFile(intermediate_file); + if (result != 0) { + return result; + } + auto status = process.GetStatus(); + if (!status[0] || status[0]->ExitStatus != 0) { + return 1; + } + + return 0; +} + class cmVSLink { int Type; diff --git a/Source/cmcmd.h b/Source/cmcmd.h index 17f2f9a..5b6c813 100644 --- a/Source/cmcmd.h +++ b/Source/cmcmd.h @@ -31,6 +31,9 @@ protected: static int ExecuteLinkScript(std::vector<std::string> const& args); static int WindowsCEEnvironment(const char* version, const std::string& name); + static int RunPreprocessor(const std::vector<std::string>& command, + const std::string& intermediate_file); + static int RunLLVMRC(std::vector<std::string> const& args); static int VisualStudioLink(std::vector<std::string> const& args, int type); }; |