CMake syvemmin

Linux.fista
Versio hetkellä 10. joulukuuta 2024 kello 11.59 – tehnyt Peran (keskustelu | muokkaukset)
Siirry navigaatioon Siirry hakuun
CMake
Käyttöliittymä teksti
Lisenssi cmake
Kotisivu cmake.org

CMaken käytön kuvaus

CMake on työkalu, jolla voidaan tehdä Makefilejä tai valmiita ohjelmistopaketteja. Se on siis Make-käskyä nähden pykälän verran abstraktimpi taso ylöspäin. Cmake:lla voidaan mm. tehdä deb- ja rpm-paketteja cpack-apuohjelman avulla. Lisäksi sen avulla voidaan hallita C/C++ kirjastoja joko valmiiksi käännettyjä moduleita tai luoda omia dynaamisia moduleita.

CMakeLists.txt on tiedosto, jonka perusteella cmake prosessoi ohjelmaprojektin. Ohjelmaprojekti voi olla esimerkiksi:testaus, ohjelman kääntäminen tai ohjelmapaketin luominen. CMakeLists.txt-tiedosto on siis yksi abstraktiotaso Makefile:stä abstraktimpaanpäin. CMakeLists.txt-tiedostot ovat käteviä erityisesti ohjelmoijille, jotka voivat niiden avulla automatisoida projektin Makefilejen ja ohjelmapakettien avulla.

CMakeLists.txt-tiedostossa voi olla monia käskyjä seka erittäin suuri määrä muuttuja-arvoja ja niitä voi itse lisätä. Tärkeimpiä käskyjä ovat esimerkiksi: cmake_minimum_required, project,set, install, include, if/else/elseif/endif, add_subdirectory, add_library, add_executable, target_link_libraries, configure_file, message, foreach, while/endwhile, function.

Kuten käskyistäkin voi päätellä, niin cmake on ohjelmointikieli. Koska siinä pystytään asettamaan muuttujia ja ehdollisia silmukoita, se täyttää kirkkaasti turingkoneen määritelmän. Tämä ohjelmointikieli on erikoistunut ohjelmien käännösten ja pakettien hallintaan. Kieli on case insensitive eli isolla ja pienellä kirjaimella ei ole eroa ohjelman prosessoinnissa. Varatut sanat saa selville käskyillä: cmake --help-command-list, cmake --help-variable-list ja cmake --help-property-list. Jos ajat käskyt, niin huomaat, että varattuja sanoja on todella monta. Esimerksiksi 3.28.3 versiossa on 1389-varattua sanaa. Onneksi kourallisella käskykannalla pääsee hyvin alkuun.

Cmake:n kotisivu on https://cmake.org/, josta löytyvät myös cmake-dokumentaatio. Cmake:n avulla käytetään myös erilaisia testaus-/paketoimis-ja käännösjärjestelmiä, kuten ctest, cpack, make, ninja jne. (joita muita kuin ctest:iä käytetään tässä esittelyssä).

Ensimmäinen cmake-projekti

make:n avulla pienen projektin kääntäminen: Luo kansio cmakeprojekti, ja sinne tiedosto: CMakeLists.txt Esim. päätteellä:

mkdir cmakeprojekti
cd cmakeprojekti
touch CMakeLists.txt

Kirjoita tiedostoon seuraavat rivit:

cmake_minimum_required(VERSION 3.21)
 
project(
    "eka-projekti"
    VERSION 0.1.0.2
    DESCRIPTION "Ensimmainen cmake-projektini"
    HOMEPAGE_URL "https://linux.fi"
    LANGUAGES "C" "CXX"
)
 
message("${PROJECT_NAME} on ensimmäinen projektimme, ja tässä on sen tiedot:")
message("Projektin versio on ${PROJECT_VERSION}")
message("Se koostuu neljästä osasta:")
message(${PROJECT_VERSION_MAJOR})
message(${PROJECT_VERSION_MINOR})
message(${PROJECT_VERSION_PATCH})
message(${PROJECT_VERSION_TWEAK})
message("Projektimme kuvaus on:${PROJECT_DESCRIPTION}")
message("Kotisivuksi olemme määritelleet tutun ${PROJECT_HOMEPAGE_URL}.")

