mirror of
https://github.com/reactos/CMake.git
synced 2025-02-28 16:05:38 +00:00
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.
This commit is contained in:
parent
5f04dfe57e
commit
1c2d031cbd
Modules/Platform
Source
Tests/RunCMake/CommandLine
@ -133,6 +133,23 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC"
|
||||
if ( "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" OR "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" )
|
||||
include(Platform/Windows-MSVC)
|
||||
|
||||
# Feed the preprocessed rc file to llvm-rc
|
||||
if(CMAKE_RC_COMPILER_INIT STREQUAL "llvm-rc")
|
||||
if(DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_RC_PREPROCESSOR CMAKE_C_COMPILER)
|
||||
elseif(DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_RC_PREPROCESSOR CMAKE_CXX_COMPILER)
|
||||
endif()
|
||||
if(DEFINED CMAKE_RC_PREPROCESSOR)
|
||||
set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -clang:-MD -clang:-MF -clang:<SOURCE>.d -E <SOURCE> -- <CMAKE_RC_COMPILER> <FLAGS> /fo <OBJECT> <OBJECT>.pp")
|
||||
if(CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
set(CMAKE_NINJA_CMCLDEPS_RC 0)
|
||||
set(CMAKE_NINJA_DEP_TYPE_RC gcc)
|
||||
endif()
|
||||
unset(CMAKE_RC_PREPROCESSOR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro(__windows_compiler_clang lang)
|
||||
set(_COMPILE_${lang} "${_COMPILE_${lang}_MSVC}")
|
||||
__windows_compiler_msvc(${lang})
|
||||
|
111
Source/cmcmd.cxx
111
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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -667,3 +667,33 @@ if(CMAKE_HOST_UNIX AND NOT CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
|
||||
run_cmake_command(closed_stderr sh -c "\"${CMAKE_COMMAND}\" --version 2>&-")
|
||||
run_cmake_command(closed_stdall sh -c "\"${CMAKE_COMMAND}\" --version <&- >&- 2>&-")
|
||||
endif()
|
||||
|
||||
function(run_llvm_rc)
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/llvm_rc-build")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
|
||||
run_cmake_command(llvm_rc_no_args ${CMAKE_COMMAND} -E cmake_llvm_rc)
|
||||
run_cmake_command(llvm_rc_no_-- ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E echo "This is a test")
|
||||
run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp -- ${CMAKE_COMMAND} -E echo "This is a test")
|
||||
run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E false -- ${CMAKE_COMMAND} -E echo "This is a test")
|
||||
run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -E false )
|
||||
if(EXISTS ${RunCMake_TEST_BINARY_DIR}/test.tmp)
|
||||
message(SEND_ERROR "${test} - FAILED:\n"
|
||||
"test.tmp was not deleted")
|
||||
endif()
|
||||
run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -E copy test.tmp llvmrc.result )
|
||||
if(EXISTS ${RunCMake_TEST_BINARY_DIR}/test.tmp)
|
||||
message(SEND_ERROR "${test} - FAILED:\n"
|
||||
"test.tmp was not deleted")
|
||||
endif()
|
||||
file(READ ${RunCMake_TEST_BINARY_DIR}/llvmrc.result LLVMRC_RESULT)
|
||||
if(NOT "${LLVMRC_RESULT}" STREQUAL "This is a test\n")
|
||||
message(SEND_ERROR "${test} - FAILED:\n"
|
||||
"llvmrc.result was not created")
|
||||
endif()
|
||||
# file(REMOVE ${RunCMake_TEST_BINARY_DIR}/llvmrc.result)
|
||||
unset(LLVMRC_RESULT)
|
||||
endfunction()
|
||||
run_llvm_rc()
|
||||
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1 @@
|
||||
Empty preprocessing command
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1 @@
|
||||
1
|
1
Tests/RunCMake/CommandLine/llvm_rc_no_---result.txt
Normal file
1
Tests/RunCMake/CommandLine/llvm_rc_no_---result.txt
Normal file
@ -0,0 +1 @@
|
||||
1
|
1
Tests/RunCMake/CommandLine/llvm_rc_no_---stderr.txt
Normal file
1
Tests/RunCMake/CommandLine/llvm_rc_no_---stderr.txt
Normal file
@ -0,0 +1 @@
|
||||
Empty resource compilation command
|
1
Tests/RunCMake/CommandLine/llvm_rc_no_args-result.txt
Normal file
1
Tests/RunCMake/CommandLine/llvm_rc_no_args-result.txt
Normal file
@ -0,0 +1 @@
|
||||
1
|
1
Tests/RunCMake/CommandLine/llvm_rc_no_args-stderr.txt
Normal file
1
Tests/RunCMake/CommandLine/llvm_rc_no_args-stderr.txt
Normal file
@ -0,0 +1 @@
|
||||
Invalid cmake_llvm_rc arguments
|
Loading…
x
Reference in New Issue
Block a user