llvm-rc: Restore include path for data after explicit preprocessing

Since commit 1c2d031cbd (Add -E cmake_llvm_rc to preprocess files for
llvm-rc, 2020-01-14, v3.17.0-rc1~24^2) with llvm-rc we explicitly
preprocess RC source files and then compile separately without -I flags.
This broke cases where the RC source references data files adjacent to
itself or in the include path.

This change adds the expansion of the include paths when calling the
llvm-rc in order for the resource files to be picked up correctly by
llvm-rc.  Since the RC compiled file is first preprocessed, the file
being compiled by llvm-rc resides in the build directory. In order for
llvm-rc to find the resource data specified relative to the .rc file
being compiled, the source file path is preppended in the include list
so that the original source path takes priority over all the other
includes paths specified.

A space was added in the CMAKE_INCLUDE_FLAG_RC to make the include
directive work properly for llvm-rc. Checks on the rc.exe showed that
the syntax change doesn't affect it's proper operation.

Fixes: #20529
This commit is contained in:
Thomas Bernard 2020-04-04 11:59:22 +02:00
parent 42cefc6bc1
commit 35a29ec827
4 changed files with 25 additions and 15 deletions

View File

@ -142,7 +142,7 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC"
endif()
if(DEFINED CMAKE_RC_PREPROCESSOR)
set(CMAKE_DEPFILE_FLAGS_RC "-clang:-MD -clang:-MF -clang:<DEPFILE>")
set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> /fo <OBJECT> <OBJECT>.pp")
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")
if(CMAKE_GENERATOR STREQUAL "Ninja")
set(CMAKE_NINJA_CMCLDEPS_RC 0)
set(CMAKE_NINJA_DEP_TYPE_RC gcc)

View File

@ -1713,25 +1713,35 @@ 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[2] == source_file_path
// args[3] == intermediate_file
// args[4..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];
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;
for (std::string const& arg : cmMakeRange(args).advance(3)) {
for (std::string const& arg : cmMakeRange(args).advance(4)) {
if (arg == "--") {
pArgTgt = &resource_compile;
} else {
if (arg.find("SOURCE_DIR") != std::string::npos) {
std::string sourceDirArg = arg;
cmSystemTools::ReplaceString(
sourceDirArg, "SOURCE_DIR",
cmSystemTools::GetFilenamePath(source_file));
pArgTgt->push_back(sourceDirArg);
} else {
pArgTgt->push_back(arg);
}
}
}
if (preprocess.empty()) {
std::cerr << "Empty preprocessing command";
return 1;

View File

@ -674,25 +674,25 @@ function(run_llvm_rc)
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} -P FailedProgram.cmake -- ${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} -P FailedProgram.cmake )
run_cmake_command(llvm_rc_no_-- ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test")
run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp -- ${CMAKE_COMMAND} -E echo "This is a test")
run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake -- ${CMAKE_COMMAND} -E echo "This is a test")
run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -P FailedProgram.cmake )
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)
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 )
if(EXISTS ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/test.tmp)
message(SEND_ERROR "${test} - FAILED:\n"
"test.tmp was not deleted")
endif()
file(READ ${RunCMake_TEST_BINARY_DIR}/llvmrc.result LLVMRC_RESULT)
file(READ ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/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()