aboutsummaryrefslogtreecommitdiff
path: root/modules/ECMAddAppIcon.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ECMAddAppIcon.cmake')
-rw-r--r--modules/ECMAddAppIcon.cmake227
1 files changed, 227 insertions, 0 deletions
diff --git a/modules/ECMAddAppIcon.cmake b/modules/ECMAddAppIcon.cmake
new file mode 100644
index 00000000..4efdd392
--- /dev/null
+++ b/modules/ECMAddAppIcon.cmake
@@ -0,0 +1,227 @@
+#.rst:
+# ECMAddAppIcon
+# -------------
+#
+# Add icons to executable files and packages.
+#
+# ::
+#
+# ecm_add_app_icon(<sources_var>
+# ICONS <icon> [<icon> [...]])
+#
+# 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).
+#
+# ``<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.
+#
+# 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.
+# * The tool iconutil (provided by Apple) is required.
+# * Supported sizes: 16, 32, 64, 128, 256, 512, 1024.
+# * At least a 128x128px 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.
+# * 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``.
+
+#=============================================================================
+# 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>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file COPYING-CMAKE-SCRIPTS for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of extra-cmake-modules, substitute the full
+# License text for the above reference.)
+
+include(CMakeParseArguments)
+
+function(ecm_add_app_icon appsources)
+ set(options)
+ set(oneValueArgs)
+ set(multiValueArgs 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()
+
+ set(known_sizes 16 32 48 64 128 256 512 1024)
+ foreach(size ${known_sizes})
+ set(icons_at_${size}px)
+ endforeach()
+
+ foreach(icon ${ARG_ICONS})
+ if (NOT EXISTS "${icon}")
+ message(AUTHOR_WARNING "${icon} does not exist, ignoring")
+ else()
+ string(REGEX MATCH "([0-9]+)\\-[^/]+\\.([a-z]+)$"
+ _dummy "${icon}")
+ set(size "${CMAKE_MATCH_1}")
+ set(ext "${CMAKE_MATCH_2}")
+ if (NOT size)
+ message(AUTHOR_WARNING "${icon} is not named correctly for ecm_add_app_icon - ignoring")
+ elseif (NOT ext STREQUAL "png")
+ message(AUTHOR_WARNING "${icon} is not a png file - ignoring")
+ else()
+ list(FIND known_sizes "${size}" offset)
+ if (offset GREATER -1)
+ list(APPEND icons_at_${size}px "${icon}")
+ endif()
+ endif()
+ endif()
+ endforeach()
+
+ set(mac_icons ${icons_at_16px}
+ ${icons_at_32px}
+ ${icons_at_64px}
+ ${icons_at_128px}
+ ${icons_at_256px}
+ ${icons_at_512px}
+ ${icons_at_1024px})
+ 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()
+
+ set (_outfilename "${CMAKE_CURRENT_BINARY_DIR}/${appsources}")
+
+ 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)
+ add_custom_command(
+ OUTPUT "${_outfilename}.iconset/icon_${sizename}.png"
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy
+ "${filename}"
+ "${_outfilename}.iconset/icon_${sizename}.png"
+ DEPENDS
+ "${_outfilename}.iconset"
+ "${filename}"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ )
+ list(APPEND iconset_icons
+ "${_outfilename}.iconset/icon_${sizename}.png")
+ endmacro()
+ foreach(size 16 32 64 128 256 512)
+ math(EXPR double_size "2 * ${size}")
+ foreach(file ${icons_at_${size}px})
+ copy_icon("${file}" "${size}x${size}")
+ endforeach()
+ foreach(file ${icons_at_${double_size}px})
+ copy_icon("${file}" "${size}x${size}@2x")
+ 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 ${appsources}.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(ICONUTIL_EXECUTABLE)
+ message(STATUS "Unable to find the iconutil utility - application will not have an application icon!")
+ endif(ICONUTIL_EXECUTABLE)
+ endif()
+endfunction()