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

Posted

技术标签:

【中文标题】如何强制 cmake 在没有完整路径的情况下使用 cl.exe?【英文标题】:How do I force cmake to use cl.exe without full path? 【发布时间】:2016-04-26 15:38:50 【问题描述】:

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

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

    非接触模式,它创建自己的“cl.exe”,在真正的 cl.exe 路径之前设置它的路径,因此在构建期间启动。

    将 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 直接从偏移量使用所需的编译器。

【问题讨论】:

据我所知,CMake 总是倾向于生成带有程序绝对路径的 makefile。至于您的情况,您可以创建 wrapper 脚本,并告诉 CMake 将其用作编译器。在脚本中,您可以使用编译器的相对路径(由PATH 变量调度),或使用其他机制来选择实际的编译器。 【参考方案1】:

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

如果你真的想强制使用特定的编译器并绕过 CMake 的编译器检查,CMakeForceCompiler module 可能就是你要找的。指向 CMake 文档的链接包含一个简单的工具链文件示例,该示例显示了如何使用作为没有路径的简单命令调用的特定编译器。 不幸的是,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 绕过其编译器检查。这样您就不会依赖以特定方式设置的构建环境。

【讨论】:

以上是关于如何强制 cmake 在没有完整路径的情况下使用 cl.exe?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 CMake 的情况下使用 Visual Studio 2013 设置 Dlib?

如何在没有完整路径的情况下附加 tar

为啥 CMake 在没有 CMAKE_CXX_FLAGS 的情况下生成 Makefile?

如何在没有 CMake 的情况下构建 yaml-cpp

CMake 包含路径

如何在给定完整路径的情况下导入模块?