cmake
Niestandardowe kroki kompilacji
Szukaj…
Wprowadzenie
Niestandardowe kroki kompilacji są przydatne do uruchamiania niestandardowych celów w kompilacji projektu lub do łatwego kopiowania plików, dzięki czemu nie trzeba tego robić ręcznie (może dll?). Tutaj pokażę dwa przykłady, pierwszy z nich dotyczy kopiowania bibliotek DLL (w szczególności bibliotek Qt5) do katalogu binarnego projektów (Debugowanie lub wydanie), a drugi do uruchamiania niestandardowego obiektu docelowego (w tym przypadku Doxygen) w swoim rozwiązaniu (jeśli korzystasz z Visual Studio).
Uwagi
Jak widać, możesz wiele zrobić z niestandardowymi celami kompilacji i krokami w cmake, ale powinieneś być ostrożny z ich używaniem, szczególnie podczas kopiowania bibliotek dll. Chociaż jest to rozsądne, może to czasami prowadzić do czegoś, co nazywa się pieszczotliwie „dll hell”.
Zasadniczo oznacza to, że możesz się zgubić, w których bibliotekach DLL zależy Twój plik wykonywalny, które ładuje i które musi uruchomić (być może ze względu na zmienną ścieżki komputera).
Poza powyższym zastrzeżeniem, niestandardowe cele mogą robić, co chcesz! Są potężne i elastyczne i są nieocenionym narzędziem w każdym projekcie cmake.
Przykład kopiowania biblioteki dll Qt5
Powiedzmy, że masz projekt zależny od Qt5 i musisz skopiować odpowiednie biblioteki dll do katalogu kompilacji i nie chcesz tego robić ręcznie; możesz wykonać następujące czynności:
cmake_minimum_required(VERSION 3.0)
project(MyQtProj LANGUAGES C CXX)
find_package(Qt5 COMPONENTS Core Gui Widgets)
#...set up your project
# add the executable
add_executable(MyQtProj ${PROJ_SOURCES} ${PROJ_HEADERS})
add_custom_command(TARGET MyQtProj POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:MyQtProj>
)
Więc teraz za każdym razem, gdy budujesz projekt, jeśli docelowe biblioteki DLL zmieniły się, które chcesz skopiować, zostaną one skopiowane po zbudowaniu twojego celu (w tym przypadku głównego pliku wykonywalnego) (zwróć uwagę na polecenie copy_if_different
); w przeciwnym razie nie zostaną skopiowane.
Dodatkowo zwróć uwagę na użycie tutaj wyrażeń generatora . Zaletą korzystania z nich jest to, że nie musisz wyraźnie określać, gdzie skopiować dll lub jakich wariantów użyć. Aby móc z nich korzystać, projekt, którego używasz (w tym przypadku Qt5) musi mieć zaimportowane cele.
Jeśli budujesz w debugowaniu, CMake wie (na podstawie zaimportowanego obiektu docelowego), aby skopiować Qt5Cored.dll, Qt5Guid.dll i Qt5Widgetsd.dll do folderu debugowania w folderze kompilacji. Jeśli budujesz w wersji, wówczas wersje .dll zostaną skopiowane do folderu wydania.
Prowadzenie niestandardowego celu
Możesz także utworzyć niestandardowy cel do uruchomienia, gdy chcesz wykonać określone zadanie. Są to zazwyczaj pliki wykonywalne uruchamiane w celu wykonywania różnych czynności. Szczególnie przydatne może być uruchomienie Doxygen w celu wygenerowania dokumentacji dla twojego projektu. Aby to zrobić, można wykonać następujące czynności w CMakeLists.txt
(dla uproszczenia będziemy contiue nasz przykładowy projekt Qt5):
cmake_minimum_required(VERSION 3.0)
project(MyQtProj LANGUAGES C CXX)
find_package(Qt5 COMPONENTS Core Gui Widgets)
#...set up your project
add_executable(MyQtProj ${PROJ_SOURCES} ${PROJ_HEADERS})
add_custom_command(TARGET MyQtProj POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:MyQtProj>
)
#Add target to build documents from visual studio.
set(DOXYGEN_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile)
#set the output directory of the documentation
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs)
# sanity check...
message("Doxygen Output ${DOXYGEN_OUTPUT_DIR}")
find_package(Doxygen)
if(DOXYGEN_FOUND)
# create the output directory where the documentation will live
file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
# configure our Doxygen configuration file. This will be the input to the doxygen
# executable
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
# now add the custom target. This will create a build target called 'DOCUMENTATION'
# in your project
ADD_CUSTOM_TARGET(DOCUMENTATION
COMMAND ${CMAKE_COMMAND} -E echo_append "Building API Documentation..."
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOXYGEN_OUTPUT_DIR}
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E echo "Done."
WORKING_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
endif(DOXYGEN_FOUND)
Teraz, gdy tworzymy nasze rozwiązanie (ponownie zakładając, że korzystasz z Visual Studio), będziesz mieć cel kompilacji o nazwie DOCUMENTATION
, który możesz zbudować w celu zregenerowania dokumentacji projektu.