1

我看到一个奇怪的构建问题,可能有点难以重现。我正在使用 CMake 和 Ninja 来构建一个使用 Qt 5.5 的 C++ 项目。我认为这个混合物的唯一相关部分是 CMake 本身,但 Qt 肯定会给构建系统增加一些皱纹,所以这也可能是罪魁祸首。

这是导致我的问题的一系列事件:

  1. 我向基类添加了一个虚拟方法声明,但忘记将其设为纯虚拟 ( =0)。我在派生类中实现了该方法,但undefined reference to vtable由于缺少基类实现而出现链接错误。
    1. 派生类之一继承QObjectautomoc. 我不认为这与构建问题有关。
  2. 在某些时候,当我试图弄清楚为什么会出现链接错误时,我删除了我的CMakeCache.txt文件。
    1. 我还删除了包含相关虚拟类和派生类的构建目录的整个父目录。我不确定这是否是问题的一部分。
  3. 我意识到我需要将基类方法设为纯虚拟,并成功完成了我的构建。
  4. 问题: ninja install不再安装我的任何二进制目标(所有这些目标都被声明OPTIONAL允许部分构建/安装项目以进行快速迭代),即使在重新运行CMake多次之后也是如此。

我重新删除CMakeCache.txt并重新运行了 CMake 和ninja,但在完全删除构建目录之前,我无法重新安装目标。

我的一位同事也遇到了这个问题,虽然我不知道是怎么回事(他可能已经删除或以其他方式损坏了他的CMakeCache.txt文件,但他实际上并不记得在看到问题之前他在做什么)。

编辑:我又遇到了这个问题,似乎当我将目标设为非时OPTIONAL,CMake 期望在CMakeFiles名为CMakeRelink.dir. 这个目录显然永远不存在。即使设置CMAKE_SKIP_INSTALL_ALL_DEPENDENCYfalse重新运行 CMake 似乎也无法解决问题,这对我来说毫无意义。

编辑 2:认为这是同一个错误,并且有一些解决方法:https ://cmake.org/Bug/view.php?id=13934

4

1 回答 1

0

这似乎是由于 CMake 如何处理其二进制文件后处理中的一个错误。默认情况下,该install命令会在安装之前从二进制文件中去除嵌入式库路径。对于 ELF 二进制文件,CMake 有某种内置的路径剥离器,它实际上读取 ELF 文件并创建一个没有嵌入路径的新文件;对于非 ELF 文件,使用不同的方案。值得注意的是,CMake 对未剥离的二进制文件使用不同的文件,具体取决于用于剥离它们的方案。我不知道为什么会这样,但这是构建错误的根本原因。

如果没有CMakeCache.txt,CMake 似乎“忘记”了使用(或应该使用)哪个方案来剥离文件。因此,它会在错误的工件目录中查找未剥离的二进制文件。

这是一个已知的(虽然有点模糊)CMake 错误;最简单的解决方法是通过设置CMAKE_EXECUTABLE_FORMAT变量显式指定(在适当时)目标二进制文件为 ELF 格式。

于 2016-05-31T19:41:16.830 回答