Skip to content

Commit 5f31b59

Browse files
committed
Make godot-cpp installable with cmake config
The install destination uses CMAKE_INSTALL_ so that package managers can choose the best location for these artifacts As BUILD_INTERFACE requires absolute path, this means that GODOT_GDEXTENSION_DIR needs to be an absolute path config filename can either be PascalCase or kebab-case, the latter was chosen to be consistent with the package's name (godot-cpp) string(JSON ...) is only available in cmake v3.19, as it is used to obtain the version, this means that config-version file is only created when using cmake v3.19 or later
1 parent 6facde3 commit 5f31b59

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ include( ${PROJECT_SOURCE_DIR}/cmake/godotcpp.cmake )
2222
godotcpp_options()
2323

2424
godotcpp_generate()
25+
26+
godotcpp_install()

cmake/godotcpp.cmake

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ function( godotcpp_options )
44
#TODO target
55

66
# Input from user for GDExtension interface header and the API JSON file
7-
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE PATH
7+
set(GODOT_GDEXTENSION_DIR "${PROJECT_SOURCE_DIR}/gdextension" CACHE PATH
88
"Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )" )
99
set(GODOT_CUSTOM_API_FILE "" CACHE FILEPATH
1010
"Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`) ( /path/to/custom_api_file )")
@@ -42,6 +42,8 @@ function( godotcpp_options )
4242
option(GODOT_SYSTEM_HEADERS "Expose headers as SYSTEM." ON)
4343
option(GODOT_WARNING_AS_ERROR "Treat warnings as errors" OFF)
4444

45+
option(GODOT_CPP_INSTALL "Enables target install for exporting godot-cpp cmake configuration" ON)
46+
4547
# Run options commands on the following to populate cache for all platforms.
4648
# This type of thing is typically done conditionally
4749
# But as scons shows all options so shall we.
@@ -203,10 +205,11 @@ function( godotcpp_generate )
203205
set(GODOT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
204206
endif ()
205207

206-
target_include_directories(${PROJECT_NAME} ${GODOT_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
207-
include
208-
${CMAKE_CURRENT_BINARY_DIR}/gen/include
209-
${GODOT_GDEXTENSION_DIR}
208+
target_include_directories(${PROJECT_NAME} ${GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
209+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
210+
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/gen/include>
211+
$<BUILD_INTERFACE:${GODOT_GDEXTENSION_DIR}>
212+
$<INSTALL_INTERFACE:include>
210213
)
211214

212215
# Add the compile flags
@@ -235,6 +238,67 @@ function( godotcpp_generate )
235238
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
236239
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
237240
OUTPUT_NAME "${OUTPUT_NAME}"
241+
EXPORT_NAME "cpp" # This ensures that the exported target is godot::cpp
238242
)
239243

240244
endfunction()
245+
246+
function( godotcpp_install )
247+
if(NOT GODOT_CPP_INSTALL)
248+
return()
249+
endif()
250+
251+
include("CMakePackageConfigHelpers")
252+
include("GNUInstallDirs")
253+
254+
# Install the library and headers to their respective install location
255+
# CMAKE_INSTALL_ are used to allow the package manager to chose the install location
256+
install(TARGETS "godot-cpp"
257+
EXPORT "godot-cpp-config"
258+
ARCHIVE
259+
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
260+
)
261+
install(
262+
DIRECTORY
263+
"${PROJECT_SOURCE_DIR}/include/"
264+
"${PROJECT_BINARY_DIR}/gen/include/"
265+
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
266+
)
267+
268+
# Install the gdextension files
269+
# The gdextension header is assumed to be the root include directory
270+
# As the JSON file is neither a header nor lib file it goes to the datadir
271+
install(FILES "${GODOT_GDEXTENSION_DIR}/gdextension_interface.h"
272+
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
273+
)
274+
install(FILES "${GODOT_GDEXTENSION_DIR}/extension_api.json"
275+
DESTINATION "${CMAKE_INSTALL_DATADIR}/godot-cpp"
276+
)
277+
278+
# Install the export config file
279+
# This allows this library to be easily consumed by cmake projects:
280+
# find_package("godot-cpp" CONFIG REQUIRED)
281+
# target_link_libaries("my-project" PRIVATE "godot::cpp")
282+
install(EXPORT "godot-cpp-config"
283+
NAMESPACE "godot::"
284+
DESTINATION "${CMAKE_INSTALL_DATADIR}/godot-cpp"
285+
)
286+
287+
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19") # string(JSON...) only available in cmake v3.19+
288+
# Use the JSON api file to get the version
289+
file(READ "${GODOT_GDEXTENSION_DIR}/extension_api.json" GODOT_GDEXTENSION_API_JSON)
290+
# GODOT_API_VERSION_MAJOR = GODOT_GDEXTENSION_API_JSON["header"]["version_major"]
291+
string(JSON GODOT_API_VERSION_MAJOR GET "${GODOT_GDEXTENSION_API_JSON}" "header" "version_major")
292+
string(JSON GODOT_API_VERSION_MINOR GET "${GODOT_GDEXTENSION_API_JSON}" "header" "version_minor")
293+
string(JSON GODOT_API_VERSION_PATCH GET "${GODOT_GDEXTENSION_API_JSON}" "header" "version_patch")
294+
set(GODOT_API_VERSION "${GODOT_API_VERSION_MAJOR}.${GODOT_API_VERSION_MINOR}.${GODOT_API_VERSION_PATCH}")
295+
# Install the config version file so that the gdextension version can be specified in find_package
296+
write_basic_package_version_file("${PROJECT_BINARY_DIR}/godot-cpp-config-version.cmake"
297+
VERSION "${GODOT_API_VERSION}"
298+
COMPATIBILITY SameMinorVersion
299+
)
300+
install(FILES "${PROJECT_BINARY_DIR}/godot-cpp-config-version.cmake"
301+
DESTINATION "${CMAKE_INSTALL_DATADIR}/godot-cpp"
302+
)
303+
endif()
304+
endfunction()

0 commit comments

Comments
 (0)