From c09f7a7296ce9bfc1eaefa17a818fa06af6da867 Mon Sep 17 00:00:00 2001 From: ytnuf <161308826+ytnuf@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:45:55 +0100 Subject: [PATCH] Make godot-cpp installable with cmake config godot-cpp can be installed like this: cmake && make && make install It can be used like this: find_pacakge("godot") target_link_libraries("my_gdextension_project" PRIVATE "godot::cpp") 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 Install pkg-config file for interoperability with other build systems --- CMakeLists.txt | 2 + cmake/godot-cpp.pc.in | 10 +++++ cmake/godotcpp.cmake | 88 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 cmake/godot-cpp.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index ff77368ba6..bf7128b9d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,3 +22,5 @@ include( ${PROJECT_SOURCE_DIR}/cmake/godotcpp.cmake ) godotcpp_options() godotcpp_generate() + +godotcpp_installable() diff --git a/cmake/godot-cpp.pc.in b/cmake/godot-cpp.pc.in new file mode 100644 index 0000000000..f0a206bfe8 --- /dev/null +++ b/cmake/godot-cpp.pc.in @@ -0,0 +1,10 @@ +prefix=${pcfiledir}/../.. +exec_prefix=${prefix} +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ + +Name: @PROJECT_NAME@ +Description: C++ bindings for the Godot script API +Version: @GODOT_API_VERSION@ +Libs: -L${libdir} -l@GODOTCPP_OUTPUT_NAME@ +Cflags: -I${includedir} diff --git a/cmake/godotcpp.cmake b/cmake/godotcpp.cmake index a5c6677964..e0ec1765f3 100644 --- a/cmake/godotcpp.cmake +++ b/cmake/godotcpp.cmake @@ -1,12 +1,14 @@ +include("GNUInstallDirs") + function( godotcpp_options ) #TODO platform #TODO target # Input from user for GDExtension interface header and the API JSON file - set(GODOT_GDEXTENSION_DIR "gdextension" CACHE PATH + set(GODOT_GDEXTENSION_DIR "${PROJECT_SOURCE_DIR}/gdextension" CACHE PATH "Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )" ) - set(GODOT_CUSTOM_API_FILE "" CACHE FILEPATH + set(GODOT_CUSTOM_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json" CACHE FILEPATH "Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`) ( /path/to/custom_api_file )") #TODO generate_bindings @@ -42,6 +44,12 @@ function( godotcpp_options ) option(GODOT_SYSTEM_HEADERS "Expose headers as SYSTEM." ON) option(GODOT_WARNING_AS_ERROR "Treat warnings as errors" OFF) + set(GODOT_USE_HOT_RELOAD "" CACHE BOOL + "Enable the extra accounting required to support hot reload. (ON|OFF)") + + set(GODOT_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/godot" CACHE PATH + "Install path to godot-cpp CMake folder (relative to install prefix)") + # Run options commands on the following to populate cache for all platforms. # This type of thing is typically done conditionally # But as scons shows all options so shall we. @@ -203,10 +211,11 @@ function( godotcpp_generate ) set(GODOT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM) endif () - target_include_directories(${PROJECT_NAME} ${GODOT_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC - include - ${CMAKE_CURRENT_BINARY_DIR}/gen/include - ${GODOT_GDEXTENSION_DIR} + target_include_directories(${PROJECT_NAME} ${GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC + $ + $ + $ + $ ) # Add the compile flags @@ -235,6 +244,73 @@ function( godotcpp_generate ) 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 ) endfunction() + +function( godotcpp_installable ) + include("CMakePackageConfigHelpers") + + # Install the library and headers to their respective install location + # CMAKE_INSTALL_* is used to allow the package manager to chose the install location + install(TARGETS "godot-cpp" + EXPORT "godot-config" + ARCHIVE + DESTINATION "${CMAKE_INSTALL_LIBDIR}" + COMPONENT "godot-cpp" + ) + install( + DIRECTORY + "${PROJECT_SOURCE_DIR}/include/" + "${PROJECT_BINARY_DIR}/gen/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT "godot-cpp" + ) + install(FILES "${GODOT_GDEXTENSION_DIR}/gdextension_interface.h" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT "godot-cpp" + ) + + # Install the export config file + # This allows this library to be easily consumed by cmake projects: + # find_package("godot-cpp" CONFIG REQUIRED) + # target_link_libaries("my-project" PRIVATE "godot::cpp") + install(EXPORT "godot-config" + NAMESPACE "godot::" + DESTINATION "${GODOT_INSTALL_CMAKEDIR}" + COMPONENT "godot-cpp" + ) + + 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_DIR}/extension_api.json" 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}") + # Install the config version file so that the gdextension version can be specified in find_package + write_basic_package_version_file("${PROJECT_BINARY_DIR}/godot-config-version.cmake" + VERSION "${GODOT_API_VERSION}" + COMPATIBILITY SameMinorVersion + ) + install(FILES "${PROJECT_BINARY_DIR}/godot-config-version.cmake" + DESTINATION "${GODOT_INSTALL_CMAKEDIR}" + COMPONENT "godot-cpp" + ) + + #Configure and install the pkg-config file + get_target_property(GODOTCPP_OUTPUT_NAME ${PROJECT_NAME} OUTPUT_NAME) + configure_file( + "${PROJECT_SOURCE_DIR}/cmake/godot-cpp.pc.in" + "${PROJECT_BINARY_DIR}/godot-cpp.pc" + @ONLY + ) + install( + FILES "${PROJECT_BINARY_DIR}/godot-cpp.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" + COMPONENT "godot-cpp" + ) + endif() +endfunction()