CMake tutorial - 2

Jean-Charles Lambert CMAKE CMAKE Tutos Jean-Charles Lambert CMAKE ● Description ● Simple example ● Advanced example ● Exercises Outline Online tutoria...

7 downloads 231 Views 168KB Size

CMAKE

CMAKE Tutos

Jean-Charles Lambert

CMAKE

Outline ● ● ● ●

Description Simple example Advanced example Exercises

Online tutorial : http://goo.gl/8jh3JS

Jean-Charles Lambert

CMAKE

Description : what is it ? -

-

A cross platform Makefile generator -

To compile source code

-

To create libraries (shared or static)

-

To build executables

-

To create bundle and installation process

Generate building process for compiled languages -

C/C++/Fortran

-

Based on a single script (CMakeLists.txt) for specifying rules

-

Can target differents platforms (Linux, MacOS, Windows)

-

Popularity (Netflix, MysQL, HDF group, KDE, Glnemo2, Unsio :) )

Jean-Charles Lambert

CMAKE

Description : concept My awesome project

src/main1.cc src/main2.cc lib1/src/file1..5.{cc/h} lib2/src/file1..10.f90 dir1/lib2/src/f1….100.{cc/h} dir2/lib3/src/f1….20.{cc/h} CMakeLists.txt

Jean-Charles Lambert

CMAKE

Description : concept My awesome project

Edit file (plain text file) CMakeLists.txt (compilation rules)

src/main1.cc src/main2.cc lib1/src/file1..5.{cc/h} lib2/src/file1..10.f90 dir1/lib2/src/f1….100.{cc/h} dir2/lib3/src/f1….20.{cc/h} CMakeLists.txt

Jean-Charles Lambert

CMAKE

Description : concept My awesome project

Edit file (plain text file) CMakeLists.txt (compilation rules)

src/main1.cc src/main2.cc lib1/src/file1..5.{cc/h} lib2/src/file1..10.f90 dir1/lib2/src/f1….100.{cc/h} dir2/lib3/src/f1….20.{cc/h} CMakeLists.txt

Building (from a terminal) mkdir build cd build

cmake .. make make install

Jean-Charles Lambert

CMAKE

Description : concept Building (from a terminal) mkdir build cd build

cmake .. make make install

Cmake command generates : ● ● ● ● ● ●

Native build systems Intermediate files Object files Build ouput Libraries Binaries

Build directory can be removed

Jean-Charles Lambert

CMAKE

Description : installation -

Linux : use your paquet manager -

-

urpmi cmake apt-get install cmake zypper install cmake yum install cmake dnf install cmake ….

MacOs : port, brew whatever… Or download and compile it ! https://cmake.org/

Jean-Charles Lambert

CMAKE

Simple example hello.cc

CMakeLists.txt #Specify the version being used as well as the language cmake_minimum_required(VERSION 2.6)

#include int main(void) { std::cerr << "Hello World\n”; return(0); }

#Name your project here project(hello) #Add “-g -O2” options to the gcc compiler add_definitions(-g -O2) # specify executable name and dependencies add_executable(hello hello.cc)

Jean-Charles Lambert

CMAKE

Simple example cmake ..

mkdir build cd build

cmake .. make

We create build directory to Isolate compilations files from sources files

-- The C compiler identification is GNU 4.9.2 -- The CXX compiler identification is GNU 4.9.2 -- 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 -- 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: /home/jcl/works/GIT/cmake-tutos/ex01/build

make Scanning dependencies of target hello [100%] Building CXX object CMakeFiles/hello.dir/hello.cc.o Linking CXX executable hello [100%] Built target hello

Jean-Charles Lambert

CMAKE

Advanced example : goal ● ● ●

Create a project with several files How to compile a library How to specify an installation directory

Jean-Charles Lambert

CMAKE

Advanced example : description Hello project

src/hello.cc lib01/CMakeLists.txt lib01/src/chello.cc lib01/src/insane.c lib01/include/chello.h

src/ : directory to store mains programs lib01/src/: directory to store sources lib files lib01/include/: directory to store includes lib files

cmake/SetupInstallLib.cmake CMakeLists.txt

