Friday, September 2, 2022

[SOLVED] CMake force include statements to have form #include <mylib/header.h>

Issue

I'm currently working on a project with different libraries, where some of their files have similar/equal names or similar/equal names as STL files. This may lead to confusion at a later point in time. Therefore, even it's handy to include my custom library headers by just writing #include<file.h>, I'd like to refactor my CMake code in a way that I have to include my headers like this: #include<mylib/file.h>.

How can I do so?

Here is an example of my current setup:

CMakeLists.txt
     |
     |- mylib
     |   |- CMakeLists.txt
     |   |- include
     |        |- header1.h
     |        |- header2.h
     |
     |- test
         |- CMakeLists.txt
         |- mylib
              |- header1_test.cpp   
              |- header2_test.cpp  

Where the three CMakeLists.txt are:

# main CMakeLists.txt

# ... requirements, etc. ...

# ... fetch and include GoogleTest ...

add_subdirectory(mylib)
add_subdirectory(test)
# mylib/CMakeLists.txt

add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE include/)
# test/CMakeLists.txt

# link directories
link_directories(../mylib)

# test executable
add_executable(header1_test mylib/header1_test.cpp)
add_executable(header2_test mylib/header2_test.cpp)

# link libraries
target_link_libraries(header1_test PRIVATE mylib PRIVATE gtest_main)
target_link_libraries(header2_test PRIVATE mylib PRIVATE gtest_main)

# discover tests
gtest_discover_tests(header1_test)
gtest_discover_tests(header2_test)

Solution

To complete comment from Tsyvarev, you need to modify your header location:

[...]
 |   |- include
 |   |   |- mylib
 |   |   |   |- header1.h
 |   |   |   |- header2.h

On a side note, the line:

# link directories
link_directories(../mylib)

is not needed. This function should be used when you need to link with a library that is not part of your CMake project and in a different location that your linker doesn't search by default. Here, you create your lib mylib via add_library and everything is under the same CMake project (you have a root CMakeLists that adds 2 subdirectories).

Also, you don't need to duplicate the keyword PRIVATE:

target_link_libraries(header2_test PRIVATE mylib gtest_main)


Answered By - Martin
Answer Checked By - Marie Seifert (WPSolving Admin)