3.7.2. Include modules

CMake modules is a common way to reuse code.

3.7.2.1. Include standard

CMake comes with a set of standard modules:

cmake_minimum_required(VERSION 2.8)
project(foo NONE)

include(ProcessorCount)

ProcessorCount(N)
message("Number of processors: ${N}")
[cmake-sources]> rm -rf _builds
[cmake-sources]> cmake -Hinclude-processor-count -B_builds
Number of processors: 4
-- Configuring done
-- Generating done
-- Build files have been written to: /.../cmake-sources/_builds

CMake documentation

Warning

Do not include Find*.cmake modules such way. Find*.cmake modules designed to be used via find_package.

3.7.2.2. Include custom

You can modify a CMAKE_MODULE_PATH variable to add the path with your custom CMake modules:

# Top level CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(foo NONE)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")

include(MyModule)
# modules/MyModule.cmake

message("Hello from MyModule!")
[cmake-sources]> rm -rf _builds
[cmake-sources]> cmake -Hinclude-users -B_builds
Hello from MyModule!
-- Configuring done
-- Generating done
-- Build files have been written to: /.../cmake-sources/_builds

CMake documentation

3.7.2.2.1. Recommendation

To avoid conflicts of your modules with modules from other projects (if they are mixed together by add_subdirectory) do “namespace” their names with the project name:

cmake_minimum_required(VERSION 2.8)
project(foo)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules")

include(tool_verifier) # BAD! What if a parent project already has 'tool_verifier'?

include(foo_tool_verifier) # Good, includes "./cmake/Modules/foo_tool_verifier.cmake"

See also

3.7.2.3. Modify correct

Note that the correct way to set this path is to append it to an existing value:

# Top level CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(foo NONE)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")

include(ProcessorCount)

ProcessorCount(N)
message("Number of processors: ${N}")

For example when a user wants to use his own modules instead of standard for any reason:

# standard/ProcessorCount.cmake

function(ProcessorCount varname)
  message("Force processor count")
  set("${varname}" 16 PARENT_SCOPE)
endfunction()

Works fine:

[cmake-sources]> rm -rf _builds
[cmake-sources]> cmake -Hmodify-path -B_builds "-DCMAKE_MODULE_PATH=`pwd`/modify-path/standard"
Force processor count
Number of processors: 16
-- Configuring done
-- Generating done
-- Build files have been written to: /.../cmake-sources/_builds

3.7.2.4. Modify incorrect

It’s not correct to set them ignoring current state:

# Top level CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules") # WRONG!

include(ProcessorCount)

ProcessorCount(N)
message("Number of processors: ${N}")

In this case if user want to use custom modules:

# standard/ProcessorCount.cmake

function(ProcessorCount varname)
  message("Force processor count")
  set("${varname}" 16 PARENT_SCOPE)
endfunction()

They will not be loaded:

[cmake-sources]> rm -rf _builds
[cmake-sources]> cmake -Hmodify-incorrect -B_builds "-DCMAKE_MODULE_PATH=`pwd`/modify-incorrect/standard"
Number of processors: 4
-- Configuring done
-- Generating done
-- Build files have been written to: /.../cmake-sources/_builds