删除`CMakeCache.txt`导致'OPTIONAL`安装目标不再构建

时间:2016-03-25 18:25:08

标签: c++ qt cmake ninja

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

这是引发我问题的一系列事件:

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

    我的一位同事也遇到了这个问题,虽然我不知道如何(他可能已经删除或以其他方式损坏了他的CMakeCache.txt档案,但他实际上并没有记住在看到问题之前他正在做什么。)

    编辑:我再次遇到此问题,看来当我将目标设为非OPTIONAL时,CMake希望在{{{{{}的各个子目录中找到它们。 1}}名为CMakeFiles的目录(在构建工件树中)。这个目录显然从未存在过。即使将CMakeRelink.dir设置为CMAKE_SKIP_INSTALL_ALL_DEPENDENCY并重新运行CMake也无法解决问题,这对我来说毫无意义。

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

1 个答案:

答案 0 :(得分:0)

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

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

这是known (though somewhat obscure) CMake bug;最简单的解决方法是通过设置CMAKE_EXECUTABLE_FORMAT变量,明确指定(在适当的时候)目标二进制文件是ELF格式。