2

I am working on a pretty large C++ project and I decided to split the source files into different modules to make managing them a bit easier. However, I ran into problems with linking the files together with CMake.
So I have two libraries, both containing some .cpp and .h files and a main.cpp file. The directory structure for the project looks like this:

root
  |-- library1
  |      |-- lib1.cpp
  |      |-- lib1.h
  |      `-- CMakeLists1.txt
  |
  |-- library2
  |      |-- lib2.cpp
  |      |-- lib2.h
  |      `-- CMakeLists2.txt
  |
  |-- main.cpp
  |-- main.h
  `-- CMakeLists.txt

Library 2 depends on library 1 and main.cpp depends on both of them. I can link main.cpp and main.h together pretty easily and use functions from main.h in main.cpp. Same goes for libraries 1 and 2.

But I cannot link library 1 to library 2 or any of them to my main.cpp. My main file looks like this:

#include <iostream>
#include "main.h"
#include "lib1.h"  // linking error at this line: file lib1.h not found


int main() {
    test();

    std::cout << "Hi, I am main!" << std::endl;
    return 0;
}


void test() {  // defined in main.h
    std::cout << "Hi, I am test!" << std::endl;
}

CMake output:

Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
~/cmake-test/main.cpp:3:10: fatal error: 'lib1.h' file not found
#include "lib1.h"
         ^~~~~~~~

CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(cmake_test)

set(CMAKE_CXX_STANDARD 20)

add_subdirectory(library1)
add_subdirectory(library2)

add_executable(main main.cpp)
target_include_directories(main PRIVATE .)

target_link_libraries(main lib1)
target_link_libraries(main lib2)

CMakeLists1.txt:

add_library(lib1 lib1.cpp)
target_include_directories(lib1 PRIVATE .)

CMakeLists2.txt:

add_library(lib2 lib2.cpp)
target_include_directories(lib2 PRIVATE .)

target_link_libraries(lib2 lib1)

How can I link the libraries in this case with CMake?

Thank you!

  • Please read this [https://stackoverflow.com/questions/17511496/how-to-create-a-shared-library-with-cmake](https://stackoverflow.com/questions/17511496/how-to-create-a-shared-library-with-cmake) and this [https://stackoverflow.com/questions/2152077/is-it-possible-to-get-cmake-to-build-both-a-static-and-shared-version-of-the-sam?noredirect=1&lq=1](https://stackoverflow.com/questions/2152077/is-it-possible-to-get-cmake-to-build-both-a-static-and-shared-version-of-the-sam?noredirect=1&lq=1) – reyad Jul 31 '20 at 12:16
  • 4
    Make the `target_include_directories` for the libraries `PUBLIC`. Otherwise you cannot access the headers in dependent projects. – vre Jul 31 '20 at 12:17
  • @vre Thank you, that's exactly what I needed. – Mikhail Stefantsev Jul 31 '20 at 12:27
  • 2
    @MikhailStefantsev as a general advice, I suggest using the new form of target link libraries: `target_link_libraries(main PRIVATE lib1)` and `target_link_libraries(lib2 PUBLIC lib1)` – Guillaume Racicot Jul 31 '20 at 12:49

1 Answers1

5

The include directories for the target_include_directories command of the libraries should be made PUBLIC. Otherwise you cannot access the headers in dependent projects.

vre
  • 6,041
  • 1
  • 25
  • 39