2013-02-08 57 views
17

我正在用C++编写一个excel文件生成器。用cmake编译和添加二进制目标文件

我有我需要的一切工作,但我仍然依靠一个外部空的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如何运行,如LD一个以上的第一步具体的命令,我已经尝试添加文件/ template.o我target_link_libraries第二,但LD只是说

/usr/bin/ld: cannot find -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) 

和添加的文件/ template.o到add_executable通话。

不幸的是,cmake的这样说:

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

这是我的理解是,在add_custom_command输出指令让我们来告诉CMake的正在由命令命令创建的内容文件。所以我现在有点困惑。

编辑2:

我更新了的CMakeLists.txt,并增加了一个目标,以确保模板文件有内置:

add_custom_target(run 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) 

当运行此,输出是如下(使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正在期待一个系统库。

+0

你有什么试过的?检查文档,特别是add_custom_command和add_custom_target从这里http://www.cmake.org/cmake/help/v2.8.10/cmake.html#section_Commands – 2013-02-09 09:21:59

+0

是的我试过了,但我必须失去一些东西,因为它没有运行。我会将其添加到问题中。 – 2013-02-11 08:23:48

+0

我还没有得到你所做的。你有template.cpp文件应该首先编译,然后你将这个目标文件与.xlsx结合?我对么?错误颇具描述性。在调用ld之前template.cpp不会被编译,或者您只需要提供$ {CMAKE_BINARY_DIR} /files/template.o到ld命令。 – 2013-02-11 10:01:46

回答

20

最后,这是我做到的。

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) 

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

然后

SET_SOURCE_FILES_PROPERTIES(
    template.o 
    PROPERTIES 
    EXTERNAL_OBJECT true 
    GENERATED true 
) 

告诉CMake的不编译文件,该文件在构建时生成的。

SET_TARGET_PROPERTIES(
    template 
    PROPERTIES 
    LINKER_LANGUAGE C 
) 

否则我们会得到错误信息,因为cmake的无法从名为“.o”弄清楚-suffix,这是一个C-连接需要。

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

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

考虑使用'WORKING_DIRECTORY' kwarg为'add_custom_command',而不是'命令cd ...'。 – ulidtko 2016-11-09 17:24:39

0

要将目标文件链接到可执行文件,请将其添加到add_executable()的源文件列表中,而不是尝试将其添加到target_link_libraries()

首先生成目标文件,参见add_custom_command()。在这种情况下,您需要使用指定OUTPUT参数的表单。

+2

这也行不通。目标文件没有链接进来,因此当ld执行其他库的链接时,.o文件中声明的变量未被引用,并且失败。 – 2013-02-12 09:37:13

相关问题