วิธีใช้ glib-compile-resources กับ CMake

Sep 02 2020

เมื่อโครงการ GTK เติบโตขึ้นแอปพลิเคชัน GTK มักจะรวมเข้ากับ gresources เพื่อแยกโค้ดและการออกแบบ UI สิ่งนี้มีประโยชน์มากเพราะนักออกแบบ UI / UX ไม่จำเป็นต้องรู้รหัสเพื่อที่จะ ... ออกแบบได้ดีและท้ายที่สุดก็มีส่วนร่วมในทักษะและความพยายามในโครงการ

ไม่เพียง แต่นักออกแบบเท่านั้น แต่โปรแกรมเมอร์ยังได้รับประโยชน์มากมาย! เนื่องจากโค้ดกลายเป็น "ตรรกะหรือการแก้ปัญหา" อย่างหนักแทนที่จะรักษาทั้ง UI และรหัสตรรกะไว้ด้วยกันในไฟล์เดียว

อย่างไรก็ตามในการรวบรวม GResource ของเราเราจำเป็นต้องมีglib-compile-resourcesเครื่องมือยูทิลิตี้ คำสั่งมักจะเป็นดังนี้:

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

แต่ฉันจะสร้างบิลด์สคริปต์ที่รวบรวมไฟล์ gresource และเชื่อมโยงกับโครงการเป้าหมายของเราได้อย่างไร ฉันยังคงเป็นมือใหม่ที่เรียนรู้ CMake และฉันก็รู้มาไกลพอที่จะรู้ว่าเป้าหมายคืออะไรวิธีตั้งค่าตัวแปรวิธีเชื่อมโยงเป้าหมายและวิธีดึงแพ็คเกจ GTK ที่จำเป็นสำหรับการเชื่อมโยง แต่ฉันไม่รู้ว่าจะดำเนินการแก้ไขสิ่งนี้อย่างไรต่อไป :(

คำตอบ

4 KeyikedalubeNdang Sep 02 2020 at 09:19

วิธีแก้ปัญหานี้ใช้add_custom_command()เพื่อรวบรวมแหล่งข้อมูลของคุณ แต่ก่อนอื่นนี่คือรายละเอียดของสิ่งที่คุณต้องการสำหรับสคริปต์ CMake ของคุณ:

  1. ดึงทรัพยากร glib-compileเป็นโปรแกรมปฏิบัติการ -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)

คำอธิบายสั้น ๆ

add_custom_command ()

  • OUTPUT - นี่คือไฟล์ทรัพยากรที่คุณสร้างขึ้น
  • WORKING_DIRECTORY - ตำแหน่งของไฟล์ XML และ glade ของคุณ
  • VERBATIM- ทำให้แน่ใจว่าการCOMMANDรับของเราARGSไม่เปลี่ยนแปลง
  • MAIN_DEPENDENCY - สำหรับ glib-compile-resources <input-file>
  • DEPENDS- ไฟล์ glade ของคุณ หากไฟล์ใด ๆ เปลี่ยนแปลงบิลด์เป้าหมายของคุณจะถูกทริกเกอร์ :)

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 add_custom_command(... DEPENDS)พึ่งพาได้รับค่าเอาท์พุทพึ่งพาใหม่และส่งมาที่ ตอนนี้เรามี CMake อัจฉริยะแล้ว :)

หากคุณต้องการใช้วิธีนี้โพสต์ด้านล่างจะมีประโยชน์มาก:

ใช้รายการเป็นการอ้างอิงบน add_custom_command

โชคดี :)