如何强制 cmake 在没有完整路径的情况下使用 cl.exe?

How do I force cmake to use cl.exe without full path?

我正在构建一个使用 CMake 的开源项目(kst,v2.0.8)。我使用 CMake v2.8.12.2 和 MSVC 2008 作为编译器,并生成 NMake makefile 以在命令行上构建它。我可以使用此设置成功构建它。这些版本是强制性的,所以我目前不能使用更高版本的 CMake 或 MSVC。

我需要能够使用 HP 的 Fortify 对 kst 执行源代码分析,并能够从命令行使用它,它以两种方式之一工作:

  1. 无接触模式,它创建自己的"cl.exe",在实际路径之前设置它的路径cl.exe,因此在构建过程中启动。

  2. 在 makefile 中将编译器设置为 Fortify 命令行,例如sourceanalyzer -b build_id cl 而不是 cl.

无论哪种方式,我都需要强制 cmake 生成到其 makefile 中的编译器成为 cmake 不会自动检测到的东西。

我已经尝试在 运行 cmake 时按照 this question 中的相同方法设置编译器,但 cmake 仍然坚持将 MSVC cl.exe 的完整路径放在 makefile 中。

cmake -DCMAKE_C_COMPILER=cl -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER=cl -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250

我还尝试将编译器设置为调用 Fortify,但是当 cmake 测试编译器时,它失败了,提示找不到编译器。 (我也在没有 FORCED=ON 参数的情况下尝试过,在那种情况下它说编译器失败。)

cmake -DCMAKE_C_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250

我可能会搜索并替换 makefile 中的所有编译器调用,但我必须记住在每次 cmake 之后都这样做,而且看到有多个项目/makefile/调用 cl (而不是在 makefile 中定义 CC 变量)。我宁愿有一种方法让 cmake 从偏移量开始使用所需的编译器。

更新: 测试表明最初建议的方法至少在某些平台上没有按预期工作。似乎使用包装器脚本可能是可行的方法。

如果你真的想强制一个特定的编译器和 by-pass CMake 的编译器检查,CMakeForceCompiler module 可能就是你要找的。 CMake 文档的 link 包含一个简单的工具链文件示例,它展示了如何使用作为没有路径的简单命令调用的特定编译器。 不幸的是,CMake 仍然会将其转换为绝对路径,因此仅靠它本身并不能解决您的问题。但是,您可以使用工具链文件指向包装器脚本并使用 CMakeForceCompiler 绕过编译器检查。这种组合应该会产生您所要求的行为,但请注意 CMakeForceCompiler 现已弃用。

请注意,在使用 CMakeForceCompiler 模块时,您需要承担更多的责任来告知 CMake 信息,尤其是您要强制使用的特定编译器的编译器 ID,但来自 CMake docs 很明显,在您的情况下,这只是 MSVC

要使用工具链文件,请使用指向您自己的自定义工具链文件的 -DCMAKE_TOOLCHAIN_FILE=path/to/file 选项调用 CMake。 CMake 文档 specific section 涵盖了工具链的使用,尽管它确实掩盖了一些重要的细节。

如@Tsyvarev 的评论中所述,使用包装脚本可能是处理此问题的最佳方式。该包装器脚本只需要将调用转发给通常的编译器命令,而无需指定路径。然后,您负责确保在进行构建时该命令将位于您的 PATH 中。像下面这样简单的东西就足以作为 Windows 上的包装批处理文件(未测试):

cl %*

现在,您可以控制 Visual Studio 编译器或 Fortify 是否完全由构建看到的 PATH 调用。就个人而言,我认为这有点脆弱,但这是你所要求的。 ;)

作为更强大的替代方案,是否可以使用两个完全独立的构建?如果是这样,那么我建议将其作为更好的选择。正常使用默认 Visual Studio 编译器构建一个,而对于另一个构建,使用工具链文件指向 Fortify 编译器以使 CMake 绕过其编译器检查。这样您就不会依赖以特定方式设置的构建环境。