CMake:将ELF嵌入可执行文件中

时间:2014-04-10 22:57:08

标签: c++ c makefile cmake elf

我有一个项目需要访问special section中嵌入到可执行文件中的ELF文件。

之前我手工制作Makefile,只是有一个shell脚本,我用objcopy复制我想嵌入.o文件的目标,然后在可执行文件中链接到这个文件。

# Create a new section and copy the binary there ($1=input $2=output name)
objcopy --input-target binary --output-target elf64-x86-64 \
        --binary-architecture i386 $1 $2.o

现在我想摆脱自定义Makefile并使用CMake生成它们。但是,我没有看到链接到这样一个文件的简单方法。我能够创建并添加此文件,但不能链接到它:

# Invoke script to package module as a library
add_custom_command(OUTPUT ${PACKAGED_FILE}
  COMMAND ./package.sh ${MODULE_FILE} ${PACKAGED_FILE}
  WORKING_DIRECTORY ${MODULE_DIR}
  DEPENDS ${MODULE_FILE}
  COMMENT packaging file into ELF object
  VERBATIM
)

add_custom_target(${PACKAGED_NAME} ALL DEPENDS ${PACKAGED_FILE})

我尝试添加:

target_link_libraries(binary ${PROJECT_BINARY_DIR}/${PACKAGED_FILE})

但是,由于文件尚未存在,因此失败。它会,但CMake不知道。将目标名称添加为链接库也无济于事,因为无法找到它。将它添加为依赖也无济于事。有谁知道如何实现这一目标?

2 个答案:

答案 0 :(得分:3)

我们在项目中做了类似的事情 - 我们CMakeLists.txt的以下部分可以解决问题:

set(PROJECT_EMBED_OBJ_FILES "")
set(PROJECT_EMBED_FILES "file1.elf" "file2.elf")
foreach(FILENAME ${PROJECT_EMBED_FILES})
    get_filename_component(FILENAME_ONLY ${FILENAME} NAME)
    get_filename_component(FILEPATH_ONLY ${FILENAME} PATH)
    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_ONLY}.o 
                       WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/${FILEPATH_ONLY} 
                       COMMAND ${CMAKE_OBJCOPY} 
                       ARGS -I binary -O elf64-x86-64 -B i386 ${FILENAME_ONLY} ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_ONLY}.o )
    list(APPEND PROJECT_EMBED_OBJ_FILES ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_ONLY}.o)
    message(STATUS "Objcopy'ing ${FILENAME}")
endforeach(FILENAME)

然后在致电add_executable

add_executable(projectname ${PROJECT_SOURCES} ${PROJECT_EMBED_OBJ_FILES})

答案 1 :(得分:0)

您可以尝试

add_custom_command(TARGET $(PROJECT_NAME).elf
    POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} ARGS -O binary ${PROJECT_NAME}.elf \ 
${PROJECT_NAME}.bin)

将此信息放在add_executable()之后。 POST_BUILD表示在构建后执行。