Search code examples
c++cmakeclionsetup-project

CMake project with independent subprojects


I am trying to create a cmake project which has the following directory structure:

root_folder
 lib
   common_library_for_all_submodules
 submodule_1
   src
    main.cpp
   tests
    main_test.cpp
 submodule_2
   src
    main.cpp
   tests
    main_test.cpp
 

Being new to C++ and also to CMake I have the following confusions and would be really glad if someone can guide me in the right direction here.

  1. Coming from a Java world I know that this is possible to create in a maven project using the modules tag in pom.xml. Is there an equivalent to this in CMake? If yes what to do we call it and can someone give me an example?

  2. I want to then import this project into CLion and when I run the root project, all the submodules should be compiled and relevant tests be run.

Note: submodule_1 and submodule_2 are not using each other's code. They are entirely independent. But they will need to share some common libraries from the root_folder/lib

Thanks a lot in advance


Solution

  • You can use several CMakeLists.txt files, use add_subdirectory statement. To declare library (which will be used in another subproject) use add_library. To declare app - add_executable. To link library to app - target_link_libraries(app1 PRIVATE utils common). This is short and very common description-example. There are more options and parameters.

    I'm attaching examples here:

    CMakeLists.txt

    project(Example)
    
    add_subdirectory(3rd-party)
    add_subdirectory(apps)
    add_subdirectory(libs)
    

    libs/CMakeLists.txt

    add_subdirectory(common)
    add_subdirectory(utils)
    

    libs/utils/CMakeLists.txt

    FILE(GLOB SOURCES *.cpp *.h)
    
    add_library(utils STATIC ${SOURCES})
    
    target_include_directories(utils PUBLIC .)
    

    apps/CMakeLists.txt

    add_subdirectory(app1)
    add_subdirectory(app2)
    

    apps/app1/CMakeLists.txt

    FILE(GLOB_RECURSE SOURCES src/*.cpp src/*.h)
    
    add_executable(app1 ${SOURCES})
    target_link_libraries(app1 PRIVATE utils common)
    

    In this example libraries utils and common are independent and could be built without each other and without apps