2013-02-08 2 views
17

저는 C++로 Excel 파일 빌더를 작성하고 있습니다.cmake로 바이너리에서 오브젝트 파일을 컴파일하고 추가하십시오.

나는 필요한 모든 것을 가지고 있지만, 압축을 풀고, 반복하고, 최종 파일을 만드는 데 필요한만큼 데이터를 추가하는 외부 빈 xlsx 파일에 의존합니다. 내가 원하는 무엇

은과 같이 오브젝트 파일에 처음으로 돌려, 내 실행 파일의 .rodata 섹션에 이진 BLOB으로 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

두 번째 단계는 그것을 ld로 할 수있는 바이너리로 연결하는 것입니다.

내 질문은 내가 어떻게 cmake와 함께이 두 단계를 자동화합니까? 나는 LD 첫 번째 단계는 위처럼 특정 명령을 실행하는 방법 기압 아무 생각이 없다, 나는 두 번째 내 target_link_libraries에 파일/template.o을 추가하는 시도했지만, 단지

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

EDIT 말한다 신분증 :

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을 추가 :

나는 내 CMakeLists.txt에 다음 사용자 지정 명령을 추가했다.

불행하게도, cmake이 말한다 :

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

그것은 add_custom_command에서 출력 명령은 우리가 COMMAND 명령에 의해 생성되는 어떤 파일 CMake를 말할 수 있다는 나의 이해이다. 그래서 나는 지금 약간 혼란 스럽다.

편집 2 :

나는 내장있어 확인 템플릿 파일을 만들기 위해, 목표를 CMakeLists.txt 업데이트 및 추가 :

add_custom_target(run ALL 
    DEPENDS template.o) 

하고 이전에 지어진됩니다 있는지 확인하는 종속성 excelbuilder 대상 :

,691,363 :

add_dependencies(excelbuilder run) 

는 또한 다음과 같이 할 수있는 사용자 지정 명령을 업데이트 I이 실행하면210

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 
/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 생성 된 폴더에있다 (세부 = 1 확인)이다. 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

결국이 방법을 사용했습니다.

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를 알 수 있습니다. cmake가 우리가 필요 C-링커 것을 -suffix은 ".o 인"에서 알아낼 수 없기 때문에

SET_TARGET_PROPERTIES(
    template 
    PROPERTIES 
    LINKER_LANGUAGE C 
) 

또는 다른 우리는 오류 메시지가 표시됩니다.

단계에서 내 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 파일에 선언 된 변수는 참조되지 않고 실패합니다. –

관련 문제