编译和添加对象文件从二进制与cmake [英] compile and add object file from binary with cmake

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

问题描述

我在C ++中编写一个excel文件生成器。



我有一切我需要工作,但我仍然依赖外部空xlsx文件,我解压缩,迭代



我想做的是通过将xlsx文件转换为二进制blob来删除这个依赖关系.rodata部分,通过将它首先转换为一个目标文件像这样:

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



我从这里得到这个信息: http://www.burtonini.com/blog/computers/ld-blobs-2007-07-13-15-50



第二步是将它链接到二进制文件,我可以使用ld。



我的问题是,如何自动化这两个步骤cmake?我不知道atm如何运行像上面的第一步的特定命令,我已经尝试添加文件/ template.o到我的target_link_libraries第二,但ld只是说

  / usr / bin / ld:找不到-lfiles / template.o 

编辑:



我添加了以下自定义命令到我的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)

$ b



不幸的是,cmake说:

  ld:无法打开输出文件/ template.o:没有这样的文件或目录

我的理解是,add_custom_command中的OUTPUT命令允许我们告诉CMake COMMAND命令正在创建什么文件。现在我有点困惑了。



编辑2:



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

  add_custom_target(运行ALL 
DEPENDS template.o)

和依赖关系,以确保它在excelbuilder目标之前构建:

  add_dependencies(excelbuilder run)

我也更新了自定义命令看起来像这样:

  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)

当我运行这个,输出如下(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]:输入目录`/ 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]:输入目录`/ home / ravloony / projects / excelparser / build'
cd / home / ravloony / projects / excelparser / build&& / usr / bin / cmake -E cmake_dependsUnix Makefiles/ home / ravloony / projects / excelparser / home / ravloony /projects/excelparser/src/lib/minizip/home/ravloony/projects/externalparser/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 ]:离开目录`/ 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]:进入目录`/ home / ravloony / projects / excelparser / build'
make [2]:对于`src / lib / minizip / CMakeFiles /minizip_1-1.dir/build'。
make [2]:离开目录`/ home / ravloony / projects / excelparser / build'
/ usr / bin / cmake -E cmake_progress_report / home / ravloony / projects / excelparser / build / CMakeFiles 19 20 21
[22%]建立目标minizip_1-1
make -f CMakeFiles / run.dir / build.make CMakeFiles / run.dir / depend
make [2]:输入目录`/ home / ravloony / projects / excelparser / build'
cd / home / ravloony / projects / excelparser / build&& / usr / bin / cmake -E cmake_dependsUnix Makefiles/ home / ravloony / projects / excelparser /home/ravloony/projects/externalparser/home/ravloony/projects/externalparser/ 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比依赖者/home/ravloony/projects/excelparser/build/CMakeFiles/run.dir/depend.internal更新。
Dependee/home/ravloony/projects/excelparser/build/CMakeFiles/CMakeDirectoryInformation.cmake比依赖者/home/ravloony/projects/excelparser/build/CMakeFiles/run.dir/depend.internal更新。
扫描目标运行的依赖关系
make [2]:离开目录`/ home / ravloony / projects / excelparser / build'
make -f CMakeFiles / run.dir / build.make CMakeFiles / run.dir / build
make [2]:输入目录`/ home / ravloony / projects / excelparser / build'
/ usr / bin / cmake -E cmake_progress_report / home / ravloony / projects / excelparser / build / CMakeFiles 22
[27%]生成template.o
ld -r -b二进制-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]:离开目录`/ home / ravloony / projects / excelparser / build'
/ usr / bin / cmake -E cmake_progress_report / home / ravloony / projects / excelparser / build / CMakeFiles 22
[27%]内部目标运行
make -f CMakeFiles / excelbuilder.dir / build .make CMakeFiles / excelbuilder.dir / depend
make [2]:输入目录`/ home / ravloony / projects / excelparser / build'
cd / home / ravloony / projects / excelparser / build& ; / usr / bin / cmake -E cmake_dependsUnix Makefiles/ home / ravloony / projects / excelparser /home/ravloony/projects/externalparser/home/ravloony/projects/externalparser/ build / home / ravloony / projects / excelparser / build / home / ravloony / projects / excelparser / build / CMakeFiles / excelbuilder.dir / DependInfo.cmake --color =
make [2]:离开目录`/ home / ravloony / projects / excelparser / build'
make -f CMakeFiles / excelbuilder.dir / build.make CMakeFiles / excelbuilder.dir / build
make [2]:输入目录`/ home / ravloony / projects / excelparser / build'
链接CXX可执行文件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:找不到-ltemplate.o
collect2:错误:ld返回1退出状态
make [2]:*** [excelbuilder]错误1
make [2]:离开目录`/ home / ravloony / projects / excelparser / build'
make [1]:*** [CMakeFiles / excelbuilder.dir / all]错误2
make [1]:离开目录`/ home / ravloony / projects / excelparser / build'
make:*** [all]错误2

但是template.o已正确生成并在文件夹中。看来ld正在等待一个系统库。

解决方案

最后,这是我做的。

  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 。不便于进行便携式编辑。

  add_library(template 
STATIC
template.o)

告诉链接器将目标文件编译成二进制文件。这也添加了一个名为的目标 c。



然后

  SET_SOURCE_FILES_PROPERTIES(
template.o
PROPERTIES
EXTERNAL_OBJECT true
GENERATED true

告诉cmake不要编译在构建时生成的文件。

  SET_TARGET_PROPERTIES(
模板
PROPERTIES
LINKER_LANGUAGE C

否则我们得到一个错误消息,因为cmake无法从.o后缀中得出它是我们需要的C链接器。



,然后在我的 target_link_libraries 步骤中,我简单地添加 template 目标。

  target_link_libraries(excelbuilder 
$ {MINIZIP_LIB_NAME}
$ {TINYXML_LIBRARIES}
$ {MYSQLCONNECTORCPP_LIBRARY}
$ {Boost_LIBRARIES}
模板


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

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.

What I want to do is 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

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

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

My question is, how do I automate these two steps with cmake? I have no idea atm 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

EDIT:

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)

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

Unfortunately, cmake says this:

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

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.

EDIT 2:

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

add_custom_target(run ALL
    DEPENDS template.o)

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)

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

but 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)

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)

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

Then

SET_SOURCE_FILES_PROPERTIES(
  template.o
  PROPERTIES
  EXTERNAL_OBJECT true
  GENERATED true
  )

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

SET_TARGET_PROPERTIES(
  template
  PROPERTIES
  LINKER_LANGUAGE 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.

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天全站免登陆