From dee3777ffd54a40e966914a2942f7cdd92b93c86 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sat, 22 Apr 2023 11:54:27 +0400 Subject: [PATCH] Add cppgir support --- .gitmodules | 3 ++ external/glib/CMakeLists.txt | 44 ++++++++------------- external/glib/cppgir | 1 + external/glib/generate_cppgir.cmake | 43 ++++++++++++++++++++ external/glib/generate_dbus.cmake | 61 +++++++++++++++++++++++++++++ external/glib/generate_gir.cmake | 45 +++++++++++++++++++++ generate_target.cmake | 9 ++++- 7 files changed, 176 insertions(+), 30 deletions(-) create mode 100644 .gitmodules create mode 160000 external/glib/cppgir create mode 100644 external/glib/generate_cppgir.cmake create mode 100644 external/glib/generate_dbus.cmake create mode 100644 external/glib/generate_gir.cmake diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c92fbea --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/glib/cppgir"] + path = external/glib/cppgir + url = https://gitlab.com/mnauw/cppgir.git diff --git a/external/glib/CMakeLists.txt b/external/glib/CMakeLists.txt index def4376..66385e3 100644 --- a/external/glib/CMakeLists.txt +++ b/external/glib/CMakeLists.txt @@ -7,33 +7,21 @@ add_library(external_glib INTERFACE IMPORTED GLOBAL) add_library(desktop-app::external_glib ALIAS external_glib) +function(add_cppgir) # isolate scope + set(BUILD_TESTING OFF) + set(BUILD_DOC OFF) + set(CMAKE_DISABLE_FIND_PACKAGE_Qt5Core ON) + add_subdirectory(cppgir) +endfunction() +add_cppgir() + +include(generate_cppgir.cmake) +generate_cppgir(external_glib Gio-2.0) + find_package(PkgConfig REQUIRED) -pkg_check_modules(GLIB2 REQUIRED IMPORTED_TARGET glib-2.0) -pkg_check_modules(GOBJECT REQUIRED IMPORTED_TARGET gobject-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) -pkg_check_modules(GIO_UNIX REQUIRED IMPORTED_TARGET gio-unix-2.0) +pkg_check_modules(GLIB2 REQUIRED IMPORTED_TARGET glib-2.0 gobject-2.0 gio-2.0 gio-unix-2.0) -if (DESKTOP_APP_USE_PACKAGED) - target_link_libraries(external_glib - INTERFACE - PkgConfig::GIO_UNIX - PkgConfig::GIO - PkgConfig::GOBJECT - PkgConfig::GLIB2 - ) -else() - target_include_directories(external_glib SYSTEM - INTERFACE - ${GIO_UNIX_INCLUDE_DIRS} - ${GIO_INCLUDE_DIRS} - ${GOBJECT_INCLUDE_DIRS} - ${GLIB2_INCLUDE_DIRS} - ) - - target_link_libraries(external_glib - INTERFACE - gio-2.0 - gobject-2.0 - glib-2.0 - ) -endif() +target_link_libraries(external_glib +INTERFACE + PkgConfig::GLIB2 +) diff --git a/external/glib/cppgir b/external/glib/cppgir new file mode 160000 index 0000000..bb2b437 --- /dev/null +++ b/external/glib/cppgir @@ -0,0 +1 @@ +Subproject commit bb2b437760a707fde6d4f51a7679fc4cc6410c3c diff --git a/external/glib/generate_cppgir.cmake b/external/glib/generate_cppgir.cmake new file mode 100644 index 0000000..675d98c --- /dev/null +++ b/external/glib/generate_cppgir.cmake @@ -0,0 +1,43 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +function(generate_cppgir target_name gir) + # cppgir generates all the dependent headers everytime, better to have a global folder + set(gen_dst ${CMAKE_BINARY_DIR}/gen) + file(MAKE_DIRECTORY ${gen_dst}) + + set(gen_timestamp ${gen_dst}/${target_name}_cppgir.timestamp) + + add_custom_command( + OUTPUT + ${gen_timestamp} + COMMAND + cppgir + --class + --expected + --ignore + ${cmake_helpers_loc}/external/glib/cppgir/data/cppgir.ignore:${cmake_helpers_loc}/external/glib/cppgir/data/cppgir_unix.ignore + --output + ${gen_dst} + ${gir} + COMMAND + echo 1> ${gen_timestamp} + COMMENT "Generating C++ wrapper for ${gir} (${target_name})" + DEPENDS + cppgir + $<$:${gir}> + ) + generate_target(${target_name} cppgir ${gen_timestamp} "" ${gen_dst}) + + get_target_property(target_type ${target_name} TYPE) + if (${target_type} STREQUAL "INTERFACE_LIBRARY") + target_link_libraries(${target_name} INTERFACE gi) + target_compile_definitions(${target_name} INTERFACE GI_INLINE GI_OBJECT_NEWV) + else() + target_link_libraries(${target_name} PUBLIC gi) + target_compile_definitions(${target_name} PUBLIC GI_INLINE GI_OBJECT_NEWV) + endif() +endfunction() diff --git a/external/glib/generate_dbus.cmake b/external/glib/generate_dbus.cmake new file mode 100644 index 0000000..663a344 --- /dev/null +++ b/external/glib/generate_dbus.cmake @@ -0,0 +1,61 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +include(${cmake_helpers_loc}/external/glib/generate_gir.cmake) +include(${cmake_helpers_loc}/external/glib/generate_cppgir.cmake) + +function(generate_dbus target_name interface_prefix namespace interface_file) + find_program(DESKTOP_APP_GDBUSCODEGEN gdbus-codegen REQUIRED) + + set(gen_dst ${CMAKE_CURRENT_BINARY_DIR}/gen) + file(MAKE_DIRECTORY ${gen_dst}) + + set(gen_timestamp ${gen_dst}/${target_name}_${namespace}_dbus.timestamp) + set(gen_files + ${gen_dst}/${target_name}_${namespace}_dbus.c + ${gen_dst}/${target_name}_${namespace}_dbus.h + ) + + add_custom_command( + OUTPUT + ${gen_timestamp} + BYPRODUCTS + ${gen_files} + COMMAND + ${DESKTOP_APP_GDBUSCODEGEN} + --interface-prefix + ${interface_prefix} + --generate-c-code + ${gen_dst}/${target_name}_${namespace}_dbus + --c-namespace + ${namespace} + --c-generate-object-manager + ${interface_file} + COMMAND + echo 1> ${gen_timestamp} + COMMENT "Generating D-Bus C code for ${namespace} (${target_name})" + DEPENDS + ${DESKTOP_APP_GDBUSCODEGEN} + ) + + add_library(${target_name}_${namespace}_dbus STATIC) + init_target(${target_name}_${namespace}_dbus "(gen)") + target_link_libraries(${target_name}_${namespace}_dbus PUBLIC desktop-app::external_glib) + generate_target(${target_name}_${namespace}_dbus timestamp ${gen_timestamp} "${gen_files}" ${gen_dst}) + + add_library(${target_name}_${namespace} INTERFACE) + init_target_folder(${target_name}_${namespace} "(gen)") + target_link_libraries(${target_name}_${namespace} INTERFACE ${target_name}_${namespace}_dbus) + generate_gir(${target_name}_${namespace} ${namespace} Gio-2.0 ${target_name}_${namespace}_dbus) + generate_cppgir(${target_name}_${namespace} ${CMAKE_CURRENT_BINARY_DIR}/gen/${target_name}_${namespace}.gir) + + get_target_property(target_type ${target_name} TYPE) + if (${target_type} STREQUAL "INTERFACE_LIBRARY") + target_link_libraries(${target_name} INTERFACE ${target_name}_${namespace}) + else() + target_link_libraries(${target_name} PUBLIC ${target_name}_${namespace}) + endif() +endfunction() diff --git a/external/glib/generate_gir.cmake b/external/glib/generate_gir.cmake new file mode 100644 index 0000000..81fe796 --- /dev/null +++ b/external/glib/generate_gir.cmake @@ -0,0 +1,45 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +function(generate_gir target_name namespace deps src_target_name) + find_program(DESKTOP_APP_GIRSCANNER g-ir-scanner REQUIRED) + + set(gen_dst ${CMAKE_CURRENT_BINARY_DIR}/gen) + file(MAKE_DIRECTORY ${gen_dst}) + + set(gen_timestamp ${gen_dst}/${target_name}_gir.timestamp) + set(gen_file ${gen_dst}/${target_name}.gir) + + add_custom_command( + OUTPUT + ${gen_timestamp} + BYPRODUCTS + ${gen_file} + COMMAND + ${DESKTOP_APP_GIRSCANNER} + -n + ${namespace} + --nsversion + 1.0 + -l + $ + --c-include + "$,INCLUDE,\\.h$>,$--c-include>" + -i + "$-i>" + -o + ${gen_file} + "$" + COMMAND + echo 1> ${gen_timestamp} + COMMAND_EXPAND_LISTS + COMMENT "Generating GIR (${target_name})" + DEPENDS + ${DESKTOP_APP_GIRSCANNER} + ${src_target_name} + ) + generate_target(${target_name} gir ${gen_timestamp} "${gen_file}" ${gen_dst}) +endfunction() diff --git a/generate_target.cmake b/generate_target.cmake index 611067f..9dc6eb8 100644 --- a/generate_target.cmake +++ b/generate_target.cmake @@ -8,7 +8,12 @@ function(generate_target parent_name postfix generated_timestamp generated_files add_custom_target(${parent_name}_${postfix} DEPENDS ${generated_timestamp}) init_target_folder(${parent_name}_${postfix} "(gen)") add_dependencies(${parent_name} ${parent_name}_${postfix}) - target_sources(${parent_name} PRIVATE ${generated_files}) - target_include_directories(${parent_name} PUBLIC ${gen_dst}) + get_target_property(parent_type ${parent_name} TYPE) + if (${parent_type} STREQUAL "INTERFACE_LIBRARY") + target_include_directories(${parent_name} SYSTEM INTERFACE ${gen_dst}) + else() + target_include_directories(${parent_name} SYSTEM PUBLIC ${gen_dst}) + target_sources(${parent_name} PRIVATE ${generated_files}) + endif() source_group("(gen)" FILES ${generated_files}) endfunction()