CMake Best Practices
In a Nutshell
Declare modules with
ADD_LIBRARY
orADD_EXECUTABLE
Declare build flags with
TARGET_xxx()
Declare dependencies with
TARGET_LINK_LIBRARIES
Specify which is
PUBLIC
and which isPRIVATE
Boilderplate
Headers
cmake_minimum_required(VERSION 3.0)
# declare top-level flags
if (MSVC)
add_compile_options(/W3 /WX)
else()
add_compile_options(-W -Wall -Werror)
endif()
Add Libraries
add_library(mylib
src/file1.c
src/file2.c
...)
Declare Flags
target_include_directories(mylib PUBLIC include)
target_include_directories(mylib PRIVATE src)
if (SOME_SETTING)
target_compile_definitions(mylib
PUBLIC WITH_SOME_SETTINGS)
endif()
Declare Dependencies
# for public (interface) dependencies
target_link_libraries(mylib PUBLIC abc)
# for private (implementation) dependencies
target_link_libraries(mylib PRIVATE xyz)
Header-only libraries
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE include)
target_link_libraries(mylib INTERFACE Boost::Boost)
INTERFACE basically indicates that we don't need to build anything
DO NOT
Don't use macros that affect all targets:
INCLUDE_DIRECTORIES()
ADD_DEFINITIONS()
LINK_LIBRARIES
Dont' use
TARGET_INCLUDE_LIBRARIES()
with path outside your own moduleDon't use
TARGET_LINK_LIBRARIES()
without specifying scope (PUBLIC, PRIVATE, or INTERFACE)Don't use
TARGET_COMPILE_OPTIONS()
to set flags that affect the ABI
Last updated
Was this helpful?