Skip to content

Commit 80ba979

Browse files
committed
Add CMake package/dependency find modules to template project
Avoid frustration for newcomers and offer a last resort for resolving dependencies. The dependencies install script may fail in certain OSes or distributions, adding the find modules to template project improves the experience once it falls back to FetchContent in case the package is not found. This change also adopts the "CMake" dir name convention present everywhere in the code base (instead of the originally expected "cmake").
1 parent a3f5172 commit 80ba979

5 files changed

Lines changed: 515 additions & 1 deletion

File tree

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# FindKTX.cmake
2+
#
3+
# Finds the KTX library
4+
#
5+
# This will define the following variables
6+
#
7+
# KTX_FOUND
8+
# KTX_INCLUDE_DIRS
9+
# KTX_LIBRARIES
10+
#
11+
# and the following imported targets
12+
#
13+
# KTX::ktx
14+
#
15+
16+
# Check if we're on Linux - if so, we'll skip the search and directly use FetchContent
17+
if(UNIX AND NOT APPLE)
18+
# On Linux, we assume KTX is not installed and proceed directly to fetching it
19+
set(KTX_FOUND FALSE)
20+
else()
21+
# On non-Linux platforms, try to find KTX using pkg-config first
22+
find_package(PkgConfig QUIET)
23+
if(PKG_CONFIG_FOUND)
24+
pkg_check_modules(PC_KTX QUIET ktx libktx ktx2 libktx2)
25+
endif()
26+
27+
# Try to find KTX using standard find_package
28+
find_path(KTX_INCLUDE_DIR
29+
NAMES ktx.h
30+
PATH_SUFFIXES include ktx KTX ktx2 KTX2
31+
HINTS
32+
${PC_KTX_INCLUDEDIR}
33+
/usr/include
34+
/usr/local/include
35+
$ENV{KTX_DIR}/include
36+
$ENV{VULKAN_SDK}/include
37+
${CMAKE_SOURCE_DIR}/external/ktx/include
38+
)
39+
40+
find_library(KTX_LIBRARY
41+
NAMES ktx ktx2 libktx libktx2
42+
PATH_SUFFIXES lib lib64
43+
HINTS
44+
${PC_KTX_LIBDIR}
45+
/usr/lib
46+
/usr/lib64
47+
/usr/local/lib
48+
/usr/local/lib64
49+
$ENV{KTX_DIR}/lib
50+
$ENV{VULKAN_SDK}/lib
51+
${CMAKE_SOURCE_DIR}/external/ktx/lib
52+
)
53+
54+
include(FindPackageHandleStandardArgs)
55+
find_package_handle_standard_args(KTX
56+
REQUIRED_VARS KTX_INCLUDE_DIR KTX_LIBRARY
57+
FAIL_MESSAGE "" # Suppress the error message to allow our fallback
58+
)
59+
60+
# Debug output if KTX is not found (only on non-Linux platforms)
61+
if(NOT KTX_FOUND)
62+
message(STATUS "KTX include directory search paths: ${PC_KTX_INCLUDEDIR}, /usr/include, /usr/local/include, $ENV{KTX_DIR}/include, $ENV{VULKAN_SDK}/include, ${CMAKE_SOURCE_DIR}/external/ktx/include")
63+
message(STATUS "KTX library search paths: ${PC_KTX_LIBDIR}, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64, $ENV{KTX_DIR}/lib, $ENV{VULKAN_SDK}/lib, ${CMAKE_SOURCE_DIR}/external/ktx/lib")
64+
endif()
65+
endif()
66+
67+
if(KTX_FOUND)
68+
set(KTX_INCLUDE_DIRS ${KTX_INCLUDE_DIR})
69+
set(KTX_LIBRARIES ${KTX_LIBRARY})
70+
71+
if(NOT TARGET KTX::ktx)
72+
add_library(KTX::ktx UNKNOWN IMPORTED)
73+
set_target_properties(KTX::ktx PROPERTIES
74+
IMPORTED_LOCATION "${KTX_LIBRARIES}"
75+
INTERFACE_INCLUDE_DIRECTORIES "${KTX_INCLUDE_DIRS}"
76+
)
77+
endif()
78+
else()
79+
# If not found, use FetchContent to download and build
80+
include(FetchContent)
81+
82+
# Only show the message on non-Linux platforms
83+
if(NOT (UNIX AND NOT APPLE))
84+
message(STATUS "KTX not found, fetching from GitHub...")
85+
endif()
86+
87+
FetchContent_Declare(
88+
ktx
89+
GIT_REPOSITORY https://github.com/KhronosGroup/KTX-Software.git
90+
GIT_TAG v4.4.2 # Use a specific tag for stability
91+
)
92+
93+
# Set options to minimize build time and dependencies
94+
set(KTX_FEATURE_TOOLS OFF CACHE BOOL "Build KTX tools" FORCE)
95+
set(KTX_FEATURE_DOC OFF CACHE BOOL "Build KTX documentation" FORCE)
96+
set(KTX_FEATURE_TESTS OFF CACHE BOOL "Build KTX tests" FORCE)
97+
98+
FetchContent_MakeAvailable(ktx)
99+
100+
# Create an alias to match the expected target name
101+
if(NOT TARGET KTX::ktx)
102+
add_library(KTX::ktx ALIAS ktx)
103+
endif()
104+
105+
set(KTX_FOUND TRUE)
106+
endif()
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Findstb.cmake
2+
#
3+
# Finds the stb library (specifically stb_image.h)
4+
#
5+
# This will define the following variables
6+
#
7+
# stb_FOUND
8+
# stb_INCLUDE_DIRS
9+
#
10+
# and the following imported targets
11+
#
12+
# stb::stb
13+
#
14+
15+
# Try to find the package using pkg-config first
16+
find_package(PkgConfig QUIET)
17+
if(PKG_CONFIG_FOUND)
18+
pkg_check_modules(PC_stb QUIET stb)
19+
endif()
20+
21+
# Find the include directory
22+
find_path(stb_INCLUDE_DIR
23+
NAMES stb_image.h
24+
PATHS
25+
${PC_stb_INCLUDE_DIRS}
26+
/usr/include
27+
/usr/local/include
28+
$ENV{VULKAN_SDK}/include
29+
${ANDROID_NDK}/sources/third_party
30+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../external
31+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../third_party
32+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/external
33+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/third_party
34+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/include
35+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../../external
36+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../../third_party
37+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../../include
38+
PATH_SUFFIXES stb
39+
)
40+
41+
# If the include directory wasn't found, use FetchContent to download and build
42+
if(NOT stb_INCLUDE_DIR)
43+
# If not found, use FetchContent to download and build
44+
include(FetchContent)
45+
46+
message(STATUS "stb_image.h not found, fetching from GitHub...")
47+
FetchContent_Declare(
48+
stb
49+
GIT_REPOSITORY https://github.com/nothings/stb.git
50+
GIT_TAG master # stb doesn't use version tags, so we use master
51+
)
52+
53+
# Set policy to suppress the deprecation warning
54+
if(POLICY CMP0169)
55+
cmake_policy(SET CMP0169 OLD)
56+
endif()
57+
58+
# Populate the content
59+
FetchContent_GetProperties(stb)
60+
if(NOT stb_POPULATED)
61+
FetchContent_Populate(stb)
62+
endif()
63+
64+
# stb is a header-only library with no CMakeLists.txt, so we just need to set the include directory
65+
set(stb_INCLUDE_DIR ${stb_SOURCE_DIR})
66+
endif()
67+
68+
# Set the variables
69+
include(FindPackageHandleStandardArgs)
70+
find_package_handle_standard_args(stb
71+
REQUIRED_VARS stb_INCLUDE_DIR
72+
)
73+
74+
if(stb_FOUND)
75+
set(stb_INCLUDE_DIRS ${stb_INCLUDE_DIR})
76+
77+
# Create an imported target
78+
if(NOT TARGET stb::stb)
79+
add_library(stb::stb INTERFACE IMPORTED)
80+
set_target_properties(stb::stb PROPERTIES
81+
INTERFACE_INCLUDE_DIRECTORIES "${stb_INCLUDE_DIRS}"
82+
)
83+
endif()
84+
endif()
85+
86+
mark_as_advanced(stb_INCLUDE_DIR)
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Findtinygltf.cmake
2+
#
3+
# Finds the tinygltf library
4+
#
5+
# This will define the following variables
6+
#
7+
# tinygltf_FOUND
8+
# tinygltf_INCLUDE_DIRS
9+
#
10+
# and the following imported targets
11+
#
12+
# tinygltf::tinygltf
13+
#
14+
15+
# First, try to find nlohmann_json
16+
find_package(nlohmann_json QUIET)
17+
if(NOT nlohmann_json_FOUND)
18+
include(FetchContent)
19+
message(STATUS "nlohmann_json not found, fetching v3.12.0 from GitHub...")
20+
FetchContent_Declare(
21+
nlohmann_json
22+
GIT_REPOSITORY https://github.com/nlohmann/json.git
23+
GIT_TAG v3.12.0 # Use a specific tag for stability
24+
)
25+
FetchContent_MakeAvailable(nlohmann_json)
26+
endif()
27+
28+
# Try to find tinygltf using standard find_package
29+
find_path(tinygltf_INCLUDE_DIR
30+
NAMES tiny_gltf.h
31+
PATHS
32+
${PC_tinygltf_INCLUDE_DIRS}
33+
/usr/include
34+
/usr/local/include
35+
$ENV{VULKAN_SDK}/include
36+
${ANDROID_NDK}/sources/third_party
37+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../external
38+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../third_party
39+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/external
40+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/third_party
41+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../attachments/include
42+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../../external
43+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../../third_party
44+
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../../include
45+
PATH_SUFFIXES tinygltf include
46+
)
47+
48+
# If not found, use FetchContent to download and build
49+
if(NOT tinygltf_INCLUDE_DIR)
50+
# If not found, use FetchContent to download and build
51+
include(FetchContent)
52+
53+
message(STATUS "tinygltf not found, fetching from GitHub...")
54+
FetchContent_Declare(
55+
tinygltf
56+
GIT_REPOSITORY https://github.com/syoyo/tinygltf.git
57+
GIT_TAG v2.8.18 # Use a specific tag for stability
58+
)
59+
60+
# Set policy to suppress the deprecation warning
61+
if(POLICY CMP0169)
62+
cmake_policy(SET CMP0169 OLD)
63+
endif()
64+
65+
# Populate the content but don't configure it yet
66+
FetchContent_GetProperties(tinygltf)
67+
if(NOT tinygltf_POPULATED)
68+
FetchContent_Populate(tinygltf)
69+
70+
# Update the minimum required CMake version to avoid deprecation warning
71+
file(READ "${tinygltf_SOURCE_DIR}/CMakeLists.txt" TINYGLTF_CMAKE_CONTENT)
72+
string(REPLACE "cmake_minimum_required(VERSION 3.6)"
73+
"cmake_minimum_required(VERSION 3.10)"
74+
TINYGLTF_CMAKE_CONTENT "${TINYGLTF_CMAKE_CONTENT}")
75+
file(WRITE "${tinygltf_SOURCE_DIR}/CMakeLists.txt" "${TINYGLTF_CMAKE_CONTENT}")
76+
77+
# Create a symbolic link to make nlohmann/json.hpp available
78+
if(EXISTS "${tinygltf_SOURCE_DIR}/json.hpp")
79+
file(MAKE_DIRECTORY "${tinygltf_SOURCE_DIR}/nlohmann")
80+
file(CREATE_LINK "${tinygltf_SOURCE_DIR}/json.hpp" "${tinygltf_SOURCE_DIR}/nlohmann/json.hpp" SYMBOLIC)
81+
endif()
82+
83+
# Set tinygltf to header-only mode
84+
set(TINYGLTF_HEADER_ONLY ON CACHE BOOL "Use header only version" FORCE)
85+
set(TINYGLTF_INSTALL OFF CACHE BOOL "Do not install tinygltf" FORCE)
86+
87+
# Add the subdirectory after modifying the CMakeLists.txt
88+
add_subdirectory(${tinygltf_SOURCE_DIR} ${tinygltf_BINARY_DIR})
89+
else()
90+
# If already populated, just make it available
91+
FetchContent_MakeAvailable(tinygltf)
92+
endif()
93+
94+
# Get the include directory from the target
95+
get_target_property(tinygltf_INCLUDE_DIR tinygltf INTERFACE_INCLUDE_DIRECTORIES)
96+
if(NOT tinygltf_INCLUDE_DIR)
97+
# If we can't get the include directory from the target, use the source directory
98+
FetchContent_GetProperties(tinygltf SOURCE_DIR tinygltf_SOURCE_DIR)
99+
set(tinygltf_INCLUDE_DIR ${tinygltf_SOURCE_DIR})
100+
endif()
101+
endif()
102+
103+
include(FindPackageHandleStandardArgs)
104+
find_package_handle_standard_args(tinygltf
105+
REQUIRED_VARS tinygltf_INCLUDE_DIR
106+
)
107+
108+
if(tinygltf_FOUND)
109+
set(tinygltf_INCLUDE_DIRS ${tinygltf_INCLUDE_DIR})
110+
111+
if(NOT TARGET tinygltf::tinygltf)
112+
add_library(tinygltf::tinygltf INTERFACE IMPORTED)
113+
set_target_properties(tinygltf::tinygltf PROPERTIES
114+
INTERFACE_INCLUDE_DIRECTORIES "${tinygltf_INCLUDE_DIRS}"
115+
INTERFACE_COMPILE_DEFINITIONS "TINYGLTF_IMPLEMENTATION;TINYGLTF_NO_EXTERNAL_IMAGE;TINYGLTF_NO_STB_IMAGE;TINYGLTF_NO_STB_IMAGE_WRITE"
116+
)
117+
if(TARGET nlohmann_json::nlohmann_json)
118+
target_link_libraries(tinygltf::tinygltf INTERFACE nlohmann_json::nlohmann_json)
119+
endif()
120+
endif()
121+
elseif(TARGET tinygltf)
122+
# If find_package_handle_standard_args failed but we have a tinygltf target from FetchContent
123+
# Create an alias for the tinygltf target
124+
if(NOT TARGET tinygltf::tinygltf)
125+
add_library(tinygltf_wrapper INTERFACE)
126+
target_link_libraries(tinygltf_wrapper INTERFACE tinygltf)
127+
target_compile_definitions(tinygltf_wrapper INTERFACE
128+
TINYGLTF_IMPLEMENTATION
129+
TINYGLTF_NO_EXTERNAL_IMAGE
130+
TINYGLTF_NO_STB_IMAGE
131+
TINYGLTF_NO_STB_IMAGE_WRITE
132+
)
133+
if(TARGET nlohmann_json::nlohmann_json)
134+
target_link_libraries(tinygltf_wrapper INTERFACE nlohmann_json::nlohmann_json)
135+
endif()
136+
add_library(tinygltf::tinygltf ALIAS tinygltf_wrapper)
137+
endif()
138+
139+
# Set variables to indicate that tinygltf was found
140+
set(tinygltf_FOUND TRUE)
141+
set(TINYGLTF_FOUND TRUE)
142+
143+
# Set include directories
144+
get_target_property(tinygltf_INCLUDE_DIR tinygltf INTERFACE_INCLUDE_DIRECTORIES)
145+
if(tinygltf_INCLUDE_DIR)
146+
set(tinygltf_INCLUDE_DIRS ${tinygltf_INCLUDE_DIR})
147+
else()
148+
# If we can't get the include directory from the target, use the source directory
149+
FetchContent_GetProperties(tinygltf SOURCE_DIR tinygltf_SOURCE_DIR)
150+
set(tinygltf_INCLUDE_DIR ${tinygltf_SOURCE_DIR})
151+
set(tinygltf_INCLUDE_DIRS ${tinygltf_INCLUDE_DIR})
152+
153+
# Explicitly set the include directory on the target
154+
if(TARGET tinygltf)
155+
set_target_properties(tinygltf PROPERTIES
156+
INTERFACE_INCLUDE_DIRECTORIES "${tinygltf_INCLUDE_DIR}"
157+
)
158+
endif()
159+
endif()
160+
endif()
161+
162+
mark_as_advanced(tinygltf_INCLUDE_DIR)

0 commit comments

Comments
 (0)