Når jeg forsøgte at lære cmake, kunne jeg ikke finde nogen god introduktion. CMake-dokumentationen er ret omfattende, men ikke egnet til en nybegynder. Der er nogle nyttige tutorials, der er knyttet til CMake, men de fleste af dem dækker kun meget specifikke problemer eller er for grundlæggende. Så jeg skrev denne korte CMake-introduktion som en destilleret version af det, jeg fandt ud af efter at have arbejdet gennem dokumenterne og fulgt spørgsmål om stackoverstrøm.
det er et igangværende arbejde, og jeg vil forsøge at forbedre det løbende.
CMake er et meta build-værktøj, der giver dig mulighed for at generere native build-scripts til en række platforme:
- unik Makefiles
- Visual Studio
- CodeBlocks
- Eclipse
- og mere…
se den fulde liste over CMake-generatorer.
lad os antage, at vi har en simpel app med en enkelt .C-fil.
Vi ved at oprette enCMakeLists.txt
fil i roden af vores projekt.
cmake_minimum_required(VERSION 2.8)project(app_project)add_executable(myapp main.c)install(TARGETS myapp DESTINATION bin)
det er alt, hvad vi behøver for at kunne bygge vores app med nogen af de tilgængelige generatorer.
add_executable
definerer vores binære med alle linkede kildefiler.
install
fortæller cmake at installere vores binære ibin
mappen til installationsmappen.
bygning
CMake understøtter out-of-source builds — så al vores kompilerede kode går ind i en mappe, der er adskilt fra kilderne.
for at starte en build opretter vi en ny mappe:
mkdir _build
cd _build
og kalder cmake med stien til projektets rod (i dette tilfælde den overordnede mappe):
cmake ..
dette vil generere build scripts ved hjælp af standardgeneratoren.
som standard installerer cmake vores build i systemmapperne.
for at definere en brugerdefineret installationsmappe sender vi den simpelthen til cmake:
cmake .. -DCMAKE_INSTALL_PREFIX=../_install
for at køre build-scriptet kan du blot bruge Makefilen:
make
make install
Vi kan nu køre vores binære fra installationsmappen:
../_install/bin/myapp
Hvis vi ønskede at bruge en anden generator, sender vi den til cmake ved hjælp af -G
parameter:
cmake .. -GXcode
dette udsender et let konfigureret kodeprojekt til at opbygge vores app.
brug af CMake med biblioteker
for at opbygge et bibliotek bruger vi et lignende script:
cmake_minimum_required(VERSION 2.8)project(libtest_project)add_library(test STATIC test.c)install(TARGETS test DESTINATION lib)
install(FILES test.h DESTINATION include)
CMake bygger biblioteket somlibtest.a
og installerer det i lib-mappen i installationsmappen.
vi inkluderer også vores offentlige headerfil i installationstrinnet og fortæller cmake at sætte den i include
.
i stedet for et statisk bibliotek kan vi også opbygge en delt lib:
add_library(test SHARED test.c)
linkning af biblioteker til eksekverbare filer med CMake
Vi kan udvide vores eksekverbare ovenfra ved at linke den til vores libray libtest.a
.
lad os starte med at tilføje bibliotekets bibliotek som en undermappe til vores myapp-projekt.
nu kan vi bruge biblioteket defineret i CMakeLists.tekst af libtest_project i MyApps CMakeLists.TST:
cmake_minimum_required(VERSION 2.8)project(myapp)add_subdirectory(libtest_project)add_executable(myapp main.c)target_link_libraries(myapp test)install(TARGETS myapp DESTINATION bin)
add_subdirectory
gør biblioteket test
defineret i libtestproject tilgængeligt for build.
i target_link_libraries
vi fortæller CMake at linke det til vores eksekverbare. CMake sørger for først at bygge test, før du linker den til myapp.
inklusive eksterne biblioteker ved hjælp af andre build-systemer
mens CMake nyder stigende interesse, er der stadig masser af biblioteker, der bruger indbyggede build-systemer som f.eks. Du kan gøre brug af dem i dit CMake-projekt uden at skulle omskrive deres build-scripts.
alt, hvad vi har brug for, er CMake ‘ s support til eksterne projekter og importerede biblioteker:
ExternalProject_Add(project_luajit
URL http://luajit.org/download/LuaJIT-2.0.1.tar.gz
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/luajit-2.0.1
CONFIGURE_COMMAND ""
BUILD_COMMAND make
INSTALL_COMMAND make install
PREFIX=${CMAKE_CURRENT_BINARY_DIR}/luajit-2.0.1
)ExternalProject_Get_Property(project_luajit install_dir)add_library(luajit STATIC IMPORTED)set_property(TARGET luajit PROPERTY IMPORTED_LOCATION ${install_dir}/lib/libluajit-5.1.a)add_dependencies(luajit project_luajit)add_executable(myapp main.c)include_directories(${install_dir}/include/luajit-2.0)target_link_libraries(myapp luajit)
ExternalProject_Add
giver os mulighed for at tilføje et eksternt projekt som et mål for vores projekt. Hvis du ikke angiver kommandoer som BUILD_COMMAND
ellerINSTALL_COMMAND
, vil CMake søge efter etCMakeLists.txt
i det eksterne projekt og udføre det.
i vores tilfælde ønsker vi at gøre brug af luajit biblioteket, som er bygget ved hjælp af en Makefile.
add_library
understøtter også importen af allerede byggede biblioteker – vi skal bare indstille densIMPORTED_LOCATION
ejendom.
Calling ExternalProject_Add
angiver kun det eksterne projekt som et mål, men bygger det ikke automatisk. Det vil kun blive bygget, hvis vi tilføjer en afhængighed til det. Vi kalder derfor add_dependencies
for at gøre vores importerede bibliotek afhængigt af det eksterne projekt.
endelig kan vi linke vores importerede bibliotek ligesom et “normalt” bibliotek medtarget_link_libraries
.