【问题标题】:Compile a single file under CMake project?在 CMake 项目下编译单个文件?
【发布时间】:2016-11-11 07:14:42
【问题描述】:

我正在开发一个 C++ 项目,该项目将包含在一个更大的项目中。

我已经看到在更大的项目中(是一个 Qt 应用程序,它是从 qmake 生成的)我能够从 linux 命令行编译单个文件,只需输入特定文件的相对路径作为参数制作。

另一方面,我在自己的项目中使用 CMake。当我为一个编译单元修改一些代码,我必须修改它的头文件时,我必须等待很长时间才能编译它的依赖关系,然后编译它自己的源文件。但是在某些情况下,我更愿意检查 *.cc 文件中的源代码是否可以无错误地编译。

有没有办法像 qmake 那样从 CMake 生成 Makefile?切换到 qmake 不再是一种选择。

【问题讨论】:

  • 在您当前的 CMake 生成的 makefile 上尝试 make help。我很确定这将列出如何只构建一个目标文件。

标签: c++ makefile compilation cmake qmake


【解决方案1】:

您不必向 CMake 脚本添加额外的自定义目标,因为 CMake 生成的 Makefile 已经包含每个 .cc 文件的 .o 目标。例如。如果您有一个名为mySourceFile.cc 的源文件,那么在您的构建目录中将会有一个Makefile,它定义了一个名为<Some Path>/mySourceFile.cc.o 的目标。如果你 cd 进入你的构建目录,你可以使用 grepack-grep 找到定义这个目标的 Makefile,然后 cd 进入那个 Makefile 的目录并构建它。

例如假设命令ack-grep mySourceFile.cc.o 打印如下内容:

foo/bar/Makefile
119:x/y/z/mySourceFile.o: x/y/z/mySourceFile.cc.o
123:x/y/z/mySourceFile.cc.o:
124:    # recipe for building target

然后您可以通过以下方式构建mySourceFile.cc.o

cd foo/bar && make x/y/z/mySourceFile.cc.o

【讨论】:

  • 您也可以使用 --target 为 cmake 指定目标,例如: cmake --build 。 --target src/foo.cpp.o
【解决方案2】:

CMake 没有通用的内置方式来执行此操作(它是 open issue),但如果您使用的是 Ninja 生成器,则可以使用 special Ninja syntax 来构建直接输出给定的源文件。例如,要编译 foo.o,您可以使用:

ninja /path/to/foo.cpp^

【讨论】:

  • 感谢您指出这一点!我也刚刚注意到它适用于源外构建,只要您指定的路径是相对于您正在构建的位置到原始源文件位置的路径
【解决方案3】:

不是开箱即用的。 CMake 不会在主 makefile 中公开那些“内部”makefile 规则。

只有在考虑 CMake 内部使用哪种文件结构时,才能执行此操作。你可以例如用于使用 CMake 生成的 makefile 调用编译单个 .obj 文件

make -f CMakeFiles/myProg.dir/build.make CMakeFiles/myProg.dir/main.cc.obj

当你有类似的东西时

cmake_minimum_required(VERSION 3.1)

project(myProg CXX)

file(WRITE "main.cc" "int main()\n{\nreturn 0;\n}") 
add_executable(myProg main.cc)

【讨论】:

    【解决方案4】:

    单独构建 src/foo.cpp:

    cmake --build . --target src/foo.cpp.o
    

    【讨论】:

    • 小修正,它将从所有使用过这个cpp的目标中构建src/foo.cpp
    • 您还可以传递常用选项,例如VERBOSE=1cmake 就像使用 make 构建此项目时所做的一样。
    【解决方案5】:

    其他人建议了从.cpp 文件名中查找目标名称(以.cpp.o 结尾)的方法,但如果您已经知道将触发.cpp 文件编译的目标名称并且您正在使用 ninja 这个建议应该更容易。

    首先构建目标:

    ninja TriggersCppCompilationLib
    

    假设您的文件已更改或尚未构建,ninja 将打印完整的目标名称。当你看到名字出现时,按回车键,这样它就不会被覆盖。然后只需从终端复制名称(例如使用 tmux 复制模式)。

    【讨论】:

      【解决方案6】:

      不,CMake 不提供编译单个文件的内置支持。

      您必须为每个目标文件添加一个目标,可能是通过一个函数迭代目录的所有文件。

      【讨论】:

      • Ose 提供的答案是正确的。这没有帮助。虽然 CMake 没有为每个 TU 提供目标,但它很好地为具体的构建系统提供了信息。必须去那里看看。
      • Makefile 可能就是这种情况。 nocnokneo 为 Ninja 提供了一个解决方案。但总的来说,没有办法。 nocnokneo 甚至链接了相应的开放错误。
      • @usr1234567 你说得对,没有通用的解决方案(例如,如果你在使用 CMake 时可以在 Visual Studio 中编译单个文件,我会感到非常惊讶)。但是提出这个问题的人并没有要求一个通用的解决方案。他们要求使用 make 的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2018-04-02
      • 2018-07-04
      • 2021-06-24
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多