如何在 CMake 中使用 glib-compile-resources

Key*_*ang 2 gtk cmake

随着任何 GTK 项目的发展,GTK 应用程序往往与资源捆绑在一起,以分离代码和 UI 设计。这非常有用,因为 UI/UX 设计人员不需要知道代码就可以……做好设计并最终为项目贡献他们的技能和努力。

不仅设计师而且程序员也受益匪浅!因为代码变得非常“逻辑或解决问题”,而不是在一个文件中同时维护 UI 和逻辑代码。

但是,要编译我们的 GResource,我们需要glib-compile-resources实用工具。命令通常是这样的:

glib-compile-resources --generate-source --target=<output-file> <input-file>
Run Code Online (Sandbox Code Playgroud)

但是如何创建一个构建脚本来编译我们的 gresource 文件并将其与我们的目标项目链接?我仍然是学习 CMake 的新手,我已经足够了解目标是什么,如何设置变量,如何链接目标,以及如何拉入所需的 GTK 包进行链接。但我不知道如何继续解决这个问题:(

Key*_*ang 6

对此的解决方案是使用add_custom_command()编译您的资源。但首先这里是您的 CMake 脚本所需的细分:

  1. glib-compile-resources作为可执行程序引入-find_program()
  2. 定义如何编译您的 gresource - add_custom_command()
  3. 然后定义您的自定义目标 - add_custom_target()
  4. 告诉 CMake 资源是一个生成的文件 - set_source_files_properties()
  5. 最后,将您的自定义目标作为依赖项添加到您的项目目标中 - add_dependencies()

这是一个示例 CMake 脚本:

cmake_minimum_required(VERSION 3.15)

project(dummy)

# Step 1:
find_program(GLIB_COMPILE_RESOURCES NAMES glib-compile-resources REQUIRED)

set(GRESOURCE_C   test.gresource.c)
set(GRESOURCE_XML test.gresource.xml)

# Step 2:
add_custom_command(
    OUTPUT ${GRESOURCE_C}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMAND ${GLIB_COMPILE_RESOURCES}
    ARGS
        --target=${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C}
        ${GRESOURCE_XML}
    VERBATIM
    MAIN_DEPENDENCY ${GRESOURCE_XML}
    DEPENDS
        for.glade
        bar.glade
)

# Step 3:
add_custom_target(
    dummy-resource
    DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C}
)

# Step 4:
add_executable(${PROJECT_NAME} dummy.c ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C})
set_source_files_properties(
    ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C}
    PROPERTIES GENERATED TRUE
)

# Step 5:
add_dependencies(${PROJECT_NAME} dummy-resource)
Run Code Online (Sandbox Code Playgroud)

简要说明

add_custom_command()

  • OUTPUT - 这是你生成的资源文件
  • WORKING_DIRECTORY - 您的 XML 和 Glade 文件所在的位置
  • VERBATIM- 确保我们COMMAND收到ARGS不变
  • MAIN_DEPENDENCY - 对于 glib-compile-resources <input-file>
  • DEPENDS- 您的林地文件。如果任何文件发生更改,则会触发您的目标构建:)

add_custom_target()

  • dummy-resource - 那是您的自定义目标名称
  • DEPENDS - 您的自定义目标需要的输出以触发您的自定义命令

set_source_files_properties()

当您第一次使用cmake命令生成构建文件时,您的资源文件尚未生成。所以 CMake 会出错,因为它不知道你的资源文件在哪里或者它来自哪里。我们需要告诉CMake“不要失败,我们的资源文件是稍后生成的”

使用--generate-dependencies而不是硬编码

现在您可能会注意到我们正在重复我们的工作,即,当我们添加新的 Glade 文件或删除现有的文件(或任何其他资源,如图标、声音、css 文件等)时,我们必须同时编辑我们的 XML 和 CMake 脚本文件。glib-compile-resources已经提供了依赖生成,因此我们可以在我们的 CMake 脚本中使用它并使其变得智能。

诀窍是将您的 .xml 文件更改为 .xml.in 作为配置文件。因此,当该配置文件更改时,您可以使用 --generate-dependencies 调用 glib 工具,获取新的依赖项输出值,并将其发送到add_custom_command(... DEPENDS). 现在我们有了一个智能的 CMake :)

如果您想采用这种方法,那么下面的帖子将非常有帮助:

使用列表作为 add_custom_command 的依赖项

祝你好运 :)