CMake is a powerful cross-platform build system that simplifies building C/C++ projects, especially when it comes to managing libraries and linking.
Create a directory for your project.
Inside the project directory, create a file named CMakeLists.txt
. This is the heart of your CMake configuration.
Create a build directory
Write your CMakeLists.txt
Move to build directory
Run cmake ..
Run make
Refer to CMake documentation for specific library names and linking instructions.
Create a separate build directory and run cmake
there.
cmake_minimum_required(VERSION 3.0)
: This line specifies the minimum required version of CMake for this project.
project(MyStaticLib)
: This line defines the project name, which is used for generating build files.
add_library(MyStaticLib STATIC source1.cpp source2.cpp)
: This line creates a static library named MyStaticLib
from the source files source1.cpp
and source2.cpp
.
target_include_directories(MyProgram PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
: This line tells the compiler where to find header files. Since the static library might have headers, we include the current binary directory (where the library is built) in the search path.
add_executable(MyProgram main.cpp)
: This line creates an executable named MyProgram
from the source file main.cpp
.
target_link_libraries(MyProgram PRIVATE MyStaticLib)
: This line links the executable MyProgram
with the previously created static library MyStaticLib
. The PRIVATE
keyword indicates that the library is private to this project and shouldn't be exposed to other projects linking against this executable.
This line is similar to creating a static library, but instead of STATIC
, we use SHARED
to create a shared library named MySharedLib
.
find_package(Threads REQUIRED)
: This line attempts to find a package named Threads
(replace with the actual library name, like OpenSSL
or SDL2
). The REQUIRED
keyword ensures CMake throws an error if the library is not found.
target_include_directories(MyProgram PRIVATE "${CMAKE_THREAD_INCLUDE_DIRS}")
: This line includes the library's header directory (CMAKE_THREAD_INCLUDE_DIRS
) in the search path for MyProgram
.
target_link_libraries(MyProgram PRIVATE Threads::Threads)
: This line links the executable with the external library's target (Threads::Threads
).
You can control which symbols from a library are visible to linked programs using compiler flags like -fvisibility=hidden
(GCC) or /DEF:{symbol}
(MSVC).
The if
statement checks the compiler ID.
If it's GCC, target_compile_properties
sets the CVISIBILITY_PRESET
property to "hidden" for the target MyLib
, effectively hiding symbols by default.
Custom Linker Flags: You can pass custom linker flags using target_link_libraries
with the LINK_OPTIONS
clause:
This line links the program MyProgram
with MyLib
and adds the linker flag -Wl,-rpath,/path/to/additional/libraries
, specifying an additional search path for libraries at runtime.
Toolchain Files: CMake allows defining toolchain files that specify compiler and linker settings for different platforms. This enables consistent builds across operating systems.
Platform-Specific Flags: Be mindful of platform-specific compiler and linker flags. CMake can handle some of these through built-in properties like CMAKE_CXX_FLAGS
or CMAKE_EXE_LINKER_FLAGS
, but you might need to add custom flags for specific needs.
CMake Minimum Version: We specify the minimum required CMake version.
Project Name: We define the project name.
Finding Threads Library: We use find_package(Threads REQUIRED)
to attempt finding the pthread
library. This might require replacing Threads
with the actual package name for your target platform (e.g., PkgConfig
on some Linux distributions).
Include Directories: We set the include directories for our project headers and the headers from the Threads
package.
Source Files: We define the source files for our application.
Linking with Threads: We link the executable MyProgram
with the target Threads::Threads
from the found library.
Platform-Specific Flags (Optional): We use conditional statements to add platform-specific linker flags. On Linux, we link with -lpthread
, and on macOS, we link with the -framework pthread
framework.