Ensimmäinen rivi määrittelee, mikä cmake:n versio vähintään vaaditaan CMakeLists.txt:n suoritukseen. Project-käskyllä määritellään projektin nimi, versio, kuvaus,kotisivu ja ohjelmointikielet. Message-käskyllä tulostetaan käännösjonoon tekstiä. Tämän avulla voimme siis tulostaa projektimme tiedot. Rivillä 11 tulostamme käännösjonoon projektimme nimen, joka on nimeltään ”eka-projekti”. Projektin nimessä tulee olla vähintään yksi miinus (’-’)merkki. Seuraavasssa rivissä tulostamme projektin täyden version, joka siis on 0.1.0.2, kuten olimme project-käskyssä sen määritelleet. Seuraavat kolme message-käskyä kirjoittaa parsitun (järjestyksessä: MAJOR.MINOR.PATCH.TWEAK)versionumeron. Niiden jälkeen kirjoitetaan projektin kuvaus (PROJECT_DESCRIPTION). Viimeisessä message-rivissä tulostuu projektin kotisivu (PROJECT_HOMEPAGE_URL).

Nyt voimme ”kääntää” projektimme, joten luomme projektin juureen kansion build, ja ajamme cmake-ohjelman sieltä osoitettuna alempaan kansioon. (HUOM: ainakin cmake-paketti pitää olla asennettuna ennen ohjelman onnistunutta ajoa.)

mkdir build
cd build
cmake ..
make all

Ohjelman pitäisi tulostaa seuraavaa…

eka-projekti on ensimmäinen projektimme, ja tässä on sen tiedot:
Projektin versio on 0.1.0.2
Se koostuu neljästä osasta:
0
1
0
2
Projektimme kuvaus on:Ensimmainen cmake-projektini
Kotisivuksi olemme määritelleet tutun https://linux.fi.
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/.../cmakeprojekti/build

Huomioitavaa on, ettei make all-käsky kirjoita mitään, eikä se luo ajettavia tiedostoja. Toisaalta cmake-ohjelma ei myöskään anna mitään virheilmoituksia, niin siksi voimme määritellä tämän testin onnistuneeksi. Lisäksi on huomoitavaa, että muuttujien nimet (VERSION, DESCRIPTION, HOMEPAGE_URL ja LANGUAGES) on kirjoitettava suurilla kirjaimilla, jotta ne toimivat.

Ensimmäinen C/C++ ohjelma

Seuraavaksi voimmekin tehdä ensimmäisen käännettävän C/C++-ohjelman. Se kirjoitetaan oikeaoppisesti src-alikansioon, joten teemme sille projektikansiomme juureen uuden kansion. Päätteellä voisi kirjoittaa seuraavaa:

cd ..
mkdir src
touch src/hello.cpp

Ensimmäisessä rivissä siirrymme build-kansiosta projektin juurikansioon. Luomme sen alle src-kansion, jossa on hyvä pitää projektimme C/C++-lähdetiedostoja.

Kirjoita äsken src-hakemistoon luotuun hello.cpp-ohjelmaan seuraavan (Esimerkin) sisältö, ja tallenna se.

#include <iostream>
int main(int args,char **argv) {
    std::cout << "ohjelman ajotiedoston nimi hakemistopolkuineen on " << argv[0] << "\n";
    return 0;
}

Ohjelman voi kääntää käskyllä build-kansiostamme:

cd build
g++ ../src/hello.cpp -o hello

Ohjelman ajaminen tapahtuu seuraavasti:

 ./hello

Seuraavaksi menemme takaisin build-kansioon, ja poistamme cmake:n tekemät tiedostot rm -r -käskyllä (varovasti rm -r käskyn kanssa, sillä se voi tuhota pahimmassa tapauksessa koko käyttäjän kotikansion, ja root-käyttäjänä se voi tuhota koko järjestelmän.).

d ..
rm -r build
mkdir build
cd build
cmake ..
make all

