Add the vendored dependencies whether or not libakgl is top-level
Embedded with add_subdirectory(), the deps/ submodules a recursive clone just checked out were ignored and find_package(SDL3 REQUIRED) ran instead, so configure failed on a machine with nothing installed. Each dependency is now added by akgl_add_vendored_dependency(), which skips it when the target is already declared or the submodule is missing; the find_package lookups run afterwards for whatever is left. The CTest suppression moves with them and is lifted before this project registers its own suites. Two consequences of the move: pkg-config is only looked for when something has to come from the system, and the build-tree RPATH keys on whether anything was vendored rather than on being the top-level project, so an embedded build's tests can find the satellite libraries too. Verified by configuring and building a consumer that embeds this repository with CMAKE_DISABLE_FIND_PACKAGE_* set for all seven dependencies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
103
CMakeLists.txt
103
CMakeLists.txt
@@ -14,10 +14,10 @@ if(AKGL_COVERAGE)
|
|||||||
find_program(GCOVR_EXECUTABLE gcovr REQUIRED)
|
find_program(GCOVR_EXECUTABLE gcovr REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
# Vendored projects own their test suites. Suppress their CTest registration so
|
||||||
|
# the suite that runs contains only the targets built here. The override is
|
||||||
# Vendored projects own their test suites. Suppress their CTest registration
|
# lifted again below, before this project registers its own tests, so an
|
||||||
# while embedded so the top-level suite contains only targets built here.
|
# embedding consumer's add_test() still reaches CTest.
|
||||||
set(AKGL_SUPPRESS_DEPENDENCY_TESTS TRUE)
|
set(AKGL_SUPPRESS_DEPENDENCY_TESTS TRUE)
|
||||||
function(add_test)
|
function(add_test)
|
||||||
if(NOT AKGL_SUPPRESS_DEPENDENCY_TESTS)
|
if(NOT AKGL_SUPPRESS_DEPENDENCY_TESTS)
|
||||||
@@ -34,53 +34,79 @@ set(JANSSON_WITHOUT_TESTS ON CACHE BOOL "Do not build vendored Jansson tests" FO
|
|||||||
set(JANSSON_EXAMPLES OFF CACHE BOOL "Do not build vendored Jansson examples" FORCE)
|
set(JANSSON_EXAMPLES OFF CACHE BOOL "Do not build vendored Jansson examples" FORCE)
|
||||||
set(JANSSON_BUILD_DOCS OFF CACHE BOOL "Do not build vendored Jansson docs" FORCE)
|
set(JANSSON_BUILD_DOCS OFF CACHE BOOL "Do not build vendored Jansson docs" FORCE)
|
||||||
|
|
||||||
add_subdirectory(deps/jansson EXCLUDE_FROM_ALL)
|
# Add one vendored dependency, if nobody has already declared it and the
|
||||||
add_subdirectory(deps/libakerror EXCLUDE_FROM_ALL)
|
# submodule is actually checked out.
|
||||||
add_subdirectory(deps/libakstdlib EXCLUDE_FROM_ALL)
|
#
|
||||||
add_subdirectory(deps/SDL EXCLUDE_FROM_ALL)
|
# A macro rather than a function on purpose: add_subdirectory() inside a
|
||||||
add_subdirectory(deps/SDL_image EXCLUDE_FROM_ALL)
|
# function runs with that function's variable scope, so every cache-ish variable
|
||||||
add_subdirectory(deps/SDL_mixer EXCLUDE_FROM_ALL)
|
# these projects set for their own subdirectories would be discarded on return.
|
||||||
add_subdirectory(deps/SDL_ttf EXCLUDE_FROM_ALL)
|
macro(akgl_add_vendored_dependency target dir)
|
||||||
|
if(NOT TARGET ${target})
|
||||||
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/CMakeLists.txt")
|
||||||
|
add_subdirectory(${dir} EXCLUDE_FROM_ALL)
|
||||||
|
set(AKGL_VENDORED_DEPENDENCIES TRUE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Added on both paths, not just when this is the top-level project. Embedded
|
||||||
|
# with add_subdirectory(), the submodules under deps/ are sitting right there --
|
||||||
|
# the recursive clone the consumer just did put them there -- and refusing to
|
||||||
|
# configure until SDL3 is installed system-wide is a failure with its own answer
|
||||||
|
# three directories away. if(NOT TARGET ...) means a consumer that has already
|
||||||
|
# declared one of these wins; the EXISTS check means a checkout without
|
||||||
|
# submodules falls through to find_package below.
|
||||||
|
akgl_add_vendored_dependency(jansson::jansson deps/jansson)
|
||||||
|
akgl_add_vendored_dependency(akerror::akerror deps/libakerror)
|
||||||
|
akgl_add_vendored_dependency(akstdlib::akstdlib deps/libakstdlib)
|
||||||
|
akgl_add_vendored_dependency(SDL3::SDL3 deps/SDL)
|
||||||
|
akgl_add_vendored_dependency(SDL3_image::SDL3_image deps/SDL_image)
|
||||||
|
akgl_add_vendored_dependency(SDL3_mixer::SDL3_mixer deps/SDL_mixer)
|
||||||
|
akgl_add_vendored_dependency(SDL3_ttf::SDL3_ttf deps/SDL_ttf)
|
||||||
|
|
||||||
# libakerror 1.0.0 sizes its own status-name registry; consumers no longer do.
|
# libakerror 1.0.0 sizes its own status-name registry; consumers no longer do.
|
||||||
# libakgl claims its status codes at runtime in akgl_heap_init() instead.
|
# libakgl claims its status codes at runtime in akgl_heap_init() instead.
|
||||||
|
|
||||||
set(AKGL_SUPPRESS_DEPENDENCY_TESTS FALSE)
|
set(AKGL_SUPPRESS_DEPENDENCY_TESTS FALSE)
|
||||||
|
|
||||||
else()
|
# Anything the vendored block did not supply has to come from the system.
|
||||||
|
if(NOT (TARGET SDL3::SDL3 AND TARGET SDL3_image::SDL3_image AND
|
||||||
|
TARGET SDL3_mixer::SDL3_mixer AND TARGET SDL3_ttf::SDL3_ttf AND
|
||||||
|
TARGET akerror::akerror AND TARGET akstdlib::akstdlib AND
|
||||||
|
TARGET jansson::jansson))
|
||||||
|
# Only needed to locate installed copies; a fully vendored build does not
|
||||||
|
# require pkg-config to be present at all.
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT TARGET SDL3::SDL3)
|
if(NOT TARGET SDL3::SDL3)
|
||||||
find_package(SDL3 REQUIRED)
|
find_package(SDL3 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
if(NOT TARGET SDL3_image::SDL3_image)
|
if(NOT TARGET SDL3_image::SDL3_image)
|
||||||
find_package(SDL3_image REQUIRED)
|
find_package(SDL3_image REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
if(NOT TARGET SDL3_mixer::SDL3_mixer)
|
if(NOT TARGET SDL3_mixer::SDL3_mixer)
|
||||||
find_package(SDL3_mixer REQUIRED)
|
find_package(SDL3_mixer REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
if(NOT TARGET SDL3_ttf::SDL3_ttf)
|
if(NOT TARGET SDL3_ttf::SDL3_ttf)
|
||||||
find_package(SDL3_ttf REQUIRED)
|
find_package(SDL3_ttf REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
# No version here: libakerror ships no akerrorConfigVersion.cmake, so asking
|
# No version here: libakerror ships no akerrorConfigVersion.cmake, so asking
|
||||||
# for one makes find_package reject every install. The floor is enforced by
|
# for one makes find_package reject every install. The floor is enforced by
|
||||||
# the #error in include/akgl/error.h instead, which feature-tests
|
# the #error in include/akgl/error.h instead, which feature-tests
|
||||||
# AKERR_FIRST_CONSUMER_STATUS.
|
# AKERR_FIRST_CONSUMER_STATUS.
|
||||||
if(NOT TARGET akerror::akerror)
|
if(NOT TARGET akerror::akerror)
|
||||||
find_package(akerror REQUIRED)
|
find_package(akerror REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
# 0.2 rather than bare: libakstdlib 0.2.0 ships an akstdlibConfigVersion.cmake
|
# 0.2 rather than bare: libakstdlib 0.2.0 ships an akstdlibConfigVersion.cmake
|
||||||
# with SameMinorVersion compatibility, mirroring its soname, so this accepts
|
# with SameMinorVersion compatibility, mirroring its soname, so this accepts
|
||||||
# any 0.2.x and refuses 0.3 and 1.0. Unversioned, this path would silently
|
# any 0.2.x and refuses 0.3 and 1.0. Unversioned, this path would silently
|
||||||
# accept an ABI-incompatible libakstdlib.
|
# accept an ABI-incompatible libakstdlib.
|
||||||
if(NOT TARGET akstdlib::akstdlib)
|
if(NOT TARGET akstdlib::akstdlib)
|
||||||
find_package(akstdlib 0.2 REQUIRED)
|
find_package(akstdlib 0.2 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
if(NOT TARGET jansson::jansson)
|
if(NOT TARGET jansson::jansson)
|
||||||
find_package(jansson)
|
find_package(jansson)
|
||||||
endif()
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GAMECONTROLLERDB_H "include/akgl/SDL_GameControllerDB.h")
|
set(GAMECONTROLLERDB_H "include/akgl/SDL_GameControllerDB.h")
|
||||||
@@ -261,8 +287,9 @@ target_link_libraries(charviewer PRIVATE akstdlib::akstdlib akerror::akerror akg
|
|||||||
# project subdirectories that are not on the loader's default search path, so a
|
# project subdirectories that are not on the loader's default search path, so a
|
||||||
# freshly built test aborts before main() with "cannot open shared object file".
|
# freshly built test aborts before main() with "cannot open shared object file".
|
||||||
# Bake those directories into the build-tree RPATH. Installed builds resolve the
|
# Bake those directories into the build-tree RPATH. Installed builds resolve the
|
||||||
# same libraries through find_package and need no help.
|
# same libraries through find_package and need no help, so this keys on whether
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
# anything was actually vendored rather than on being the top-level project.
|
||||||
|
if(AKGL_VENDORED_DEPENDENCIES)
|
||||||
set(AKGL_VENDORED_RPATH
|
set(AKGL_VENDORED_RPATH
|
||||||
"$<TARGET_FILE_DIR:SDL3::SDL3>"
|
"$<TARGET_FILE_DIR:SDL3::SDL3>"
|
||||||
"$<TARGET_FILE_DIR:SDL3_image::SDL3_image>"
|
"$<TARGET_FILE_DIR:SDL3_image::SDL3_image>"
|
||||||
|
|||||||
Reference in New Issue
Block a user