skompiluj i dodaj plik obiektowy z binarnego za pomocą cmake

Piszę program Excel file builder w C++.

Mam wszystko, czego potrzebuję działa, ale nadal polegam na zewnętrznym pustym pliku xlsx, który rozpakowuję, iteruję i dodaję dane w razie potrzeby, aby utworzyć ostateczny plik.

Chcę usunąć tę zależność, zamieniając plik xlsx w binarny blob w .sekcja rodata mojego pliku wykonywalnego, zamieniając go najpierw w plik obiektowy jak tak:

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

I got this info from here : http://www.burtonini.com/blog/computers/ld-blobs-2007-07-13-15-50

Drugim krokiem jest połączenie go z binarnym, co mogę zrobić z ld.

Moje pytanie brzmi, jak zautomatyzować te dwa kroki za pomocą cmake? Nie mam pojęcia jak uruchomić konkretne polecenia takie jak wyżej ld w pierwszym kroku i próbowałem dodać pliki / szablon.o do mojego target_link_libraries na drugi, ale LD tylko mówi

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

EDIT:

Dodałem następujące polecenie niestandardowe do moich Cmakelistów.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 dodano pliki / szablon.o do wywołania add_executable.

Niestety, cmake mówi tak:

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

Rozumiem, że polecenie OUTPUT w poleceniu add_custom_command pozwala nam powiedzieć CMake jaki plik jest tworzony przez polecenia. Więc jestem trochę zdezorientowany.

EDIT 2:

Zaktualizowałem Cmakelisty.txt i dodano cel, aby upewnić się, że plik szablonu został zbudowany:

add_custom_target(run ALL
    DEPENDS template.o)

I zależność, aby na pewno zostanie zbudowany przed celem excelbuildera:

add_dependencies(excelbuilder run)

Zaktualizowałem również własne polecenie, aby wyglądało tak:

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ące (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

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

 18
Author: Tom Macdonald, 2013-02-08

2 answers

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)

Polecenia cd są tam, ponieważ ld ustawia nazwy automatycznie deklarowanych zmiennych na coś w zależności od pełnej ścieżki przekazywanej do pliku wejściowego. Więc jeśli plik wejściowy był / home / user / project/files / template.XLSX, zmienna byłaby czymś w rodzaju _binary_home_user_project_files_template_xlsx_start. Niefajne jak na przenośną kompilację.

add_library(template
        STATIC
        template.o)

Mówi linkerowi, aby skompilował plik obiektowy do pliku binarnego. To również dodaje cel o nazwie template.

Then

SET_SOURCE_FILES_PROPERTIES(
  template.o
  PROPERTIES
  EXTERNAL_OBJECT true
  GENERATED true
  )

Aby powiedzieć cmake, aby nie kompilował pliku, który jest generowany w czasie kompilacji.

SET_TARGET_PROPERTIES(
  template
  PROPERTIES
  LINKER_LANGUAGE C 
  )

Albo otrzymujemy komunikat o błędzie, ponieważ cmake nie może dowiedzieć się z ".o " - przyrostek, że jest to łącznik C, którego potrzebujemy.

A potem w moim 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
            )
 22
Author: Tom Macdonald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 11:30:15

Aby połączyć plik obiektowy z wykonywalnym, 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 formy, która określa parametr OUTPUT.

 0
Author: Angew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-09 12:42:54