Huomaa, että edelleenkin ohjelmat (cmake ja make) suoriutuvat toimistaan ilman virheilmoituksia, mutta edelleenkään tuotoksena ei tule käänettyä ohjelmaa.

Ajamisen jälkeen huomaamme, ettei cmake-käännä ohjelmaa, vaan se toimii edelleen samalla tavalla kuin aiemminkin eli tulostaa eka-projekti:n tiedot. Jotta saadaksemme cmake:n kääntämään ohjelman pitää meidän tehdä pieniä muutoksia. Lisäämme seuraavanlaisen rivin aikaisemmin luomamme CMakeLists.txt-tiedoston loppuun:

add_executable("hello" "src/hello.cpp")

Lisäyksen jälkeen CMakeLists.txt-tiedoston pitäisi näyttää tältä:

cmake_minimum_required(VERSION 3.21)

project(
    "eka-projekti"
    VERSION 0.1.0.2
    DESCRIPTION "Ensimmainen cmake-projektini"
    HOMEPAGE_URL "https://linux.fi"
    LANGUAGES "C" "CXX"
)

message("${PROJECT_NAME} on ensimmäinen projektimme, ja tässä on sen tiedot:")
message("Projektin versio on ${PROJECT_VERSION}")
message("Se koostuu neljästä osasta:")
message(${PROJECT_VERSION_MAJOR})
message(${PROJECT_VERSION_MINOR})
message(${PROJECT_VERSION_PATCH})
message(${PROJECT_VERSION_TWEAK})
message("Projektimme kuvaus on:${PROJECT_DESCRIPTION}")
message("Kotisivuksi olemme määritelleet tutun ${PROJECT_HOMEPAGE_URL}.")

add_executable("hello" "src/hello.cpp")

Nyt voimmekin ajaa cmake ja make all -ohjelmat build-hakemistostamme eli päätteessä (varmuuden vuoksi tässä poistetaan aiemmin luotu build-kansion sisältö. Todennäköisesti mkdir build antaa virheilmoituksen, kun kyseinen hakemisto on jo olemassa):

cd ..
mkdir build
cd build
rm -r *
cmake ..
make all

Komentosarjan pitäisi olla vastaavaa kuin tämä:

-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
eka-projekti on ensimmäinen projektimme, ja tässä on sen tiedot:
Projektin versio on 0.1.0.2
Se koostuu neljästä osasta:
0
1
0
2
Projektimme kuvaus on:Ensimmainen cmake-projektini
Kotisivuksi olemme määritelleet tutun https://linux.fi.
-- Configuring done (0.6s)
-- Generating done (0.0s)
-- Build files have been written to: /home/.../cmakeprojekti/build

Sitten cmake-ohjelman ajamisen jälkeen ajamme make-ohjelman (make all).

make all
[ 50%] Building CXX object CMakeFiles/hello.dir/src/hello.cpp.o
[100%] Linking CXX executable hello
[100%] Built target hello

Nyt ohjelma on käännetty, ja sen pitäisi tulostaa seuraavaa, kun ohjelman ajaa...

./hello
ohjelman ajotiedoston nimi hakemistopolkuineen on ./hello

Vielä emme siis ole päässeet nauttimaan cmake:n erityisen hienoista ominaisuuksista, mutta ensimmäisen C/C++-ohjelman onnistuimme kuitenkin kääntää ajettavaksi ohjelmaksi.

Cmake-ohjelman mallien käyttäminen

Käyttö

Yleensä projekti käännetään ajamalla sen lähdekoodihakemistossa komento

cmake .

Käännösprosessia voi ohjata määrittelemällä -D-valitsimella käännöstä ohjaavia muuttujia:

cmake -D<muuttuja>=arvo

Esimerkiksi g++:n käännösvalitsimiin voi vaikuttaa muuttujalla CMAKE_CXX_FLAGS:

cmake -DCMAKE_CXX_FLAGS="-g -O2" .

Tämän jälkeen CMake yleensä luo Makefilen, jonka avulla ohjelma voidaan asentaa tyypillisesti komennolla

make all install

Katso myös