Search code examples
c++cmake

How to share variables between different CMakeList.txt?


I have a project with multiple CMakeList.txt, one for code, one for units tests and 2 other for libraries and I want to share some lines of the CMakeList.txt to avoid duplicate like:

cmake_minimum_required(VERSION 3.0) or set(CMAKE_CXX_STANDARD 17)

Can I use something like include("MyProject/CMakeConfig.txt")?


Solution

  • Usually, you have one CMake lists file that is at the toplevel of the project and the other used as subdirectories. Since cmake_minimum_required and project are required once by project, you should be fine writing nothing in your case.

    Here's an example of a structure:

    Top level ./CMakeLists.txt:

    cmake_minimum_required(VERSION 3.29)
    project(my-project CXX)
    
    # set global property for all this file and subdirectories
    set(CMAKE_CXX_STANDARD 17)
    
    # targets of your projects
    add_executable(your-exec src/file1.cpp src/file2.cpp src/file3.cpp)
    add_library(your-lib src/file4.cpp src/file5.cpp src/file6.cpp)
    
    find_package(liba REQUIRED)
    
    target_link_libraries(your-exec PUBLIC liba::liba)
    target_include_directory(...)
    
    # needs to be at the top level
    enable_testing()
    
    # We'll define the targets for tests in the tests folder
    add_subdirectory(tests)
    

    In tests/CMakeLists.txt:

    find_package(Catch2 REQUIRED)
    add_executable(test1 test1.cpp)
    
    # link into you lib and a test framework
    target_link_libraries(test1 PRIVATE your-lib Catch2::Catch2) 
    add_test(NAME test1 COMMAND test1)
    

    All the added subdirectories will inherit the basic properties of the project, such as the minimum CMake version, enabled languages and explicitly set directory based property such as CMAKE_CXX_STANDARD.

    All that said, it's always a good idea to add C++17 as a requirement to use your project:

    # All users of your-lib need C++17
    target_compile_features(your-lib PUBLIC cxx_std_17)