How can I use a library without a header file path in cmake?

349 views Asked by At

I'm trying to create a simple library using cmake and create an app that uses it. However, while creating an app, I must specify the path to the header file used in the library for the build to succeed. I want to create an app with only the library without the header file path.

create library

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

project(mylibrary)

include_directories("/path/to/src")

add_library(mylib SHARED ./foo.cpp ./foo.h)

target_include_directories(mylib PRIVATE "/path/to/src")
target_link_directories(mylib PRIVATE "/path/to/src)


set_property(TARGET mylib PROPERTY CXX_STANDARD 17)

create app

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

project(myapp)

add_executable(test ./main.cpp)

# target_include_directories(test PRIVATE "/path/to/src")

target_link_libraries(test PRIVATE "/path/to/src/libmylib.dylib")
target_link_directories(test PRIVATE "/path/to/src")

set_property(TARGET test PROPERTY CXX_STANDARD 17)

and include header in main.cpp

#include "foo.h"

int main(int argc, const char** argv) {
    return 0;
}

If i build like this An error occurs.

'foo.h' file not found #include "foo.h"

but

target_include_directories(test PRIVATE "/path/to/src")

If i add this command and specify the path to the header file, the build will proceed normally. This applies not only to the libraries I created but also to external libraries.

I thought that as long as I had a library, I could import and use the header files within it. And I want to use it like that.

Is there a way to use the library without the header file path??

1

There are 1 answers

0
Thomas On

CMake knows how to link with the output of another CMake library target. You can add your library to the build using add_subdirectory, which makes your mylib library target available in the executable project:

add_subdirectory(/path/to/mylib)
target_link_libraries(test mylib)

The nice thing about this is that it automatically propagates required build flags to your main app, including the include paths. However, that only happens for include paths that are PUBLIC, not PRIVATE, so in your library project you'll want:

target_include_directories(mylib PUBLIC "/path/to/src")

Full example:

mylib/CMakeLists.txt:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

project(mylibrary)

# Don't mention header files here, just implementation files.
add_library(mylib SHARED ./foo.cpp)

target_include_directories(mylib PUBLIC "/path/to/src")

set_property(TARGET mylib PROPERTY CXX_STANDARD 17)

myapp/CMakeLists.txt:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

project(myapp)

add_executable(test ./main.cpp)

# Second argument, `mylib`, is the build output directory.
# This is only required if `mylib` is not in a subdirectory of `myapp`.
add_subdirectory("/path/to/mylib" mylib)

# `mylib` is the name of the library target given to `add_library`.
target_link_libraries(test mylib)

set_property(TARGET test PROPERTY CXX_STANDARD 17)