Commit bd9bfc64 authored by Mateusz Zych's avatar Mateusz Zych Committed by Brad King

MSVC: Respect CMAKE_RC_COMPILER and CMAKE_MT in vs_link_{dll,exe}

CMake commands vs_link_dll and vs_link_exe, performing linking on MSVC,
are responsible for calling resource compiler and manifest tool.

Before this commit, both of these tools were called directly, with the
expectation that they are available in the `PATH`. This has been fixed
by respecting CMake variables `CMAKE_RC_COMPILER` and `CMAKE_MT`
defining paths to these tools.

Fixes: #17804
parent 00336767
......@@ -5,6 +5,7 @@ set(CMAKE_ASM@ASM_DIALECT@_COMPILER_AR "@_CMAKE_ASM_COMPILER_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_RANLIB "@_CMAKE_ASM_COMPILER_RANLIB@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_MT "@CMAKE_MT@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@")
......
......@@ -21,6 +21,7 @@ set(CMAKE_C_COMPILER_AR "@CMAKE_C_COMPILER_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
set(CMAKE_C_COMPILER_RANLIB "@CMAKE_C_COMPILER_RANLIB@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_MT "@CMAKE_MT@")
set(CMAKE_COMPILER_IS_GNUCC @CMAKE_COMPILER_IS_GNUCC@)
set(CMAKE_C_COMPILER_LOADED 1)
set(CMAKE_C_COMPILER_WORKS @CMAKE_C_COMPILER_WORKS@)
......
......@@ -28,3 +28,4 @@ set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES@
set(CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_MT "@CMAKE_MT@")
......@@ -23,6 +23,7 @@ set(CMAKE_CXX_COMPILER_AR "@CMAKE_CXX_COMPILER_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
set(CMAKE_CXX_COMPILER_RANLIB "@CMAKE_CXX_COMPILER_RANLIB@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
set(CMAKE_MT "@CMAKE_MT@")
set(CMAKE_COMPILER_IS_GNUCXX @CMAKE_COMPILER_IS_GNUCXX@)
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS @CMAKE_CXX_COMPILER_WORKS@)
......
......@@ -14,29 +14,48 @@
# CMAKE_AR
# CMAKE_RANLIB
# CMAKE_LINKER
# CMAKE_MT
# CMAKE_STRIP
# CMAKE_INSTALL_NAME_TOOL
# on UNIX, cygwin and mingw
if(CMAKE_LINKER)
# we only get here if CMAKE_LINKER was specified using -D or a pre-made CMakeCache.txt
# (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
# find the linker in the PATH if necessary
get_filename_component(_CMAKE_USER_LINKER_PATH "${CMAKE_LINKER}" PATH)
if(NOT _CMAKE_USER_LINKER_PATH)
find_program(CMAKE_LINKER_WITH_PATH NAMES ${CMAKE_LINKER} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
if(CMAKE_LINKER_WITH_PATH)
set(CMAKE_LINKER ${CMAKE_LINKER_WITH_PATH})
get_property(_CMAKE_LINKER_CACHED CACHE CMAKE_LINKER PROPERTY TYPE)
if(_CMAKE_LINKER_CACHED)
set(CMAKE_LINKER "${CMAKE_LINKER}" CACHE STRING "Default Linker" FORCE)
# Resolve full path of CMAKE_TOOL from user-defined name and SEARCH_PATH.
function(__resolve_tool_path CMAKE_TOOL SEARCH_PATH DOCSTRING)
if(${CMAKE_TOOL})
# We only get here if CMAKE_TOOL was
# specified using -D or a pre-made CMakeCache.txt (e.g. via ctest)
# or set in CMAKE_TOOLCHAIN_FILE.
get_filename_component(_CMAKE_USER_TOOL_PATH "${${CMAKE_TOOL}}" DIRECTORY)
# Is CMAKE_TOOL a user-defined name instead of a full path?
if(NOT _CMAKE_USER_TOOL_PATH)
# Find CMAKE_TOOL in the SEARCH_PATH directory by user-defined name.
find_program(_CMAKE_TOOL_WITH_PATH NAMES ${${CMAKE_TOOL}} HINTS ${SEARCH_PATH})
if(_CMAKE_TOOL_WITH_PATH)
# Overwrite CMAKE_TOOL with full path found in SEARCH_PATH.
set(${CMAKE_TOOL} ${_CMAKE_TOOL_WITH_PATH} PARENT_SCOPE)
get_property(_CMAKE_TOOL_CACHED CACHE ${CMAKE_TOOL} PROPERTY TYPE)
# If CMAKE_TOOL is present in the CMake Cache, then overwrit it as well.
if(_CMAKE_TOOL_CACHED)
set(${CMAKE_TOOL} "${_CMAKE_TOOL_WITH_PATH}" CACHE STRING ${DOCSTRING} FORCE)
endif()
endif()
unset(_CMAKE_LINKER_CACHED)
unset(_CMAKE_TOOL_WITH_PATH CACHE)
endif()
unset(CMAKE_LINKER_WITH_PATH CACHE)
endif()
endif()
endfunction()
__resolve_tool_path(CMAKE_LINKER "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Linker")
__resolve_tool_path(CMAKE_MT "${_CMAKE_TOOLCHAIN_LOCATION}" "Default Manifest Tool")
set(_CMAKE_TOOL_VARS "")
......@@ -49,8 +68,9 @@ if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC"
AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android"))
find_program(CMAKE_LINKER NAMES link HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_MT NAMES mt HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
list(APPEND _CMAKE_TOOL_VARS CMAKE_LINKER)
list(APPEND _CMAKE_TOOL_VARS CMAKE_LINKER CMAKE_MT)
# in all other cases search for ar, ranlib, etc.
else()
......
......@@ -298,8 +298,8 @@ unset(_MACHINE_ARCH_FLAG)
macro(__windows_compiler_msvc lang)
if(NOT MSVC_VERSION LESS 1400)
# for 2005 make sure the manifest is put in the dll with mt
set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
endif()
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
......
......@@ -17,8 +17,8 @@ endforeach()
set(CMAKE_CUDA_LINK_EXECUTABLE
"<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_LIBRARIES>${__IMPLICT_LINKS}")
set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
set(CMAKE_CUDA_CREATE_SHARED_LIBRARY
"${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}")
......
......@@ -65,6 +65,7 @@ static const char* ruleReplaceVars[] = {
"CMAKE_CURRENT_BINARY_DIR",
"CMAKE_RANLIB",
"CMAKE_LINKER",
"CMAKE_MT",
"CMAKE_CUDA_HOST_COMPILER",
"CMAKE_CUDA_HOST_LINK_LAUNCHER",
"CMAKE_CL_SHOWINCLUDES_PREFIX"
......
......@@ -1517,6 +1517,8 @@ class cmVSLink
std::string ManifestFileRC;
std::string ManifestFileRes;
std::string TargetFile;
std::string MtPath;
std::string RcPath;
public:
cmVSLink(int type, bool verbose)
......@@ -1660,6 +1662,12 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
} else if (cmHasLiteralPrefix(*arg, "--intdir=")) {
intDir = arg->substr(9);
++arg;
} else if (cmHasLiteralPrefix(*arg, "--rc=")) {
this->RcPath = arg->substr(5);
++arg;
} else if (cmHasLiteralPrefix(*arg, "--mt=")) {
this->MtPath = arg->substr(5);
++arg;
} else {
std::cerr << "unknown argument '" << *arg << "'\n";
return false;
......@@ -1799,7 +1807,7 @@ int cmVSLink::LinkIncremental()
// Compile the resource file.
std::vector<std::string> rcCommand;
rcCommand.push_back("rc");
rcCommand.push_back(this->RcPath.empty() ? "rc" : this->RcPath);
rcCommand.push_back("/fo" + this->ManifestFileRes);
rcCommand.push_back(this->ManifestFileRC);
if (!RunCommand("RC Pass 1", rcCommand, this->Verbose, FORMAT_DECIMAL)) {
......@@ -1858,7 +1866,7 @@ int cmVSLink::LinkNonIncremental()
int cmVSLink::RunMT(std::string const& out, bool notify)
{
std::vector<std::string> mtCommand;
mtCommand.push_back("mt");
mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
mtCommand.push_back("/nologo");
mtCommand.push_back("/manifest");
if (this->LinkGeneratesManifest) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment