2013-02-08 11 views
17

私はC++でExcelファイルビルダーを作成しています。cmakeでバイナリからオブジェクトファイルをコンパイルして追加します。

私は作業が必要なすべてを持っていますが、私はまだ解凍し、繰り返して、最後のファイルを作成するのに必要なだけデータを追加する外部の空のxlsxファイルに依存しています。私が何をしたいか

はそうのようなオブジェクトファイルに最初にそれを回すことで、私の実行可能ファイルの.rodataセクションにバイナリブロブへのxlsxファイルを回すことによって、この依存関係を削除することです:

$ 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

2番目のステップは、ldで行うことができるバイナリにリンクすることです。

私の質問は、どのように私はこれらの2つのステップをcmakeで自動化しますか?私は、LDの最初のステップのために上記のような特定のコマンドを実行する方法気圧見当がつかない、と私は2番目のための私のtarget_link_librariesにファイル/ template.oを追加しようとしたが、ちょうど

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

EDITは言うLD:

私は私の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) 

をしてadd_executableコールにファイル/ template.oを追加しました。

残念ながら、cmakeのは、このことを言う:

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

add_custom_commandでOUTPUTコマンドは、私たちはCOMMANDコマンドによって作成されているどのファイルCMakeのを伝えることを可能にするというのが私の理解です。だから私はちょっと混乱している。

EDIT 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 –

+0

ええ、私はそれを試みましたが、実行されていないため何かが欠けているはずです。それを質問に追加します。 –

+0

私はまだあなたがしているものを得ていません。最初にコンパイルする必要があるtemplate.cppファイルがあります。次に、このオブジェクトファイルを.xlsxと組み合わせますか?私は正しいですか?かなり記述的なエラー。 ldを起動する前にtemplate.cppがコンパイルされていないか、ldコマンドに$ {CMAKE_BINARY_DIR} /files/template.oを指定するだけです。 –

答えて

20

最後に、これが私のやり方です。 ldが自動的に入力されたファイルに渡された完全なパスに応じて、何かに変数を宣言した。名を設定するためcdコマンドがある

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) 

したがって、入力ファイルが/home/user/project/files/template.xlsxの場合、変数は_binary_home_user_project_files_template_xlsx_startのようになります。携帯用コンパイルではクールではありません。

add_library(template 
     STATIC 
     template.o) 

は、オブジェクトファイルをバイナリにコンパイルするように指示します。これにはtemplateというターゲットも追加されます。

その後、ビルド時に生成されたファイルを、コンパイルしないcmakeのを伝えるために

SET_SOURCE_FILES_PROPERTIES(
    template.o 
    PROPERTIES 
    EXTERNAL_OBJECT true 
    GENERATED true 
) 

SET_TARGET_PROPERTIES(
    template 
    PROPERTIES 
    LINKER_LANGUAGE C 
) 

もないとcmakeのは「の.o」から把握することはできませんので、我々は、エラーメッセージが表示されます、それは我々が必要とするC-リンカーであることを-suffix。

の手順で、target_link_librariesの手順では、単にtemplateをターゲットに追加しました。

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

'WORKING_DIRECTORY' kwargを' command cd ... 'の代わりに' add_custom_command'に使うことを検討してください。 – ulidtko

0

オブジェクトファイルをexectuableにリンクするには、target_link_libraries()に追加する代わりに、ソースファイルのリストにadd_executable()を追加します。

最初にオブジェクトファイルを生成する場合は、add_custom_command()を参照してください。この場合、OUTPUTパラメータを指定するフォームを使用します。

+2

これも機能しません。オブジェクトファイルはリンクされていないので、ldが他のライブラリをリンクするときに、.oファイルで宣言された変数は参照されず、失敗します。 –

関連する問題