build - 使用 cmake 复制普通的 .o 文件

标签 build cmake

我正在尝试让 cmake(在 Linux 上)创建一些静态对象 (.o) 文件并将它们安装到外部目录。为此,我有一个列表 object_sources,其中包含源的项目路径,并将其放在顶层 CMakeLists.txt:

set(local_objects "")
foreach(file ${object_sources})
    get_filename_component(cur ${file} NAME_WE)
    add_library("${cur}.o" OBJECT ${file})
    list(APPEND local_objects "${cur}.o")
# To confirm these variables are what I think they are:
    message("---> ${cur} | ${file}")
endforeach()

install(
# Also tried FILES, see below.
    TARGETS ${local_objects}
    CONFIGURATIONS Debug
# Also tried nothing instead of 'OBJECTS' (same outcome)
# and LIBRARY (cmake fails on error).
    OBJECTS
    DESTINATION "/some/external/dir"
)       

关于使用 FILES,它无法工作,因为实际上从未创建过 foo.o,所以我没有必要尝试获得正确的项目路径。

当我到达 cmake 构建目录中的实际 make 命令时,它会在此过程中吐出 Built target foo.o 等。但是,如前所述,任何地方都不会创建 foo.oinstall/some 中创建一个 objects-Debug 目录/external/dir 包含每个目标的目录,使用它的名称(例如,foo.o/),并在其中一些嵌套的目录底部是我想要的对象,与错误的名称:foo.cpp.o

Cmake 可以根据需要构建其构建树,并随意命名其临时对象,但我真的希望能够请求最终产品对象 foo.o(不是 foo.cpp.o) 并以这种方式安装它。

这可能吗?我开始认为这与 cmake 的(隐含的)目的完全相反,我应该将这些类型的任务分开放在 shell 脚本或 makefile 中(两者都需要大约三行),并且只使用 cmake用于规范库和可执行文件。

或者:如果我将每个对象创建为静态存档 (lib.a),我相信我可以让它工作,但这里的部分问题是需要修改其他东西的构建脚本,或者提取他们通过脚本(在这种情况下,我还不如在脚本中完成所有事情)。

最佳答案

我不知道在 CMake 中执行此操作的好方法,但也许最简单的方法是使用 OBJECT图书馆。这将允许您使用 generator expressions 获取目标文件,更具体地说是 TARGET_OBJECTS 表达式。这是一个包含空 main 的单个 foo.c 文件的最小示例:

cmake_minimum_required(VERSION 3.11)

project(foo C)

set(SOURCES foo.c)

add_library(foo_obj OBJECT ${SOURCES})

add_executable(foo $<TARGET_OBJECTS:foo_obj>)

set(OBJS $<TARGET_OBJECTS:foo_obj>)
message(STATUS "these are my objects: ${OBJS}") # generator expression printed here, not evaluated yet

add_custom_target(print_foo_objs
  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_OBJECTS:foo_obj>)

set(OBJ_ROOT_DIR $<TARGET_PROPERTY:foo,BINARY_DIR>) 

add_custom_target(copy_foo_objs
  COMMAND ${CMAKE_COMMAND} -E make_directory ${OBJ_ROOT_DIR}/myobjects/
  COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_OBJECTS:foo_obj> ${OBJ_ROOT_DIR}/myobjects/ 
  COMMAND_EXPAND_LISTS) # UPDATE

请注意,作为生成器表达式,您将无法在配置期间访问它(因此,消息 将包含文本声明的生成器表达式),但只能在生成阶段访问.

如果您仍然需要重命名对象文件(即从 foo.c.ofoo.o),您可以调用自定义外部脚本来为您完成. 此外,可能存在清理等问题,这将迫使您添加更多自定义目标和/或命令(以及相关的依赖项)来处理它。这种方法的另一个缺点。

更新:COMMAND_EXPAND_LISTS 允许在生成器表达式中扩展列表,它已添加到 CMake 3.8 及更高版本中(参见 here)。

关于build - 使用 cmake 复制普通的 .o 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51988350/

相关文章:

java - Spring 配置更改触发 TeamCity 构建?

c++ - 制作配方以防止重建非依赖目标

java - Maven 无法解析类 teSTLink.api.java.client.TestLinkAPIException

xcode - 无法附加到进程 ID Xcode

c - 使用 CMake 在 CLion 中构建引发错误

android - 1.12版后如何在Flutter中禁用Proguard?

qt - 安静的 clang

linux - 使用 CMake 将共享库包含到 Linux 应用程序中——GCC 链接器错误

linux - 如何通过 add_custom_command 指定 LD_LIBRARY_PATH?

android - 如何使用 cmake 和 Android NDK 在 C++ 中加载线程支持