用cmake复制普通的.o文件

时间:2018-08-23 14:38:01

标签: build cmake

我正在尝试获取cmake(在Linux上)以创建一些静态对象(.o)文件并将其安装到外部目录。为此,我有一个列表<div [ngStyle]="{'visibility':isDivVisible ? 'visible' : 'hidden'}"></div>,其中包含源的项目路径,并将其放在顶层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,所以我没有任何尝试去获取正确的项目路径。

当我在cmake构建目录中找到实际的foo.o命令时,它会在此过程中弹出内置目标foo.o 等。但是,如上所述,make从未在任何地方创建,foo.oinstall中创建一个objects-Debug目录,其中包含每个目标使用其名称的目录(例如{{ 1}}),并在其中包含一些嵌套目录,这些目录的底部是我想要的对象,名称错误:/some/external/dir

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

有可能吗?我开始认为这完全与cmake的(隐式)目的背道而驰,我应该将这些类型的任务放在shell脚本或makefile中(在这两个过程中大约需要三行)分开,只使用cmake规范库和可执行文件。

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

1 个答案:

答案 0 :(得分:1)

我不知道在CMake中执行此操作的好方法,但也许最麻烦的是使用OBJECT库。这将允许您使用generator expressions,更具体地说是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/)

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

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