diff options
author | l10n daemon script <scripty@kde.org> | 2015-11-08 21:01:33 +0000 |
---|---|---|
committer | l10n daemon script <scripty@kde.org> | 2015-11-08 21:01:33 +0000 |
commit | 7feccae76e01a65b406995b5ba9526fe9ade4299 (patch) | |
tree | 99011137f4dedcf4bf242e167ac7dc70d9136b8e /modules | |
parent | a1bb0b0488843165e606771b75a3a67ba8a131a6 (diff) | |
parent | c88bc78e0ca3834c46b89ca9d14b404751da5d4a (diff) | |
download | extra-cmake-modules-5.16.0.tar.gz extra-cmake-modules-5.16.0.tar.bz2 |
Merge remote-tracking branch 'origin/master' into local_releasev5.16.0-rc2v5.16.0
Diffstat (limited to 'modules')
24 files changed, 840 insertions, 188 deletions
diff --git a/modules/ECMAddAppIcon.cmake b/modules/ECMAddAppIcon.cmake new file mode 100644 index 00000000..f90d4c33 --- /dev/null +++ b/modules/ECMAddAppIcon.cmake @@ -0,0 +1,229 @@ +#.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``. +# +# 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> +# +# 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() diff --git a/modules/ECMAddTests.cmake b/modules/ECMAddTests.cmake index ed1e0f66..e9e2fc53 100644 --- a/modules/ECMAddTests.cmake +++ b/modules/ECMAddTests.cmake @@ -2,43 +2,59 @@ # ECMAddTests # ----------- # -# Add test executables. +# Convenience functions for adding tests. # # :: # -# ecm_add_test(<sources> LINK_LIBRARIES <library> [<library> [...]] -# [TEST_NAME <name>] -# [NAME_PREFIX <prefix>] -# [GUI]) +# ecm_add_tests(<sources> LINK_LIBRARIES <library> [<library> [...]] +# [NAME_PREFIX <prefix>] +# [GUI] +# [TARGET_NAMES_VAR <target_names_var>] +# [TEST_NAMES_VAR <test_names_var>]) # -# Add a new unit test using the passed source files. The parameter TEST_NAME is -# used to set the name of the resulting test, and the target built for and run -# by the test. It may be omitted if there is exactly one source file. In that -# case the name of the source file (without the file extension) will be used as -# the test name. +# A convenience function for adding multiple tests, each consisting of a +# single source file. For each file in <sources>, an executable target will be +# created (the name of which will be the basename of the source file). This +# will be linked against the libraries given with LINK_LIBRARIES. Each +# executable will be added as a test with the same name. # -# If NAME_PREFIX is given, this prefix will be prepended to the test name, but -# not the target name. As a result, it will not prevent clashes between tests +# If NAME_PREFIX is given, this prefix will be prepended to the test names, but +# not the target names. As a result, it will not prevent clashes between tests # with the same name in different parts of the project, but it can be used to # give an indication of where to look for a failing test. # -# If the flag GUI is passed the test binary will be a GUI executable, otherwise -# the resulting binary will be a console application. The test will be linked -# against the libraries and/or targets passed to LINK_LIBRARIES. +# If the flag GUI is passed the test binaries will be GUI executables, otherwise +# the resulting binaries will be console applications (regardless of the value +# of CMAKE_WIN32_EXECUTABLE or CMAKE_MACOSX_BUNDLE). Be aware that this changes +# the executable entry point on Windows (although some frameworks, such as Qt, +# abstract this difference away). +# +# The TARGET_NAMES_VAR and TEST_NAMES_VAR arguments, if given, should specify a +# variable name to receive the list of generated target and test names, +# respectively. This makes it convenient to apply properties to them as a +# whole, for example, using set_target_properties() or set_tests_properties(). # +# The generated target executables will have the effects of ecm_mark_as_test() +# (from the :module:`ECMMarkAsTest` module) applied to it. # # :: # -# ecm_add_tests(<sources> LINK_LIBRARIES <library> [<library> [...]] -# [NAME_PREFIX <prefix>] -# [GUI]) +# ecm_add_test(<sources> LINK_LIBRARIES <library> [<library> [...]] +# [TEST_NAME <name>] +# [NAME_PREFIX <prefix>] +# [GUI]) +# +# This is a single-test form of ecm_add_tests that allows multiple source files +# to be used for a single test. If using multiple source files, TEST_NAME must +# be given; this will be used for both the target and test names (and, as with +# ecm_add_tests(), the NAME_PREFIX argument will be prepended to the test name). +# # -# This is a convenient version of ecm_add_test() for when you have many tests -# that consist of a single source file each. It behaves like calling -# ecm_add_test() once for each source file, with the same named arguments. +# Since pre-1.0.0. #============================================================================= # Copyright 2013 Alexander Richardson <arichardson.kde@gmail.com> +# Copyright 2015 Alex Merry <alex.merry@kde.org> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file COPYING-CMAKE-SCRIPTS for details. @@ -50,18 +66,21 @@ # (To distribute this file outside of extra-cmake-modules, substitute the full # License text for the above reference.) +include(CMakeParseArguments) include(ECMMarkAsTest) include(ECMMarkNonGuiExecutable) function(ecm_add_test) set(options GUI) - set(oneValueArgs TEST_NAME NAME_PREFIX) + # TARGET_NAME_VAR and TEST_NAME_VAR are undocumented args used by + # ecm_add_tests + set(oneValueArgs TEST_NAME NAME_PREFIX TARGET_NAME_VAR TEST_NAME_VAR) set(multiValueArgs LINK_LIBRARIES) - cmake_parse_arguments(ECM_ADD_TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - set(_sources ${ECM_ADD_TEST_UNPARSED_ARGUMENTS}) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set(_sources ${ARG_UNPARSED_ARGUMENTS}) list(LENGTH _sources _sourceCount) - if(ECM_ADD_TEST_TEST_NAME) - set(_targetname ${ECM_ADD_TEST_TEST_NAME}) + if(ARG_TEST_NAME) + set(_targetname ${ARG_TEST_NAME}) elseif(${_sourceCount} EQUAL "1") #use the source file name without extension as the testname get_filename_component(_targetname ${_sources} NAME_WE) @@ -70,31 +89,53 @@ function(ecm_add_test) message(FATAL_ERROR "ecm_add_test() called with multiple source files but without setting \"TEST_NAME\"") endif() - set(_testname "${ECM_ADD_TEST_NAME_PREFIX}${_targetname}") - add_executable(${_targetname} ${_sources}) - if(NOT ECM_ADD_TEST_GUI) + set(_testname ${ARG_NAME_PREFIX}${_targetname}) + set(gui_args) + if(ARG_GUI) + set(gui_args WIN32 MACOSX_BUNDLE) + endif() + add_executable(${_targetname} ${gui_args} ${_sources}) + if(NOT ARG_GUI) ecm_mark_nongui_executable(${_targetname}) endif() add_test(NAME ${_testname} COMMAND ${_targetname}) - target_link_libraries(${_targetname} ${ECM_ADD_TEST_LINK_LIBRARIES}) + target_link_libraries(${_targetname} ${ARG_LINK_LIBRARIES}) ecm_mark_as_test(${_targetname}) + if (ARG_TARGET_NAME_VAR) + set(${ARG_TARGET_NAME_VAR} "${_targetname}" PARENT_SCOPE) + endif() + if (ARG_TEST_NAME_VAR) + set(${ARG_TEST_NAME_VAR} "${_testname}" PARENT_SCOPE) + endif() endfunction() function(ecm_add_tests) set(options GUI) - set(oneValueArgs NAME_PREFIX) + set(oneValueArgs NAME_PREFIX TARGET_NAMES_VAR TEST_NAMES_VAR) set(multiValueArgs LINK_LIBRARIES) - cmake_parse_arguments(ECM_ADD_TESTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if(ECM_ADD_TESTS_GUI) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(ARG_GUI) set(_exe_type GUI) else() set(_exe_type "") endif() - foreach(_test_source ${ECM_ADD_TESTS_UNPARSED_ARGUMENTS}) + set(test_names) + set(target_names) + foreach(_test_source ${ARG_UNPARSED_ARGUMENTS}) ecm_add_test(${_test_source} - NAME_PREFIX ${ECM_ADD_TESTS_NAME_PREFIX} - LINK_LIBRARIES ${ECM_ADD_TESTS_LINK_LIBRARIES} - ${_exe_type} + NAME_PREFIX ${ARG_NAME_PREFIX} + LINK_LIBRARIES ${ARG_LINK_LIBRARIES} + TARGET_NAME_VAR target_name + TEST_NAME_VAR test_name + ${_exe_type} ) + list(APPEND _test_names "${test_name}") + list(APPEND _target_names "${target_name}") endforeach() + if (ARG_TARGET_NAMES_VAR) + set(${ARG_TARGET_NAMES_VAR} "${_target_names}" PARENT_SCOPE) + endif() + if (ARG_TEST_NAMES_VAR) + set(${ARG_TEST_NAMES_VAR} "${_test_names}" PARENT_SCOPE) + endif() endfunction() diff --git a/modules/ECMCoverageOption.cmake b/modules/ECMCoverageOption.cmake index 8d435de8..4c1db9de 100644 --- a/modules/ECMCoverageOption.cmake +++ b/modules/ECMCoverageOption.cmake @@ -2,19 +2,20 @@ # ECMCoverageOption # -------------------- # -# Creates a BUILD_COVERAGE option, so the project can be built with code coverage -# support. +# Allow users to easily enable GCov code coverage support. # -# :: +# Code coverage allows you to check how much of your codebase is covered by +# your tests. This module makes it easy to build with support for +# `GCov <https://gcc.gnu.org/onlinedocs/gcc/Gcov.html>`_. # -# BUILD_COVERAGE -# -# If it's on, the project will be compiled with code coverage support, using -# gcov. Otherwise, it will be built normally. -# -# :: +# When this module is included, a ``BUILD_COVERAGE`` option is added (default +# OFF). Turning this option on enables GCC's coverage instrumentation, and +# links against ``libgcov``. # +# Note that this will probably break the build if you are not using GCC. # +# Since 1.3.0. + #============================================================================= # Copyright 2014 Aleix Pol Gonzalez <aleixpol@kde.org> # diff --git a/modules/ECMCreateQmFromPoFiles.cmake b/modules/ECMCreateQmFromPoFiles.cmake index b66e5989..b4194723 100644 --- a/modules/ECMCreateQmFromPoFiles.cmake +++ b/modules/ECMCreateQmFromPoFiles.cmake @@ -68,6 +68,8 @@ # # This generates a C++ file which loads "mylib.qm" at startup, assuming it has # been installed by ecm_create_qm_from_po_files(), and compiles it into ``mylib``. +# +# Since pre-1.0.0. #============================================================================= # Copyright 2014 Aurélien Gâteau <agateau@kde.org> @@ -108,13 +110,18 @@ endfunction() function(_ECM_QM_CREATE_TARGET install_destination catalog_name) # Find lconvert - get_target_property(lrelease_location Qt5::lrelease LOCATION) - get_filename_component(lrelease_path ${lrelease_location} PATH) - find_program(lconvert_executable - NAMES lconvert-qt5 lconvert - PATHS ${lrelease_path} - NO_DEFAULT_PATH - ) + if(TARGET Qt5::lconvert) + set(lconvert_executable Qt5::lconvert) + else() + # Qt < 5.3.1 does not define Qt5::lconvert + get_target_property(lrelease_location Qt5::lrelease LOCATION) + get_filename_component(lrelease_path ${lrelease_location} PATH) + find_program(lconvert_executable + NAMES lconvert-qt5 lconvert + PATHS ${lrelease_path} + NO_DEFAULT_PATH + ) + endif() if (catalog_name) set(install_args RENAME ${catalog_name}.qm) @@ -138,7 +145,7 @@ function(_ECM_QM_CREATE_TARGET install_destination catalog_name) COMMAND ${lconvert_executable} ARGS -i ${it} -o ${tsfile} -target-language ${language} COMMAND Qt5::lrelease - ARGS -compress -removeidentical -silent ${tsfile} -qm ${qmfile} + ARGS -removeidentical -silent ${tsfile} -qm ${qmfile} DEPENDS ${it} ) install( diff --git a/modules/ECMEnableSanitizers.cmake b/modules/ECMEnableSanitizers.cmake index a0df80e2..e64599b6 100644 --- a/modules/ECMEnableSanitizers.cmake +++ b/modules/ECMEnableSanitizers.cmake @@ -2,9 +2,10 @@ # ECMEnableSanitizers # ------------------- # -# Enable compiler sanitizer flags +# Enable compiler sanitizer flags. +# +# The following sanitizers are supported: # -# The following sanitizers are supported : # - Address Sanitizer # - Memory Sanitizer # - Thread Sanitizer @@ -14,53 +15,59 @@ # All of them are implemented in Clang, depending on your version, and # there is an work in progress in GCC, where some of them are currently # implemented. -# This module will check your current compiler version to see if it support -# the sanitizers that you want to enable # -# How to use it ? -# --------------- -# This module is included in KDECompilerSettings. Therefore you don't have -# to change your CMakeLists.txt +# This module will check your current compiler version to see if it +# supports the sanitizers that you want to enable +# +# Usage +# ===== +# +# Simply add:: +# +# include(ECMEnableSanitizers) +# +# to your ``CMakeLists.txt``. Note that this module is included in +# KDECompilerSettings, so projects using that module do not need to also +# include this one. # -# It introduce a new cached variable : -# ECM_ENABLE_SANITIZERS +# The sanitizers are not enabled by default. Instead, you must set +# ``ECM_ENABLE_SANITIZERS`` (either in your ``CMakeLists.txt`` or on the +# command line) to a semicolon-separated list of sanitizers you wish to enable. +# The options are: # -# which can take the following values : # - address # - memory # - thread # - leak # - undefined # -# You can enable two sanitizers in the same build, depending on their -# compatibility by separating each one with a semicolon : -# ECM_ENABLE_SANITIZERS='address;undefined' +# The sanitizers "address", "memory" and "thread" are mutually exclusive. You +# cannot enable two of them in the same build. # +# "leak" requires the "address" sanitizer. # -# The sanitizers `address`, `memory` and `thread` are mutually exclusive. -# You cannot enable two of them in the same build. +# .. note:: # -# `undefined` can be used with every other sanitizers +# To reduce the overhead induced by the instrumentation of the sanitizers, it +# is advised to enable compiler optimizations (``-O1`` or higher). # -# `leak` can be enable with the `address` sanitizer. +# Example +# ======= # -# Finally, to reduce the overhead induced by the instrumentation of the -# sanitizers, it is advised to use -O1, or higher to improve the performances. +# This is an example of usage:: # -# Example -# ------- -# This is an example of usage : -# mkdir _build -# cd _build -# cmake -DECM_ENABLE_SANITIZERS='address' .. +# mkdir build +# cd build +# cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' .. # -# If you want to use multiple sanitizers +# .. note:: # -# cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' .. +# Most of the sanitizers will require Clang. To enable it, use:: # -# => Most of the sanitizers will require Clang. To enable it, use : -# -DCMAKE_CXX_COMPILER=clang++ +# -DCMAKE_CXX_COMPILER=clang++ # +# Since 1.3.0. + #============================================================================= # Copyright 2014 Mathieu Tarral <mathieu.tarral@gmail.com> # @@ -118,7 +125,7 @@ macro (enable_sanitizer_flags sanitize_option) set(XSAN_COMPILE_FLAGS "-fsanitize=leak") set(XSAN_LINKER_FLAGS "lsan") elseif (${sanitize_option} MATCHES "undefined") - check_compiler_version("99.99" "3.1") + check_compiler_version("4.9" "3.1") set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls") else () message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.") diff --git a/modules/ECMFindModuleHelpers.cmake b/modules/ECMFindModuleHelpers.cmake index 79bd6fb8..63cccb93 100644 --- a/modules/ECMFindModuleHelpers.cmake +++ b/modules/ECMFindModuleHelpers.cmake @@ -92,6 +92,8 @@ # 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> diff --git a/modules/ECMGenerateHeaders.cmake b/modules/ECMGenerateHeaders.cmake index bac50869..cefc82df 100644 --- a/modules/ECMGenerateHeaders.cmake +++ b/modules/ECMGenerateHeaders.cmake @@ -6,26 +6,35 @@ # # :: # -# ecm_generate_headers(<camelcase_headers_var> -# HEADER_NAMES <CamelCaseHeader> [<CamelCaseHeader> [...]] +# ecm_generate_headers(<camelcase_forwarding_headers_var> +# HEADER_NAMES <CamelCaseName> [<CamelCaseName> [...]] +# [ORIGINAL <CAMELCASE|LOWERCASE>] # [OUTPUT_DIR <output_dir>] # [PREFIX <prefix>] # [REQUIRED_HEADERS <variable>] +# [COMMON_HEADER <HeaderName>] # [RELATIVE <relative_path>]) # # For each CamelCase header name passed to HEADER_NAMES, a file of that name -# will be generated that will include a lowercased version with ``.h`` appended. -# For example, the header ``ClassA`` will include ``classa.h``. The file -# locations of these generated headers will be stored in -# <camelcase_headers_var>. -# -# PREFIX places the headers in subdirectories. This should be a CamelCase name -# like KParts, which will cause the CamelCase headers to be placed in the KParts -# directory (eg: KParts/Part). It will also, for the convenience of code in the -# source distribution, generate forwarding lowercase headers, like -# kparts/part.h. This allows includes like "#include <kparts/part.h>" to be -# used before installation, as long as the include_directories are set -# appropriately. +# will be generated that will include a version with ``.h`` appended. +# For example, the generated header ``ClassA`` will include ``classa.h`` (or +# ``ClassA.h``, see ORIGINAL). +# If a CamelCaseName consists of multiple comma-separated files, e.g. +# ``ClassA,ClassB,ClassC``, then multiple camelcase header files will be +# generated which are redirects to the first header file. +# The file locations of these generated headers will be stored in +# <camelcase_forwarding_headers_var>. +# +# ORIGINAL specifies how the name of the original header is written: lowercased +# or also camelcased. The default is LOWERCASE. Since 1.8.0. +# +# PREFIX places the generated headers in subdirectories. This should be a +# CamelCase name like ``KParts``, which will cause the CamelCase forwarding +# headers to be placed in the ``KParts`` directory (e.g. ``KParts/Part``). It +# will also, for the convenience of code in the source distribution, generate +# forwarding headers based on the original names (e.g. ``kparts/part.h``). This +# allows includes like ``"#include <kparts/part.h>"`` to be used before +# installation, as long as the include_directories are set appropriately. # # OUTPUT_DIR specifies where the files will be generated; this should be within # the build directory. By default, ``${CMAKE_CURRENT_BINARY_DIR}`` will be used. @@ -35,14 +44,17 @@ # headers will be appended so that they can be installed together with the # generated ones. This is mostly intended as a convenience so that adding a new # header to a project only requires specifying the CamelCase variant in the -# CMakeLists.txt file; the lowercase variant will then be added to this +# CMakeLists.txt file; the original variant will then be added to this # variable. # -# The RELATIVE argument indicates where the lowercase headers can be found +# COMMON_HEADER generates an additional convenience header which includes all +# other header files. +# +# The RELATIVE argument indicates where the original headers can be found # relative to CMAKE_CURRENT_SOURCE_DIR. It does not affect the generated -# CamelCase files, but ecm_generate_headers() uses it when checking that the -# lowercase header exists, and to generate lowercase forwarding headers when -# PREFIX is set. +# CamelCase forwarding files, but ecm_generate_headers() uses it when checking +# that the original header exists, and to generate originally named forwarding +# headers when PREFIX is set. # # To allow other parts of the source distribution (eg: tests) to use the # generated headers before installation, it may be desirable to set the @@ -64,6 +76,7 @@ # MLBar # # etc # REQUIRED_HEADERS MyLib_HEADERS +# COMMON_HEADER MLGeneral # ) # install(FILES ${MyLib_FORWARDING_HEADERS} ${MyLib_HEADERS} # DESTINATION ${CMAKE_INSTALL_PREFIX}/include @@ -77,7 +90,9 @@ # MyLib_FORWARDING_HEADERS # HEADERS # Foo -# Bar +# # several classes are contained in bar.h, so generate +# # additional files +# Bar,BarList # # etc # PREFIX MyLib # REQUIRED_HEADERS MyLib_HEADERS @@ -88,10 +103,13 @@ # install(FILES ${MyLib_HEADERS} # DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mylib # COMPONENT Devel) +# +# Since pre-1.0.0. #============================================================================= # Copyright 2013 Aleix Pol Gonzalez <aleixpol@blue-systems.com> # Copyright 2014 Alex Merry <alex.merry@kdemail.net> +# Copyright 2015 Patrick Spendrin <patrick.spendrin@kdab.com> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file COPYING-CMAKE-SCRIPTS for details. @@ -105,9 +123,9 @@ include(CMakeParseArguments) -function(ECM_GENERATE_HEADERS camelcase_headers_var) +function(ECM_GENERATE_HEADERS camelcase_forwarding_headers_var) set(options) - set(oneValueArgs OUTPUT_DIR PREFIX REQUIRED_HEADERS RELATIVE) + set(oneValueArgs ORIGINAL OUTPUT_DIR PREFIX REQUIRED_HEADERS COMMON_HEADER RELATIVE) set(multiValueArgs HEADER_NAMES) cmake_parse_arguments(EGH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -119,6 +137,14 @@ function(ECM_GENERATE_HEADERS camelcase_headers_var) message(FATAL_ERROR "Missing header_names argument to ECM_GENERATE_HEADERS") endif() + if(NOT EGH_ORIGINAL) + # default + set(EGH_ORIGINAL "LOWERCASE") + endif() + if(NOT EGH_ORIGINAL STREQUAL "LOWERCASE" AND NOT EGH_ORIGINAL STREQUAL "CAMELCASE") + message(FATAL_ERROR "Unexpected value for original argument to ECM_GENERATE_HEADERS: ${EGH_ORIGINAL}") + endif() + if(NOT EGH_OUTPUT_DIR) set(EGH_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") endif() @@ -132,34 +158,64 @@ function(ECM_GENERATE_HEADERS camelcase_headers_var) if (NOT "${EGH_PREFIX}" MATCHES "^.*/$") set(EGH_PREFIX "${EGH_PREFIX}/") endif() - string(TOLOWER "${EGH_PREFIX}" lowercaseprefix) + if (EGH_ORIGINAL STREQUAL "CAMELCASE") + set(originalprefix "${EGH_PREFIX}") + else() + string(TOLOWER "${EGH_PREFIX}" originalprefix) + endif() endif() - foreach(_CLASSNAME ${EGH_HEADER_NAMES}) - string(TOLOWER "${_CLASSNAME}" lowercaseclassname) - set(FANCY_HEADER_FILE "${EGH_OUTPUT_DIR}/${EGH_PREFIX}${_CLASSNAME}") - set(_actualheader "${CMAKE_CURRENT_SOURCE_DIR}/${EGH_RELATIVE}${lowercaseclassname}.h") + foreach(_classnameentry ${EGH_HEADER_NAMES}) + string(REPLACE "," ";" _classnames ${_classnameentry}) + list(GET _classnames 0 _baseclass) + + if (EGH_ORIGINAL STREQUAL "CAMELCASE") + set(originalbasename "${_baseclass}") + else() + string(TOLOWER "${_baseclass}" originalbasename) + endif() + + set(_actualheader "${CMAKE_CURRENT_SOURCE_DIR}/${EGH_RELATIVE}${originalbasename}.h") if (NOT EXISTS ${_actualheader}) message(FATAL_ERROR "Could not find \"${_actualheader}\"") endif() - if (NOT EXISTS ${FANCY_HEADER_FILE}) - file(WRITE ${FANCY_HEADER_FILE} "#include \"${lowercaseprefix}${lowercaseclassname}.h\"\n") - endif() - list(APPEND ${camelcase_headers_var} "${FANCY_HEADER_FILE}") - if (EGH_REQUIRED_HEADERS) - list(APPEND ${EGH_REQUIRED_HEADERS} "${_actualheader}") - endif() - if (EGH_PREFIX) - # Local forwarding header, for namespaced headers, e.g. kparts/part.h - set(REGULAR_HEADER_NAME ${EGH_OUTPUT_DIR}/${lowercaseprefix}${lowercaseclassname}.h) - if (NOT EXISTS ${REGULAR_HEADER_NAME}) - file(WRITE ${REGULAR_HEADER_NAME} "#include \"${_actualheader}\"\n") + + foreach(_CLASSNAME ${_classnames}) + set(FANCY_HEADER_FILE "${EGH_OUTPUT_DIR}/${EGH_PREFIX}${_CLASSNAME}") + if (NOT EXISTS ${FANCY_HEADER_FILE}) + file(WRITE ${FANCY_HEADER_FILE} "#include \"${originalprefix}${originalbasename}.h\"\n") endif() - endif() + list(APPEND ${camelcase_forwarding_headers_var} "${FANCY_HEADER_FILE}") + if (EGH_PREFIX) + # Local forwarding header, for namespaced headers, e.g. kparts/part.h + if(EGH_ORIGINAL STREQUAL "CAMELCASE") + set(originalclassname "${_CLASSNAME}") + else() + string(TOLOWER "${_CLASSNAME}" originalclassname) + endif() + set(REGULAR_HEADER_NAME ${EGH_OUTPUT_DIR}/${originalprefix}${originalclassname}.h) + if (NOT EXISTS ${REGULAR_HEADER_NAME}) + file(WRITE ${REGULAR_HEADER_NAME} "#include \"${_actualheader}\"\n") + endif() + endif() + endforeach() + + list(APPEND _REQUIRED_HEADERS "${_actualheader}") endforeach() - set(${camelcase_headers_var} ${${camelcase_headers_var}} PARENT_SCOPE) + if(EGH_COMMON_HEADER) + #combine required headers into 1 big convenience header + set(COMMON_HEADER ${EGH_OUTPUT_DIR}/${EGH_PREFIX}${EGH_COMMON_HEADER}) + file(WRITE ${COMMON_HEADER} "// convenience header\n") + foreach(_header ${_REQUIRED_HEADERS}) + get_filename_component(_base ${_header} NAME) + file(APPEND ${COMMON_HEADER} "#include \"${_base}\"\n") + endforeach() + list(APPEND ${camelcase_forwarding_headers_var} "${COMMON_HEADER}") + endif() + + set(${camelcase_forwarding_headers_var} ${${camelcase_forwarding_headers_var}} PARENT_SCOPE) if (NOT EGH_REQUIRED_HEADERS STREQUAL "") - set(${EGH_REQUIRED_HEADERS} ${${EGH_REQUIRED_HEADERS}} PARENT_SCOPE) + set(${EGH_REQUIRED_HEADERS} ${${EGH_REQUIRED_HEADERS}} ${_REQUIRED_HEADERS} PARENT_SCOPE) endif () endfunction() diff --git a/modules/ECMGeneratePkgConfigFile.cmake b/modules/ECMGeneratePkgConfigFile.cmake index eb0e385d..eaef7b41 100644 --- a/modules/ECMGeneratePkgConfigFile.cmake +++ b/modules/ECMGeneratePkgConfigFile.cmake @@ -1,8 +1,11 @@ #.rst: # ECMGeneratePkgConfigFile -# ------------------ +# ------------------------ # -# Generate a ``.pc`` file for the benefit of autotools-based projects. +# Generate a `pkg-config <http://www.freedesktop.org/wiki/Software/pkg-config/>`_ +# file for the benefit of +# `autotools <http://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html>`_-based +# projects. # # :: # @@ -15,38 +18,41 @@ # [DEFINES -D<variable=value>...] # [INSTALL]) # -# BASE_NAME is the name of the module. It's the name projects will use to find -# the module. +# ``BASE_NAME`` is the name of the module. It's the name projects will use to +# find the module. # -# LIB_NAME is the name of the library that is being exported. If undefined, it -# will default to the BASE_NAME. That means the LIB_NAME will be set as the name -# field as well as the library to link to. +# ``LIB_NAME`` is the name of the library that is being exported. If undefined, +# it will default to the ``BASE_NAME``. That means the ``LIB_NAME`` will be set +# as the name field as well as the library to link to. # -# FILENAME_VAR is specified with a variable name. This variable will receive the -# location of the generated file will be set, within the build directory. This -# way it can be used in case some processing is required. See also INSTALL. +# ``FILENAME_VAR`` is specified with a variable name. This variable will +# receive the location of the generated file will be set, within the build +# directory. This way it can be used in case some processing is required. See +# also ``INSTALL``. # -# INCLUDE_INSTALL_DIR specifies where the includes will be installed. If it's not -# specified, it will default to INSTALL_INCLUDEDIR, CMAKE_INSTALL_INCLUDEDIR or just -# "include/" in case they are specified, with the BASE_NAME postfixed. +# ``INCLUDE_INSTALL_DIR`` specifies where the includes will be installed. If +# it's not specified, it will default to ``INSTALL_INCLUDEDIR``, +# ``CMAKE_INSTALL_INCLUDEDIR`` or just "include/" in case they are specified, +# with the BASE_NAME postfixed. # -# LIB_INSTALL_DIR specifies where the library is being installed. If it's not -# specified, it will default to LIB_INSTALL_DIR, CMAKE_INSTALL_LIBDIR or just -# "lib/" in case they are specified. +# ``LIB_INSTALL_DIR`` specifies where the library is being installed. If it's +# not specified, it will default to ``LIB_INSTALL_DIR``, +# ``CMAKE_INSTALL_LIBDIR`` or just "lib/" in case they are specified. # -# DEFINES is a list of preprocessor defines that it is recommended users of the -# library pass to the compiler when using it. +# ``DEFINES`` is a list of preprocessor defines that it is recommended users of +# the library pass to the compiler when using it. # -# INSTALL will cause the module to be installed to the ``pkgconfig`` subdirectory -# of LIB_INSTALL_DIR, unless the ECM_PKGCONFIG_INSTALL_DIR cache variable is set -# to something different. Note that the first call to ecm_generate_pkgconfig_file -# with the INSTALL argument will cause ECM_PKGCONFIG_INSTALL_DIR to be set to the -# cache, and will be used in any subsequent calls. -# -# To properly use this macro a version needs to be set. To retrieve it ``ECM_PKGCONFIG_INSTALL_DIR`` -# uses PROJECT_VERSION. To set it, use the project() command (only available since CMake 3.0) or the -# ecm_setup_version() macro. +# ``INSTALL`` will cause the module to be installed to the ``pkgconfig`` +# subdirectory of ``LIB_INSTALL_DIR``, unless the ``ECM_PKGCONFIG_INSTALL_DIR`` +# cache variable is set to something different. Note that the first call to +# ecm_generate_pkgconfig_file with the ``INSTALL`` argument will cause +# ``ECM_PKGCONFIG_INSTALL_DIR`` to be set to the cache, and will be used in any +# subsequent calls. # +# To properly use this macro a version needs to be set. To retrieve it, +# ``ECM_PKGCONFIG_INSTALL_DIR`` uses ``PROJECT_VERSION``. To set it, use the +# project() command (only available since CMake 3.0) or the ecm_setup_version() +# macro. # # Example usage: # @@ -59,6 +65,7 @@ # INSTALL # ) # +# Since 1.3.0. #============================================================================= # Copyright 2014 Aleix Pol Gonzalez <aleixpol@kde.org> diff --git a/modules/ECMGeneratePriFile.cmake b/modules/ECMGeneratePriFile.cmake index b353e867..af4b8771 100644 --- a/modules/ECMGeneratePriFile.cmake +++ b/modules/ECMGeneratePriFile.cmake @@ -68,6 +68,8 @@ # QT += KArchive # # in their ``.pro`` file. +# +# Since pre-1.0.0. #============================================================================= # Copyright 2014 David Faure <faure@kde.org> @@ -156,16 +158,16 @@ function(ECM_GENERATE_PRI_FILE) file(GENERATE OUTPUT ${PRI_FILENAME} CONTENT - "QT.@PRI_TARGET_BASENAME@.VERSION = @PROJECT_VERSION_STRING@ -QT.@PRI_TARGET_BASENAME@.MAJOR_VERSION = @PROJECT_VERSION_MAJOR@ -QT.@PRI_TARGET_BASENAME@.MINOR_VERSION = @PROJECT_VERSION_MINOR@ -QT.@PRI_TARGET_BASENAME@.PATCH_VERSION = @PROJECT_VERSION_PATCH@ -QT.@PRI_TARGET_BASENAME@.name = @PRI_TARGET_LIBNAME@ -QT.@PRI_TARGET_BASENAME@.defines = @PRI_TARGET_DEFINES@ -QT.@PRI_TARGET_BASENAME@.includes = @PRI_TARGET_INCLUDES@ -QT.@PRI_TARGET_BASENAME@.private_includes = -QT.@PRI_TARGET_BASENAME@.libs = @PRI_TARGET_LIBS@ -QT.@PRI_TARGET_BASENAME@.depends = @PRI_TARGET_QTDEPS@ + "QT.${PRI_TARGET_BASENAME}.VERSION = ${PROJECT_VERSION_STRING} +QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PROJECT_VERSION_MAJOR} +QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PROJECT_VERSION_MINOR} +QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PROJECT_VERSION_PATCH} +QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_LIBNAME} +QT.${PRI_TARGET_BASENAME}.defines = ${PRI_TARGET_DEFINES} +QT.${PRI_TARGET_BASENAME}.includes = ${PRI_TARGET_INCLUDES} +QT.${PRI_TARGET_BASENAME}.private_includes = +QT.${PRI_TARGET_BASENAME}.libs = ${PRI_TARGET_LIBS} +QT.${PRI_TARGET_BASENAME}.depends = ${PRI_TARGET_QTDEPS} " ) endfunction() diff --git a/modules/ECMInstallIcons.cmake b/modules/ECMInstallIcons.cmake index 19d44d36..549ebe19 100644 --- a/modules/ECMInstallIcons.cmake +++ b/modules/ECMInstallIcons.cmake @@ -59,6 +59,8 @@ # # With this syntax, the file ``hi22-actions-menu_new.png`` would be installed # into ``<icon_install_dir>/hicolor/22x22/actions/menu_new.png`` +# +# Since pre-1.0.0. #============================================================================= # Copyright 2014 Alex Merry <alex.merry@kde.org> @@ -109,6 +111,8 @@ macro(_ecm_install_icons_v1 _defaultpath) set(_l10n_SUBDIR ".") endif(_lang) + set(_themes) + # first the png icons file(GLOB _icons *.png) foreach (_current_ICON ${_icons} ) @@ -121,6 +125,7 @@ macro(_ecm_install_icons_v1 _defaultpath) set(_theme_GROUP ${_ECM_ICON_THEME_${_type}}) if( _theme_GROUP) + list(APPEND _themes "${_theme_GROUP}") _ECM_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake ${_defaultpath}/${_theme_GROUP}/${_size}x${_size} ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR}) @@ -139,6 +144,7 @@ macro(_ecm_install_icons_v1 _defaultpath) set(_theme_GROUP ${_ECM_ICON_THEME_${_type}}) if( _theme_GROUP) + list(APPEND _themes "${_theme_GROUP}") _ECM_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake ${_defaultpath}/${_theme_GROUP}/${_size}x${_size} ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR}) @@ -156,13 +162,21 @@ macro(_ecm_install_icons_v1 _defaultpath) set(_theme_GROUP ${_ECM_ICON_THEME_${_type}}) if( _theme_GROUP) + list(APPEND _themes "${_theme_GROUP}") _ECM_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake ${_defaultpath}/${_theme_GROUP}/scalable ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR}) endif( _theme_GROUP) endforeach (_current_ICON) - _ecm_update_iconcache("${_defaultpath}" hicolor) + if (_themes) + list(REMOVE_DUPLICATES _themes) + foreach(_theme ${_themes}) + _ecm_update_iconcache("${_defaultpath}" "${_theme}") + endforeach() + else() + message(AUTHOR_WARNING "No suitably-named icons found") + endif() endmacro() @@ -184,7 +198,9 @@ endmacro() # Updates the mtime of the icon theme directory, so caches that # watch for changes to the directory will know to update. +# If present, this also runs gtk-update-icon-cache (which despite the name is also used by Qt). function(_ecm_update_iconcache installdir theme) + find_program(GTK_UPDATE_ICON_CACHE_EXECUTABLE NAMES gtk-update-icon-cache) # We don't always have touch command (e.g. on Windows), so instead # create and delete a temporary file in the theme dir. install(CODE " @@ -192,6 +208,10 @@ function(_ecm_update_iconcache installdir theme) if (NOT DESTDIR_VALUE) file(WRITE \"${installdir}/${theme}/temp.txt\" \"update\") file(REMOVE \"${installdir}/${theme}/temp.txt\") + set(HAVE_GTK_UPDATE_ICON_CACHE_EXEC ${GTK_UPDATE_ICON_CACHE_EXECUTABLE}) + if (HAVE_GTK_UPDATE_ICON_CACHE_EXEC) + execute_process(COMMAND ${GTK_UPDATE_ICON_CACHE_EXECUTABLE} -q -t -i . WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}/${installdir}/${theme}\") + endif () endif (NOT DESTDIR_VALUE) ") endfunction() @@ -221,8 +241,9 @@ function(ecm_install_icons) endif() foreach(icon ${ARG_ICONS}) + get_filename_component(filename "${icon}" NAME) string(REGEX MATCH "([0-9sc]+)\\-([a-z]+)\\-([^/]+)\\.([a-z]+)$" - _dummy "${icon}") + complete_match "${filename}") set(size "${CMAKE_MATCH_1}") set(group "${CMAKE_MATCH_2}") set(name "${CMAKE_MATCH_3}") @@ -232,6 +253,12 @@ function(ecm_install_icons) elseif(NOT size STREQUAL "sc" AND NOT size GREATER 0) message(WARNING "${icon} size (${size}) is invalid - ignoring") else() + if (NOT complete_match STREQUAL filename) + # We can't stop accepting filenames with leading characters, + # because that would break existing projects, so just warn + # about them instead. + message(AUTHOR_WARNING "\"${icon}\" has characters before the size; it should be renamed to \"${size}-${group}-${name}.${ext}\"") + endif() if(NOT _ECM_ICON_GROUP_${group}) message(WARNING "${icon} group (${group}) is not recognized") endif() diff --git a/modules/ECMMarkAsTest.cmake b/modules/ECMMarkAsTest.cmake index 24b8cfc7..9027bf30 100644 --- a/modules/ECMMarkAsTest.cmake +++ b/modules/ECMMarkAsTest.cmake @@ -13,6 +13,8 @@ # # BUILD_TESTING is created as a cache variable by the CTest module and by the # :kde-module:`KDECMakeSettings` module. +# +# Since pre-1.0.0. #============================================================================= # Copyright 2012 Stephen Kelly <steveire@gmail.com> diff --git a/modules/ECMMarkNonGuiExecutable.cmake b/modules/ECMMarkNonGuiExecutable.cmake index 9b680216..59737d4c 100644 --- a/modules/ECMMarkNonGuiExecutable.cmake +++ b/modules/ECMMarkNonGuiExecutable.cmake @@ -11,6 +11,8 @@ # This will indicate to CMake that the specified targets should not be included # in a MACOSX_BUNDLE and should not be WIN32_EXECUTABLEs. On platforms other # than MacOS X or Windows, this will have no effect. +# +# Since pre-1.0.0. #============================================================================= # Copyright 2012 Stephen Kelly <steveire@gmail.com> diff --git a/modules/ECMOptionalAddSubdirectory.cmake b/modules/ECMOptionalAddSubdirectory.cmake index 6cbafa2d..2b890055 100644 --- a/modules/ECMOptionalAddSubdirectory.cmake +++ b/modules/ECMOptionalAddSubdirectory.cmake @@ -24,6 +24,8 @@ # .. code-block:: sh # # cmake -DDISABLE_ALL_OPTIONAL_SUBDIRECTORIES=TRUE -DBUILD_foo=TRUE myproject +# +# Since pre-1.0.0. #============================================================================= # Copyright 2007 Alexander Neundorf <neundorf@kde.org> diff --git a/modules/ECMPackageConfigHelpers.cmake b/modules/ECMPackageConfigHelpers.cmake index bc99d1cb..d1d0408f 100644 --- a/modules/ECMPackageConfigHelpers.cmake +++ b/modules/ECMPackageConfigHelpers.cmake @@ -5,7 +5,9 @@ # Helper macros for generating CMake package config files. # # ``write_basic_package_version_file()`` is the same as the one provided by the -# CMakePackageConfigHelpers module in CMake; see that module's documentation for +# `CMakePackageConfigHelpers +# <http://www.cmake.org/cmake/help/v2.8.12/cmake.html#module:CMakePackageConfigHelpers>`_ +# module in CMake; see that module's documentation for # more information. # # :: @@ -18,7 +20,23 @@ # # # This behaves in the same way as configure_package_config_file() from CMake -# 2.8.12, except that it adds an extra helper macro: find_dependency(). +# 2.8.12, except that it adds an extra helper macro: find_dependency(). It is +# highly recommended that you read the `documentation for +# CMakePackageConfigHelpers +# <http://www.cmake.org/cmake/help/v2.8.12/cmake.html#module:CMakePackageConfigHelpers>`_ +# for more information, particularly with regard to the PATH_VARS argument. +# +# Note that there is no argument that will disable the find_dependency() macro; +# if you do not require this macro, you should use +# ``configure_package_config_file`` from the CMakePackageConfigHelpers module. +# +# CMake 3.0 includes a CMakeFindDependencyMacro module that provides the +# find_dependency() macro (which you can ``include()`` in your package config +# file), so this file is only useful for projects wishing to provide config +# files that will work with CMake 2.8.12. +# +# Additional Config File Macros +# ============================= # # :: # @@ -29,14 +47,7 @@ # REQUIRED which were passed to the original find_package() call. It also sets # an informative diagnostic message if the dependency could not be found. # -# Note that there is no argument to disable the find_dependency() macro; if you -# do not require this macro, you should just use the CMakeFindDependencyMacro -# module directly. -# -# CMake 3.0.0 will include a CMakeFindDependencyMacro module that will provide -# the find_dependency() macro (which you can include() in your package config -# file), so this file is only useful for projects whose minimum required version -# is 2.8.12. +# Since pre-1.0.0. #============================================================================= # Copyright 2014 Alex Merry <alex.merry@kdemail.net> diff --git a/modules/ECMPoQmTools.cmake b/modules/ECMPoQmTools.cmake index 74dc6563..12bcf6b6 100644 --- a/modules/ECMPoQmTools.cmake +++ b/modules/ECMPoQmTools.cmake @@ -65,6 +65,8 @@ # ``<install_destination>`` defaults to ``${LOCALE_INSTALL_DIR}`` if defined, # otherwise it uses ``${CMAKE_INSTALL_LOCALEDIR}`` if that is defined, otherwise # it uses ``share/locale``. +# +# Since pre-1.0.0. #============================================================================= # Copyright 2007-2009 Kitware, Inc. @@ -119,18 +121,20 @@ function(ecm_process_po_files_as_qm lang) endif() # Find lrelease and lconvert - - # This gives us Qt5::lrelease but unfortunately no Qt5::lconvert See - # https://bugreports.qt-project.org/browse/QTBUG-37937 find_package(Qt5LinguistTools CONFIG REQUIRED) - get_target_property(lrelease_location Qt5::lrelease LOCATION) - get_filename_component(lrelease_path ${lrelease_location} PATH) - find_program(lconvert_executable - NAMES lconvert-qt5 lconvert - PATHS ${lrelease_path} - NO_DEFAULT_PATH - ) + if(TARGET Qt5::lconvert) + set(lconvert_executable Qt5::lconvert) + else() + # Qt < 5.3.1 does not define Qt5::lconvert + get_target_property(lrelease_location Qt5::lrelease LOCATION) + get_filename_component(lrelease_path ${lrelease_location} PATH) + find_program(lconvert_executable + NAMES lconvert-qt5 lconvert + PATHS ${lrelease_path} + NO_DEFAULT_PATH + ) + endif() # Create commands to turn po files into qm files set(qm_files) @@ -151,7 +155,7 @@ function(ecm_process_po_files_as_qm lang) COMMAND ${lconvert_executable} ARGS -i ${po_file} -o ${ts_file} -target-language ${lang} COMMAND Qt5::lrelease - ARGS -compress -removeidentical -silent ${ts_file} -qm ${qm_file} + ARGS -removeidentical -silent ${ts_file} -qm ${qm_file} DEPENDS ${po_file} ) if (ARGS_INSTALL_DESTINATION) diff --git a/modules/ECMQmLoader.cpp.in b/modules/ECMQmLoader.cpp.in index bc01bf98..423d1c93 100644 --- a/modules/ECMQmLoader.cpp.in +++ b/modules/ECMQmLoader.cpp.in @@ -2,6 +2,33 @@ * * Building this file in a library ensures translations are automatically loaded * when an application makes use of the library. + * + * + * Copyright 2014 Aurélien Gâteau <agateau@kde.org> + * Copyright 2015 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 <QCoreApplication> #include <QLocale> diff --git a/modules/ECMQtDeclareLoggingCategory.cmake b/modules/ECMQtDeclareLoggingCategory.cmake new file mode 100644 index 00000000..b7f1ad39 --- /dev/null +++ b/modules/ECMQtDeclareLoggingCategory.cmake @@ -0,0 +1,118 @@ +#.rst: +# ECMQtDeclareLoggingCategory +# --------------------------- +# +# Generate declarations for logging categories in Qt5. +# +# :: +# +# ecm_qt_declare_logging_category(<sources_var> +# HEADER <filename> +# IDENTIFIER <identifier> +# CATEGORY_NAME <category_name> +# [DEFAULT_SEVERITY +# <Debug|Info|Warning| +# Critical|Fatal>]) +# +# A header file, ``<filename>``, will be generated along with a corresponding +# source file, which will be added to ``<sources_var>``. These will provide a +# QLoggingCategory category that can be referred to from C++ code using +# ``<identifier>``, and from the logging configuration using +# ``<category_name>``. +# +# If ``<filename>`` is not absolute, it will be taken relative to the current +# binary directory. +# +# If the code is compiled against Qt 5.4 or later, by default it will only log +# output that is at least the severity specified by ``DEFAULT_SEVERITY``, or +# "Warning" level if ``DEFAULT_SEVERITY`` is not given. Note that, due to a +# bug in Qt 5.5, "Info" may be treated as more severe than "Fatal". +# +# ``<identifier>`` may include namespaces (eg: ``foo::bar::IDENT``). +# +# Since 5.14.0. + +#============================================================================= +# Copyright 2015 Alex Merry <alex.merry@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) + +set(_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_CPP "${CMAKE_CURRENT_LIST_DIR}/ECMQtDeclareLoggingCategory.cpp.in") +set(_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_H "${CMAKE_CURRENT_LIST_DIR}/ECMQtDeclareLoggingCategory.h.in") + +function(ecm_qt_declare_logging_category sources_var) + set(options) + set(oneValueArgs HEADER IDENTIFIER CATEGORY_NAME DEFAULT_SEVERITY) + set(multiValueArgs) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(ARG_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to ecm_qt_declare_logging_category: ${ARG_UNPARSED_ARGUMENTS}") + endif() + if(NOT ARG_HEADER) + message(FATAL_ERROR "Missing HEADER argument for ecm_qt_declare_logging_category") + endif() + if(NOT ARG_IDENTIFIER) + message(FATAL_ERROR "Missing IDENTIFIER argument for ecm_qt_declare_logging_category") + endif() + if(NOT ARG_CATEGORY_NAME) + message(FATAL_ERROR "Missing CATEGORY_NAME argument for ecm_qt_declare_logging_category") + endif() + if(NOT ARG_DEFAULT_SEVERITY) + set(ARG_DEFAULT_SEVERITY Warning) + else() + set(acceptible_severities Debug Info Warning Critical Fatal) + list(FIND acceptible_severities "${ARG_DEFAULT_SEVERITY}" pos) + if (pos EQUAL -1) + message(FATAL_ERROR "Unknown DEFAULT_SEVERITY ${pos}") + endif() + endif() + + if (NOT IS_ABSOLUTE "${ARG_HEADER}") + set(ARG_HEADER "${CMAKE_CURRENT_BINARY_DIR}/${ARG_HEADER}") + endif() + + string(REPLACE "::" ";" namespaces "${ARG_IDENTIFIER}") + list(LENGTH namespaces len) + math(EXPR last_pos "${len} - 1") + list(GET namespaces ${last_pos} IDENTIFIER) + list(REMOVE_AT namespaces ${last_pos}) + + set(OPEN_NAMESPACES) + set(CLOSE_NAMESPACES) + foreach(ns ${namespaces}) + set(OPEN_NAMESPACES "${OPEN_NAMESPACES} namespace ${ns} {") + set(CLOSE_NAMESPACES "} ${CLOSE_NAMESPACES}") + endforeach() + + string(FIND "${ARG_HEADER}" "." pos REVERSE) + if (pos EQUAL -1) + set(cpp_filename "${ARG_HEADER}.cpp") + else() + string(SUBSTRING "${ARG_HEADER}" 0 ${pos} cpp_filename) + set(cpp_filename "${cpp_filename}.cpp") + endif() + + get_filename_component(HEADER_NAME "${ARG_HEADER}" NAME) + + string(REPLACE "::" "_" GUARD_NAME "${ARG_IDENTIFIER}_H") + string(TOUPPER "${GUARD_NAME}" GUARD_NAME) + + configure_file("${_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_CPP}" "${cpp_filename}") + configure_file("${_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_H}" "${ARG_HEADER}") + + set(sources "${${sources_var}}") + list(APPEND sources "${cpp_filename}") + set(${sources_var} "${sources}" PARENT_SCOPE) +endfunction() + diff --git a/modules/ECMQtDeclareLoggingCategory.cpp.in b/modules/ECMQtDeclareLoggingCategory.cpp.in new file mode 100644 index 00000000..20c14af5 --- /dev/null +++ b/modules/ECMQtDeclareLoggingCategory.cpp.in @@ -0,0 +1,11 @@ +// This file is autogenerated by CMake: DO NOT EDIT + +#include "@HEADER_NAME@" + +@OPEN_NAMESPACES@ +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +Q_LOGGING_CATEGORY(@IDENTIFIER@, "@ARG_CATEGORY_NAME@", Qt@ARG_DEFAULT_SEVERITY@Msg) +#else +Q_LOGGING_CATEGORY(@IDENTIFIER@, "@ARG_CATEGORY_NAME@") +#endif +@CLOSE_NAMESPACES@ diff --git a/modules/ECMQtDeclareLoggingCategory.h.in b/modules/ECMQtDeclareLoggingCategory.h.in new file mode 100644 index 00000000..fedecd2f --- /dev/null +++ b/modules/ECMQtDeclareLoggingCategory.h.in @@ -0,0 +1,11 @@ +// This file is autogenerated by CMake: DO NOT EDIT + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <QLoggingCategory> +@OPEN_NAMESPACES@ +Q_DECLARE_LOGGING_CATEGORY(@IDENTIFIER@) +@CLOSE_NAMESPACES@ + +#endif diff --git a/modules/ECMQueryQmake.cmake b/modules/ECMQueryQmake.cmake index c880671f..8f4cf177 100644 --- a/modules/ECMQueryQmake.cmake +++ b/modules/ECMQueryQmake.cmake @@ -19,6 +19,7 @@ function(query_qmake result_variable qt_variable) file(TO_CMAKE_PATH "${output}" output_path) set(${result_variable} "${output_path}" PARENT_SCOPE) else() - message(FATAL "QMake call failed: ${error}") + message(WARNING "Failed call: ${QMAKE_EXECUTABLE} -query \"${qt_variable}\"") + message(FATAL_ERROR "QMake call failed: ${return_code}") endif() endfunction() diff --git a/modules/ECMSetupVersion.cmake b/modules/ECMSetupVersion.cmake index b908f96e..33d0ada1 100644 --- a/modules/ECMSetupVersion.cmake +++ b/modules/ECMSetupVersion.cmake @@ -73,6 +73,9 @@ # first argument. In all other respects, it behaves like the other form of the # command. # +# Since pre-1.0.0. +# +# COMPATIBLITY option available since 1.6.0. #============================================================================= # Copyright 2014 Alex Merry <alex.merry@kde.org> diff --git a/modules/ECMUninstallTarget.cmake b/modules/ECMUninstallTarget.cmake new file mode 100644 index 00000000..1e9bb91e --- /dev/null +++ b/modules/ECMUninstallTarget.cmake @@ -0,0 +1,58 @@ +#.rst: +# ECMUninstallTarget +# ------------------ +# +# Add an ``uninstall`` target. +# +# By including this module, an ``uninstall`` target will be added to your CMake +# project. This will remove all files installed (or updated) by a previous +# invocation of the ``install`` target. It will not remove files created or +# modified by an ``install(SCRIPT)`` or ``install(CODE)`` command; you should +# create a custom uninstallation target for these and use ``add_dependency`` to +# make the ``uninstall`` target depend on it: +# +# .. code-block:: cmake +# +# include(ECMUninstallTarget) +# install(SCRIPT install-foo.cmake) +# add_custom_target(uninstall_foo COMMAND ${CMAKE_COMMAND} -P uninstall-foo.cmake) +# add_dependency(uninstall uninstall_foo) +# +# The target will fail if the ``install`` target has not yet been run (so it is +# not possible to run CMake on the project and then immediately run the +# ``uninstall`` target). +# +# .. warning:: +# +# CMake deliberately does not provide an ``uninstall`` target by default on +# the basis that such a target has the potential to remove important files +# from a user's computer. Use with caution. +# +# Since 1.7.0. + +#============================================================================= +# Copyright 2015 Alex Merry <alex.merry@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.) + +if (NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_LIST_DIR}/ecm_uninstall.cmake.in" + "${CMAKE_BINARY_DIR}/ecm_uninstall.cmake" + IMMEDIATE + @ONLY + ) + + add_custom_target(uninstall + COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/ecm_uninstall.cmake" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + ) +endif() diff --git a/modules/ECMUseFindModules.cmake b/modules/ECMUseFindModules.cmake index a48f599b..0a8a40fb 100644 --- a/modules/ECMUseFindModules.cmake +++ b/modules/ECMUseFindModules.cmake @@ -44,6 +44,8 @@ # be installed along with config files if they are required as a dependency (for # example, if targets provided by the find module are in the link interface of a # library). +# +# Since pre-1.0.0. #============================================================================= # Copyright 2011 Alexander Neundorf <neundorf@kde.org> diff --git a/modules/ecm_uninstall.cmake.in b/modules/ecm_uninstall.cmake.in new file mode 100644 index 00000000..379239ba --- /dev/null +++ b/modules/ecm_uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif() + else() + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif() +endforeach() |