Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Build 使用cmake复制普通.o文件_Build_Cmake - Fatal编程技术网

Build 使用cmake复制普通.o文件

Build 使用cmake复制普通.o文件,build,cmake,Build,Cmake,我试图让cmake(在linux上)创建一些静态对象(.o)文件,并将它们安装到外部目录。为此,我有一个列表,object\u sources,其中包含源的项目路径,并将其放在顶层CMakeLists.txt: set(local_objects "") foreach(file ${object_sources}) get_filename_component(cur ${file} NAME_WE) add_library("${cur}.o" OBJECT ${file})

我试图让cmake(在linux上)创建一些静态对象(.o)文件,并将它们安装到外部目录。为此,我有一个列表,
object\u 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"
)       
关于使用
文件
,它无法工作,因为实际上从未创建
foo.o
,因此我没有必要尝试获得正确的项目路径

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

Cmake可以随心所欲地构建其构建树,并随意命名其临时对象,但我真的希望能够请求一个最终产品对象
foo.o
(而不是
foo.cpp.o
),并以这种方式安装它

可能吗?我开始认为这与cmake的(隐式)目的完全相反,我应该在一个shell脚本或makefile中将这类任务分开(这两个脚本或makefile都需要大约三行),只需将cmake用于标准的lib和可执行文件


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

我不知道在CMake中有什么好方法可以做到这一点,但也许最简单的方法就是使用库。这将允许您使用
target\u 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
cmake_最低要求(3.11版)
项目(FooC)
集合(源foo.c)
添加库(foo_obj对象${SOURCES})
添加可执行文件(foo$)
集合(OBJS$)
消息(状态“这些是我的对象:${OBJS}”)#此处打印的生成器表达式,尚未计算
添加自定义目标(打印对象)
命令${CMAKE_COMMAND}-E echo$)
集合(对象根目录$)
添加自定义目标(复制对象)
COMMAND${CMAKE_COMMAND}-E make_目录${OBJ_ROOT_DIR}/myobjects/
COMMAND${CMAKE\u COMMAND}-E copy\u如果不同$${OBJ\u ROOT\u DIR}/myobjects/
命令(展开列表)#更新
请注意,作为生成器表达式,您将无法在配置期间访问它(因此,
消息
将包含文本声明的生成器表达式),而只能在生成阶段访问

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


更新:
命令\u EXPAND\u LISTS
允许在生成器表达式中扩展列表,它是在CMake 3.8及更高版本中添加的(请参阅)。

对于重命名,您不能使用
安装(…重命名…
命令吗?@Alexiswillke这可能是正确的,但它仅在安装单个文件时才起作用,正确吗?我正在我的项目中尝试此解决方案,尽管我的对象库已创建,可执行文件已生成并运行,但自定义目标(print_foo_objs,copy_foo_objs)不会被调用。@jws答案中提供的示例默认情况下不会调用它们,必须手动指定它们。否则,您可以使用
ALL
选项设置适合您的依赖项或将其添加到默认构建目标(请参见)@Ragul可能您过度使用了此机制。我还是不太明白。您应该创建一个单独的问题,并详细描述它。有人会回答的。注释部分有其局限性。请参阅: