2013-02-08 11 views
17

Piszę program do tworzenia plików Excel w C++.skompiluj i dodaj plik obiektowy z binarnego z cmake

Mam wszystko, co potrzebne do pracy, ale nadal polegam na zewnętrznym pustym pliku Xlsx, który rozpakowuję, iteruję i dodaje dane również w razie potrzeby do utworzenia ostatecznego pliku.

Co chcę zrobić, to usunąć tę zależność obracając plik XLSX do binarnego blob w .rodata części mojego pliku wykonywalnego, obracając go najpierw do pliku obiektowego tak:

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

Mam tę informację stąd: http://www.burtonini.com/blog/computers/ld-blobs-2007-07-13-15-50

Drugim krokiem jest połączenie go z plikiem binarnym, który mogę zrobić z Ld.

Moje pytanie brzmi: jak zautomatyzować te dwa kroki za pomocą cmake? Nie mam pojęcia atm jak uruchomić konkretne polecenia jak ld jednym powyżej w pierwszym etapie, a ja próbowałem dodawanie plików/template.o do moich target_link_libraries na sekundę, ale ld tylko mówi

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

EDIT:

dodałem następujące polecenie niestandardowe do mojego 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) 

i dodane pliki/template.o do add_executable rozmowy.

Niestety CUpewnij mówi tak:

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

To jest moje zrozumienie, że polecenie Wyjście W add_custom_command pozwala nam powiedzieć CMake co plik jest tworzony przez komendy polecenia. Teraz jestem trochę zdezorientowany.

EDIT 2:

zaktualizowałem CMakeLists.txt i dodał cel, aby upewnić się, że plik szablonu został zbudowany:

add_custom_target(run ALL 
    DEPENDS template.o) 

i zależność, aby upewnić się, że zostanie zbudowany przed cel excelbuilder:

add_dependencies(excelbuilder run) 

ja również zaktualizowane polecenia niestandardowego wyglądać następująco:

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) 

Kiedy uruchamiam to, wyjście jest następująco (marka 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 

ale template.o został poprawnie wygenerowany i znajduje się w folderze. Wygląda na to, że ld oczekuje biblioteki systemowej.

+0

Co próbowaliście? Sprawdź dokumentację, szczególnie add_custom_command i add_custom_target stąd http://www.cmake.org/cmake/help/v2.8.10/cmake.html#section_Commands –

+0

Tak, spróbowałem, ale muszę czegoś przegapić, ponieważ nie działa. Dodam to do pytania. –

+0

Nadal nie dostaję tego, co robisz. Masz plik template.cpp, który powinien najpierw zostać skompilowany, a następnie połączyć ten plik obiektowy z .xlsx? Mam rację? Błąd dość opisowy. Albo szablon.cpp nie jest skompilowany przed wywołaniem ld, albo wystarczy podać $ {CMAKE_BINARY_DIR} /files/template.o komendę ld. –

Odpowiedz

20

W końcu tak to zrobiłem.

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) 

W cd polecenia są tam dlatego ld ustawia nazwy automatycznie zadeklarowanych zmiennych do czegoś w zależności od pełnej ścieżki przekazywane do pliku wejściowego. Więc jeśli plik wejściowy był /home/user/project/files/template.xlsx, zmienna byłaby podobna do _binary_home_user_project_files_template_xlsx_start. Nie fajne w przenośnej kompilacji.

add_library(template 
     STATIC 
     template.o) 

mówi łącznikowi, aby skompilował plik obiektowy do pliku binarnego. Dodaje to również cel o nazwie template.

Następnie

SET_SOURCE_FILES_PROPERTIES(
    template.o 
    PROPERTIES 
    EXTERNAL_OBJECT true 
    GENERATED true 
) 

powiedzieć cmake nie skompilować plik, który jest generowany w czasie kompilacji.

SET_TARGET_PROPERTIES(
    template 
    PROPERTIES 
    LINKER_LANGUAGE C 
) 

Albo otrzymamy komunikat o błędzie, ponieważ cmake nie może dowiedzieć się od „.o” -suffix że jest to C-łącznik musimy.

, a następnie w kroku target_link_libraries po prostu dodałem template jako cel.

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

Rozważ użycie kwarka 'WORKING_DIRECTORY' do' add_custom_command' zamiast 'COMMAND cd ...'. – ulidtko

0

Aby powiązać plik obiektu z możliwym do edycji, dodaj go do listy plików źródłowych w add_executable() zamiast próbować dodać go do target_link_libraries().

Aby wygenerować plik obiektowy, zobacz add_custom_command(). W takim przypadku będziesz chciał użyć jego formularza, który określa parametr OUTPUT.

+2

To również nie działa. Plik obiektowy nie jest połączony, więc gdy ld wykonuje łączenie innych bibliotek, zmienne zadeklarowane w pliku .o nie są przywoływane i nie działają. –

Powiązane problemy