0

I have a CMake project in C++ and I have been struggling how to setup the CMakeLists.txt files properly. In the external folder there are some dependencies located, which are added to the root CMakelists.txt by the add_subdirectory command. It is important to mention that Project_B needs Project_A. Here is the simplified version of the folder structure:

$ tree
.
├── external
│    ├── Project_A 
|         ├──include 
|              ├── project_A.h
│         ├── projectA_0.cpp
│         └── CMakeLists.txt
|
|    ├── Project_B
|         ├──include 
|              ├── project_B.h
│         ├── projectB_0.cpp
│         └── CMakeLists.txt
|
├── root_0.cpp
├── root_1.cpp
└── CMakeLists.txt

Here is the simplified root CMakeLists.txt

# root CMakeLists.txt

cmake_minimum_required(VERSION 3.19)
project(foo)

add_subdirectory(external/Project_A)
add_subdirectory(external/Project_B)


add_executable(${PROJECT_NAME} root_0.cpp
                               root_1.cpp)

target_include_directories(${PROJECT_NAME} PUBLIC 
                                             external/Project_A/include
                                             external/Project_B/include)

target_link_libraries(${PROJECT_NAME} PUBLIC
                                            project_a
                                            project_b)

Here is the CMakeLists.txt of Project_A, which is also a dependency for Project_B. I decided to create a config.cmake file for this project and import it by Project_B.

# Project_A CMakeLists.txt

cmake_minimum_required(VERSION 3.19)
project(project_a)

target_include_directories(${PROJECT_NAME} PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
        )

add_library(${PROJECT_NAME} STATIC projectA_0.cpp)

export(TARGETS ${PROJECT_NAME}
        NAMESPACE project_a::
        FILE ${CMAKE_SOURCE_DIR}/project_a_Config.cmake )

and here is the CMakeLists.txt of Project_B.The project_a_Config.cmake is loaded with the help of find_package() function. The path of the include dir from A is written in the project_a_Config.cmake. However, I can not make those headers included properly. Should I use a *.cmake.in file?

# Project_B CMakeLists.txt

cmake_minimum_required(VERSION 3.19)

project(project_b)

add_library(${PROJECT_NAME} STATIC projectB_0.cpp)

find_package(project_a CONFIG REQUIRED HINTS ../)

target_include_directories(${PROJECT_NAME} PUBLIC
                                            include
                                            project_a::project_a )

target_link_libraries(${PROJECT_NAME} PUBLIC
                                            project_a )

If there are any further problems with the structure or the used functions, just let me know! Thank you!

Fox1942
  • 276
  • 2
  • 18
  • 2
    "However, I can not make those headers included properly." - What error message have you got with the current code? BTW, since the `project_b` is built at the same time as a `project_a` (as a part of the root project), `find_package(project_a)` is not needed: simple linking with `project_a` is sufficient. – Tsyvarev Feb 25 '22 at 21:46
  • Clion gives me "file not found" error at the #include<...> directive-s. All of the them are underlined with red. I suppose there is some problem at the target_include_directories() in Project_B. If find_package() is not needed, how can I specify the path of the includes? I read, that using target_include_directories with a path outside a module is an anti-pattern. – Fox1942 Feb 26 '22 at 08:11
  • "Clion gives me "file not found" error at the #include<...> directive-s." - Does this error occur during the **build** of the project? Or does it shown only by CLion when you ask it to find the header? If it is a build error, then show the **exact error message**, which should not only the line in the header file, but also the **source** file which is compiled. – Tsyvarev Feb 26 '22 at 12:03
  • It is also a **build** error, so I am showing you the **exact error message**: fatal error: external/Project_A/include/project_a.h: No such file or directory – Fox1942 Feb 26 '22 at 14:59
  • The one-line shown in the "problems" window in CLion is not a **full** (complete) error message. As I said above, the complete error message should contain the name of **source** file (with `.cpp` extension). Anyway, the include path `external/Project_A/include/project_a.h` conflicts with your include directories. This path corresponds to the **root directory** used as include directory. But your include directory `external/Project_A/include` corresponds to the `#include ` – Tsyvarev Feb 26 '22 at 18:52

0 Answers0