[go: up one dir, main page]

Skip to content

CMake contribution rules

Joerg-Christian Boehme edited this page Apr 1, 2018 · 4 revisions
  1. Don't make any assumption about the platform or compiler!
    CMake takes care that it works on all compilers and platforms.
    Compiler and platform test results are cached in CMakeCache.txt

  2. Don't modify global compile/link flags.

  3. Don't assume that this project root is the build root.

  4. Don't make any global changes!

  5. Always add Poco namespace alias for libraries.
    Like: add_library(Poco::Foundation ALIAS foundation)

  6. Don't pass STATIC/SHARED on add_library(), unless they cannot be built otherwise!
    Leave the control of BUILD_SHARED_LIBS to the clients

  7. Link against namespaced targets.
    Like: target_link_libraries(crypto Poco::Foundation OpenSSL::Crypto)

  8. Specify the dependencies are PRIVATE or PUBLIC.

    • PRIVATE Only used for this target
    • PUBLIC Used for this target and all targets that link against it.
      This will also export into the xxxConfig.cmake for find_package().
    • INTERFACE Only used for targets that link against this library.
target_<usage_requirement>(<target>
   <PRIVATE|PUBLIC|INTERFACE] <lib> ...
   [<PRIVATE|PUBLIC|INTERFACE] <lib> ...]
   ...
)

  1. Don't use link_libraries() command.
    Use: target_link_libraries()

  2. Don't use link_directories() command.
    Use: target_link_libraries()

  3. Don't use include_directories() command.
    Use: target_include_directories()

  4. Don't use add_definitons() command.
    Use: target_compile_definitons()

  5. Don't use add_compile_options() command.
    Use: target_compile_options()

  6. Don't add definitons or options to CMAKE_<LANG>_FLAGS.
    Use: target_compile_definitons()

  7. Wrap compiler specific options in an appropriate condition.
    Like:

if(CMAKE_COMPILER_IS_GNUCXX)
   target_compile_options(foo
        PUBLIC -fno-elide-constructors
   )
endif()
  1. Don't add or pass -std=c++11 or -std=c++yy to CMAKE_<LANG>_FLAGS or target_compile_options().
    Use: target_compile_features()

  2. No need to call add_dependencies().

  3. Don't use file(GLOB ..) in configure mode. (List all sources explicitly!)
    Like:

file(GLOB sources "*.cpp")
add_library(mylib ${sources})
  1. Avoid custom variables, variables are fragile. Use targets and properties!
    If it is not possilbe to avoid, add POCO_ as prefix!

  2. Modern cmake is about targets and properties!
    Here an overview howto use:

    Constructors for targets:

    add_executable()
    add_library()

    Target member variables:

    See properties on targets in cmake documentation.

    Target member functions:

    get_target_property()
    set_target_properties()
    get_property(TARGET)
    set_property(TARGET)
    target_compile_definitions()
    target_compile_features()
    target_compile_options()
    target_include_directories()
    target_link_libraries()
    target_sources()

This best practices are from Daniel Pfeifer. He has a good experience about cmake.
It is recommended to look at his presentation: C++Now 2017: Daniel Pfeifer “Effective CMake"

Link: