Writing Makefiles is a complicated process. They are powerful tools and, as such, show quite high level of complexity. In order to make typical project development easier higher level tools have been raised. One of such tools is CMake. Think of CMake for Make as C/C++ compiler for assembly language.
CMake transforms project description saved in CMakeLists.txt file into classical Makefile that could be run by make tool. You write your project description in a high level notation, allowing CMake to take care of the details.
Let's setup sample single source code executable, the simplest possible way (I'll skip sample_cmake.cpp creation as it's just C++ source code with main()):
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project (SampleCmake)
add_executable(SampleCmake sample_cmake.cpp)
Then the build:
$ cmake .
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- 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/darek/src/cmake
$ make Scanning dependencies of target SampleCmake [100%] Building CXX object CMakeFiles/SampleCmake.dir/sample_cmake.cpp.o Linking CXX executable SampleCmake [100%] Built target SampleCmake
After the procedure one can find the output in current directory: SampleCmake binary (compiled for your host architecture, cross-compiling is a separate story).
More complicated example involves splitting project into separate shared library files. Let's create one in a subdirectory myLibrary/, new CMakeLists.txt there:
project (myLibrary)
add_library(MyLibrary SHARED sample_library.cpp)
Then you need to reference this library from Main CMakeLists.txt file:
add_subdirectory(myLibrary)
include_directories (myLibrary)
target_link_libraries (SampleCmake MyLibrary)
What happens there?
- myLibrary subdirectory is added to the build
- subdirectory for include files is specified
- SampleCmake binary will use MyLibrary
Let's build the stuff now:
$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/darek/src/cmake
$ make
Scanning dependencies of target MyLibrary
[ 50%] Building CXX object myLibrary/CMakeFiles/MyLibrary.dir/sample_library.cpp.o
Linking CXX shared library libMyLibrary.so
[ 50%] Built target MyLibrary
Scanning dependencies of target SampleCmake
[100%] Building CXX object CMakeFiles/SampleCmake.dir/sample_cmake.cpp.o
Linking CXX executable SampleCmake
[100%] Built target SampleCmake
Then you will get: an executable in current directory (SampleCmake) and a library in subdirectory (myLibrary/libMyLibrary.so).
Of course, some "obvious" make targets (as make clean) would work as expected. Others (make install_ might be enabled in a CMake configuration.
Interesting function (also visible in QMake) is the ability to detect changes in CMake project files and autoatically rebuild Makefiles. After 1st CMake run you don't need to run it again, just use standard make interface.