在 CMake 项目下编译单个文件

Compile a single file under CMake project?

本文关键字:单个 文件 编译 CMake 项目      更新时间:2023-10-16

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

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

另一方面,我将CMake用于我自己的项目。当我修改编译单元的一些代码并且必须修改其头文件时,我必须等待很长时间才能编译其依赖项,然后编译其自己的源文件。但是在某些情况下,我更愿意检查 *.cc 文件中的源代码是否可以编译而没有错误。

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

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

例如,假设命令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

> CMake 没有通用的内置方法来执行此操作(这是一个悬而未决的问题),但如果您使用的是 Ninja 生成器,您可以使用特殊的 Ninja 语法来构建给定源文件的直接输出。例如,要编译foo.o您将使用:

ninja /path/to/foo.cpp^

不是开箱即用的。CMake 不会在主生成文件中公开这些"内部"生成文件规则。

仅当您考虑 CMake 在内部使用哪种文件结构时,才能执行此操作。例如,您可以使用CMake生成的生成文件调用编译单个.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)

要单独构建 src/foo.cpp:

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

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

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

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

首先构建目标:

ninja TriggersCppCompilationLib

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