-
Notifications
You must be signed in to change notification settings - Fork 12
Cmake best practices and guidelines
Paul Fultz II edited this page Jun 22, 2017
·
4 revisions
This goes over cmake best practices and guidelines from Daniel Pfeifer's talks on cmake: Effective cmake and Cmake introduction and best practices
- Prefer the latest version of CMake.
- Please don’t set 2.8 as the minimum.
- If you use 2.6 or 2.4, God kills a kitten.
- Make sure that all your projects can be built both standalone and as a subproject of another project
- Don’t assume that your project root is the build root.
- Don’t modify global compile/link flags.
- Don’t make any global changes!
- Finds preinstalled dependencies
- Can set some variables and define imported targets.
- Use a Find module for third party libraries that do not support clients to use CMake
- The library interface may change during installation. Use the
BUILD_INTERFACE
andINSTALL_INTERFACE
generator expressions as filters.
- Always add namespaced aliases for libraries.
- When you export
Foo
in namespaceFoo::
, also create an aliasFoo::Foo
- Dont’t make libraries
STATIC
/SHARED
unless they cannot be built otherwise. - Leave the control of
BUILD_SHARED_LIBS
to your clients!
- Prefer to link against namespaced targets.
- Specify the dependencies are private or public.
- Avoid the
link_libraries()
command. - Avoid the
link_directories()
command. - No need to call
add_dependencies()
. - Use
target_link_libraries
to express direct dependencies - Don't abuse requirements! E:
-Wall
is not a requirement
- Avoid the
include_directories()
command.
- Avoid the
add_definitions()
command. - Avoid adding definitions to
CMAKE_<LANG>_FLAGS
.
- Wrap compiler specific options in an appropriate condition.
- Avoid the
add_compile_options()
command. - Avoid adding options to
CMAKE_<LANG>_FLAGS
.
- Variables are so CMake 2.8.12: Modern CMake is about Targets and Properties!
- Avoid custom variables in the arguments of project commands
- Explicit is better than implicit
- Contribute it to CMake!
- If it is accepted, it is no longer a custom function.
- Otherwise, the reason for rejection should give you a hint.
- The maintainers are very helpful and experienced.
- System packages: work out of the box
- Prebuilt libraries: need to be put into
CMAKE_PREFIX_PATH
- Subprojects: need to turn
find_package(Foo)
into a no-op
- The way you use CMake affects your users!
- Cmake is code: Use the same principles for
CMakeLists.txt
and modules as for the rest of your codebase. - Create macros to wrap commands that have output parameters, otherwise, create a function.
- Don't use
file(GLOB)
in projects.