用cmake复制普通的.o文件 [英] Copy out plain .o files with cmake

查看:338
本文介绍了用cmake复制普通的.o文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to get cmake (on linux) to create some static object (.o) files and install them to an external directory. To that end I have a list, object_sources, containing the project path of the sources, and put this in the top level 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"
)       

关于使用文件,它不能工作,因为实际上是 foo.o 从未创建,所以我尝试获取毫无意义正确的项目路径。

With regard to using FILES, it cannot work because in fact a foo.o is never created, so there is no point in me trying to get the correct project path.

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

When I get to the actual make command in the cmake build directory, it spits out Built target foo.o, etc., during the process. However, as mentioned, no foo.o is ever created anywhere, and the install creates an objects-Debug directory in /some/external/dir containing directories for each target using its name (e.g., foo.o/) and inside that some more nested directories at the bottom of which is the object I want, with the wrong name: foo.cpp.o.

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

Cmake can structure its build tree however it wants and name its temporaries whatever it likes, but I would really like to be able to ask for a final product object foo.o (not foo.cpp.o) and have it installed that way.

有可能吗?我开始认为这完全与cmake的(隐式)目的背道而驰,我应该将这些类型的任务放在shell脚本或makefile中分开处理(任一个都需要三行),而只需使用cmake

Is that possible? I'm beginning to think this is all very contrary to the (implicit) purposes of cmake, and that I should keep these kinds of tasks separate in a shell script or makefile (it takes about three lines in either), and just use cmake for the normative libs and executables.

或者:我相信,如果我将每个对象都创建为静态存档(lib.a),我可以使它工作,但是一部分这里的问题是,需要修改其他内容的构建脚本,或者通过脚本提取它们(在这种情况下,我也可以在脚本中完成整个操作)。

Or: I believe I could get this to work if I created each object as a static archive (lib.a) instead, but part of the issue here is that would require modifying the build scripts of something else, or else extracting them via a script (in which case I might as well do the whole thing in the script).

推荐答案

我不知道在CMake中执行此操作的好方法,但也许最不麻烦的是使用 对象 库。这将允许您使用生成器表达式,更具体地说是 TARGET_OBJECTS 表达式。这是一个最小的示例,其中单个 foo.c 文件包含一个空的 main

I'm not aware of a good way to do this in CMake, but maybe the least fussy would be to use an OBJECT library. This would allow you to get the object files for a target using generator expressions, more specifically the TARGET_OBJECTS expression. This is a minimal example with a single foo.c file containing an empty 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/)

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

Please note that as a generator expression, you will not have access to it during configuration (hence, that message will contain the generator expression as it was textually declared), but only during the generation phase.

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

If you still need to rename the object files (i.e. from foo.c.o to foo.o) you can maybe call a custom external script to do that for you. Moreover, there might be issues with cleanup, etc. which will force you to add more custom targets and/or commands (and associated dependencies) to deal with it. Another downside of this approach.

这篇关于用cmake复制普通的.o文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