浏览代码

MSVC: Restore support for non-incremental linking without 'rc' in PATH

Since commit 0b552eb877 (MSVC: Embed manifests directly for
non-incremental vs_link_exe links, 2023-02-20, v3.27.0-rc1~438^2) we
tell the MSVC `link` tool to embed manifests directly rather than
running `mt` ourselves.  However, `link` expects `rc` to be in the PATH
when embedding manifests.  Although that is normally true, some users
prepare minimal environments and explicitly specify include and link
directories for the Windows SDK.  In such cases, `rc` is not in the PATH
and is explicitly specified in `CMAKE_RC_COMPILER`.  Restore support for
such cases by explicitly adding the RC location to the end of the PATH.

Fixes: #25047
Brad King 2 年之前
父节点
当前提交
8a07bcc149
共有 1 个文件被更改,包括 20 次插入0 次删除
  1. 20 0
      Source/cmcmd.cxx

+ 20 - 0
Source/cmcmd.cxx

@@ -2502,6 +2502,26 @@ int cmVSLink::LinkIncremental()
 
 int cmVSLink::LinkNonIncremental()
 {
+  // The MSVC link tool expects 'rc' to be in the PATH if it needs to embed
+  // manifests, but the user might explicitly set 'CMAKE_RC_COMPILER' instead.
+  // Add its location as a fallback at the end of PATH.
+  if (cmSystemTools::FileIsFullPath(this->RcPath)) {
+    std::string rcDir = cmSystemTools::GetFilenamePath(this->RcPath);
+#ifdef _WIN32
+    std::replace(rcDir.begin(), rcDir.end(), '/', '\\');
+    char const pathSep = ';';
+#else
+    char const pathSep = ':';
+#endif
+    cm::optional<std::string> path = cmSystemTools::GetEnvVar("PATH");
+    if (path) {
+      path = cmStrCat(*path, pathSep, rcDir);
+    } else {
+      path = rcDir;
+    }
+    cmSystemTools::PutEnv(cmStrCat("PATH=", *path));
+  }
+
   // Sort out any manifests.
   if (this->LinkGeneratesManifest || !this->UserManifests.empty()) {
     std::string opt =