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

2024-01-12

我正在构建一个使用 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 时按照相同的方法设置编译器这个问题 https://stackoverflow.com/questions/23477379/how-does-cmake-find-cxx-compiler但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 的调用(而不是定义 CC makefile 中的变量)。我宁愿有一种方法让 cmake 从偏移量开始使用所需的编译器。


UPDATED:测试表明最初建议的方法至少在某些平台上无法按预期工作。看来使用包装脚本可能是可行的方法。

如果您确实想强制使用特定编译器并绕过 CMake 的编译器检查,则CMakeForceCompiler module https://cmake.org/cmake/help/latest/module/CMakeForceCompiler.html可能就是您正在寻找的。指向 CMake 文档的链接包含一个简单的工具链文件示例,该示例展示了如何使用作为没有路径的简单命令调用的特定编译器。不幸的是,CMake 仍然将其转换为绝对路径,因此它本身并不能解决您的问题。但是,您可以使用工具链文件指向包装器脚本并使用CMakeForceCompiler绕过编译器检查。这种组合应该会产生您所要求的行为,但请注意CMakeForceCompiler现已弃用。

请注意,使用时CMakeForceCompiler模块中,您承担了更多的责任来告诉 CMake 信息,特别是您想要强制使用的特定编译器的编译器 ID,但是来自CMake 文档 https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html看起来很清楚这只是MSVC在你的情况下。

要使用工具链文件,请使用以下命令调用 CMake-DCMAKE_TOOLCHAIN_FILE=path/to/file指向您自己的自定义工具链文件的选项。 CMake 文档有一个具体部分 https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html涵盖了工具链的使用,尽管它确实掩盖了一些重要的细节。

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

cl %*

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何强制 cmake 使用没有完整路径的 cl.exe? 的相关文章

  • 具有相同参数类型但具有不同常量限定符的 std::vector 的转换

    问题很简单 静态转换 或其他一些转换 通常是安全的 std vector lt Foo gt to std vector lt const Foo gt 就二进制而言 我不明白为什么本机类型会有所不同 毕竟const是一种语言约束 不应影响
  • 是否有可能劫持标准输出

    我正在尝试使用 C 重定向 Windows XP 上已运行进程的标准输出 我知道如果我自己生成进程 我可以做到这一点 但对于这个应用程序 我更喜欢一个 监听器 我可以附加到另一个进程 这在纯 Net 中可能吗 如果不可能 在 Win32 中
  • 深拷贝和动态转换 unique_ptr

    假设我有一个如下所示的类 class A virtual A class B public A class C public A 我还有一个 unique ptr 向量 它是这样声明的 std vector
  • 最新 .Net MongoDb.Driver 的连接问题

    我创建了一个 MongoLab 沙箱数据库 我与 MongoChef 连接 效果很好 我通过 Nuget 安装了 MongoDB Driver 2 2 2 我编写了一些简单的 C 演示代码 但就是无法使其工作 连接字符串是直接从 Mongo
  • 如何从 Qt 应用程序通过 ODBC 连接到 MySQL 数据库?

    我有一个新安装的 MySQL 服务器 它监听 localhost 3306 从 Qt 应用程序连接到它的正确方法是什么 原来我需要将MySQL添加到ODBC数据源 我在遵循这个视频教程后做到了这一点 https youtu be K3GZi
  • 组合框下拉位置

    我有一个最大化的表单 其中包含 500px 的组合框控件 停靠在右上角 Width 尝试打开组合框后 列表的一半超出了屏幕 如何强制列表显示在表单中 棘手的问题 我找不到解决这个问题的好办法 只是一个解决方法 添加一个新类并粘贴如下所示的代
  • 无法加载程序集问题

    我收到以下错误 无法加载程序集 错误详细信息 System BadImageFormatException 无法加载文件或程序集 文件 或其依赖项之一 该程序集是由比当前加载的运行时更新的运行时构建的 无法加载 该程序集是使用 Net Fr
  • Linq 合并列表

    我的课 public class Foo public int A get set public List
  • Visual Studio 中列表框的上移、下移按钮[重复]

    这个问题在这里已经有答案了 我正在尝试制作一个上移按钮和一个下移按钮 以移动 Microsoft Visual Studio 2012 中列表框中的选定项目 我已经在 WDF jquery winforms 和其他一些表单中看到了其他示例
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 如何让XmlReader读取C#中的属性?

    我有一个 XML Stream 其中包含以下 XML 内容
  • 我在使用 ado.net 时收到错误 Argument 2 may not be pass with ref keywords

    int t 0 cmd Parameters AddWithValue Res ref t 我在第二行收到错误 参数 2 不能与 ref 关键字一起传递 您只能通过引用传递参数ref if the 范围 is a ref参数也是如此 Add
  • 如何从外语线程调用Python函数(C++)

    我正在开发一个程序 使用 DirectShow 来抓取音频数据 媒体文件 DirectShow 使用线程将音频数据传递给回调 我的程序中的函数 然后我让该回调函数调用另一个函数 Python 中的函数 我使用 Boost Python 来包
  • DataGridView 行背景颜色没有改变

    我想根据加载时的特定条件更改 DGV 行的背景颜色 即使在 Windows 窗体中也是如此 但我看不到任何 DGV 行的颜色有任何变化 谁能告诉我如何解决这个问题 private void frmSecondaryPumps Load ob
  • valgrind 在 Raspberry Pi 上返回未处理的指令

    我最近一直在尝试在运行 Debian GNU Linux7 0 喘息 的树莓派 型号 b 上使用 valgrind 来调试分段错误 每次我在编译的 C 程序上运行 valgrind 时 都会得到类似以下内容的信息 disInstr arm
  • Type.GetInterfaces() 仅适用于声明的接口

    首先 像这样的问题有很多 也许有些OP甚至在问同样的问题 问题是这些问题的答案 无论是否接受 都没有真正回答这个问题 至少我找不到 如何确定类直接声明的接口 而不是由父级或声明的接口继承的接口 e g interface I interfa
  • 连接到没有元数据的网络服务

    我想连接到此网络服务 https training api temando com schema 2009 06 server wsdl https training api temando com schema 2009 06 serve
  • 从对列表创建邻接列表类型结构

    在 C 中 我有 class Pair int val1 int val2 我有一个来自以下来源的配对列表 List
  • 使用 CodeDOM 将程序集添加到 BuildManager 会导致间歇性错误

    我正在使用 CodeDOM 在运行时创建内存中程序集 如下所示 public Assembly Compile CodeCompileUnit targetUnit string path Path GetDirectoryName new
  • 实体框架代码首次日期字段创建

    我正在使用实体框架代码优先方法来创建我的数据库表 下面的代码 创建一个DATETIME数据库中的列 但我想创建一个DATE柱子 DataType DataType Date DisplayFormatAttribute ApplyForma

随机推荐