Search code examples
c++cmake

CMake build library dynamically as sub_directory and link to main executable


I'm not very good with CMake and so I am trying to create a minimalistic example of what I would like to achieve.

I wish to write a library, which is compiled with my main project and then dynamically linked against my project executable.

This is my test project file system:

enter image description here

CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(TestProject)

add_subdirectory(lib_wrapper)

add_executable(TestExe main.cpp)

target_link_libraries(TestExe libwrapper)
target_include_directories(TestExe PUBLIC ../lib_wrapper)
target_include_directories(TestExe PUBLIC ../src)

lib_wrapper/CMakeLists.txt:

add_library (wrapper wrapper.cpp)

target_include_directories (wrapper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

src/main.cpp:

#include <src/a_header.h>

int main()
{
    int j = 0;
    return 0;
}

src/a_header.h:

#pragma once

#include <lib_wrapper/wrapper.h>
#include <iostream>

inline void some_func()
{
    std::cout << "some_func()" << std::endl;

    // Call a function from lib_wrapper/wrapper.h
}

cmake .. generates for the main project successfully. However, when I make in folder Test I get:

Test/main.cpp:3:10: fatal error: src/a_header.h: No such file or directory
    3 | #include <src/a_header.h>

Could someone please help? And any additional advice to improve things is welcome.


Solution

  • Your problem that the root folder Test is not in the include directories list when building the TestExe target.

    One way to do this is to add ${CMAKE_SOURCE_DIR} to the end of either of your target_include_directories(TestExe PUBLIC ... lines before the ) or you may want to replace these with this:

    target_include_directories(TestExe PRIVATE 
        ${CMAKE_SOURCE_DIR} 
        ../lib_wrapper 
        .
    )
    

    I changed PUBLIC to PRIVATE because usually an executable target is not inherited by other targets and thus does not need to share include directories with other targets.

    Your second error as @Tsyvarev mentioned in the comments is:

    target_link_libraries(TestExe libwrapper)
    

    This should be

    target_link_libraries(TestExe wrapper)
    

    since your library target name is wrapper:

    add_library (wrapper wrapper.cpp)