--- /dev/null
+# Generates a .qrc file named ${QRC_FILE} with path prefix ${PREFIX}, containing
+# all files matching the glob ${PATTERNS} in the current working directory.
+# This script is intended to be executed using the cmake -P syntax, so the
+# arguments we're interested in start at ARGV3.
+
+set(QRC_FILE ${CMAKE_ARGV3})
+set(PREFIX ${CMAKE_ARGV4})
+set(PATTERNS ${CMAKE_ARGV5})
+
+# Find all files matching PATTERNS in the current working directory
+if (PATTERNS)
+ file(GLOB_RECURSE files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${PATTERNS})
+endif()
+
+# Generate a temporary file first, so we don't touch the real thing unless something changed
+set(qrc_tmp ${QRC_FILE}.tmp)
+file(WRITE ${qrc_tmp} "<!DOCTYPE RCC>\n<RCC version=\"1.0\">\n<qresource prefix=\"/${PREFIX}\">\n")
+foreach(file ${files})
+ # Record the timestamp of last modification so changes are detected
+ file(TIMESTAMP ${file} timestamp)
+ file(APPEND ${qrc_tmp} " <file timestamp=\"${timestamp}\">${file}</file>\n")
+endforeach()
+file(APPEND ${qrc_tmp} "</qresource>\n</RCC>\n")
+
+# Check if the newly generated file has the same contents (including timestamps) as the existing one.
+# If the files are the same, don't touch the original to avoid useless rebuilds.
+if (EXISTS ${QRC_FILE})
+ file(MD5 ${QRC_FILE} orig_sum)
+ file(MD5 ${qrc_tmp} tmp_sum)
+ if (NOT orig_sum STREQUAL tmp_sum)
+ file(RENAME ${qrc_tmp} ${QRC_FILE})
+ else()
+ file(REMOVE ${qrc_tmp})
+ endif()
+else()
+ file(RENAME ${qrc_tmp} ${QRC_FILE})
+endif()
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
###################################################################################################
+include(CMakeParseArguments)
+
###################################################################################################
# Adds a library target for a Quassel module.
#
set(TARGET ${target} PARENT_SCOPE)
endfunction()
+###################################################################################################
+# Provides a library that contains data files as a Qt resource (.qrc).
+#
+# quassel_add_resource(QrcName
+# [BASEDIR basedir]
+# [PREFIX prefix]
+# PATTERNS pattern1 pattern2...
+# [DEPENDS dep1 dep2...]
+# )
+#
+# The first parameter is the CamelCased name of the resource; the library target will be called
+# "Quassel::Resource::QrcName". The library provides a Qt resource named "qrcname" (lowercased QrcName)
+# containing the files matching PATTERNS relative to BASEDIR (by default, the current source dir).
+# The resource prefix can be set by giving the PREFIX argument.
+# Additional target dependencies can be specified with DEPENDS.
+#
+function(quassel_add_resource _name)
+ set(options )
+ set(oneValueArgs BASEDIR PREFIX)
+ set(multiValueArgs DEPENDS PATTERNS)
+ cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if (NOT ARG_BASEDIR)
+ set(ARG_BASEDIR ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+ get_filename_component(basedir ${ARG_BASEDIR} REALPATH)
+
+ string(TOLOWER ${_name} lower_name)
+
+ set(qrc_target quassel-qrc-${lower_name})
+ set(qrc_file ${lower_name}.qrc)
+ set(qrc_src qrc_${lower_name}.cpp)
+ set(qrc_filepath ${CMAKE_CURRENT_BINARY_DIR}/${qrc_file})
+ set(qrc_srcpath ${CMAKE_CURRENT_BINARY_DIR}/${qrc_src})
+
+ # This target will always be built, so the qrc file will always be freshly generated.
+ # That way, changes to the glob result are always taken into account.
+ add_custom_target(${qrc_target} VERBATIM
+ COMMENT "Generating ${qrc_file}"
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/GenerateQrc.cmake "${qrc_filepath}" "${ARG_PREFIX}" "${ARG_PATTERNS}"
+ DEPENDS ${ARG_DEPENDS}
+ BYPRODUCTS ${qrc_filepath}
+ WORKING_DIRECTORY ${basedir}
+ )
+ set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${qrc_filepath})
+
+ # RCC sucks and expects the data files relative to the qrc file, with no way to configure it differently.
+ # Only when reading from stdin ("-") it takes the working directory as a base, so we have to use this if
+ # we want to use generated qrc files (which obviously cannot be placed in the source directory).
+ # Since neither autorcc nor qt5_add_resources() support this, we have to invoke rcc manually :(
+ #
+ # On Windows, input redirection apparently doesn't work, however piping does. Use this for all platforms for
+ # consistency, accommodating for the fact that the 'cat' equivalent on Windows is 'type'.
+ if (WIN32)
+ set(cat_cmd type)
+ else()
+ set(cat_cmd cat)
+ endif()
+ add_custom_command(VERBATIM
+ COMMENT "Generating ${qrc_src}"
+ COMMAND ${cat_cmd} "$<SHELL_PATH:${qrc_filepath}>"
+ | "$<SHELL_PATH:$<TARGET_FILE:Qt5::rcc>>" --name "${lower_name}" --output "$<SHELL_PATH:${qrc_srcpath}>" -
+ DEPENDS ${qrc_target}
+ MAIN_DEPENDENCY ${qrc_filepath}
+ OUTPUT ${qrc_srcpath}
+ WORKING_DIRECTORY ${basedir}
+ )
+
+ # Generate library target that can be referenced elsewhere
+ quassel_add_module(Resource::${_name})
+ target_sources(${TARGET} PRIVATE ${qrc_srcpath})
+ set_target_properties(${TARGET} PROPERTIES AUTOMOC OFF AUTOUIC OFF AUTORCC OFF)
+
+ # Set variable for referencing the target from outside
+ set(RESOURCE_TARGET ${TARGET} PARENT_SCOPE)
+endfunction()
+
+###################################################################################################
+# target_link_if_exists(Target
+# [PUBLIC dep1 dep2...]
+# [PRIVATE dep3 dep4...]
+# )
+#
+# Convenience function to add dependencies to a target only if they exist. This is useful when
+# handling targets that are conditionally created, e.g. resource libraries depending on -DEMBED_DATA.
+#
+# NOTE: In order to link a given target, it must already have been created, i.e its subdirectory
+# must already have been added. This is also true for globally visible ALIAS targets that
+# can otherwise be linked to regardless of creation order; "if (TARGET...)" does not
+# support handling this case correctly.
+#
+function(target_link_if_exists _target)
+ set(options )
+ set(oneValueArgs )
+ set(multiValueArgs PUBLIC PRIVATE)
+ cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if (ARG_PUBLIC)
+ foreach(dep ${ARG_PUBLIC})
+ if (TARGET ${dep})
+ target_link_libraries(${_target} PUBLIC ${dep})
+ endif()
+ endforeach()
+ endif()
+
+ if (ARG_PRIVATE)
+ foreach(dep ${ARG_PRIVATE})
+ if (TARGET ${dep})
+ target_link_libraries(${_target} PRIVATE ${dep})
+ endif()
+ endforeach()
+ endif()
+endfunction()
+
######################################
# Macros for dealing with translations
######################################