Table of Contents
CMake Functions and Macros
function(name arg1 arg2) ... endfunction() defines a reusable function. macro(name arg1 arg2) ... endmacro() defines a macro. Functions create a new scope; variables set inside don't escape. Macros are text substitution; they don't create scope.
Defining a function:
function(add_my_library name) message(STATUS "Adding library ${name}") add_library(${name} ${ARGN}) endfunction() add_my_library(mylib source1.cpp source2.cpp)
The function receives name, source1.cpp, source2.cpp. ${ARGN} captures all arguments after name. Variables inside the function are local.
Returning values from functions:
function(compute_result output_var) set(result 42) set(${output_var} ${result} PARENT_SCOPE) endfunction() compute_result(MY_RESULT) message("Result: ${MY_RESULT}")
To return a value, set a variable in the caller's scope with PARENT_SCOPE.
Defining a macro:
macro(my_macro name) message("Processing ${name}") add_executable(${name} ${ARGN}) endmacro() my_macro(myapp main.cpp util.cpp)
Macros behave like text substitution. Variables set inside affect the caller. Use macros sparingly; functions are usually cleaner.
Common function patterns:
function(setup_target target) target_include_directories(${target} PRIVATE include/) target_compile_options(${target} PRIVATE -Wall -Wextra) endfunction() add_library(mylib src/lib.cpp) setup_target(mylib)
Use functions for reusable logic: wrapping repeated add_library() calls, setting up test targets, configuring common include paths or flags. Prefer functions over macros (cleaner scope, no variable pollution). Macros are useful for wrapper commands that need special scoping behavior (e.g., modifying caller's variables intentionally).
