如何从CMake构建目标中仅生成目标文件(*.o)?

Nic*_*ick 11 build-process cmake

我正在尝试使用CMake构建一个目标文件,但我似乎无法让CMake构建除完整可执行文件之外的其他东西.我基本上是在寻找以下编译的结果(结果将加载到VxWorks目标并链接):

$(CC) $(CFLAGS) $(INC_DIRS) -c src/object.c
Run Code Online (Sandbox Code Playgroud)

我已经尝试更改目标的OUTPUT_NAME属性,但这似乎也没有帮助.

我想我可以通过使用自定义命令来解决这个问题,但这似乎我正在解决CMake提供的好东西.

谢谢你的帮助!

wat*_*i16 6

这个答案是在CMake邮件列表中给我的,它就像一个魅力:

查看以下${CMAKE_SOURCE_DIR}/cpo脚本:

#!/bin/sh
d=$1; shift
while [ "$1" != "--" ]; do
    cp $1 $d/$(basename $1); shift
done
Run Code Online (Sandbox Code Playgroud)

现在,请查看以下CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(CPO C) 
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
ADD_LIBRARY(f SHARED f.c)
SET_TARGET_PROPERTIES(f PROPERTIES RULE_LAUNCH_LINK
    "${CMAKE_SOURCE_DIR}/cpo ${CMAKE_BINARY_DIR} <OBJECTS> --"
)
Run Code Online (Sandbox Code Playgroud)

启动脚本"cpo"使目标"f"在作为第一个参数而不是库传入的目录中生成目标文件; 其他一切都应该像往常一样.关键是脚本对<OBJECTS>占位符的访问,因此它可以对目标文件进行操作,而忽略" - "后面的实际链接命令.这样,您可以在链接发生之​​前使用CMake的所有功能进行编译和拦截.IMO,这是一个非常干净的解决方案,应该很容易适应您的需求; 缺点是使用RULE_LAUNCH_LINK仅限于Makefile发电机.


squ*_*les 5

从 CMake 3.1 开始,CMake 已经能够创建对象库

OBJECT类型定义了编译给定源文件所产生的目标文件的非归档集合。

创建目标文件(无库或可执行文件),请将此OBJECT关键字与add_library()命令一起使用:

# This will create object.c.o (or object.c.obj on Windows) when built.
add_library(MyObj OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/src/object.c)
Run Code Online (Sandbox Code Playgroud)

您稍后可以引用要编译到其他库或可执行文件中的目标文件:

add_library(MyLibrary STATIC $<TARGET_OBJECTS:MyObj> MyClass1.cpp Helpers.cpp)
Run Code Online (Sandbox Code Playgroud)

  • @einpoklum “STATIC”关键字(或其他库类型关键字)后面的“add_library”参数应该是“源”文件。因为`MyObj`不是源文件,而是目标名称,所以我们必须通过使用`TARGET_OBJECTS`引用它来告诉CMake这种特殊情况。 (2认同)

Rob*_*ard 2

我会走自定义命令路径。请记住,如果您设置了 GENERATED 和 EXTERNAL_OBJECT 源文件属性,您仍然可以使用这些目标文件与 CMake 进行编译。