How to use glib-compile-resources with CMake

会有一股神秘感。 提交于 2021-01-05 11:31:47

问题


As any GTK project grows, GTK applications tend to be bundled with gresources to separate out code and UI design. This is very useful because UI/UX designers don't need to know code in order to... well design and ultimately contribute their skills and effort to the project.

Not only designers but programmers too benefit a lot! Because code becomes heavily "logic or problem solving" instead of maintaining both UI and logic code together in one single file.

However, to compile our GResource we need glib-compile-resources utility tool. The command usually goes like this:

glib-compile-resources --generate-source --target=<output-file> <input-file>

But how do I create a build script that compiles our gresource files and link it with our target project? I'm still a newbie learning CMake and I've gotten far enough to know what a target is, how to set a variable, how to link a target, and also how to pull in the required GTK packages for linking. But I don't have any clue how to proceed ahead with solving this :(


回答1:


A solution to this is using add_custom_command() to compile your gresources. But first here's a breakdown of what you need for your CMake script:

  1. Pull in glib-compile-resources as executable program - find_program()
  2. Define how to compile your gresource - add_custom_command()
  3. Then define your custom target - add_custom_target()
  4. Tell CMake that resource is a generated file - set_source_files_properties()
  5. Finally, add your custom target to your project target as a dependency - add_dependencies()

Here's a sample CMake script:

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)

Brief explanation

add_custom_command()

  • OUTPUT - This is your generated resource file
  • WORKING_DIRECTORY - Where your XML and glade files are located
  • VERBATIM - Makes sure our COMMAND receives ARGS unchanged
  • MAIN_DEPENDENCY - for glib-compile-resources <input-file>
  • DEPENDS - Your glade file(s). If any of the file changes then your target build is triggered :)

add_custom_target()

  • dummy-resource - That's your custom target name
  • DEPENDS - The output your custom target needs in order to trigger your custom command

set_source_files_properties()

When you first generate your build files using cmake command, your resource file isn't generated yet. So CMake will run into error because it doesn't know where your resource file is or where it's coming from. We need to tell CMake "Don't fail, our resource file is generated later"

Use --generate-dependencies instead of hard-coding

Now you might notice we are duplicating our effort ie., when we add new glade files or remove existing ones (or any other resources such as icon, sounds, css files, etc) we have to edit both our XML and CMake script files. glib-compile-resources already provide dependency generation so we can use that in our CMake script and make it smart.

The trick is to change your .xml file to .xml.in as a configuration file. So when that configuration file changes, you call glib tool with --generate-dependencies, get new dependency output values, and send that to add_custom_command(... DEPENDS). Now we have an intelligent CMake :)

If you want to approach this method then the below post would be really helpful:

Use list as dependencies on add_custom_command

Good luck :)



来源:https://stackoverflow.com/questions/63697778/how-to-use-glib-compile-resources-with-cmake

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!