Jean-Charles Lambert

cmake/: directory to store cmake modules

CMAKE

Advanced example : source files src/hello.cc #include #include int main(void) { CHello hello("hello world"); hello.display(); hello.crazy(); }

lib01/src/chello.cc #include #include extern "C" { int insane(int,int,char*); } class CHello { public: CHello(const std::string myhello):mystring(myhello) { } void display(); void crazy(); private: std::string mystring; };

lib01/include/chello.h

Jean-Charles Lambert

#ifndef CHELLO_H #define CHELLO_H #include void CHello::display() { std::cerr << mystring << "\n"; } void CHello::crazy() { insane(1,1,(char *) ""); } #endif //CHELLO_H

lib01/src/insane.c #include int insane(int t,int _, char * a) { return!0
CMAKE

Advanced example : running cmake mkdir build cd build

cmake .. make

PROCESS: New executable hello detected from top level src directory

Jean-Charles Lambert

cmake .. -- The C compiler identification is GNU 4.9.2 -- The CXX compiler identification is GNU 4.9.2 -- 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 -- 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 -- New executable ==> hello -- Configuring done -- Generating done -- Build files have been written to: /home/jcl/works/GIT/cmake-tutos/ex02/build

CMAKE

Advanced example : running make make

mkdir build cd build cmake ..

make

PROCESS: Compilation of shared library libMYlib.so Compilation of executable hello

Jean-Charles Lambert

Scanning dependencies of target MYlib [ 33%] Building CXX object lib01/CMakeFiles/MYlib.dir/src/chello.cc.o [ 66%] Building C object lib01/CMakeFiles/MYlib.dir/src/insane.c.o Linking CXX shared library ../lib/libMYlib.so [ 66%] Built target MYlib Scanning dependencies of target hello [100%] Building CXX object CMakeFiles/hello.dir/src/hello.cc.o Linking CXX executable hello [100%] Built target hello

CMAKE

Advanced example : anatomy Hello project

src/hello.cc lib01/CMakeLists.txt lib01/src/chello.cc lib01/src/insane.c lib01/include/chello.h cmake/SetupInstallLib.cmake

CMakeLists.txt

CMakeLists.txt cmake_minimum_required(VERSION 2.6) #Name your project here project(hello) # custom cmake modules path SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) # Special rules for lib installation include(SetupInstallLib) #Add “-g -O2” options to the gcc compiler add_definitions(-g -O2) # add library to build (located in "lib01" directory) add_subdirectory(lib01) # add lib directory as include search dir include_directories(lib01/include) # Find all c++ main exes sources files FILE(GLOB main_src src/*.cc) # build cpp executables according to the source FOREACH(main_exe ${main_src}) get_filename_component(exe ${main_exe} NAME_WE) # get full name without directory MESSAGE( STATUS "New executable ==> " ${exe}) # print exe name add_executable (${exe} ${main_exe}) # specify exe file to cpmpile target_link_libraries (${exe} MYlib ) # specify library dependencies INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) # binaries install directory ENDFOREACH() # Install destinattion directory if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set (CMAKE_INSTALL_PREFIX $ENV{HOME}/local CACHE PATH "" FORCE) endif()

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) cmake_minimum_required(VERSION 2.6) project(hello)

SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) include(SetupInstallLib) add_definitions(-g -O2)



CMAKE_MODULE_PATH : cmake module path = files with “.cmake” extension



${PROJECT_SOURCE_DIR}/lib : top level source directory for the current project.



include(SetupInstallLib) : load cmake module => SetupInstallLib.cmake

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) add_subdirectory(lib01) include_directories(lib01/include)



add_subdirectory(lib01) : add subdirectory “lib01” to the build and process its CMakeList.txt file You must have a lib01/CMakeLists.txt file



