使用CMake从二进制文件编译并添加目标文件 [英] Compile and add an object file from a binary with CMake

查看:105
本文介绍了使用CMake从二进制文件编译并添加目标文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用C ++编写Excel文件生成器.

I am writing an Excel file builder in C++.

我有需要做的所有事情,但是我仍然依赖于一个外部的空.xlsx文件,该文件会解压缩,遍历并根据需要添加数据以创建最终文件.

I have everything I need working, but I still rely on an external empty .xlsx file which I unzip, iterate through, and add data too as needed to create the final file.

我想通过将.xlsx文件转换为可执行文件的.rodata部分中的二进制blob来删除此依赖关系,方法是先将其转换为目标文件,如下所示:

I want to remove this dependency by turning the .xlsx file into a binary blob in the .rodata section of my executable, by turning it first into an object file like so:

$ ld -r -b binary -o template.o template.xlsx
$ objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents template.o template.o

我从博客文章 ="a href =" http://www.burtonini.com/blog/computers/ld-blobs-2007-07-13-15-50"rel =" nofollow noreferrer> http://www.burtonini.com/blog/computers/ld-blobs-2007-07-13-15-50 .

I got this information from the blog post http://www.burtonini.com/blog/computers/ld-blobs-2007-07-13-15-50.

第二步是将其链接到二进制文件中,这可以通过ld完成.

The second step is to link it into the binary, which I can do with ld.

如何使用CMake自动执行这两个步骤?

How do I automate these two steps with CMake?

此刻,我不知道如何第一步执行上面的ld之类的特定命令,并且我已经尝试了第二步将files/template.o添加到我的target_link_libraries中,但是ld只是说: /p>

I have no idea at the moment how to run specific commands like the ld one above for the first step, and I have tried adding files/template.o to my target_link_libraries for the second, but ld just says:

/usr/bin/ld: cannot find -lfiles/template.o

我在CMakeLists.txt中添加了以下自定义命令:

I added the following custom command to my CMakeLists.txt:

add_custom_command(OUTPUT files/template.o
      COMMAND ld -r -b binary -o files/template.o files/template.xlsx
      COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents files/template.o files/template.o)

并将文件/template.o添加到add_executable调用中.

and added files/template.o to the add_executable call.

不幸的是,CMake这样说:

Unfortunately, CMake says this:

ld:无法打开输出文件files/template.o:没有此类文件或目录

ld: cannot open output file files/template.o: No such file or directory

据我了解,add_custom_command中的OUTPUT命令允许我们告诉CMake COMMAND命令正在创建哪个文件.所以我现在有点困惑.

It is my understanding that the OUTPUT command in the add_custom_command allows us to tell CMake what file is being created by the COMMAND commands. So I'm a bit confused now.

我更新了CMakeLists.txt文件并添加了一个目标,以确保已构建模板文件:

I updated the CMakeLists.txt file and added a target, to make sure the template file got built:

add_custom_target(run ALL
    DEPENDS template.o)

以及用于确保它在excelbuilder目标之前构建的依赖项:

And a dependency to make sure that it gets built before the excelbuilder target:

add_dependencies(excelbuilder run)

我还更新了自定义命令,使其看起来像这样:

I also updated the custom command to look like this:

add_custom_command(OUTPUT template.o
      COMMAND ld -r -b binary -o template.o ${CMAKE_CURRENT_SOURCE_DIR}/files/template.xlsx
      COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents template.o template.o)

运行此命令时,输出如下(使VERBOSE = 1)

When I run this, the output is as follows (make VERBOSE=1)

