Ero sivun ”CMake syvemmin” versioiden välillä
Siirry navigaatioon
Siirry hakuun
ei muokkausyhteenvetoa
Ei muokkausyhteenvetoa |
Ei muokkausyhteenvetoa |
||
Rivi 200: | Rivi 200: | ||
Vielä emme siis ole päässeet nauttimaan cmake:n erityisen hienoista ominaisuuksista, mutta ensimmäisen C/C++-ohjelman onnistuimme kuitenkin kääntää ajettavaksi ohjelmaksi. | 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 == | == Cmake-ohjelman mallien käyttäminen == | ||
C++/C-ohjelmalle mallin luominen cmake:n ja CMakeLists.txt:n avulla. Ensimmäisessä esimerkissämme tulostimme message-käskyllä projektin tiedot tulostusjonoon. Nyt lisäämme kyseiset tiedot ohjelmamme lähdekoodeihin, jotka sitten tulostamme ajettavassa ohjelmassa. | |||
Luomme projektimme juureen cmakemallit-kansion, johon kirjoitamme cmake-kielellä pohjan käännettäävää ohjelmaa varten. Annamme tiedostonnimeksi asetukset.cmake. | |||
Luo projektikansiomme juureen cmake-kansio, johon luo config.h.cmake-tiedosto. Siihen kirjoita seuraava sisältö: | |||
<syntaxhighlight lang=CMake line > | |||
#ifndef CONFIG_H | |||
#define CONFIG_H | |||
#define PROJECT "@PROJECT_NAME@" | |||
#define PROJECT_VERSION "@PROJECT_VERSION@" | |||
#define PROJECT_VERSION_MAJOR "@PROJECT_VERSION_MAJOR@" | |||
#define PROJECT_VERSION_MINOR "@PROJECT_VERSION_MINOR@" | |||
#define PROJECT_VERSION_PATCH "@PROJECT_VERSION_PATCH@" | |||
#define PROJECT_VERSION_TWEAK "@PROJECT_VERSION_TWEAK@" | |||
#define PROJECT_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@" | |||
#define PROJECT_DESCRIPTION "@PROJECT_DESCRIPTION@" | |||
#endif | |||
</syntaxhighlight> | |||
Malli on siis lähes samanlainen kuin puhdaskin C-otsaketiedosto. ”@...@”-välissä määritellyn cmake-muuttujan cmake muuttaa saman muuttujan arvoksi ennen C-kielisen ohjelman kääntämistä. Nämä ovat siis samat arvot kuin CMakeLists.txt-tiedoston message-käskyllä annetuissa muuttujissa. | |||
Tosin CMakeLists.txt-tiedostoon pitää lisätä käsky, jotta cmake osaa kirjoittaa header-tiedoston oikealla nimellä oikeaan paikkaan. Käsky, joka pitää lisätä on configure_file, ja tarkemmin: | |||
<syntaxhighlight lang=Cmake line start=21> | |||
configure_file(${CMAKE_SOURCE_DIR}/cmake/config.h.cmake ${CMAKE_SOURCE_DIR}/src/config.h) | |||
</syntaxhighlight> | |||
se pidän loogisena, että sen paikka on ennen add_executable-käskyä, mutta se saattaa toimia myös sen jälkeen. Tämän muutoksen jälkeen CMakeLists.txt-tiedosto on kokonaisuudessaan seuraavan lainen … | |||
<syntaxhighlight lang=cmake line > | |||
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}.") | |||
configure_file(${CMAKE_SOURCE_DIR}/cmake/config.h.cmake ${CMAKE_SOURCE_DIR}/src/config.h) | |||
add_executable("hello" "src/hello.cpp") | |||
</syntaxhighlight> | |||
Elikkä configure_file-käskyllä lisätään config.h.cmake-tiedoston ohjeiden mukaisesti projektin tiedot C-ystävälliseen muotoon #define-käskyjen muodossa. ${CMAKE_SOURCE_DIR} on lähdekoodin polku, /cmake/config.h.cmake-on lähdekoodipolussa olevan tiedoston nimi. /src/config.h on lähdekoodin (koko)polku, jonne asetustiedosto (config.h) lisätään. | |||
Tämän jälkeen voit testata onnistuuko kääntäminen. | |||
<syntaxhighlight lang=bash line > | |||
d .. | |||
mkdir build | |||
cd build | |||
rm -r * | |||
cmake .. | |||
make all | |||
</syntaxhighlight> | |||
Kääntämisen jälkeen ./hello-ohjelman pitäisi toimia samalla tavalla kuin ennen, mutta jos huomaat, niin projektin src-hakemistoon ilmestyi uusi config.h-tiedosto. Jotta saisimme konkreettista hyötyä mallitiedostosta, niin sen generoima otsaketiedosto kannattaa lisätä hello.cpp ohjelmaan #include-käskyllä: #include ”config.h”. Tämän jälkeen hello.cpp-tiedostomme on siis seuraavan mukainen… | |||
<syntaxhighlight lang=C++ line > | |||
#include <iostream> | |||
#include "config.h" | |||
int main(int args,char **argv) { | |||
std::cout << "ohjelman ajotiedoston nimi hakemistopolkuineen on " << argv[0] << "\n"; | |||
std::cout << PROJECT; | |||
std::cout << "\n" << PROJECT_VERSION ; | |||
std::cout << "\n" << PROJECT_VERSION_MAJOR ; | |||
std::cout << "\n" << PROJECT_VERSION_MINOR; | |||
std::cout << "\n" << PROJECT_VERSION_PATCH; | |||
std::cout << "\n" << PROJECT_VERSION_TWEAK; | |||
std::cout << "\n" << PROJECT_HOMEPAGE_URL; | |||
std::cout << "\n" << PROJECT_DESCRIPTION; | |||
std::cout << "\n"; | |||
return 0 | |||
} | |||
</syntaxhighlight> | |||
Tiedosto puu (ilman build-kansiota) on seuraavannäköinen… | |||
<syntaxhighlight lang=bash > | |||
$ tree cmakeprojekti | |||
cmakeprojekti | |||
├── cmake | |||
│ └── config.h.cmake | |||
├── CMakeLists.txt | |||
└── src | |||
├── config.h | |||
└── hello.cpp | |||
3 directories, 4 files | |||
</syntaxhighlight> | |||
Tämän jälkeen voitkin koeajaa ohjelman: | |||
<syntaxhighlight lang=bash line > | |||
cd .. | |||
rm -r build | |||
mkdir build | |||
cd build | |||
cmake .. | |||
make all | |||
./hello | |||
</syntaxhighlight> | |||
./hello:n pitäisi tulostaa seuraavaa… | |||
<syntaxhighlight lang=bash> | |||
eka-projekti | |||
0 | |||
1 | |||
0 | |||
2 | |||
https://linux.fi | |||
Ensimmäinen cmake-projektini | |||
</syntaxhighlight> | |||
== Oman kirjaston lisääminen (.h) == | |||
Cmake:lla voi määritellä ja kääntää omia kirjastoja joko lähdeohjelmien kanssa tai pelkän käännöksen ja otsaketiedostojen (.h) avulla. Lisäämme itse tekemämme kirjaston, joka palauttaa liukulukujen välisen kertolaskun tuloksen palautteena. | |||
Siispä lisäämme lib-hakemiston kirjaston lähdekoodia varten ja include-hakemiston otsaketiedostoja varten. Päätteellä se tapahtuu seuraavalla tavalla, mikäli olet päätteellä projektin build-hakemistossa. | |||
<syntaxhighlight lang=bash line> | |||
mkdir ../lib;touch ../lib/mylib.cpp | |||
mkdir ../include;touch ../include/mylib.h | |||
</syntaxhighlight> | |||
Tämän jälkeen projektin hakemistopuu näyttää tältä: | |||
<syntaxhighlight lang=bash> | |||
cmakeprojekti | |||
├── build | |||
├── cmake | |||
│ └── config.h.cmake | |||
├── CMakeLists.txt | |||
├── include | |||
│ └── mylib.h | |||
├── lib | |||
│ └── mylib.cpp | |||
└── src | |||
├── config.h | |||
└── hello.cpp | |||
</syntaxhighlight> | |||
Kirjoita mylib.h-tiedostoon seuraavanlainen otsaketiedosto: | |||
<syntaxhighlight lang=C line > | |||
#ifndef MYLIB_H | |||
#define MYLIB_H | |||
double multiply(double v1,double v2); | |||
#endif | |||
</syntaxhighlight> | |||
Vastaavasti kirjoita mylib.cpp-tiedostoon seuraavanlainen ohjelmasisältö: | |||
<syntaxhighlight lang=C line > | |||
#include "mylib.h" | |||
double multiply(double v1,double v2) { | |||
// multiply-funktion toteutus. | |||
// Palauttaa v1:n ja v2:n välisen kertolaskun tuloksen. | |||
return v1*v2; | |||
} | |||
</syntaxhighlight> | |||
Jotta voimme testata ohjelman toimintaa, niin meidän pitää tehdä muutoksia (hello.cpp) pääohjelmaamme. Lisäämme #include <mylib.h> ja rivit ohjelman testaamista varten. | |||
Muutosten jälkeen hello.cpp-näyttää tällaiselta: | |||
<syntaxhighlight lang=C++ line > | |||
#include <iostream> | |||
#include "config.h" | |||
#include <mylib.h> | |||
int main(int args,char **argv) { | |||
std::cout << "ohjelman ajotiedoston nimi hakemistopolkuineen on " << argv[0] << "\n"; | |||
std::cout << PROJECT; | |||
std::cout << "\n" << PROJECT_VERSION ; | |||
std::cout << "\n" << PROJECT_VERSION_MAJOR ; | |||
std::cout << "\n" << PROJECT_VERSION_MINOR; | |||
std::cout << "\n" << PROJECT_VERSION_PATCH; | |||
std::cout << "\n" << PROJECT_VERSION_TWEAK; | |||
std::cout << "\n" << PROJECT_HOMEPAGE_URL; | |||
std::cout << "\n" << PROJECT_DESCRIPTION; | |||
std::cout << "\n" << multiply(3,5); | |||
if(args>2) { | |||
std::cout << "\n" << multiply(atof(argv[1]) ,atof(argv[2])); | |||
} | |||
std::cout << "\n"; | |||
} | |||
</syntaxhighlight> | |||
Huomioi uudet rivit: 3,15-18 ! | |||
Edelliseen verrattuna ohjelmaan on tullut uusi #include-rivi #include-rivien viimeiseksi, jossa otetaan käyttöön oma tekemä mylib-kirjasto. Sen lisäksi mylib-kirjastossa olevaa multiply-funktiota testataan vakioilla, ja jos ohjelmalle syötetään parametreja kaksi tai enemmän, niin ohjelma yrittää muuttaa niistä kahta ensimmäista numeroksi ja kertoa ne keskenään. Muutokset ovat korostettu keltaisella taustavärillä. | |||
Tämän osion lopuksi teemme tarvittavat muutokset CMakeLists.txt-tiedostoon, tiedostoon lisätään seuraavat rivit configure_file-käskyn jälkeen: | |||
<syntaxhighlight lang=Cmake line start=22 > | |||
add_library(mylib lib/mylib.cpp) | |||
target_include_directories(mylib PUBLIC include) | |||
</syntaxhighlight> | |||
add_library-käskyllä lisätään projektiin mylib.cpp-kirjasto käännettäväksi, ja target_include_directories-käskyllä laitetaan include-hakemisto näkyväksi C/C++-kääntäjälle, josta kääntäjä osaa hakea (.h) header-tiedostot. | |||
CMakeLists.txt-tiedoston loppuun lisätään vielä rivi, jolla kirjasto linkitetään projektin hello.cpp-ohjelmaan. | |||
<syntaxhighlight lang=CMake line Start=28> | |||
target_link_libraries(hello mylib ) | |||
</syntaxhighlight> | |||
Tämän jälkeen CMakeLists.txt-tiedoston pitäisi näyttää tältä: | |||
<syntaxhighlight lang=CMake line > | |||
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}.") | |||
configure_file(${CMAKE_SOURCE_DIR}/cmake/config.h.cmake ${CMAKE_SOURCE_DIR}/src/config.h) | |||
add_library(mylib lib/mylib.cpp) | |||
target_include_directories(mylib PUBLIC include) | |||
add_executable("hello" "src/hello.cpp") | |||
target_link_libraries(hello mylib ) | |||
</syntaxhighlight> | |||
== Oman hello-ohjelman uusien ominaisuuksien kokeilu == | |||
Ensin käännetään ohjelma: | |||
Mene päätteellä projektin juureen, ja suorita alla olevat käskyt. (Sinun tulee tietää, mitä käskyt tekevät, koska väärässä kansiossa annettuna nämä käskyt saattavat tehdä arvaamatonta tuhoa): | |||
<syntaxhighlight lang=bash line > | |||
mkdir build | |||
cd build | |||
rm -r * | |||
cmake .. | |||
make all | |||
</syntaxhighlight> | |||
Suoritusten jälkeen sinulla pitäisi olla valmiiksi käännettynä hello-ohjelma, jota voit testata esimerkiksi seuraavalla tavalla: | |||
<syntaxhighlight lang=bash > | |||
./hello | |||
./hello 5 9 | |||
</syntaxhighlight> | |||
Ohjelma tulostaneen seuraavan kaltaista: | |||
<syntaxhighlight lang=bash > | |||
ohjelman ajotiedoston nimi hakemistopolkuineen on ./hello | |||
eka-projekti | |||
0.1.0.2 | |||
0 | |||
1 | |||
0 | |||
2 | |||
https://linux.fi | |||
Ensimmainen cmake-projektini | |||
15 | |||
ohjelman ajotiedoston nimi hakemistopolkuineen on ./hello | |||
eka-projekti | |||
0.1.0.2 | |||
0 | |||
1 | |||
0 | |||
2 | |||
https://linux.fi | |||
Ensimmainen cmake-projektini | |||
15 | |||
45 | |||
</syntaxhighlight> | |||
Tällä hetkellä puun pitäisi näyttää tältä: | |||
<syntaxhighlight lang=bash > | |||
cmakeprojekti | |||
├── cmake | |||
│ └── config.h.cmake | |||
├── CMakeLists.txt | |||
├── include | |||
│ └── mylib.h | |||
├── lib | |||
│ └── mylib.cpp | |||
└── src | |||
├── config.h | |||
└── hello.cpp | |||
</syntaxhighlight> | |||
==Käyttö== | ==Käyttö== | ||
==Katso myös== | ==Katso myös== |