CMake is a cross-platform build system generator that simplifies the compilation process for multi-language projects. It generates native build scripts (Makefiles, Visual Studio projects, etc.) from platform-independent configuration files.
Installation
Most Linux distributions include CMake in their package repositories. For Windows or systems without pre-installed CMake, download the latest version from the official website.
# Ubuntu/Debian
sudo apt-get install cmake
# CentOS/RHEL
sudo yum install cmake
Basic Hello World Example
Source Code
// greeting.cpp
#include <iostream>
int main() {
std::cout << "Hello World" << std::endl;
return 0;
}
CMake Configuration
# CMakeLists.txt
PROJECT(GreetingApp)
SET(SOURCE_FILES greeting.cpp)
MESSAGE(STATUS "Build directory: ${GreetingApp_BINARY_DIR}")
MESSAGE(STATUS "Source directory: ${GreetingApp_SOURCE_DIR}")
ADD_EXECUTABLE(greeter ${SOURCE_FILES})
Build Process
mkdir build
cd build
cmake ..
make
./greeter
Core CMake Concepts
PROJECT Directive
Specifies the project name and supported languages:
PROJECT(MyProject) # All languages
PROJECT(MyProject CXX) # C++ only
PROJECT(MyProject C CXX) # C and C++
Defines two variables:
PROJECT_BINARY_DIR: Build directory pathPROJECT_SOURCE_DIR: Source directory path
SET Directive
Defines variables for source files:
SET(APP_SOURCES main.cpp)
SET(APP_SOURCES main.cpp util.cpp)
ADD_EXECUTABLE Directive
Creates executable targets:
ADD_EXECUTABLE(myapp ${APP_SOURCES})
Syntax Rules
- Variables referenced with
${VARIABLE_NAME} - Commands are case-insensitive (convention: uppercase)
- Parameters separated by spaces or semicolons
- Filenames with spaces require quotes
External Build Metohdology
Recommended approach to keep source directory clean:
project/
├── CMakeLists.txt
├── src/
└── build/ # Created directory
# Build commands
mkdir build
cd build
cmake ..
make
Project Structure Organization
Directory Layout
project/
├── CMakeLists.txt
├── src/
│ ├── CMakeLists.txt
│ └── main.cpp
├── doc/
│ └── documentation.txt
├── LICENSE
└── README.md
Multi-directory Configuration
Root CMakeLists.txt:
PROJECT(MainProject)
ADD_SUBDIRECTORY(src bin)
src/CMakeLists.txt:
ADD_EXECUTABLE(mainapp main.cpp)
Output Path Configuration
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
Installation Targets
File Installation
INSTALL(FILES LICENSE README.md DESTINATION share/doc/project)
Program Installation
INSTALL(PROGRAMS scripts/launcher.sh DESTINATION bin)
Directory Installlation
INSTALL(DIRECTORY doc/ DESTINATION share/doc/project)
Custom Installation Prefix
cmake -DCMAKE_INSTALL_PREFIX=/custom/path ..
Library Creation
Shared Library
# lib/CMakeLists.txt
SET(LIB_SOURCES utility.cpp)
ADD_LIBRARY(mylib SHARED ${LIB_SOURCES})
Static Library
ADD_LIBRARY(mylib_static STATIC ${LIB_SOURCES})
Library Naming
SET_TARGET_PROPERTIES(mylib_static PROPERTIES OUTPUT_NAME "mylib")
SET_TARGET_PROPERTIES(mylib_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
Versioning
SET_TARGET_PROPERTIES(mylib PROPERTIES VERSION 1.2 SOVERSION 1)
Library Installation
INSTALL(FILES mylib.h DESTINATION include/mylib)
INSTALL(TARGETS mylib mylib_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
Using External Libraries
Header Search Paths
INCLUDE_DIRECTORIES(/usr/include/mylib)
Library Linking
TARGET_LINK_LIBRARIES(myapp mylib)
Custom Library Paths
LINK_DIRECTORIES(/custom/lib/path)
Environment Variables
export CMAKE_INCLUDE_PATH=/custom/include/path
export CMAKE_LIBRARY_PATH=/custom/lib/path
Debug Build Configuration
cmake -DCMAKE_BUILD_TYPE=debug ..