使用 cmake 复制纯 .o 文件

2024-03-12

我试图让 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从未创建过,因此我尝试获取正确的项目路径是没有意义的。

当我到达实际情况时make命令在cmake构建目录中,它吐出构建目标 foo.o等过程中。然而,正如所提到的,没有foo.o任何地方都曾被创造过,并且install创建一个objects-Debug目录在/some/external/dir使用其名称包含每个目标的目录(例如,foo.o/)并在其中一些更多的嵌套目录,其底部是我想要的对象,但名称错误:foo.cpp.o.

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

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

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


我不知道在 CMake 中执行此操作的好方法,但也许最不挑剔的方法是使用OBJECT https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/Object-Library图书馆。这将允许您使用以下方式获取目标的目标文件生成器表达式 https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html,更具体地说TARGET_OBJECTS表达。这是一个最小的例子,只有一个foo.c文件包含一个空的main:

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

请注意,作为生成器表达式,您在配置期间将无法访问它(因此,message将包含文本声明的生成器表达式),但仅限于生成阶段。

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

UPDATE: COMMAND_EXPAND_LISTS允许在生成器表达式中扩展列表,它被添加到 CMake 3.8 及更高版本中(请参阅here https://cmake.org/cmake/help/latest/command/add_custom_target.html).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 cmake 复制纯 .o 文件 的相关文章

随机推荐