Hymir
Hymir

Reputation: 931

Include header files from static library with CMake

I have a problem building a CMake project with a static library. My project strucutre looks like that:

Foo/
|-- CMakeLists.txt
|-- lib/
    |-- CMakeLists.txt
    |-- libA/
        |-- CMakeLists.txt
        |-- libA.cpp
        |-- libA.h
        |-- libAB.h
|-- src/
    |-- CMakeLists.txt
    |-- main.cpp
    |-- srcDirA/
        |-- CMakeLists.txt
        |-- srcA.h
    |-- srcDirB/
        |-- CMakeLists.txt
        |-- srcB.cpp
        |-- srcB.h

And the */CMakeLists.txt look like that:

Foo/CMakeLists.txt:

cmake_minimum_required(VERSION 3.5.1)
project(FOO)

set(CMAKE_CXX_STANDARD 11)

add_subdirectory(lib)
add_subdirectory(src)

Foo/lib/CMakeLists.txt:

add_subdirectory(libA)

Foo/lib/libA/CMakeLists.txt:

add_library (staticLibA STATIC libA.cpp)

Foo/src/CMakeLists.txt:

add_subdirectory(srcDirA)
add_subdirectory(srcDirB)
include_directories(".")

add_executable(foo main.cpp)
target_link_libraries(foo LINK_PUBLIC libA)

Foo/src/srcDirA/CMakeLists.txt is empty

Foo/src/srcDirB/CMakeLists.txt is empty

Now I am trying to include the header from my static library into my main project like this:

Foo/src/main.cpp:

#include "srcDirB/srcB.h"
#include "libA/libA.h"  

int main() {
   //...
   return 0;
}

If I try to build this with CMake, libA is generated but I am getting a fatal error:

libA/libA.h: No such file or directory.

Does anyone know what I am doing wrong? Do I have to create a ProjectConfig.cmake file?

Upvotes: 6

Views: 10863

Answers (1)

You don't need to create any Config files; these are for importing 3rd-party projects.

Since you're using CMake >= 3.5.1, you can esaily specify usage requirements for your libraries. Usage requirements are things like flags or include directories which clients need to build with the library.

So in Foo/lib/libA/CMakeLists.txt:, you'll do this:

add_library (staticLibA STATIC libA.cpp)
target_include_directories(staticLibA INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/..)

Or, if you want the same include directory to apply to libA itself (which is likely), use PUBLIC instead of INTERFACE.

That's all you really need to do. However, given the modern CMake you're using, you should replace your use of the legacy keyword LINK_PUBLIC with its modern equivalent PUBLIC.

Also, since you mention both CMakeLists in .../srcDir* are empty, why have them there in the first place? You can easily get rid of both them and the related add_subdirectory calls.

Upvotes: 10

Related Questions