summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorThomas Bernard <tbernard@go-engineering.de>2020-01-14 10:31:34 (GMT)
committerBrad King <brad.king@kitware.com>2020-02-04 13:19:12 (GMT)
commit1c2d031cbdbf28f99ef36e5db5e4d9de1b97fff9 (patch)
treeb987d5cf32bdf9b094f830e0e7c91112709301c8 /Source
parent5f04dfe57ebf1abee29101228844ebaa721356a2 (diff)
downloadCMake-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.cxx111
-rw-r--r--Source/cmcmd.h3
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);
};