$ make VERBOSE=1
/usr/bin/cmake -H/home/ravloony/projects/excelparser -B/home/ravloony/projects/excelparser/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/ravloony/projects/excelparser/build/CMakeFiles /home/ravloony/projects/excelparser/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/ravloony/projects/excelparser/build'
make -f src/lib/minizip/CMakeFiles/minizip_1-1.dir/build.make src/lib/minizip/CMakeFiles/minizip_1-1.dir/depend
make[2]: Entering directory `/home/ravloony/projects/excelparser/build'
cd /home/ravloony/projects/excelparser/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ravloony/projects/excelparser /home/ravloony/projects/excelparser/src/lib/minizip /home/ravloony/projects/excelparser/build /home/ravloony/projects/excelparser/build/src/lib/minizip /home/ravloony/projects/excelparser/build/src/lib/minizip/CMakeFiles/minizip_1-1.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/ravloony/projects/excelparser/build'
make -f src/lib/minizip/CMakeFiles/minizip_1-1.dir/build.make src/lib/minizip/CMakeFiles/minizip_1-1.dir/build
make[2]: Entering directory `/home/ravloony/projects/excelparser/build'
make[2]: Nothing to be done for `src/lib/minizip/CMakeFiles/minizip_1-1.dir/build'.
make[2]: Leaving directory `/home/ravloony/projects/excelparser/build'
/usr/bin/cmake -E cmake_progress_report /home/ravloony/projects/excelparser/build/CMakeFiles  17 18 19 20 21
[ 22%] Built target minizip_1-1
make -f CMakeFiles/run.dir/build.make CMakeFiles/run.dir/depend
make[2]: Entering directory `/home/ravloony/projects/excelparser/build'
cd /home/ravloony/projects/excelparser/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ravloony/projects/excelparser /home/ravloony/projects/excelparser /home/ravloony/projects/excelparser/build /home/ravloony/projects/excelparser/build /home/ravloony/projects/excelparser/build/CMakeFiles/run.dir/DependInfo.cmake --color=
Dependee "/home/ravloony/projects/excelparser/build/CMakeFiles/run.dir/DependInfo.cmake" is newer than depender "/home/ravloony/projects/excelparser/build/CMakeFiles/run.dir/depend.internal".
Dependee "/home/ravloony/projects/excelparser/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/ravloony/projects/excelparser/build/CMakeFiles/run.dir/depend.internal".
Scanning dependencies of target run
make[2]: Leaving directory `/home/ravloony/projects/excelparser/build'
make -f CMakeFiles/run.dir/build.make CMakeFiles/run.dir/build
make[2]: Entering directory `/home/ravloony/projects/excelparser/build'
/usr/bin/cmake -E cmake_progress_report /home/ravloony/projects/excelparser/build/CMakeFiles 22
[ 27%] Generating template.o
ld -r -b binary -o template.o /home/ravloony/projects/excelparser/files/template.xlsx
objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents template.o template.o
make[2]: Leaving directory `/home/ravloony/projects/excelparser/build'
/usr/bin/cmake -E cmake_progress_report /home/ravloony/projects/excelparser/build/CMakeFiles  22
[ 27%] Built target run
make -f CMakeFiles/excelbuilder.dir/build.make CMakeFiles/excelbuilder.dir/depend
make[2]: Entering directory `/home/ravloony/projects/excelparser/build'
cd /home/ravloony/projects/excelparser/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ravloony/projects/excelparser /home/ravloony/projects/excelparser /home/ravloony/projects/excelparser/build /home/ravloony/projects/excelparser/build /home/ravloony/projects/excelparser/build/CMakeFiles/excelbuilder.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/ravloony/projects/excelparser/build'
make -f CMakeFiles/excelbuilder.dir/build.make CMakeFiles/excelbuilder.dir/build
make[2]: Entering directory `/home/ravloony/projects/excelparser/build'
Linking CXX executable excelbuilder
/usr/bin/cmake -E cmake_link_script CMakeFiles/excelbuilder.dir/link.txt --verbose=1
/usr/bin/c++   -std=c++0x  -g -ftest-coverage -fprofile-arcs -fpermissive    CMakeFiles/excelbuilder.dir/src/common/exception.cpp.o CMakeFiles/excelbuilder.dir/src/excelbuilder/retriever.cpp.o CMakeFiles/excelbuilder.dir/src/excelbuilder/xlsx.cpp.o CMakeFiles/excelbuilder.dir/src/common/config.cpp.o CMakeFiles/excelbuilder.dir/src/excelbuilder/main.cpp.o  -o excelbuilder -rdynamic src/lib/minizip/libminizip_1-1.so -ltinyxml2 -lmysqlcppconn -lboost_regex-mt -ltemplate.o -lz -Wl,-rpath,/home/ravloony/projects/excelparser/build/src/lib/minizip
/usr/bin/ld: cannot find -ltemplate.o
collect2: error: ld returned 1 exit status
make[2]: *** [excelbuilder] Error 1
make[2]: Leaving directory `/home/ravloony/projects/excelparser/build'
make[1]: *** [CMakeFiles/excelbuilder.dir/all] Error 2
make[1]: Leaving directory `/home/ravloony/projects/excelparser/build'
make: *** [all] Error 2

但是文件template.o已正确生成并且位于该文件夹中.似乎ld需要一个系统库.

But file template.o has been correctly generated and is in the folder. It seems that ld is expecting a system library.

推荐答案

最后,这就是我的方法.

In the end, this is how I did it.

add_custom_command(OUTPUT template.o
      COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR}/files && ld -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/template.o template.xlsx
      COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents ${CMAKE_CURRENT_BINARY_DIR}/template.o ${CMAKE_CURRENT_BINARY_DIR}/template.o)

之所以使用cd命令,是因为ld根据传递给输入文件的完整路径将自动声明的变量的名称设置为某种名称.因此,如果输入文件为/home/user/project/files/template.xlsx,则变量将类似于_binary_home_user_project_files_template_xlsx_start.不适合便携式编译.

The cd commands are there because ld sets the names of the automatically declared variables to something depending on the full path passed to the input file. So if the input file was /home/user/project/files/template.xlsx, the variable would be something like _binary_home_user_project_files_template_xlsx_start. Not cool for portable compilation.

add_library(template
        STATIC
        template.o)

告诉链接器将目标文件编译为二进制文件.这还会添加一个名为template的目标.

tells the linker to compile the object file into the binary. This also adds a target called template.

然后

SET_SOURCE_FILES_PROPERTIES(
  template.o
  PROPERTIES
  EXTERNAL_OBJECT true
  GENERATED true
  )

告诉CMake不要编译在生成时生成的文件.

to tell CMake not to compile the file, which is generated at build time.

SET_TARGET_PROPERTIES(
  template
  PROPERTIES
  LINKER_LANGUAGE C 
  )

否则我们会收到一条错误消息,因为CMake无法从后缀".o"得知它是我们需要的C 链接器.

Or else we get an error message, because CMake can't figure out from the ".o"-suffix that it is a C linker we need.

然后在我的target_link_libraries步骤中,我简单地添加了template作为目标.

And then in my target_link_libraries step, I simply added template as a target.

target_link_libraries (excelbuilder
            ${MINIZIP_LIB_NAME}
            ${TINYXML_LIBRARIES}
            ${MYSQLCONNECTORCPP_LIBRARY}
            ${Boost_LIBRARIES}
            template
            )

这篇关于使用CMake从二进制文件编译并添加目标文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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