虽然我仍在进行研究以正确提出问题,但我找到了三个解决方案。考虑到找到这些信息有多难,我还是决定在这里发布问题和答案。
1。使用全局变量CMAKE_MSVCIDE_RUN_PATH
有一个专门用于解决这个确切问题的特殊变量——CMAKE_MSVCIDE_RUN_PATH。如果设置,则会在自定义构建步骤脚本中添加如下一行:
set PATH=<CMAKE_MSVCIDE_RUN_PATH>;%PATH%
所以所有需要的就是在一个好地方做这样的事情:
set(CMAKE_MSVCIDE_RUN_PATH ${LibFoo_RUNTIME_LIBRARY_DIRS})
我最初只在 CMake 源代码中注意到这个变量,因为它在 CMake 3.10 之前没有记录。所以你可能无法在旧版本 CMake 的文档中找到它,但别担心,它是 supported since 2006。
优点:
▪ 可以在一个中心位置启用
▪ 其他地方的任何add_custom_command() 命令都不需要更改
▪ 只设置路径本身,不需要显式编写批处理命令
▪ 具有明确名称和意图的显而易见的选择
缺点:
▪ 整个 CMake 项目和所有自定义命令的全局
▪ 仅适用于“Visual Studio 9 2008”及更高版本的生成器
2。使用两个 COMMAND 参数显式设置 PATH
在 Visual Studio 中为自定义构建步骤生成的脚本包含一些序言,然后是命令本身,然后是一些尾声。难道不能通过另一个COMMAND参数在真正的命令之前简单地添加set PATH=...吗?
documentation for add_custom_command() 说:
COMMAND
指定要在构建时执行的命令行。如果指定了多个COMMAND,它们将按顺序执行,但不一定必须组合成有状态的 shell 或批处理脚本。
所以不,这不能保证是可能的。但是 Visual Studio 项目生成器实际上是does it like this,即各个命令只是一个接一个地附加,所以下面的工作就完成了:
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Table.h"
COMMAND set "PATH=${LibFoo_RUNTIME_LIBRARY_DIRS};%PATH%"
COMMAND TableGenerator "${CMAKE_CURRENT_BINARY_DIR}/Table.h"
DEPENDS TableGenerator)
优点:
▪ PATH 可以为每个自定义命令显式更改
缺点:
▪ 依赖于生成器的未记录行为
▪ 有必要为 Windows 重写整个命令并保持两个版本同步
▪ 每个自定义命令都必须明确更改
3。使用file(GENERATE ...) 创建自定义脚本
上面引用的documentation for add_custom_command() 继续:
要运行完整的脚本,请使用configure_file() 命令或file(GENERATE) 命令创建它,然后指定COMMAND 来启动它。
由于额外的临时文件和命令,这有点混乱:
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTableGenerator.cmd"
CONTENT "set PATH=${LibFoo_RUNTIME_LIBRARY_DIRS};%PATH%
%1 ${CMAKE_CURRENT_BINARY_DIR}/Table.h")
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Table.h"
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/RunTableGenerator.cmd" "$<TARGET_FILE:TableGenerator>"
DEPENDS TableGenerator)
请注意将可执行文件的路径作为参数发送的尴尬方式。这是必要的,因为脚本只编写一次,但TableGenerator 可能针对不同的配置(调试和发布)位于不同的位置。如果直接在内容中使用生成器表达式,则会打印 CMake 错误,并且项目将无法为除一种配置之外的所有配置正确构建。
优点:
▪ 可以为每个自定义命令显式更改 PATH
▪ 完整记录和推荐的解决方案
缺点:
▪ CMakefiles 中非常嘈杂
▪ 有必要为 Windows 重写整个命令并保持两个版本同步
▪ 每个自定义命令都必须明确更改
4。通过 CMake 包装器启动自定义命令
请参阅下面由 Dvir Yitzchaki 提供的其他答案。
我个人选择了解决方案 #1,因为它干净且简单,甚至在 CMake 版本 3.10 中正确记录和支持它之前。这也应该是您前进的最佳方式,除非您需要做一些更特别的事情。