X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=cmake%2FQuasselMacros.cmake;h=1c0c687ca8137ddae4bd85812bf9a094842cd657;hp=08eaaa8c43e9ceb4bbe6da80d607fd9d5f967333;hb=a078e08390e41385a3145f22e83afbf622621c2f;hpb=18746a803a6cf040c6525f8916bb721c1edbce1f diff --git a/cmake/QuasselMacros.cmake b/cmake/QuasselMacros.cmake index 08eaaa8c..1c0c687c 100644 --- a/cmake/QuasselMacros.cmake +++ b/cmake/QuasselMacros.cmake @@ -6,6 +6,8 @@ # For details see the accompanying COPYING-CMAKE-SCRIPTS file. ################################################################################################### +include(CMakeParseArguments) + ################################################################################################### # Adds a library target for a Quassel module. # @@ -43,37 +45,116 @@ function(quassel_add_module _module) set(TARGET ${target} PARENT_SCOPE) endfunction() -###################################### -# Macros for dealing with translations -###################################### - -# This generates a .ts from a .po file -macro(generate_ts outvar basename) - set(input ${basename}.po) - set(output ${CMAKE_BINARY_DIR}/po/${basename}.ts) - add_custom_command(OUTPUT ${output} - COMMAND $ - ARGS -i ${input} - -of ts - -o ${output} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/po -# This is a workaround to add (duplicate) strings that lconvert missed to the .ts - COMMAND $ - ARGS -silent - ${CMAKE_SOURCE_DIR}/src/ - -ts ${output} - DEPENDS ${basename}.po) - set(${outvar} ${output}) -endmacro(generate_ts outvar basename) - -# This generates a .qm from a .ts file -macro(generate_qm outvar basename) - set(input ${CMAKE_BINARY_DIR}/po/${basename}.ts) - set(output ${CMAKE_BINARY_DIR}/po/${basename}.qm) - add_custom_command(OUTPUT ${output} - COMMAND $ - ARGS -silent - ${input} - DEPENDS ${basename}.ts) - set(${outvar} ${output}) -endmacro(generate_qm outvar basename) +################################################################################################### +# 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} "$" + | "$>" --name "${lower_name}" --output "$" - + 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()