1

I'm building a static library and linking it into my executable target. The library builds fine in a vacuum, but when I try to include a header from the library, I get a "No such file" error pointing at the static library's dependency.

My understanding is that my static lib should privately include its dependencies, and the consumer shouldn't have to do anything besides linking the library. Is this wrong? Or am I just including the static lib's dependencies improperly?

CMakeLists.txt for the static lib:

# Find SDL2 and associated libs
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_mixer REQUIRED)
find_package(SDL2_ttf REQUIRED)

# Build static library dependency SDL2pp
set(SDL2PP_WITH_IMAGE ON)
set(SDL2PP_WITH_MIXER ON)
set(SDL2PP_WITH_TTF ON)
add_subdirectory("${PROJECT_SOURCE_DIR}/../Libraries/libSDL2pp/"
                 "${CMAKE_CURRENT_BINARY_DIR}/Libraries/libSDL2pp/")


# Add our static library target
add_library(Framework_Game STATIC
    Private/GameManager.cpp
    Public/GameManager.h
)

target_include_directories(Framework_Game
    PRIVATE
        ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} 
        ${SDL2_MIXER_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS}
        ${SDL2PP_INCLUDE_DIRS}
        ${CMAKE_CURRENT_SOURCE_DIR}/Private
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/Public
)

target_link_libraries(Framework_Game 
    PRIVATE
        ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES}
        ${SDL2_MIXER_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS}
        ${SDL2PP_LIBRARIES} 
)

CMakeLists.txt for the executable:

add_executable(NewWorlds Launch.cpp)

target_link_libraries(NewWorlds 
    PRIVATE
        Framework_Game
)

GameManager.h includes SDL2pp with #include <SDL2pp/SDL2pp.hh. I'm then including it in Launch.cpp with #include <GameManager.h>, which gives the error SDL2pp/SDL2pp.hh: No such file or directory

2 Answers 2

3

You made the SDL2pp dependency private for Framework_Game thus it doesn't propagate to targets depending on Framework_Game. I don't know the SDL2pp library so I can't tell exactly which of these need to be public, but

target_include_directories(Framework_Game
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/Private
    PUBLIC
        ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} 
        ${SDL2_MIXER_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS}
        ${SDL2PP_INCLUDE_DIRS}
        ${CMAKE_CURRENT_SOURCE_DIR}/Public
)

target_link_libraries(Framework_Game 
    PUBLIC
        ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES}
        ${SDL2_MIXER_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS}
        ${SDL2PP_LIBRARIES} 
)

will definitely work.

Sign up to request clarification or add additional context in comments.

Comments

1

My understanding is that my static lib should privately include its dependencies, and the consumer shouldn't have to do anything besides linking the library. Is this wrong? Or am I just including the static lib's dependencies improperly?

This is a design decision, but yes, that's usually the good practice. But it means that no SDL header must be included in the public headers of the library! That's your job. Otherwise, you need to propagate the dependency, as Corristo said.

2 Comments

Using either approach, I get past the original issue but run into SDL2pp getting undefined reference errors as it tries to call SDL functions. Is there something I'm missing in supplying SDL2pp with the SDL dependencies? This is a new issue, SDL2pp was working fine before I moved this code out to a library.
Got it to work by changing SDL2pp from passing old-style variables to Modern target-based linking.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.