Compilation mit CMake
← Modulkonzept Beispiel | ● | Debugging →
CMake = cross-platform build tool
Automatisiert das Compilieren und Linken von C/C++ Modulen:
Einfaches Beispiel fĂĽr folgendes Haupt- und ein Neben-Modul:
main.cpp:
#include "square.h" /* local headers */
int main() /* main function */
{
double x=10; /* local initialized variable */
printf("square of %g is %g\n", x, square(x));
return(0); /* error code 0 means ok */
}
square.h (module header):
#define SQUARE_H
double square(double x); // function prototype
#endif /* end of guard */
square.cpp (module implementation):
double square(double x)
{return(x*x);} // function implementation
FĂĽr das obige Beispiel definieren wir nun ein CMake Projektdatei, welche CMake die Quelltextdateien mitteilt, welche zu einem Programm kompiliert und gelinkt werden sollen. Dazu mĂĽssen in der Datei CMakeLists.txt die CMake-Variablen HDRS und SRCS entsprechend definiert werden.
CMakeLists.txt:
PROJECT(MyProject) CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98") SET(HDRS square.h) # module headers go here (*.h) SET(SRCS main.cpp square.cpp) # module implementations go here (*.cpp) ADD_EXECUTABLE(main ${HDRS} ${SRCS}) # compile and link main executable
Wir starten CMake im Projektverzeichnis mit der Kommandozeile:
cmake .
Dies erzeugt aus der CMakeLists.txt Datei ein sogenanntes Makefile fĂĽr das Unix Make-Tool. Wenn wir nun das Make-Tool starten, so erzeugt dieses durch Aufruf der GCC Toolchain ein ausfĂĽhrbares Programm:
make
Beispielablauf anhand eines CMake Beispiels, das via SVN vom SVN Server “Schorsch” heruntergeladen wird:
Beispielablauf:
~/Desktop> svn co svn://schorsch.efi.fh-nuernberg.de/cmake.cpp A cmake.cpp/main.cpp A cmake.cpp/module.cpp A cmake.cpp/module.h A cmake.cpp/CMakeLists.txt Checked out revision 1. ~/Desktop> cd cmake.cpp/ ~/Desktop/cmake.cpp> cmake . -- The C compiler identification is GNU 4.2.1 -- The CXX compiler identification is GNU 4.2.1 -- Checking whether C compiler has -isysroot -- Checking whether C compiler has -isysroot - yes -- Checking whether C compiler supports OSX deployment target flag -- Checking whether C compiler supports OSX deployment target flag - yes -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Checking whether CXX compiler has -isysroot -- Checking whether CXX compiler has -isysroot - yes -- Checking whether CXX compiler supports OSX deployment target flag -- Checking whether CXX compiler supports OSX deployment target flag - yes -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /Users/roettger/Desktop/cmake.cpp ~/Desktop/cmake.cpp> make Scanning dependencies of target MyProject [ 50%] Building CXX object CMakeFiles/MyProject.dir/module.cpp.o Linking CXX static library libMyProject.a [ 50%] Built target MyProject Scanning dependencies of target main [100%] Building CXX object CMakeFiles/main.dir/main.cpp.o Linking CXX executable main [100%] Built target main
Die jeweiligen Kommandozeilen zum Aufruf der GCC Toolchain lassen sich mit folgendem Kommando mitverfolgen:
make VERBOSE=1
Beispielablauf:
~/Desktop/cmake.cpp> make VERBOSE=1 make -f CMakeFiles/Makefile2 all make -f CMakeFiles/MyProject.dir/build.make CMakeFiles/MyProject.dir/depend cd /Users/roettger/Desktop/cmake.cpp && /Users/roettger/bin/cmake -E cmake_depends "Unix Makefiles" /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp/CMakeFiles/MyProject.dir/DependInfo.cmake --color= make -f CMakeFiles/MyProject.dir/build.make CMakeFiles/MyProject.dir/build [ 50%] Building CXX object CMakeFiles/MyProject.dir/module.cpp.o /usr/bin/c++ -I/Users/roettger/Desktop/cmake.cpp -o CMakeFiles/MyProject.dir/module.cpp.o -c /Users/roettger/Desktop/cmake.cpp/module.cpp Linking CXX static library libMyProject.a /Users/roettger/bin/cmake -P CMakeFiles/MyProject.dir/cmake_clean_target.cmake /Users/roettger/bin/cmake -E cmake_link_script CMakeFiles/MyProject.dir/link.txt --verbose=1 /usr/bin/ar cr libMyProject.a CMakeFiles/MyProject.dir/module.cpp.o /usr/bin/ranlib libMyProject.a [ 50%] Built target MyProject make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/depend cd /Users/roettger/Desktop/cmake.cpp && /Users/roettger/bin/cmake -E cmake_depends "Unix Makefiles" /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp /Users/roettger/Desktop/cmake.cpp/CMakeFiles/main.dir/DependInfo.cmake --color= make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/build [100%] Building CXX object CMakeFiles/main.dir/main.cpp.o /usr/bin/c++ -I/Users/roettger/Desktop/cmake.cpp -o CMakeFiles/main.dir/main.cpp.o -c /Users/roettger/Desktop/cmake.cpp/main.cpp Linking CXX executable main /Users/roettger/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1 /usr/bin/c++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/main.dir/main.cpp.o -o main libMyProject.a [100%] Built target main
Zum AusfĂĽhren des erzeugten Programms geben wir nun ein:
./main
Oder alles noch einmal zusammen:
cmake . && make && ./main
Falls ein Modulquelltext verändert wurde, so kompiliert und linkt CMake/Make automatisch nur das veränderte Modul und ebenso alle Module, welche von diesem veränderten Module eventuell abhängen (sogenannte dependencies) neu:
make
Beispielablauf:
[ 50%] Built target MyProject [100%] Built target main
CMake kann aus der selben Projektdefinition auch Projekte für Visual C++ oder XCode erzeugen. Standardmässig erzeugt es aber Makefiles für Unix. Weil die Projektdefinition nicht von der jeweiligen Plattform abhängt, ist diese Art der Projektdefinition plattformunabhängig.
Siehe auch:
Tipp: KDevelop kann CMake Projekte importieren. D.h. Sie müssen auch mit CMake nicht auf den Komfort einer IDE verzichten, sind aber prinzipiell nicht auf einen bestimmte Plattform wie bei Visual-C/C++ beschränkt.
Noch ein Tipp: Um einen bestimmten Compiler-Standard, also z.B. den C++ Standard 2011 vorzugeben, fĂĽgen wir die folgende Zeile im CMakeLists.txt hinzu:
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Prinzipiell gibt es die Standards c++98, c++03, c++11, c++14, c++17, usw…
Empfohlen ist fĂĽr die elektronische Abgabe der c++98 Standard!
← Modulkonzept Beispiel | ● | Debugging →