diff options
author | Dominik Schmidt <dev@dominik-schmidt.de> | 2018-01-04 23:06:23 +0300 |
---|---|---|
committer | Dominik Schmidt <dev@dominik-schmidt.de> | 2018-01-13 15:58:17 +0300 |
commit | 81c20352e1dfd7800f7c43ce8dc9bb08b68b33ce (patch) | |
tree | 23012ddf6fb031c15844223deda7576cf097f0c8 /cmake | |
parent | 4e52ee9ebd6672bb3f1099e27f3cd2cf9a0635d4 (diff) |
Use new ECMAddAppIcon macro for application icons.
cmake/modules/ECMAddAppIcon.cmake is heavily patched to support sidebar icons, OUTFILE_BASE parameter and to not include 64 and 64@2x icons on macOS which are not supported. All changes are made in a way that we can upstream this.
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/modules/ECMAddAppIcon.cmake | 332 | ||||
-rw-r--r-- | cmake/modules/ECMFindModuleHelpers.cmake | 297 | ||||
-rw-r--r-- | cmake/modules/ECMFindModuleHelpersStub.cmake | 1 | ||||
-rw-r--r-- | cmake/modules/FindPng2Ico.cmake | 117 |
4 files changed, 747 insertions, 0 deletions
diff --git a/cmake/modules/ECMAddAppIcon.cmake b/cmake/modules/ECMAddAppIcon.cmake new file mode 100644 index 000000000..ee2296ead --- /dev/null +++ b/cmake/modules/ECMAddAppIcon.cmake @@ -0,0 +1,332 @@ +#.rst: +# ECMAddAppIcon +# ------------- +# +# Add icons to executable files and packages. +# +# :: +# +# ecm_add_app_icon(<sources_var> +# ICONS <icon> [<icon> [...]] +# [SIDEBAR_ICONS <icon> [<icon> [...]] # Since 5.4x +# [OUTFILE_BASE <name>]) # Since 5.4x +# ) +# +# The given icons, whose names must match the pattern:: +# +# <size>-<other_text>.png +# +# will be added to the executable target whose sources are specified by +# ``<sources_var>`` on platforms that support it (Windows and Mac OS X). +# Other icon files are ignored but on Mac SVG files can be supported and +# it is thus possible to mix those with png files in a single macro call. +# +# ``<size>`` is a numeric pixel size (typically 16, 32, 48, 64, 128 or 256). +# ``<other_text>`` can be any other text. See the platform notes below for any +# recommendations about icon sizes. +# +# ``SIDEBAR_ICONS`` can be used to add Mac OS X sidebar +# icons to the generated iconset. They are used when a folder monitored by the +# application is dragged into Finder's sidebar. Since 5.4x. +# +# ``OUTFILE_BASE`` will be used as the basename for the icon file. If +# you specify it, the icon file will be called ``<OUTFILE_BASE>.icns`` on Mac OS X +# and ``<OUTFILE_BASE>.ico`` on Windows. If you don't specify it, it defaults +# to ``<sources_var>.<ext>``. Since 5.4x. +# +# +# Windows notes +# * Icons are compiled into the executable using a resource file. +# * Icons may not show up in Windows Explorer if the executable +# target does not have the ``WIN32_EXECUTABLE`` property set. +# * The tool png2ico is required. See :find-module:`FindPng2Ico`. +# * Supported sizes: 16, 32, 48, 64, 128. +# +# Mac OS X notes +# * The executable target must have the ``MACOSX_BUNDLE`` property set. +# * Icons are added to the bundle. +# * If the ksvg2icns tool from KIconThemes is available, .svg and .svgz +# files are accepted; the first that is converted successfully to .icns +# will provide the application icon. SVG files are ignored otherwise. +# * The tool iconutil (provided by Apple) is required for bitmap icons. +# * Supported sizes: 16, 32, 64, 128, 256 (and 512, 1024 after OS X 10.9). +# * At least a 128x128px (or an SVG) icon is required. +# * Larger sizes are automatically used to substitute for smaller sizes on +# "Retina" (high-resolution) displays. For example, a 32px icon, if +# provided, will be used as a 32px icon on standard-resolution displays, +# and as a 16px-equivalent icon (with an "@2x" tag) on high-resolution +# displays. That is why you should provide 64px and 1024px icons although +# they are not supported anymore directly. Instead they will be used as +# 32px@2x and 512px@2x. ksvg2icns handles this internally. +# * This function sets the ``MACOSX_BUNDLE_ICON_FILE`` variable to the name +# of the generated icns file, so that it will be used as the +# ``MACOSX_BUNDLE_ICON_FILE`` target property when you call +# ``add_executable``. +# * Sidebar icons should typically provided in 16, 32, 64, 128 and 256px. +# +# Since 1.7.0. + + +#============================================================================= +# Copyright 2014 Alex Merry <alex.merry@kde.org> +# Copyright 2014 Ralf Habacker <ralf.habacker@freenet.de> +# Copyright 2006-2009 Alexander Neundorf, <neundorf@kde.org> +# Copyright 2006, 2007, Laurent Montel, <montel@kde.org> +# Copyright 2007 Matthias Kretz <kretz@kde.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(CMakeParseArguments) + +function(ecm_add_app_icon appsources) + set(options) + set(oneValueArgs OUTFILE_BASE) + set(multiValueArgs ICONS SIDEBAR_ICONS) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT ARG_ICONS) + message(FATAL_ERROR "No ICONS argument given to ecm_add_app_icon") + endif() + if(ARG_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to ecm_add_app_icon: ${ARG_UNPARSED_ARGUMENTS}") + endif() + + if(APPLE) + find_program(KSVG2ICNS NAMES ksvg2icns) + foreach(icon ${ARG_ICONS}) + get_filename_component(icon_full ${icon} ABSOLUTE) + get_filename_component(icon_type ${icon_full} EXT) + # do we have ksvg2icns in the path and did we receive an svg (or compressed svg) icon? + if(KSVG2ICNS AND (${icon_type} STREQUAL ".svg" OR ${icon_type} STREQUAL ".svgz")) + # convert the svg icon to an icon resource + execute_process(COMMAND ${KSVG2ICNS} "${icon_full}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} RESULT_VARIABLE KSVG2ICNS_ERROR) + if(${KSVG2ICNS_ERROR}) + message(AUTHOR_WARNING "ksvg2icns could not generate an OS X application icon from ${icon}") + else() + # install the icns file we just created + get_filename_component(icon_name ${icon_full} NAME_WE) + set(MACOSX_BUNDLE_ICON_FILE ${icon_name}.icns PARENT_SCOPE) + set(${appsources} "${${appsources}};${CMAKE_CURRENT_BINARY_DIR}/${icon_name}.icns" PARENT_SCOPE) + set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${icon_name}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + # we're done now + return() + endif() + endif() + endforeach() + endif() + + + _ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;32;48;64;128;256;512;1024") + if(ARG_SIDEBAR_ICONS) + _ecm_add_app_icon_categorize_icons("${ARG_SIDEBAR_ICONS}" "sidebar_icons" "16;18;32;36;64") + endif() + + set(mac_icons + # Icons: https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html#//apple_ref/doc/uid/TP40012302-CH7-SW4 + ${icons_at_16px} + ${icons_at_32px} + ${icons_at_64px} + ${icons_at_128px} + ${icons_at_256px} + ${icons_at_512px} + ${icons_at_1024px} + + # Sidebar Icons: https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/Finder.html#//apple_ref/doc/uid/TP40014214-CH15-SW15 + ${sidebar_icons_at_16px} + ${sidebar_icons_at_18px} + ${sidebar_icons_at_32px} + ${sidebar_icons_at_36px} + ${sidebar_icons_at_64px}) + if (NOT icons_at_128px) + message(AUTHOR_WARNING "No 128px icon provided; this will not work on Mac OS X") + endif() + + + set(windows_icons ${icons_at_16px} + ${icons_at_32px} + ${icons_at_48px} + ${icons_at_64px} + ${icons_at_128px}) + if (NOT windows_icons) + message(AUTHOR_WARNING "No icons suitable for use on Windows provided") + endif() + + if (ARG_OUTFILE_BASE) + set (_outfilebasename "${ARG_OUTFILE_BASE}") + else() + set (_outfilebasename "${appsources}") + endif() + set (_outfilename "${CMAKE_CURRENT_BINARY_DIR}/${_outfilebasename}") + + if (WIN32 AND windows_icons) + set(saved_CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}") + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_FIND_MODULE_DIR}) + find_package(Png2Ico) + set(CMAKE_MODULE_PATH "${saved_CMAKE_MODULE_PATH}") + + if (Png2Ico_FOUND) + if (Png2Ico_HAS_RCFILE_ARGUMENT) + add_custom_command( + OUTPUT "${_outfilename}.rc" "${_outfilename}.ico" + COMMAND Png2Ico::Png2Ico + ARGS + --rcfile "${_outfilename}.rc" + "${_outfilename}.ico" + ${windows_icons} + DEPENDS ${windows_icons} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + else() + add_custom_command( + OUTPUT "${_outfilename}.ico" + COMMAND Png2Ico::Png2Ico + ARGS "${_outfilename}.ico" ${windows_icons} + DEPENDS ${windows_icons} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + # this bit's a little hacky to make the dependency stuff work + file(WRITE "${_outfilename}.rc.in" "IDI_ICON1 ICON DISCARDABLE \"${_outfilename}.ico\"\n") + add_custom_command( + OUTPUT "${_outfilename}.rc" + COMMAND ${CMAKE_COMMAND} + ARGS -E copy "${_outfilename}.rc.in" "${_outfilename}.rc" + DEPENDS "${_outfilename}.ico" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + endif() + set(${appsources} "${${appsources}};${_outfilename}.rc" PARENT_SCOPE) + else() + message(WARNING "Unable to find the png2ico utility - application will not have an application icon!") + endif() + elseif (APPLE AND mac_icons) + # first generate .iconset directory structure, then convert to .icns format using the Mac OS X "iconutil" utility, + # to create retina compatible icon, you need png source files in pixel resolution 16x16, 32x32, 64x64, 128x128, + # 256x256, 512x512, 1024x1024 + find_program(ICONUTIL_EXECUTABLE NAMES iconutil) + if (ICONUTIL_EXECUTABLE) + add_custom_command( + OUTPUT "${_outfilename}.iconset" + COMMAND ${CMAKE_COMMAND} + ARGS -E make_directory "${_outfilename}.iconset" + ) + set(iconset_icons) + macro(copy_icon filename sizename type) + add_custom_command( + OUTPUT "${_outfilename}.iconset/${type}_${sizename}.png" + COMMAND ${CMAKE_COMMAND} + ARGS -E copy + "${filename}" + "${_outfilename}.iconset/${type}_${sizename}.png" + DEPENDS + "${_outfilename}.iconset" + "${filename}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + list(APPEND iconset_icons + "${_outfilename}.iconset/${type}_${sizename}.png") + endmacro() + foreach(size 16 32 128 256 512) + math(EXPR double_size "2 * ${size}") + foreach(file ${icons_at_${size}px}) + copy_icon("${file}" "${size}x${size}" "icon") + endforeach() + foreach(file ${icons_at_${double_size}px}) + copy_icon("${file}" "${size}x${size}@2x" "icon") + endforeach() + endforeach() + + foreach(size 16 18 32) + math(EXPR double_size "2 * ${size}") + foreach(file ${sidebar_icons_at_${size}px}) + copy_icon("${file}" "${size}x${size}" "sidebar") + endforeach() + foreach(file ${sidebar_icons_at_${double_size}px}) + copy_icon("${file}" "${size}x${size}@2x" "sidebar") + endforeach() + endforeach() + + # generate .icns icon file + add_custom_command( + OUTPUT "${_outfilename}.icns" + COMMAND ${ICONUTIL_EXECUTABLE} + ARGS + --convert icns + --output "${_outfilename}.icns" + "${_outfilename}.iconset" + DEPENDS "${iconset_icons}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + # This will register the icon into the bundle + set(MACOSX_BUNDLE_ICON_FILE "${_outfilebasename}.icns" PARENT_SCOPE) + + # Append the icns file to the sources list so it will be a dependency to the + # main target + set(${appsources} "${${appsources}};${_outfilename}.icns" PARENT_SCOPE) + + # Install the icon into the Resources dir in the bundle + set_source_files_properties("${_outfilename}.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + else() + message(STATUS "Unable to find the iconutil utility - application will not have an application icon!") + endif() + endif() +endfunction() + +macro(_ecm_add_app_icon_categorize_icons icons type known_sizes) + set(_${type}_known_sizes) + foreach(size ${known_sizes}) + set(${type}_at_${size}px) + list(APPEND _${type}_known_sizes ${size}) + endforeach() + + + foreach(icon ${icons}) + get_filename_component(icon_full ${icon} ABSOLUTE) + if (NOT EXISTS "${icon_full}") + message(AUTHOR_WARNING "${icon_full} does not exist, ignoring") + else() + get_filename_component(icon_name ${icon} NAME) + string(REGEX MATCH "([0-9]+)\\-[^/]+\\.([a-z]+)$" + _dummy "${icon_name}") + set(size "${CMAKE_MATCH_1}") + set(ext "${CMAKE_MATCH_2}") + + if (NOT (ext STREQUAL "svg" OR ext STREQUAL "svgz")) + if (NOT size) + message(AUTHOR_WARNING "${icon_full} is not named correctly for ecm_add_app_icon - ignoring") + elseif (NOT ext STREQUAL "png") + message(AUTHOR_WARNING "${icon_full} is not a png file - ignoring") + else() + list(FIND _${type}_known_sizes ${size} offset) + + if (offset GREATER -1) + list(APPEND ${type}_at_${size}px "${icon_full}") + elseif() + message(STATUS "not found ${type}_at_${size}px ${icon_full}") + endif() + endif() + endif() + endif() + endforeach() +endmacro() diff --git a/cmake/modules/ECMFindModuleHelpers.cmake b/cmake/modules/ECMFindModuleHelpers.cmake new file mode 100644 index 000000000..f2e32f959 --- /dev/null +++ b/cmake/modules/ECMFindModuleHelpers.cmake @@ -0,0 +1,297 @@ +#.rst: +# ECMFindModuleHelpers +# -------------------- +# +# Helper macros for find modules: ecm_find_package_version_check(), +# ecm_find_package_parse_components() and +# ecm_find_package_handle_library_components(). +# +# :: +# +# ecm_find_package_version_check(<name>) +# +# Prints warnings if the CMake version or the project's required CMake version +# is older than that required by extra-cmake-modules. +# +# :: +# +# ecm_find_package_parse_components(<name> +# RESULT_VAR <variable> +# KNOWN_COMPONENTS <component1> [<component2> [...]] +# [SKIP_DEPENDENCY_HANDLING]) +# +# This macro will populate <variable> with a list of components found in +# <name>_FIND_COMPONENTS, after checking that all those components are in the +# list of KNOWN_COMPONENTS; if there are any unknown components, it will print +# an error or warning (depending on the value of <name>_FIND_REQUIRED) and call +# return(). +# +# The order of components in <variable> is guaranteed to match the order they +# are listed in the KNOWN_COMPONENTS argument. +# +# If SKIP_DEPENDENCY_HANDLING is not set, for each component the variable +# <name>_<component>_component_deps will be checked for dependent components. +# If <component> is listed in <name>_FIND_COMPONENTS, then all its (transitive) +# dependencies will also be added to <variable>. +# +# :: +# +# ecm_find_package_handle_library_components(<name> +# COMPONENTS <component> [<component> [...]] +# [SKIP_DEPENDENCY_HANDLING]) +# [SKIP_PKG_CONFIG]) +# +# Creates an imported library target for each component. The operation of this +# macro depends on the presence of a number of CMake variables. +# +# The <name>_<component>_lib variable should contain the name of this library, +# and <name>_<component>_header variable should contain the name of a header +# file associated with it (whatever relative path is normally passed to +# '#include'). <name>_<component>_header_subdir variable can be used to specify +# which subdirectory of the include path the headers will be found in. +# ecm_find_package_components() will then search for the library +# and include directory (creating appropriate cache variables) and create an +# imported library target named <name>::<component>. +# +# Additional variables can be used to provide additional information: +# +# If SKIP_PKG_CONFIG, the <name>_<component>_pkg_config variable is set, and +# pkg-config is found, the pkg-config module given by +# <name>_<component>_pkg_config will be searched for and used to help locate the +# library and header file. It will also be used to set +# <name>_<component>_VERSION. +# +# Note that if version information is found via pkg-config, +# <name>_<component>_FIND_VERSION can be set to require a particular version +# for each component. +# +# If SKIP_DEPENDENCY_HANDLING is not set, the INTERFACE_LINK_LIBRARIES property +# of the imported target for <component> will be set to contain the imported +# targets for the components listed in <name>_<component>_component_deps. +# <component>_FOUND will also be set to false if any of the compoments in +# <name>_<component>_component_deps are not found. This requires the components +# in <name>_<component>_component_deps to be listed before <component> in the +# COMPONENTS argument. +# +# The following variables will be set: +# +# ``<name>_TARGETS`` +# the imported targets +# ``<name>_LIBRARIES`` +# the found libraries +# ``<name>_INCLUDE_DIRS`` +# the combined required include directories for the components +# ``<name>_DEFINITIONS`` +# the "other" CFLAGS provided by pkg-config, if any +# ``<name>_VERSION`` +# the value of ``<name>_<component>_VERSION`` for the first component that +# has this variable set (note that components are searched for in the order +# they are passed to the macro), although if it is already set, it will not +# be altered +# +# Note that these variables are never cleared, so if +# ecm_find_package_handle_library_components() is called multiple times with +# different components (typically because of multiple find_package() calls) then +# ``<name>_TARGETS``, for example, will contain all the targets found in any +# call (although no duplicates). +# +# Since pre-1.0.0. + +#============================================================================= +# Copyright 2014 Alex Merry <alex.merry@kde.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(CMakeParseArguments) + +macro(ecm_find_package_version_check module_name) + if(CMAKE_VERSION VERSION_LESS 2.8.12) + message(FATAL_ERROR "CMake 2.8.12 is required by Find${module_name}.cmake") + endif() + if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12) + message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use Find${module_name}.cmake") + endif() +endmacro() + +macro(ecm_find_package_parse_components module_name) + set(ecm_fppc_options SKIP_DEPENDENCY_HANDLING) + set(ecm_fppc_oneValueArgs RESULT_VAR) + set(ecm_fppc_multiValueArgs KNOWN_COMPONENTS DEFAULT_COMPONENTS) + cmake_parse_arguments(ECM_FPPC "${ecm_fppc_options}" "${ecm_fppc_oneValueArgs}" "${ecm_fppc_multiValueArgs}" ${ARGN}) + + if(ECM_FPPC_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to ecm_find_package_parse_components: ${ECM_FPPC_UNPARSED_ARGUMENTS}") + endif() + if(NOT ECM_FPPC_RESULT_VAR) + message(FATAL_ERROR "Missing RESULT_VAR argument to ecm_find_package_parse_components") + endif() + if(NOT ECM_FPPC_KNOWN_COMPONENTS) + message(FATAL_ERROR "Missing KNOWN_COMPONENTS argument to ecm_find_package_parse_components") + endif() + if(NOT ECM_FPPC_DEFAULT_COMPONENTS) + set(ECM_FPPC_DEFAULT_COMPONENTS ${ECM_FPPC_KNOWN_COMPONENTS}) + endif() + + if(${module_name}_FIND_COMPONENTS) + set(ecm_fppc_requestedComps ${${module_name}_FIND_COMPONENTS}) + + if(NOT ECM_FPPC_SKIP_DEPENDENCY_HANDLING) + # Make sure deps are included + foreach(ecm_fppc_comp ${ecm_fppc_requestedComps}) + foreach(ecm_fppc_dep_comp ${${module_name}_${ecm_fppc_comp}_component_deps}) + list(FIND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}" ecm_fppc_index) + if("${ecm_fppc_index}" STREQUAL "-1") + if(NOT ${module_name}_FIND_QUIETLY) + message(STATUS "${module_name}: ${ecm_fppc_comp} requires ${${module_name}_${ecm_fppc_comp}_component_deps}") + endif() + list(APPEND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}") + endif() + endforeach() + endforeach() + else() + message(STATUS "Skipping dependency handling for ${module_name}") + endif() + list(REMOVE_DUPLICATES ecm_fppc_requestedComps) + + # This makes sure components are listed in the same order as + # KNOWN_COMPONENTS (potentially important for inter-dependencies) + set(${ECM_FPPC_RESULT_VAR}) + foreach(ecm_fppc_comp ${ECM_FPPC_KNOWN_COMPONENTS}) + list(FIND ecm_fppc_requestedComps "${ecm_fppc_comp}" ecm_fppc_index) + if(NOT "${ecm_fppc_index}" STREQUAL "-1") + list(APPEND ${ECM_FPPC_RESULT_VAR} "${ecm_fppc_comp}") + list(REMOVE_AT ecm_fppc_requestedComps ${ecm_fppc_index}) + endif() + endforeach() + # if there are any left, they are unknown components + if(ecm_fppc_requestedComps) + set(ecm_fppc_msgType STATUS) + if(${module_name}_FIND_REQUIRED) + set(ecm_fppc_msgType FATAL_ERROR) + endif() + if(NOT ${module_name}_FIND_QUIETLY) + message(${ecm_fppc_msgType} "${module_name}: requested unknown components ${ecm_fppc_requestedComps}") + endif() + return() + endif() + else() + set(${ECM_FPPC_RESULT_VAR} ${ECM_FPPC_DEFAULT_COMPONENTS}) + endif() +endmacro() + +macro(ecm_find_package_handle_library_components module_name) + set(ecm_fpwc_options SKIP_PKG_CONFIG SKIP_DEPENDENCY_HANDLING) + set(ecm_fpwc_oneValueArgs) + set(ecm_fpwc_multiValueArgs COMPONENTS) + cmake_parse_arguments(ECM_FPWC "${ecm_fpwc_options}" "${ecm_fpwc_oneValueArgs}" "${ecm_fpwc_multiValueArgs}" ${ARGN}) + + if(ECM_FPWC_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to ecm_find_package_handle_components: ${ECM_FPWC_UNPARSED_ARGUMENTS}") + endif() + if(NOT ECM_FPWC_COMPONENTS) + message(FATAL_ERROR "Missing COMPONENTS argument to ecm_find_package_handle_components") + endif() + + include(FindPackageHandleStandardArgs) + find_package(PkgConfig) + foreach(ecm_fpwc_comp ${ECM_FPWC_COMPONENTS}) + set(ecm_fpwc_dep_vars) + set(ecm_fpwc_dep_targets) + if(NOT SKIP_DEPENDENCY_HANDLING) + foreach(ecm_fpwc_dep ${${module_name}_${ecm_fpwc_comp}_component_deps}) + list(APPEND ecm_fpwc_dep_vars "${module_name}_${ecm_fpwc_dep}_FOUND") + list(APPEND ecm_fpwc_dep_targets "${module_name}::${ecm_fpwc_dep}") + endforeach() + endif() + + if(NOT ECM_FPWC_SKIP_PKG_CONFIG AND ${module_name}_${ecm_fpwc_comp}_pkg_config) + pkg_check_modules(PKG_${module_name}_${ecm_fpwc_comp} QUIET + ${${module_name}_${ecm_fpwc_comp}_pkg_config}) + endif() + + find_path(${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR + NAMES ${${module_name}_${ecm_fpwc_comp}_header} + HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_INCLUDE_DIRS} + PATH_SUFFIXES ${${module_name}_${ecm_fpwc_comp}_header_subdir} + ) + find_library(${module_name}_${ecm_fpwc_comp}_LIBRARY + NAMES ${${module_name}_${ecm_fpwc_comp}_lib} + HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_LIBRARY_DIRS} + ) + + set(${module_name}_${ecm_fpwc_comp}_VERSION "${PKG_${module_name}_${ecm_fpwc_comp}_VERSION}") + if(NOT ${module_name}_VERSION) + set(${module_name}_VERSION ${${module_name}_${ecm_fpwc_comp}_VERSION}) + endif() + + find_package_handle_standard_args(${module_name}_${ecm_fpwc_comp} + FOUND_VAR + ${module_name}_${ecm_fpwc_comp}_FOUND + REQUIRED_VARS + ${module_name}_${ecm_fpwc_comp}_LIBRARY + ${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR + ${ecm_fpwc_dep_vars} + VERSION_VAR + ${module_name}_${ecm_fpwc_comp}_VERSION + ) + + mark_as_advanced( + ${module_name}_${ecm_fpwc_comp}_LIBRARY + ${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR + ) + + if(${module_name}_${ecm_fpwc_comp}_FOUND) + list(APPEND ${module_name}_LIBRARIES + "${${module_name}_${ecm_fpwc_comp}_LIBRARY}") + list(APPEND ${module_name}_INCLUDE_DIRS + "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}") + set(${module_name}_DEFINITIONS + ${${module_name}_DEFINITIONS} + ${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS}) + if(NOT TARGET ${module_name}::${ecm_fpwc_comp}) + add_library(${module_name}::${ecm_fpwc_comp} UNKNOWN IMPORTED) + set_target_properties(${module_name}::${ecm_fpwc_comp} PROPERTIES + IMPORTED_LOCATION "${${module_name}_${ecm_fpwc_comp}_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${ecm_fpwc_dep_targets}" + ) + endif() + list(APPEND ${module_name}_TARGETS + "${module_name}::${ecm_fpwc_comp}") + endif() + endforeach() + if(${module_name}_LIBRARIES) + list(REMOVE_DUPLICATES ${module_name}_LIBRARIES) + endif() + if(${module_name}_INCLUDE_DIRS) + list(REMOVE_DUPLICATES ${module_name}_INCLUDE_DIRS) + endif() + if(${module_name}_DEFINITIONS) + list(REMOVE_DUPLICATES ${module_name}_DEFINITIONS) + endif() + if(${module_name}_TARGETS) + list(REMOVE_DUPLICATES ${module_name}_TARGETS) + endif() +endmacro() diff --git a/cmake/modules/ECMFindModuleHelpersStub.cmake b/cmake/modules/ECMFindModuleHelpersStub.cmake new file mode 100644 index 000000000..bb8c9a62f --- /dev/null +++ b/cmake/modules/ECMFindModuleHelpersStub.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/../modules/ECMFindModuleHelpers.cmake) diff --git a/cmake/modules/FindPng2Ico.cmake b/cmake/modules/FindPng2Ico.cmake new file mode 100644 index 000000000..d84f66730 --- /dev/null +++ b/cmake/modules/FindPng2Ico.cmake @@ -0,0 +1,117 @@ +#.rst: +# FindPng2Ico +# ----------- +# +# Try to find png2ico. +# +# If the png2ico executable is not in your PATH, you can provide +# an alternative name or full path location with the ``Png2Ico_EXECUTABLE`` +# variable. +# +# This will define the following variables: +# +# ``Png2Ico_FOUND`` +# True if png2ico is available. +# +# ``Png2Ico_EXECUTABLE`` +# The png2ico executable. +# +# If ``Png2Ico_FOUND`` is TRUE, it will also define the following imported +# target: +# +# ``Png2Ico::Png2Ico`` +# The png2ico executable. +# +# and the following variables: +# +# ``Png2Ico_HAS_COLORS_ARGUMENT`` +# Whether png2ico accepts a ``--colors`` argument. `Matthias Benkmann's +# tool <http://www.winterdrache.de/freeware/png2ico/>`_ does, while the +# version of png2ico from the `"KDE On Windows" (kdewin) +# <https://projects.kde.org/projects/kdesupport/kdewin>`_ project does not. +# +# ``Png2Ico_HAS_RCFILE_ARGUMENT`` +# Whether png2ico accepts an ``--rcfile`` argument. The version of png2ico +# from the `"KDE On Windows" (kdewin) +# <https://projects.kde.org/projects/kdesupport/kdewin>`_ project does, +# while `Matthias Benkmann's tool +# <http://www.winterdrache.de/freeware/png2ico/>`_ does not. +# +# Since 1.7.0. + +#============================================================================= +# Copyright 2014 Alex Merry <alex.merry@kde.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +include(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpersStub.cmake) + +ecm_find_package_version_check(Png2Ico) + +# Find png2ico +find_program(Png2Ico_EXECUTABLE NAMES png2ico) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Png2Ico + FOUND_VAR + Png2Ico_FOUND + REQUIRED_VARS + Png2Ico_EXECUTABLE +) + +mark_as_advanced(Png2Ico_EXECUTABLE) + +if (Png2Ico_FOUND) + execute_process( + COMMAND "${Png2Ico_EXECUTABLE}" --help + OUTPUT_VARIABLE _png2ico_help_text + ERROR_VARIABLE _png2ico_help_text + ) + if (_png2ico_help_text MATCHES ".*--rcfile .*") + set(Png2Ico_HAS_RCFILE_ARGUMENT TRUE) + else() + set(Png2Ico_HAS_RCFILE_ARGUMENT FALSE) + endif() + if (_png2ico_help_text MATCHES ".*--colors .*") + set(Png2Ico_HAS_COLORS_ARGUMENT TRUE) + else() + set(Png2Ico_HAS_COLORS_ARGUMENT FALSE) + endif() + unset(_png2ico_help_text) + + if (NOT TARGET Png2Ico::Png2Ico) + add_executable(Png2Ico::Png2Ico IMPORTED) + set_target_properties(Png2Ico::Png2Ico PROPERTIES + IMPORTED_LOCATION "${Png2Ico_EXECUTABLE}" + ) + endif() +endif() + +include(FeatureSummary) +set_package_properties(Png2Ico PROPERTIES + URL "http://www.winterdrache.de/freeware/png2ico/ or https://projects.kde.org/projects/kdesupport/kdewin" + DESCRIPTION "Executable that converts a collection of PNG files into a Windows icon file" +) + |