【发布时间】:2013-01-24 10:46:09
【问题描述】:
我正在用 C++ 编写一个 Excel 文件生成器。
我拥有工作所需的一切,但我仍然依赖于一个外部的空 .xlsx 文件,我根据需要解压缩、迭代并添加数据以创建最终文件。
我想通过将 .xlsx 文件转换为可执行文件的 .rodata 部分中的二进制 blob 来消除这种依赖关系,方法是先将其转换为像这样的目标文件:
$ 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 自动执行这两个步骤?
目前我不知道如何在第一步运行特定命令,例如上面的ld,第二步我尝试将files/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)
并将 files/template.o 添加到 add_executable 调用中。
不幸的是,CMake 是这样说的:
ld: 无法打开输出文件 files/template.o: 没有这样的文件或目录
据我了解,add_custom_command 中的 OUTPUT 命令允许我们告诉 CMake COMMAND 命令正在创建什么文件。所以我现在有点困惑。
我更新了 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)
当我运行这个时,输出如下(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 似乎在期待一个系统库。
【问题讨论】:
-
你试过什么?检查文档,特别是 add_custom_command 和 add_custom_target 从这里cmake.org/cmake/help/v2.8.10/cmake.html#section_Commands
-
是的,我试过了,但我一定错过了一些东西,因为它没有运行。我会把它添加到问题中。
-
我还是不明白你在做什么。您有应该首先编译的 template.cpp 文件,然后将此目标文件与 .xlsx 结合起来?我对么?错误非常具有描述性。在调用 ld 之前不会编译 template.cpp,或者您只需向 ld 命令提供 ${CMAKE_BINARY_DIR}/files/template.o。
-
没有template.cpp。只有一个 xlsx 文件,我使用 ld 命令将其转换为目标文件。我不想让ld找到template.o,我想让它生成它。
-
链接已损坏 (404)。