include_directories(lib01/include) : add lib01/include path to compilation include search path Equivalent to : g++ -Ilib01/include .. You can have multiple include_directories() command, path wil be appended

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) FILE(GLOB main_src src/*.cc) FOREACH(main_exe ${main_src}) get_filename_component(exe ${main_exe} NAME_WE) MESSAGE( STATUS "New executable ==> " ${exe}) add_executable (${exe} ${main_exe}) target_link_libraries (${exe} MYlib ) INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) ENDFOREACH()



FILE(GLOB main_src src/*.cc) : create a variable main_src with all c++ sources files from top level src directory.

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) FILE(GLOB main_src src/*.cc) FOREACH(main_exe ${main_src}) get_filename_component(exe ${main_exe} NAME_WE) MESSAGE( STATUS "New executable ==> " ${exe}) add_executable (${exe} ${main_exe}) target_link_libraries (${exe} MYlib ) INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) ENDFOREACH()



FILE(GLOB main_src src/*.cc) : create a variable main_src with all c++ sources files from top level src directory.



FOREACH(main_exe ${main_src}) : loop over main_src variable to fill up main_exe variable

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) FILE(GLOB main_src src/*.cc) FOREACH(main_exe ${main_src}) get_filename_component(exe ${main_exe} NAME_WE) MESSAGE( STATUS "New executable ==> " ${exe}) add_executable (${exe} ${main_exe}) target_link_libraries (${exe} MYlib ) INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) ENDFOREACH()



FILE(GLOB main_src src/*.cc) : create a variable main_src with all c++ sources files from top level src directory.

● ●

FOREACH(main_exe ${main_src}) : loop over main_src variable to fill up main_exe variable get_filename_component(exe ${main_exe} NAME_W) : set exe variable from main_exe without directory name nor extension : main_exe=src/hello.cc → exe=hello

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) FILE(GLOB main_src src/*.cc) FOREACH(main_exe ${main_src}) get_filename_component(exe ${main_exe} NAME_WE) MESSAGE( STATUS "New executable ==> " ${exe}) add_executable (${exe} ${main_exe}) target_link_libraries (${exe} MYlib ) INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) ENDFOREACH()



FILE(GLOB main_src src/*.cc) : create a variable main_src with all c++ sources files from top level src directory.

● ●

FOREACH(main_exe ${main_src}) : loop over main_src variable to fill up main_exe variable get_filename_component(exe ${main_exe} NAME_W) : set exe variable from main_exe



without diretory name nor extension : main_exe=src/hello.cc → exe=hello add_executable (${exe} ${main_exe}) : add new executable exe which depends from main_exe

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) FILE(GLOB main_src src/*.cc) FOREACH(main_exe ${main_src}) get_filename_component(exe ${main_exe} NAME_WE) MESSAGE( STATUS "New executable ==> " ${exe}) add_executable (${exe} ${main_exe}) target_link_libraries (${exe} MYlib ) INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) ENDFOREACH()



FILE(GLOB main_src src/*.cc) : create a variable main_src with all c++ sources files from top level src directory.

● ● ● ●

FOREACH(main_exe ${main_src}) : loop over main_src variable to fill up main_exe variable get_filename_component(exe ${main_exe} NAME_W) : set exe variable from main_exe without diretory name nor extension : main_exe=src/hello.cc → exe=hello add_executable (${exe} ${main_exe}) : add new executable exe which depends from main_exe target_link_libraries (${exe} MYlib ) : executable must be linked against MYlib library (libMYlib.so)

Jean-Charles Lambert

CMAKE

Advanced example : anatomy Hello project

src/hello.cc lib01/CMakeLists.txt lib01/src/chello.cc lib01/src/insane.c lib01/include/chello.h cmake/SetupInstallLib.cmake

CMakeLists.txt

Jean-Charles Lambert

lib01/CMakeLists.txt

# Find all library sources files FILE(GLOB SRCLIB src/*.cc src/*.c) # src sources files relatives too lib01 # add current directory as include search dir include_directories(include) # create library "MYlib" add_library (MYlib SHARED ${SRCLIB}) # Destination path for the lib SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) INSTALL(FILES include/chello.h DESTINATION include) INSTALL(FILES ${PROJECT_BINARY_DIR}/lib/libMYlib.so DESTINATION lib)

CMAKE

Advanced example : anatomy (lib01/CMakeLists.txt) **REMEMBER** : add_subdirectory(lib01) from top level CMakeLists.txt

FILE(GLOB SRCLIB src/*.cc src/*.c)

include_directories(include)



FILE(GLOB SRCLIB src/*.cc src/*.c) : create a variable SRC_LIB with all c++/c sources files from src subdirectory, actually lib01/src (recursive search)



include_directories(include) : add include, actually lib01/include, path to compilation include search path

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (lib01/CMakeLists.txt) add_library (MYlib SHARED ${SRCLIB})

SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)



add_library (MYlib SHARED ${SRCLIB}) : Add a SHARED lib libMYlib.so to the project using the specified source files from SRCLIB variable. Note: no lib prefix nor .so suffix



STATIC instead of SHARED => static library



SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) : library directory destination PROJECT_BINARY_DIR : directory from where you enter cmake command, here build

Jean-Charles Lambert

CMAKE

Advanced example : running make install make install

mkdir build cd build cmake ..

make make install

PROCESS: Install binaries, libraries and headers in default or specific location

Jean-Charles Lambert

[ 66%] Built target MYlib [100%] Built target hello Install the project... -- Install configuration: "" -- Installing: /home/jcl/local/bin/hello -- Set runtime path of "/home/jcl/local/bin/hello" to "/home/jcl/local/lib" -- Installing: /home/jcl/local/include/chello.h -- Installing: /home/jcl/local/lib/libMYlib.so

CMAKE

Advanced example : anatomy (installation) Hello project

src/hello.cc lib01/CMakeLists.txt lib01/src/chello.cc lib01/src/insane.c lib01/include/chello.h cmake/SetupInstallLib.cmake

CMakeLists.txt

cmake install statements INSTALL(FILES include/chello.h DESTINATION include) INSTALL(FILES ${PROJECT_BINARY_DIR}/lib/libMYlib.so DESTINATION lib)

# Install destinattion directory if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set (CMAKE_INSTALL_PREFIX $ENV{HOME}/local CACHE PATH "" FORCE) endif() SET(CMAKE_SKIP_BUILD_RPATH FALSE) # when building, don't use the install RPATH already # (but later on when installing) SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") # add the automatically determined parts of the RPATH # which point to directories outside the build tree to the install RPATH SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # check RPATH to be used when installing is not a system directory LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) IF("${isSystemDir}" STREQUAL "-1") SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") ENDIF("${isSystemDir}" STREQUAL "-1")

INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin)

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (cmake/SetupInstallLib) **REMEMBER** : include(SetupInstallLib) from top level CMakeLists.txt

if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set (CMAKE_INSTALL_PREFIX $ENV{HOME}/local CACHE PATH "" FORCE) endif() SET(CMAKE_SKIP_BUILD_RPATH FALSE) SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) IF("${isSystemDir}" STREQUAL "-1") SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") ENDIF("${isSystemDir}" STREQUAL "-1")



CMAKE_INSTALL_PREFIX : specify install base directory path



set (CMAKE_INSTALL_PREFIX $ENV{HOME}/local CACHE PATH "" FORCE) : installation by default in ${HOME}/local directory



To change default install directory path, re-run : cmake .. -DCMAKE_INSTALL_PREFIX=/mynewpath/directory make install

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (CMakeLists.txt) FOREACH(main_exe ${main_src}) …. …. INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) ENDFOREACH()



INSTALL(TARGETS ${exe} RUNTIME DESTINATION bin) : install every exe binary file to installation_path/bin directory

Jean-Charles Lambert

CMAKE

Advanced example : anatomy (from lib01/CMakeLists.txt) INSTALL(FILES include/chello.h DESTINATION include) INSTALL(FILES ${PROJECT_BINARY_DIR}/lib/libMYlib.so DESTINATION lib)



INSTALL(FILES include/chello.h DESTINATION include) : install chello.h to installation_path/include directory



INSTALL(FILES ${PROJECT_BINARY_DIR}/lib/libMYlib.so DESTINATION lib) : install library libMYlib.so to installation_path/lib directory Note : library comes from ${PROJECT_BINARY_DIR}/lib directory

Jean-Charles Lambert

Subscribe

© Copyright 2013 - 2019 AZDOC.PL All rights reserved.