如何使用CMake安装目标文件

3ks5zfa0  于 2023-01-30  发布在  其他
关注(0)|答案(1)|浏览(185)

CMake中有一个对象库:

add_library( librevolta_runtime_x86 OBJECT
    crt0.S
    crti.S
    crtn.S
)

install( TARGETS librevolta_runtime_x86 EXPORT revolta
    OBJECTS DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
)

链接到我的静态库:

add_library( revolta STATIC )

target_link_libraries( revolta
PUBLIC
    librevolta-runtime-x86
)

# Install all the revolta headers into include directory and copy the built library
install( TARGETS revolta EXPORT revolta
    FILE_SET HEADERS    DESTINATION "${CMAKE_INSTALL_PREFIX}/include"
    ARCHIVE             DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
)

# Export librevolta targets 
install( EXPORT revolta DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/revolta" )

问题是一旦构建并安装了库revota,结果是:

<CMAKE_INSTALL_PREFIX>/lib/objects-Debug/librevolta-runtime-x86/crt0.S.obj
<CMAKE_INSTALL_PREFIX>/lib/objects-Debug/librevolta-runtime-x86/crti.S.obj
<CMAKE_INSTALL_PREFIX>/lib/objects-Debug/librevolta-runtime-x86/crtn.S.obj

但我需要弥补安装如下:

<CMAKE_INSTALL_PREFIX>/lib/crt0.o
<CMAKE_INSTALL_PREFIX>/lib/crti.o
<CMAKE_INSTALL_PREFIX>/lib/crtn.o

注意:<CMAKE_INSTALL_PREFIX>只是在CMake变量中指定的路径的占位符。
因此我需要:
1.将目标文件从*.S.obj重命名为简单的*.o
1.修改路径,以便所有目标文件都安装到pure <CMAKE_INSTALL_PREFIX>/lib/目录中
1.由于target_link_libraries(...)相关性,请将librevolta_runtime_x86作为revolta导出集的成员
非常感谢任何愿意帮助我的人。马丁

9gm1akwq

9gm1akwq1#

编辑:简单的宏如承诺的那样

macro(install_objects OBJFILE_LIST)

foreach(OBJFILE ${${OBJFILE_LIST}})
    # Available since CMake 3.20 you can use get_filename_component
    # To get any specific information you can wish for about a file
    # Before 3.20 you would have to use string(REGEX MATCH ...)
    # get_filename_component(OBJ_DIR ${OBJFILE} DIRECTORY) <-- path
    # get_filename_component(OBJ_EXT ${OBJFILE} EXT) <-- extension
   
    get_filename_component(OBJ_NAME ${OBJFILE} NAME)
    
    # You can uncomment the message to see what you can get 
    # MESSAGE(STATUS "OBJ_DIR: ${OBJ_DIR} OBJ_NAME: ${OBJ_NAME} OBJ_EXT: ${OBJ_EXT}")

    # This is just an example, but you can also use ${OBJ_DIR} for example to specify a better path
    install(FILES ${OBJFILE} DESTINATION [wherever_you_want_them] RENAME "${OBJ_NAME}.o")
endforeach(OBJFILE)

endmacro(install_objects)

#example usage
set(MY_OBJECTS 
    "test.s.obj" 
    "somepath/test2.S.obj" 
    "whatever/whatever/test3.s.OBJ" 
    )
install_objects(MY_OBJECTS)

上面的MY_OBJECTS将为您提供以下变量:

-- OBJ_DIR:  OBJ_NAME: test.s.obj OBJ_EXT: .s.obj
-- OBJ_DIR: somepath OBJ_NAME: test2.S.obj OBJ_EXT: .S.obj
-- OBJ_DIR: whatever/whatever OBJ_NAME: test3.s.OBJ OBJ_EXT: .s.OBJ

正如您所看到的,它非常健壮,并且可以保持CMakeLists.txt的整洁。

这将简化您的目标文件安装。IMO它还回答了ad 1)和ad 2)

Ad 3)我不确定你的问题是什么,或者到底发生了什么,因为问题本身集中在安装对象上。
有什么特殊的原因需要安装中间对象文件吗?这是一个重要的问题,因为静态库在链接时会被解压缩和优化-以look at this question/answer为例。
当你知道你的代码库的某些部分会被编译多次(由于它使用相同的代码)时,OBJECT库在CMake中是很有用的,将这些部分耦合到一个可重用的对象库中是有意义的。

抛开这些不谈你要找的是

INSTALL(FILES file-name.abc DESTINATION dest-folder RENAME file-name.xyz)

相关问题