Skip to content

Commit

Permalink
Make godot-cpp installable with cmake config
Browse files Browse the repository at this point in the history
This is so this library can be used via a package manager

The install destination uses CMAKE_INSTALL_ so that package managers
can choose the best location for these artifacts

godot-cpp-dev is the installed component this is so that if this
library is a subproject, the user can install their project without
installing this library by specifying the components

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
  • Loading branch information
ytnuf committed Mar 23, 2024
1 parent a62f633 commit 10df0ac
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 5 deletions.
18 changes: 13 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
# -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 -DANDROID_PLATFORM=android-23 -DCMAKE_BUILD_TYPE=Debug .
# cmake --build .
#
# Installation (after the library is built):
# cmake --install <insert_build_directory_here> --component godot-cpp-dev
#
#
# Protip
# Generate the buildfiles in a sub directory to not clutter the root directory with build files:
# mkdir build && cd build && cmake -G "Unix Makefiles" .. && cmake --build .
Expand Down Expand Up @@ -65,9 +69,8 @@ if(NOT DEFINED BITS)
endif()

# Input from user for GDExtension interface header and the API JSON file
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE STRING "")
set(GODOT_GDEXTENSION_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gdextension" CACHE STRING "")
set(GODOT_CUSTOM_API_FILE "" CACHE STRING "")

set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
Expand Down Expand Up @@ -183,9 +186,10 @@ if (GODOT_CPP_SYSTEM_HEADERS)
endif ()

target_include_directories(${PROJECT_NAME} ${GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
include
${CMAKE_CURRENT_BINARY_DIR}/gen/include
${GODOT_GDEXTENSION_DIR}
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/gen/include>
$<BUILD_INTERFACE:${GODOT_GDEXTENSION_DIR}>
$<INSTALL_INTERFACE:include>
)

# Add the compile flags
Expand Down Expand Up @@ -213,4 +217,8 @@ set_target_properties(${PROJECT_NAME}
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
OUTPUT_NAME "${OUTPUT_NAME}"
EXPORT_NAME "cpp" # This ensures that the exported target is godot::cpp
)


include("cmake/install.cmake")
1 change: 1 addition & 0 deletions cmake/config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/godot-cpp-target.cmake")
67 changes: 67 additions & 0 deletions cmake/install.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

include("CMakePackageConfigHelpers")
include("GNUInstallDirs")

# Install the library and headers to their respective install location
# CMAKE_INSTALL_ are used to allow the package manager to chose the install location
# Components are used so that if godot-cpp is a subproject, the user can chose not to install it
install(TARGETS "godot-cpp"
EXPORT "godot-cpp-target"
ARCHIVE
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
COMPONENT "godot-cpp-dev"
)
install(
DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}/include/"
"${CMAKE_CURRENT_BINARY_DIR}/gen/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
COMPONENT "godot-cpp-dev"
)
# Install the gdextension files
# The gdextension header is assumed to be the root include directory
# As the JSON file is neither a header nor lib file it goes to the datadir
install(FILES "${GODOT_GDEXTENSION_DIR}/gdextension_interface.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
COMPONENT "godot-cpp-dev"
)
install(FILES "${GODOT_GDEXTENSION_API_FILE}"
DESTINATION "${CMAKE_INSTALL_DATADIR}/godot-cpp"
COMPONENT "godot-cpp-dev"
)

# Install the export config file
# This allows this library to be easily consumed by cmake projects:
# find_package("godot-cpp" 4.2.0 CONFIG REQUIRED)
# target_link_libaries("my-project" PRIVATE "godot::cpp")
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake"
RENAME "godot-cpp-config.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/godot-cpp"
COMPONENT "godot-cpp-dev"
)
install(EXPORT "godot-cpp-target"
NAMESPACE "godot::"
DESTINATION "${CMAKE_INSTALL_DATADIR}/godot-cpp"
COMPONENT "godot-cpp-dev"
)

if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19") # string(JSON...) only available in cmake v3.19+
# Use the JSON api file to get the version
file(READ "${GODOT_GDEXTENSION_API_FILE}" GODOT_GDEXTENSION_API_JSON)
# GODOT_API_VERSION_MAJOR = GODOT_GDEXTENSION_API_JSON["header"]["version_major"]
string(JSON GODOT_API_VERSION_MAJOR GET "${GODOT_GDEXTENSION_API_JSON}" "header" "version_major")
string(JSON GODOT_API_VERSION_MINOR GET "${GODOT_GDEXTENSION_API_JSON}" "header" "version_minor")
string(JSON GODOT_API_VERSION_PATCH GET "${GODOT_GDEXTENSION_API_JSON}" "header" "version_patch")
set(GODOT_API_VERSION "${GODOT_API_VERSION_MAJOR}.${GODOT_API_VERSION_MINOR}.${GODOT_API_VERSION_PATCH}")
unset(GODOT_GDEXTENSION_API_JSON)

# Install the config version file so that the gdextension version can be specified in find_package
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/godot-cpp-config-version.cmake"
VERSION "${GODOT_API_VERSION}"
COMPATIBILITY SameMinorVersion
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/godot-cpp-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/godot-cpp"
COMPONENT "godot-cpp-dev"
)
endif()

0 comments on commit 10df0ac

Please sign in to comment.