summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2016-10-10 14:46:59 +0200
committerMilan Crha <mcrha@redhat.com>2016-10-10 14:46:59 +0200
commit3cba4951951a40e299296b0a401f9406ac3ac9a2 (patch)
treefddbd053e47e446b2fee9b3ee7bfe0a0e2252b9a /cmake
parentdad728dfd69aaba8edfe84a8f922a012dbad32ac (diff)
downloadevolution-3cba4951951a40e299296b0a401f9406ac3ac9a2.tar.gz
Convert from autotools to CMake
Diffstat (limited to 'cmake')
-rw-r--r--cmake/cmake_uninstall.cmake.in21
-rw-r--r--cmake/modules/CheckTarget.cmake21
-rw-r--r--cmake/modules/CodeCoverageGCOV.cmake45
-rw-r--r--cmake/modules/DistTargets.cmake87
-rw-r--r--cmake/modules/EvolutionMacros.cmake63
-rw-r--r--cmake/modules/FindIntltool.cmake209
-rw-r--r--cmake/modules/FindLDAP.cmake133
-rw-r--r--cmake/modules/FindSMIME.cmake146
-rw-r--r--cmake/modules/GLibTools.cmake277
-rw-r--r--cmake/modules/GtkDoc.cmake150
-rw-r--r--cmake/modules/IconCache.cmake74
-rw-r--r--cmake/modules/InstalledTests.cmake88
-rw-r--r--cmake/modules/PkgConfigEx.cmake90
-rw-r--r--cmake/modules/PrintableOptions.cmake74
-rw-r--r--cmake/modules/SetupBuildFlags.cmake80
-rw-r--r--cmake/modules/UninstallTarget.cmake13
-rwxr-xr-xcmake/verify-news-file.sh56
17 files changed, 1627 insertions, 0 deletions
diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in
new file mode 100644
index 0000000000..2037e36539
--- /dev/null
+++ b/cmake/cmake_uninstall.cmake.in
@@ -0,0 +1,21 @@
+if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+file(READ "@CMAKE_CURRENT_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(NOT "${rm_retval}" STREQUAL 0)
+ else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
+ endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+endforeach(file)
diff --git a/cmake/modules/CheckTarget.cmake b/cmake/modules/CheckTarget.cmake
new file mode 100644
index 0000000000..71824a990a
--- /dev/null
+++ b/cmake/modules/CheckTarget.cmake
@@ -0,0 +1,21 @@
+# CheckTarget.cmake
+#
+# Defines a custom target 'check', which gathers test programs like 'make check'
+# This is taken from https://cmake.org/Wiki/CMakeEmulateMakeCheck
+#
+# What you do is to call command:
+# add_check_test(_name)
+# where _name is the name of the test, as defined by add_executable().
+# Note it is a good idea to use EXCLUDE_FROM_ALL within the add_executable().
+
+include(CTest)
+
+# Disable this to not have verbose tests
+set(CMAKE_CTEST_COMMAND ${CMAKE_CTEST_COMMAND} -V)
+
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
+
+macro(add_check_test _name)
+ add_test(NAME ${_name} COMMAND ${_name})
+ add_dependencies(check ${_name})
+endmacro(add_check_test)
diff --git a/cmake/modules/CodeCoverageGCOV.cmake b/cmake/modules/CodeCoverageGCOV.cmake
new file mode 100644
index 0000000000..bf670e0a59
--- /dev/null
+++ b/cmake/modules/CodeCoverageGCOV.cmake
@@ -0,0 +1,45 @@
+# CodeCoverageGCOV.cmake
+#
+# Adds options ENABLE_CODE_COVERAGE, which builds the project with
+# code coverage support
+#
+# It sets variables:
+# CODE_COVERAGE_DEFINES - to be used with target_compile_definitions() and similar
+# CODE_COVERAGE_CFLAGS - to be used with target_compile_options() and similar for C code
+# CODE_COVERAGE_CXXFLAGS - to be used with target_compile_options() and similar for C++ code
+# CODE_COVERAGE_LDFLAGS - to be used with target_link_libraries() and similar
+#
+# These variables should be added as the last in the options, because they change compilation
+
+include(CheckLibraryExists)
+include(PrintableOptions)
+
+add_printable_option(ENABLE_CODE_COVERAGE "Enable build with GCOV code coverage" OFF)
+
+if(ENABLE_CODE_COVERAGE)
+ if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+ CHECK_LIBRARY_EXISTS("gcov" "gcov_exit" "" HAVE_GCOV_LIBRARY)
+ if(HAVE_GCOV_LIBRARY)
+ set(CODE_COVERAGE_CFLAGS "-O0 -g -fprofile-arcs -ftest-coverage")
+ set(CODE_COVERAGE_LDFLAGS "-lgcov")
+
+ add_definitions(-DNDEBUG)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CODE_COVERAGE_CFLAGS}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CODE_COVERAGE_CFLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CODE_COVERAGE_LDFLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CODE_COVERAGE_LDFLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CODE_COVERAGE_LDFLAGS}")
+ set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${CODE_COVERAGE_LDFLAGS}")
+ else(HAVE_GCOV_LIBRARY)
+ message(FATAL_ERROR "Cannot fing gcov library, use -DENABLE_CODE_COVERAGE=OFF disable it")
+ endif(HAVE_GCOV_LIBRARY)
+
+ else("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+ message(FATAL_ERROR "Code coverage requires gcc compiler, use -DENABLE_CODE_COVERAGE=OFF disable it")
+ endif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+else(ENABLE_CODE_COVERAGE)
+ set(CODE_COVERAGE_DEFINES "")
+ set(CODE_COVERAGE_CFLAGS "")
+ set(CODE_COVERAGE_CXXFLAGS "")
+ set(CODE_COVERAGE_LDFLAGS "")
+endif(ENABLE_CODE_COVERAGE)
diff --git a/cmake/modules/DistTargets.cmake b/cmake/modules/DistTargets.cmake
new file mode 100644
index 0000000000..2551d3aa25
--- /dev/null
+++ b/cmake/modules/DistTargets.cmake
@@ -0,0 +1,87 @@
+# DistTarget.cmake
+#
+# Defines custom targets related to distributing source code.
+# It requires to have populated 'PROJECT_NAME' and 'PROJECT_VERSION' variables,
+# possibly through the project() command. It also uses 'PROJECT_DISTCONFIGURE_PARAMS'
+# variable when configuring the unpacked distribution.
+#
+# Added targets:
+# dist - only creates a tarball
+# disttest - creates a tarball and 'make && make install' it to a temporary prefix
+# to verify that the code can be built and installed; it also verifies
+# that the first line of the NEWS file contains the same version as
+# the tarball and that it claims today's date.
+# distcheck - similar to 'disttest', only runs also 'make check' before installing
+
+# Filenames for tarball
+set(ARCHIVE_BASE_NAME ${PROJECT_NAME}-${PROJECT_VERSION})
+set(ARCHIVE_FULL_NAME ${ARCHIVE_BASE_NAME}.tar.xz)
+
+add_custom_target(dist
+ COMMAND ${CMAKE_COMMAND} -E echo "Creating '${ARCHIVE_FULL_NAME}'..."
+ COMMAND git archive --prefix=${ARCHIVE_BASE_NAME}/ HEAD | xz -z > ${CMAKE_BINARY_DIR}/${ARCHIVE_FULL_NAME}
+ COMMAND ${CMAKE_COMMAND} -E echo "Distribution tarball '${ARCHIVE_FULL_NAME}' created at ${CMAKE_BINARY_DIR}"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+)
+
+set(disttest_extract_dir "${CMAKE_BINARY_DIR}/${ARCHIVE_BASE_NAME}")
+set(disttest_build_dir "${disttest_extract_dir}/_build")
+set(disttest_install_dir "${disttest_extract_dir}/_install")
+
+add_custom_command(OUTPUT ${disttest_build_dir}/Makefile
+ # remove any left-over directory
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${disttest_extract_dir}
+
+ # extract the tarball
+ COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR} tar -xf ${ARCHIVE_FULL_NAME}
+
+ # verify the NEWS file contains what it should contain
+ COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}
+ bash ${CMAKE_SOURCE_DIR}/cmake/verify-news-file.sh "${disttest_extract_dir}/NEWS" "${PROJECT_VERSION}"
+
+ # create a _build sub-directory
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${disttest_build_dir}"
+
+ # configure the project with PROJECT_DISTCHECK_PARAMS
+ COMMAND ${CMAKE_COMMAND} -E chdir "${disttest_build_dir}"
+ ${CMAKE_COMMAND} -G "Unix Makefiles"
+ ${PROJECT_DISTCONFIGURE_PARAMS}
+ -DCMAKE_BUILD_TYPE=Release
+ -DCMAKE_INSTALL_PREFIX="${disttest_install_dir}"
+ ..
+
+ # 'make' the project
+ COMMAND ${CMAKE_COMMAND} -E chdir ${disttest_build_dir} make -j
+
+ DEPENDS dist
+ COMMENT "Building from distribution tarball ${ARCHIVE_FULL_NAME}..."
+)
+
+add_custom_target(distcheck
+ # 'make check' the project
+ COMMAND ${CMAKE_COMMAND} -E chdir ${disttest_build_dir} make -j check
+
+ # 'make install' the project
+ COMMAND ${CMAKE_COMMAND} -E chdir ${disttest_build_dir} make -j install
+
+ # if we get this far, then everything worked, thus clean up
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${disttest_extract_dir}
+
+ # and show the good news
+ COMMAND ${CMAKE_COMMAND} -E echo "distcheck of '${ARCHIVE_FULL_NAME}' succeeded"
+
+ DEPENDS ${disttest_build_dir}/Makefile
+)
+
+add_custom_target(disttest
+ # 'make install' the project
+ COMMAND ${CMAKE_COMMAND} -E chdir ${disttest_build_dir} make -j install
+
+ # if we get this far, then everything worked, thus clean up
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${disttest_extract_dir}
+
+ # and show the good news
+ COMMAND ${CMAKE_COMMAND} -E echo "disttest of '${ARCHIVE_FULL_NAME}' succeeded"
+
+ DEPENDS ${disttest_build_dir}/Makefile
+)
diff --git a/cmake/modules/EvolutionMacros.cmake b/cmake/modules/EvolutionMacros.cmake
new file mode 100644
index 0000000000..0491e135a0
--- /dev/null
+++ b/cmake/modules/EvolutionMacros.cmake
@@ -0,0 +1,63 @@
+# EvolutionMacros.cmake
+#
+# Utility macros for evolution-related files
+#
+# add_error_files(_part _file0)
+# Adds build and install rules to create .error files from .error.xml
+# files in the current source directory. The _file0 is expected to be
+# without the .xml extension. The macro can receive one or more error
+# files. There is created a custom "${_part}-error-files" target.
+#
+# add_eplug_file(_part _eplug_filename)
+# Adds build and install rules to create .eplug files from .eplug.xml
+# files in the current source directory. The _eplug_filename is expected
+# to be without the .xml extension. The macro can receive exactly one
+# eplug file. There is created a custom "${_part}-eplug-file" target.
+
+include(FindIntltool)
+
+macro(add_custom_xml_files _part _destination _targetsuffix _ext _mergeparam _file0)
+ set(filedeps)
+
+ foreach(file ${_file0} ${ARGN})
+ intltool_merge(${file}${_ext} ${file} --xml-style --utf8 ${_mergeparam})
+
+ get_filename_component(_path ${file} DIRECTORY)
+ if(_path STREQUAL "")
+ set(builtfile ${CMAKE_CURRENT_BINARY_DIR}/${file})
+ else(_path STREQUAL "")
+ set(builtfile ${file})
+ endif(_path STREQUAL "")
+
+ install(FILES ${builtfile}
+ DESTINATION ${_destination}
+ )
+
+ list(APPEND filedeps ${builtfile})
+ endforeach(file)
+
+ add_custom_target(${_part}-${_targetsuffix}-files ALL
+ DEPENDS ${filedeps}
+ )
+endmacro(add_custom_xml_files)
+
+macro(add_error_files _part _file0)
+ add_custom_xml_files(${_part} ${errordir} error .xml --no-translations ${_file0} ${ARGN})
+endmacro(add_error_files)
+
+macro(add_eplug_file _part _eplug_filename)
+ set(PLUGINDIR "${plugindir}")
+ set(SOEXT "${CMAKE_SHARED_MODULE_SUFFIX}")
+ set(LOCALEDIR "${LOCALE_INSTALL_DIR}")
+
+ configure_file(${_eplug_filename}.xml
+ ${CMAKE_CURRENT_BINARY_DIR}/${_eplug_filename}.in
+ @ONLY
+ )
+
+ unset(PLUGINDIR)
+ unset(SOEXT)
+ unset(LOCALEDIR)
+
+ add_custom_xml_files(${_part} ${plugindir} plugin .in --no-translations ${CMAKE_CURRENT_BINARY_DIR}/${_eplug_filename})
+endmacro(add_eplug_file)
diff --git a/cmake/modules/FindIntltool.cmake b/cmake/modules/FindIntltool.cmake
new file mode 100644
index 0000000000..f6f27fe504
--- /dev/null
+++ b/cmake/modules/FindIntltool.cmake
@@ -0,0 +1,209 @@
+# FindIntltool.cmake
+#
+# Searches for intltool and gettext. It aborts, if anything cannot be found.
+# Requires GETTEXT_PO_DIR to be set to full path of the po/ directory.
+#
+# Output is:
+# INTLTOOL_UPDATE - an intltool-update executable path, as found
+# INTLTOOL_EXTRACT - an intltool-extract executable path, as found
+# INTLTOOL_MERGE - an intltool-merge executable path, as found
+#
+# and anything from the FindGettext module.
+#
+# The below provided macros require GETTEXT_PACKAGE to be set.
+#
+# intltool_add_check_potfiles_target()
+# Adds a check-potfiles target, which verifies that all files with translations
+# are added in the POTFILES.in file inside GETTEXT_PO_DIR. This macro can be called
+# only inside GETTEXT_PO_DIR.
+#
+# intltool_add_pot_file_target()
+# Creates a new target pot-file, which generates ${GETTEXT_PACKAGE}.pot file into
+# the CMAKE_CURERNT_BINARY_DIR. This target is not part of ALL.
+# This can be called only inside GETTEXT_PO_DIR.
+#
+# intltool_process_po_files()
+# Processes all files in the GETTEXT_PO_DIR and generates .gmo files for them
+# in CMAKE_CURRENT_BINARY_DIR. These are added into a new target gmo-files.
+# It also installs them into proper location under LOCALE_INSTALL_DIR.
+# This can be called only inside GETTEXT_PO_DIR.
+#
+# intltool_setup_po_dir()
+# Shortcut to setup intltool's po/ directory by adding all custom targets
+# and such. this can be called only inside GETTEXT_PO_DIR.
+#
+# intltool_merge(_in_filename _out_filename ...args)
+# Adds rule to call intltool-merge. The args are optional arguments.
+# This can be called in any folder, only the GETTEXT_PO_DIR should
+# be properly set, otherwise the call will fail.
+#
+# add_appdata_file(_infilename _outfilename)
+# A shortcut to call intltool-merge() for an appdata file and install it
+# to ${SHARE_INSTALL_DIR}/appdata
+
+include(FindGettext)
+
+if(NOT GETTEXT_FOUND)
+ message(FATAL_ERROR "gettext not found, please install at least 0.18.3 version")
+endif(NOT GETTEXT_FOUND)
+
+if(NOT GETTEXT_FOUND)
+ message(FATAL_ERROR "gettext not found, please install at least 0.18.3 version")
+endif(NOT GETTEXT_FOUND)
+
+if(GETTEXT_VERSION_STRING VERSION_LESS "0.18.3")
+ message(FATAL_ERROR "gettext version 0.18.3+ required, but version '${GETTEXT_VERSION_STRING}' found instead. Please update your gettext")
+endif(GETTEXT_VERSION_STRING VERSION_LESS "0.18.3")
+
+find_program(XGETTEXT xgettext)
+if(NOT XGETTEXT)
+ message(FATAL_ERROR "xgettext executable not found. Please install or update your gettext to at least 0.18.3 version")
+endif(NOT XGETTEXT)
+
+find_program(INTLTOOL_UPDATE intltool-update)
+if(NOT INTLTOOL_UPDATE)
+ message(FATAL_ERROR "intltool-update not found. Please install it (usually part of an 'intltool' package)")
+endif(NOT INTLTOOL_UPDATE)
+
+find_program(INTLTOOL_EXTRACT intltool-extract)
+if(NOT INTLTOOL_EXTRACT)
+ message(FATAL_ERROR "intltool-extract not found. Please install it (usually part of an 'intltool' package)")
+endif(NOT INTLTOOL_EXTRACT)
+
+find_program(INTLTOOL_MERGE intltool-merge)
+if(NOT INTLTOOL_MERGE)
+ message(FATAL_ERROR "intltool-merge not found. Please install it (usually part of an 'intltool' package)")
+endif(NOT INTLTOOL_MERGE)
+
+macro(intltool_add_check_potfiles_target)
+ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+ message(FATAL_ERROR "intltool_add_pot_file_target() can be called only inside GETTEXT_PO_DIR ('${GETTEXT_PO_DIR}'), but it is called inside '${CMAKE_CURRENT_SOURCE_DIR}' instead")
+ endif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+
+ add_custom_target(check-potfiles
+ COMMAND ${INTLTOOL_UPDATE} -m
+ WORKING_DIRECTORY ${GETTEXT_PO_DIR}
+ )
+endmacro(intltool_add_check_potfiles_target)
+
+macro(intltool_add_pot_file_target)
+ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+ message(FATAL_ERROR "intltool_add_pot_file_target() can be called only inside GETTEXT_PO_DIR ('${GETTEXT_PO_DIR}'), but it is called inside '${CMAKE_CURRENT_SOURCE_DIR}' instead")
+ endif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${GETTEXT_PACKAGE}.pot
+ COMMAND ${CMAKE_COMMAND} -E env INTLTOOL_EXTRACT="${INTLTOOL_EXTRACT}" XGETTEXT="${XGETTEXT}" srcdir=${CMAKE_CURRENT_SOURCE_DIR} ${INTLTOOL_UPDATE} --gettext-package ${GETTEXT_PACKAGE} --pot
+ )
+
+ add_custom_target(pot-file
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${GETTEXT_PACKAGE}.pot
+ )
+endmacro(intltool_add_pot_file_target)
+
+macro(intltool_process_po_files)
+ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+ message(FATAL_ERROR "intltool_process_po_files() can be called only inside GETTEXT_PO_DIR ('${GETTEXT_PO_DIR}'), but it is called inside '${CMAKE_CURRENT_SOURCE_DIR}' instead")
+ endif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+
+ file(GLOB po_files ${GETTEXT_PO_DIR}/*.po)
+
+ set(LINGUAS)
+ set(LINGUAS_GMO)
+
+ foreach(file IN LISTS po_files)
+ get_filename_component(lang ${file} NAME_WE)
+ list(APPEND LINGUAS ${lang})
+ list(APPEND LINGUAS_GMO ${lang}.gmo)
+
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo ${CMAKE_CURRENT_SOURCE_DIR}/${lang}.po
+ DEPENDS ${lang}.po
+ )
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo
+ DESTINATION ${LOCALE_INSTALL_DIR}/${lang}/LC_MESSAGES/
+ RENAME ${GETTEXT_PACKAGE}.mo
+ )
+ if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo.m)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo.m
+ DESTINATION ${LOCALE_INSTALL_DIR}/${lang}/LC_MESSAGES/
+ RENAME ${GETTEXT_PACKAGE}.mo.m
+ )
+ endif(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo.m)
+ endforeach(file)
+
+ add_custom_target(gmo-files ALL
+ DEPENDS ${LINGUAS_GMO}
+ )
+endmacro(intltool_process_po_files)
+
+macro(intltool_setup_po_dir)
+ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+ message(FATAL_ERROR "intltool_setup_po_dir() can be called only inside GETTEXT_PO_DIR ('${GETTEXT_PO_DIR}'), but it is called inside '${CMAKE_CURRENT_SOURCE_DIR}' instead")
+ endif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL GETTEXT_PO_DIR)
+
+ intltool_add_check_potfiles_target()
+ intltool_add_pot_file_target()
+ intltool_process_po_files()
+endmacro(intltool_setup_po_dir)
+
+macro(intltool_merge _in_filename _out_filename)
+ set(_in ${_in_filename})
+ set(_out ${_out_filename})
+
+ get_filename_component(_path ${_in} DIRECTORY)
+ if(_path STREQUAL "")
+ set(_in ${CMAKE_CURRENT_SOURCE_DIR}/${_in})
+ endif(_path STREQUAL "")
+
+ get_filename_component(_path ${_out} DIRECTORY)
+ if(_path STREQUAL "")
+ set(_out ${CMAKE_CURRENT_BINARY_DIR}/${_out})
+ endif(_path STREQUAL "")
+
+ set(_has_no_translations OFF)
+ set(_args)
+ foreach(_arg ${ARGN})
+ list(APPEND _args "${_arg}")
+ if(_arg STREQUAL "--no-translations")
+ set(_has_no_translations ON)
+ endif(_arg STREQUAL "--no-translations")
+ endforeach(_arg)
+
+ if(_has_no_translations)
+ add_custom_command(OUTPUT ${_out}
+ COMMAND ${INTLTOOL_MERGE} ${_args} --quiet "${_in}" "${_out}"
+ DEPENDS ${_in}
+ )
+ else(_has_no_translations)
+ add_custom_command(OUTPUT ${_out}
+ COMMAND ${INTLTOOL_MERGE} ${_args} --quiet --cache="${CMAKE_BINARY_DIR}/po/.intltool-merge-cache" "${GETTEXT_PO_DIR}" "${_in}" "${_out}"
+ DEPENDS ${_in}
+ )
+ endif(_has_no_translations)
+endmacro(intltool_merge)
+
+macro(add_appdata_file _infilename _outfilename)
+ if(NOT TARGET appdata-files)
+ add_custom_target(appdata-files ALL)
+ endif(NOT TARGET appdata-files)
+
+ set(_out ${_outfilename})
+ get_filename_component(_outtarget ${_out} NAME_WE)
+ get_filename_component(_path ${_out} DIRECTORY)
+ if(_path STREQUAL "")
+ set(_out ${CMAKE_CURRENT_BINARY_DIR}/${_out})
+ endif(_path STREQUAL "")
+
+ intltool_merge(${_infilename} ${_out} --xml-style --utf8)
+
+ add_custom_target(appdata-${_outtarget}
+ DEPENDS ${_out}
+ )
+
+ add_dependencies(appdata-files appdata-${_outtarget})
+
+ install(FILES ${_out}
+ DESTINATION ${SHARE_INSTALL_DIR}/appdata
+ )
+endmacro(add_appdata_file)
diff --git a/cmake/modules/FindLDAP.cmake b/cmake/modules/FindLDAP.cmake
new file mode 100644
index 0000000000..bc3bf86714
--- /dev/null
+++ b/cmake/modules/FindLDAP.cmake
@@ -0,0 +1,133 @@
+# FindLDAP.cmake
+#
+# Searches for OpenLDAP/SunLDAP library
+#
+# Adds these options:
+# -DWITH_OPENLDAP=ON/OFF/PATH - enable/disable OpenLDAP, eventually set prefix to find it
+# -DWITH_SUNLDAP=OFF/ON/PATH - enable/disable SunLDAP, eventually set prefix to find it
+# -DWITH_STATIC_LDAP=OFF/ON - enable/disable static LDAP linking
+#
+# The OpenLDAP has precedence over SunLDAP, if both are specified. The default is to use OpenLDAP.
+#
+# The output is:
+# HAVE_LDAP - set to ON, if LDAP support is enabled and libraries found
+# SUNLDAP - set to ON, when using SunLDAP implementation
+# LDAP_CFLAGS - CFLAGS to use with target_compile_options() and similar commands
+# LDAP_INCLUDE_DIRS - include directories to use with target_include_directories() and similar commands
+# LDAP_LIBS - libraries to use with target_link_libraries() and similar commands
+
+include(CheckCSourceCompiles)
+include(CheckLibraryExists)
+include(PrintableOptions)
+
+add_printable_variable_path(WITH_OPENLDAP "Enable LDAP support using OpenLDAP, default ON" "ON")
+add_printable_variable_path(WITH_SUNLDAP "Enable LDAP support using SunLDAP, default OFF" "OFF")
+add_printable_option(WITH_STATIC_LDAP "Link LDAP statically, default OFF" OFF)
+
+if((NOT WITH_OPENLDAP) AND (NOT WITH_SUNLDAP))
+ return()
+endif((NOT WITH_OPENLDAP) AND (NOT WITH_SUNLDAP))
+
+string(LENGTH "${CMAKE_BINARY_DIR}" bindirlen)
+string(SUBSTRING "${WITH_OPENLDAP}" 0 ${bindirlen} substr)
+string(TOUPPER "${WITH_OPENLDAP}" optupper)
+
+if(("${optupper}" STREQUAL "ON") OR ("${substr}" STREQUAL "${CMAKE_BINARY_DIR}"))
+ set(WITH_OPENLDAP "/usr")
+endif(("${optupper}" STREQUAL "ON") OR ("${substr}" STREQUAL "${CMAKE_BINARY_DIR}"))
+
+string(SUBSTRING "${WITH_SUNLDAP}" 0 ${bindirlen} substr)
+string(TOUPPER "${WITH_SUNLDAP}" optupper)
+
+if(("${optupper}" STREQUAL "ON") OR ("${substr}" STREQUAL "${CMAKE_BINARY_DIR}"))
+ set(WITH_SUNLDAP "/usr")
+endif(("${optupper}" STREQUAL "ON") OR ("${substr}" STREQUAL "${CMAKE_BINARY_DIR}"))
+
+unset(bindirlen)
+unset(substr)
+unset(optupper)
+
+set(HAVE_LDAP ON)
+set(SUNLDAP OFF)
+
+macro(add_ldap_lib_if_provides _lib _symbol)
+ CHECK_LIBRARY_EXISTS(${_lib} ${_symbol} "" lib${_lib}_provides_${_symbol})
+ if(lib${_lib}_provides_${_symbol})
+ set(LDAP_LIBS "${LDAP_LIBS} -l${_lib}")
+ endif(lib${_lib}_provides_${_symbol})
+endmacro(add_ldap_lib_if_provides)
+
+set(LDAP_PREFIX "")
+if(WITH_OPENLDAP)
+ set(LDAP_PREFIX "${WITH_OPENLDAP}")
+else(WITH_OPENLDAP)
+ set(LDAP_PREFIX "${WITH_SUNLDAP}")
+ set(SUNLDAP ON)
+endif(WITH_OPENLDAP)
+
+set(LDAP_CFLAGS "")
+set(LDAP_INCLUDE_DIRS "${LDAP_PREFIX}/include")
+set(LDAP_LIBS "-L${LDAP_PREFIX}/lib${LIB_SUFFIX}")
+
+set(CMAKE_REQUIRED_INCLUDES "${LDAP_INCLUDE_DIRS}")
+set(CMAKE_REQUIRED_LIBRARIES "${LDAP_LIBS}")
+
+if(WITH_OPENLDAP)
+ CHECK_C_SOURCE_COMPILES("#include \"ldap.h\"
+ int main(void) {
+ #if !defined(LDAP_VENDOR_VERSION) || LDAP_VENDOR_VERSION < 20000
+ #error OpenLDAP version not at least 2.0
+ #endif
+ return 0; }" openldap_2_x)
+ if(NOT openldap_2_x)
+ message(FATAL_ERROR "At least 2.0 OpenLDAP version required")
+ endif(NOT openldap_2_x)
+else(WITH_OPENLDAP)
+ CHECK_C_SOURCE_COMPILES("#include \"ldap.h\"
+ int main(void) {
+ #if !defined(LDAP_VENDOR_VERSION) || LDAP_VENDOR_VERSION < 500
+ #error SunLDAP version not at least 2.0
+ #endif
+ return 0; }" sunldap_2_x)
+ if(NOT sunldap_2_x)
+ message(FATAL_ERROR "At least 2.0 SunLDAP version required")
+ endif(NOT sunldap_2_x)
+endif(WITH_OPENLDAP)
+
+add_ldap_lib_if_provides(resolv res_query)
+add_ldap_lib_if_provides(resolv __res_query)
+add_ldap_lib_if_provides(socket bind)
+CHECK_LIBRARY_EXISTS(lber ber_get_tag "" liblber_provides_ber_get_tag)
+if(liblber_provides_ber_get_tag)
+ if(WITH_STATIC_LDAP)
+ set(LDAP_LIBS "${LDAP_LIBS} ${LDAP_PREFIX}/lib${LIB_SUFFIX}/liblber.a")
+# # libldap might depend on OpenSSL... We need to pull
+# # in the dependency libs explicitly here since we're
+# # not using libtool for the configure test.
+# if test -f ${LDAP_PREFIX}/lib${LIB_SUFFIX}/libldap.la; then
+# LDAP_LIBS="`. ${LDAP_PREFIX}/libPLIB_SUFFIX}/libldap.la; echo $dependency_libs` $LDAP_LIBS"
+# fi
+ else(WITH_STATIC_LDAP)
+ set(LDAP_LIBS "${LDAP_LIBS} -llber")
+ endif(WITH_STATIC_LDAP)
+endif(liblber_provides_ber_get_tag)
+
+CHECK_LIBRARY_EXISTS(ldap ldap_open "" libldap_provides_ldap_open)
+if(libldap_provides_ldap_open)
+ if(WITH_STATIC_LDAP)
+ set(LDAP_LIBS "${LDAP_LIBS} ${LDAP_PREFIX}/lib${LIB_SUFFIX}/libldap.a")
+ else(WITH_STATIC_LDAP)
+ set(LDAP_LIBS "${LDAP_LIBS} -lldap")
+ endif(WITH_STATIC_LDAP)
+else(libldap_provides_ldap_open)
+ if(WITH_OPENLDAP)
+ message(FATAL_ERROR "Could not find OpenLDAP libraries")
+ else(WITH_OPENLDAP)
+ message(FATAL_ERROR "Could not find SunLDAP libraries")
+ endif(WITH_OPENLDAP)
+endif(libldap_provides_ldap_open)
+
+unset(CMAKE_REQUIRED_INCLUDES)
+unset(CMAKE_REQUIRED_LIBRARIES)
+
+add_definitions(-DLDAP_DEPRECATED)
diff --git a/cmake/modules/FindSMIME.cmake b/cmake/modules/FindSMIME.cmake
new file mode 100644
index 0000000000..3f47a65fc1
--- /dev/null
+++ b/cmake/modules/FindSMIME.cmake
@@ -0,0 +1,146 @@
+# FindSMIME.cmake
+#
+# Searches for Mozilla's NSS and NSPR libraries, unless -DENABLE_SMIME=OFF is used
+#
+# The output is:
+# mozilla_nspr - if non-empty, then a pkg-config package name for nspr
+# mozilla_nss - if non-empty, then a pkg-config package name for nss
+# MANUAL_NSPR_INCLUDES - if non-empty, then contains manual nspr include directory, used for target_include_directories() and similar commands
+# MANUAL_NSPR_LIBS - if non-empty, then contains manual nspr libraries, used for target_link_libraries() and similar commands
+# MANUAL_NSS_INCLUDES - if non-empty, then contains manual nss include directory, used for target_include_directories() and similar commands
+# MANUAL_NSS_LIBS - if non-empty, then contains manual nss libraries, used for target_link_libraries() and similar commands
+# MOZILLA_NSS_LIB_DIR - a lib directory where Mozilla stores its libraries
+
+include(CheckIncludeFiles)
+include(CheckCSourceCompiles)
+include(PrintableOptions)
+include(PkgConfigEx)
+
+add_printable_option(ENABLE_SMIME "Enable SMIME support through Mozilla nss" ON)
+add_printable_variable_path(WITH_NSPR_INCLUDES "Prefix of Mozilla nspr4 includes" "")
+add_printable_variable_path(WITH_NSPR_LIBS "Prefix of Mozilla nspr4 libs" "")
+add_printable_variable_path(WITH_NSS_INCLUDES "Prefix of Mozilla nss3 includes" "")
+add_printable_variable_path(WITH_NSS_LIBS "Prefix of Mozilla nss3 libs" "")
+
+if(NOT ENABLE_SMIME)
+ return()
+endif(NOT ENABLE_SMIME)
+
+set(mozilla_nspr "")
+set(mozilla_nss "")
+set(MOZILLA_NSS_LIB_DIR "")
+
+# Use pkg-config when none is specified
+if((WITH_NSPR_INCLUDES STREQUAL "") AND (WITH_NSPR_LIBS STREQUAL "") AND (WITH_NSS_INCLUDES STREQUAL "") AND (WITH_NSS_INCLUDES STREQUAL ""))
+ foreach(pkg nspr mozilla-nspr firefox-nspr xulrunner-nspr seamonkey-nspr)
+ pkg_check_exists(_have_pkg ${pkg})
+ if(_have_pkg)
+ set(mozilla_nspr ${pkg})
+ break()
+ endif(_have_pkg)
+ endforeach(pkg)
+
+ foreach(pkg nss mozilla-nss firefox-nss xulrunner-nss seamonkey-nss)
+ pkg_check_exists(_have_pkg ${pkg})
+ if(_have_pkg)
+ set(mozilla_nss ${pkg})
+ break()
+ endif(_have_pkg)
+ endforeach(pkg)
+
+ if((NOT (mozilla_nspr STREQUAL "")) AND (NOT (mozilla_nss STREQUAL "")))
+ pkg_check_variable(_nss_libdir ${mozilla_nss} libdir)
+
+ set(MANUAL_NSPR_INCLUDES "")
+ set(MANUAL_NSPR_LIBS "")
+ set(MANUAL_NSS_INCLUDES "")
+ set(MANUAL_NSS_LIBS "")
+ set(MOZILLA_NSS_LIB_DIR "${_nss_libdir}")
+ return()
+ endif((NOT (mozilla_nspr STREQUAL "")) AND (NOT (mozilla_nss STREQUAL "")))
+endif()
+
+# Manual search, even when pkg-config failed
+
+# ******************
+# Check for NSPR 4
+# ******************
+
+if(NOT (WITH_NSPR_INCLUDES STREQUAL ""))
+ set(CMAKE_REQUIRED_INCLUDES ${WITH_NSPR_INCLUDES})
+endif(NOT (WITH_NSPR_INCLUDES STREQUAL ""))
+
+CHECK_INCLUDE_FILES(nspr.h prio.h _have_headers)
+
+unset(CMAKE_REQUIRED_INCLUDES)
+
+if(NOT _have_headers)
+ message(FATAL_ERROR "NSPR headers not found. Use -DWITH_NSPR_INCLUDES=/path/to/nspr to specify the include dir of NSPR.")
+endif(NOT _have_headers)
+
+set(MANUAL_NSPR_INCLUDES "${WITH_NSPR_INCLUDES}")
+
+set(nsprlibs "-lplc4 -lplds4 -lnspr4")
+
+set(CMAKE_REQUIRED_INCLUDES ${MANUAL_NSPR_INCLUDES})
+set(CMAKE_REQUIRED_LIBRARIES ${nsprlibs})
+CHECK_C_SOURCE_COMPILES("#include <prinit.h>
+ int main(void) { PR_Initialized(); return 0; }" _nsprlibs_okay)
+unset(CMAKE_REQUIRED_FLAGS)
+unset(CMAKE_REQUIRED_LIBRARIES)
+
+if(NOT _nsprlibs_okay)
+ message(FATAL_ERROR "NSPR libs not found. Use -DWITH_NSPR_LIBS=/path/to/libs to specify the libdir of NSPR")
+endif(NOT _nsprlibs_okay)
+
+set(MANUAL_NSPR_LIBS "")
+
+if(NOT (WITH_NSPR_LIBS STREQUAL ""))
+ set(MANUAL_NSPR_LIBS "-L${WITH_NSPR_LIBS}")
+endif(NOT (WITH_NSPR_LIBS STREQUAL ""))
+
+set(MANUAL_NSPR_LIBS "${MANUAL_NSPR_LIBS} ${nsprlibs}")
+
+# *****************
+# Check for NSS 3
+# *****************
+
+if(NOT (WITH_NSS_INCLUDES STREQUAL ""))
+ set(CMAKE_REQUIRED_INCLUDES ${WITH_NSS_INCLUDES})
+endif(NOT (WITH_NSS_INCLUDES STREQUAL ""))
+
+CHECK_INCLUDE_FILES(nss.h ssl.h smime.h _have_headers)
+
+unset(CMAKE_REQUIRED_INCLUDES)
+
+if(NOT _have_headers)
+ message(FATAL_ERROR "NSS headers not found. Use -DWITH_NSS_INCLUDES=/path/to/nss to specify the include dir of NSS.")
+endif(NOT _have_headers)
+
+set(MANUAL_NSS_INCLUDES "${WITH_NSS_INCLUDES} ${MANUAL_NSPR_INCLUDES}")
+
+set(nsslibs "-lssl3 -lsmime3 -lnss3")
+
+set(CMAKE_REQUIRED_INCLUDES ${MANUAL_NSS_INCLUDES})
+set(CMAKE_REQUIRED_LIBRARIES ${nsslibs} ${nsprlibs})
+CHECK_C_SOURCE_COMPILES("#include <nss.h>
+ int main(void) { NSS_Init(\"\"); return 0; }" _nsslibs_okay)
+unset(CMAKE_REQUIRED_FLAGS)
+unset(CMAKE_REQUIRED_LIBRARIES)
+
+if(NOT _nsslibs_okay)
+ message(FATAL_ERROR "NSS libs not found. Use -DWITH_NSS_LIBS=/path/to/libs to specify the libdir of NSS")
+endif(NOT _nsslibs_okay)
+
+set(MANUAL_NSS_LIBS "")
+
+if(NOT (WITH_NSS_LIBS STREQUAL ""))
+ set(MANUAL_NSS_LIBS "-L${WITH_NSS_LIBS}")
+ set(MOZILLA_NSS_LIB_DIR "${WITH_NSS_LIBS}")
+endif(NOT (WITH_NSS_LIBS STREQUAL ""))
+
+set(MANUAL_NSS_LIBS "${MANUAL_NSS_LIBS} ${nsslibs} ${MANUAL_NSPR_LIBS}")
+
+if(MOZILLA_NSS_LIB_DIR STREQUAL "")
+ set(MOZILLA_NSS_LIB_DIR "${LIB_INSTALL_DIR}")
+endif(MOZILLA_NSS_LIB_DIR STREQUAL "")
diff --git a/cmake/modules/GLibTools.cmake b/cmake/modules/GLibTools.cmake
new file mode 100644
index 0000000000..ba05824228
--- /dev/null
+++ b/cmake/modules/GLibTools.cmake
@@ -0,0 +1,277 @@
+# GLibTools.cmake
+#
+# Provides functions to run glib tools.
+#
+# Functions:
+#
+# glib_mkenums(_output_filename_noext _enums_header _define_name)
+# runs glib-mkenums to generate enumtypes .h and .c files from _enums_header.
+# It searches for files in the current source directory and exports to the current
+# binary directory.
+#
+# An example call is:
+# glib_mkenums(camel-enumtypes camel-enums.h CAMEL_ENUMTYPES_H)
+# which uses camel-enums.h as the source of known enums and generates
+# camel-enumtypes.h which will use the CAMEL_ENUMTYPES_H define
+# and also generates camel-enumtypes.c with the needed code.
+#
+# glib_genmarshal(_output_filename_noext _prefix _marshallist_filename)
+# runs glib-genmarshal to process ${_marshallist_filename} to ${_output_filename_noext}.c
+# and ${_output_filename_noext}.h files in the current binary directory, using
+# the ${_prefix} as the function prefix.
+#
+# gdbus_codegen(_xml _interface_prefix _c_namespace _files_prefix _list_gens)
+# runs gdbus-codegen to generate GDBus code from _xml file description,
+# using _interface_prefix, _c_namespace and _files_prefix as arguments.
+# The _list_gens is a list variable are stored expected generated files.
+#
+# An example call is:
+# set(GENERATED_DBUS_LOCALE
+# e-dbus-localed.c
+# e-dbus-localed.h
+# )
+# gdbus_codegen(org.freedesktop.locale1.xml org.freedesktop. E_DBus e-dbus-localed GENERATED_DBUS_LOCALE)
+#
+# gdbus_codegen_custom(_xml _interface_prefix _c_namespace _files_prefix _list_gens _args)
+# The same as gdbus_codegen() except allows to pass other arguments to the call,
+# like for example --c-generate-object-manager
+#
+# add_gsettings_schemas(_target _schema0 ...)
+# Adds one or more GSettings schemas. The extension is supposed to be .gschema.xml. The schema file generation
+# is added as a dependency of _target.
+#
+# glib_compile_resources _sourcedir _outputprefix _cname _inxml ...deps)
+# Calls glib-compile-resources as defined in _inxml and using _outputprefix and_cname as other arguments
+# beside _sourcedir. The optional arguments are other dependencies.
+
+include(PkgConfigEx)
+include(UninstallTarget)
+
+find_program(GLIB_MKENUMS glib-mkenums)
+if(NOT GLIB_MKENUMS)
+ message(FATAL_ERROR "Cannot find glib-mkenums, which is required to build ${PROJECT_NAME}")
+endif(NOT GLIB_MKENUMS)
+
+function(glib_mkenums _output_filename_noext _enums_header _define_name)
+ set(HEADER_TMPL "
+/*** BEGIN file-header ***/
+#ifndef ${_define_name}
+#define ${_define_name}
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* Enumerations from \"@filename@\" */
+
+/*** END file-production ***/
+
+/*** BEGIN enumeration-production ***/
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+
+/*** END enumeration-production ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* ${_define_name} */
+/*** END file-tail ***/")
+
+ file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/enumtypes-${_output_filename_noext}.h.tmpl" "${HEADER_TMPL}\n")
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.h
+ COMMAND ${GLIB_MKENUMS} --template "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/enumtypes-${_output_filename_noext}.h.tmpl" "${CMAKE_CURRENT_SOURCE_DIR}/${_enums_header}" >${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.h
+ )
+
+set(SOURCE_TMPL "
+/*** BEGIN file-header ***/
+#include \"${_output_filename_noext}.h\"
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from \"@filename@\" */
+#include \"@filename@\"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+ static volatile gsize the_type__volatile = 0;
+
+ if (g_once_init_enter (&the_type__volatile)) {
+ static const G\@Type\@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { \@VALUENAME\@,
+ \"@VALUENAME@\",
+ \"@valuenick@\" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ GType the_type = g_\@type\@_register_static (
+ g_intern_static_string (\"@EnumName@\"),
+ values);
+ g_once_init_leave (&the_type__volatile, the_type);
+ }
+ return the_type__volatile;
+}
+
+/*** END value-tail ***/")
+
+ file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/enumtypes-${_output_filename_noext}.c.tmpl" "${SOURCE_TMPL}\n")
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.c
+ COMMAND ${GLIB_MKENUMS} --template "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/enumtypes-${_output_filename_noext}.c.tmpl" "${CMAKE_CURRENT_SOURCE_DIR}/${_enums_header}" >${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.c
+ )
+endfunction(glib_mkenums)
+
+find_program(GLIB_GENMARSHAL glib-genmarshal)
+if(NOT GLIB_GENMARSHAL)
+ message(FATAL_ERROR "Cannot find glib-genmarshal, which is required to build ${PROJECT_NAME}")
+endif(NOT GLIB_GENMARSHAL)
+
+function(glib_genmarshal _output_filename_noext _prefix _marshallist_filename)
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.h
+ COMMAND ${GLIB_GENMARSHAL} --header --prefix=${_prefix} "${CMAKE_CURRENT_SOURCE_DIR}/${_marshallist_filename}" >${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.h.tmp
+ COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.h.tmp ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.h
+ DEPENDS ${_marshallist_filename}
+ )
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.c
+ COMMAND ${CMAKE_COMMAND} -E echo " #include \\\"${_output_filename_noext}.h\\\"" >${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.c.tmp
+ COMMAND ${GLIB_GENMARSHAL} --body --prefix=${_prefix} "${CMAKE_CURRENT_SOURCE_DIR}/${_marshallist_filename}" >>${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.c.tmp
+ COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.c.tmp ${CMAKE_CURRENT_BINARY_DIR}/${_output_filename_noext}.c
+ DEPENDS ${_marshallist_filename}
+ )
+endfunction(glib_genmarshal)
+
+find_program(GDBUS_CODEGEN gdbus-codegen)
+if(NOT GDBUS_CODEGEN)
+ message(FATAL_ERROR "Cannot find gdbus-codegen, which is required to build ${PROJECT_NAME}")
+endif(NOT GDBUS_CODEGEN)
+
+function(gdbus_codegen_custom _xml _interface_prefix _c_namespace _files_prefix _list_gens _args)
+ add_custom_command(
+ OUTPUT ${${_list_gens}}
+ COMMAND ${GDBUS_CODEGEN}
+ ARGS --interface-prefix ${_interface_prefix}
+ --c-namespace ${_c_namespace}
+ --generate-c-code ${_files_prefix}
+ --generate-docbook ${_files_prefix}
+ ${_args}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${_xml}
+ VERBATIM
+ )
+endfunction(gdbus_codegen_custom)
+
+function(gdbus_codegen _xml _interface_prefix _c_namespace _files_prefix _list_gens)
+ gdbus_codegen_custom(${_xml} ${_interface_prefix} ${_c_namespace} ${_files_prefix} ${_list_gens} "")
+endfunction(gdbus_codegen)
+
+add_printable_option(ENABLE_SCHEMAS_COMPILE "Enable GSettings regeneration of gschemas.compile on install" ON)
+
+if(CMAKE_CROSSCOMPILING)
+ find_program(GLIB_COMPILE_SCHEMAS glib-compile-schemas)
+else(CMAKE_CROSSCOMPILING)
+ pkg_check_variable(GLIB_COMPILE_SCHEMAS gio-2.0 glib_compile_schemas)
+endif(CMAKE_CROSSCOMPILING)
+
+if(NOT GLIB_COMPILE_SCHEMAS)
+ message(FATAL_ERROR "Cannot find glib-compile-schemas, which is required to build ${PROJECT_NAME}")
+endif(NOT GLIB_COMPILE_SCHEMAS)
+
+set(GSETTINGS_SCHEMAS_DIR "${SHARE_INSTALL_DIR}/glib-2.0/schemas/")
+
+macro(add_gsettings_schemas _target _schema0)
+ set(_install_code)
+
+ foreach(_schema ${_schema0} ${ARGN})
+ string(REPLACE ".xml" ".valid" _outputfile "${_schema}")
+ get_filename_component(_outputfile "${_outputfile}" NAME)
+
+ get_filename_component(_schema_fullname "${_schema}" DIRECTORY)
+ get_filename_component(_schema_filename "${_schema}" NAME)
+ if(_schema_fullname STREQUAL "")
+ set(_schema_fullname ${CMAKE_CURRENT_SOURCE_DIR}/${_schema})
+ else(_schema_fullname STREQUAL "")
+ set(_schema_fullname ${_schema})
+ endif(_schema_fullname STREQUAL "")
+
+ add_custom_command(
+ OUTPUT ${_outputfile}
+ COMMAND ${GLIB_COMPILE_SCHEMAS} --strict --dry-run --schema-file=${_schema_fullname}
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_schema_fullname}" "${CMAKE_CURRENT_BINARY_DIR}/${_outputfile}"
+ DEPENDS ${_schema_fullname}
+ VERBATIM
+ )
+ add_custom_target(gsettings-schemas-${_schema_filename} ALL DEPENDS ${_outputfile})
+ add_dependencies(${_target} gsettings-schemas-${_schema_filename})
+ if(ENABLE_SCHEMAS_COMPILE)
+ # this is required to compile gsettings schemas like after 'make install,
+ # because there is no better way in CMake to run a code/script after
+ # the whole `make install`
+ set(_install_code "${_install_code}
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different \"${_schema_fullname}\" \"${GSETTINGS_SCHEMAS_DIR}\""
+ )
+ endif(ENABLE_SCHEMAS_COMPILE)
+
+ # Do both, to have 'uninstall' working properly
+ install(FILES ${_schema_fullname}
+ DESTINATION ${GSETTINGS_SCHEMAS_DIR})
+ endforeach(_schema)
+
+ if(_install_code)
+ # Compile gsettings schemas and ensure that all of them are in the place.
+ install(CODE
+ "execute_process(${_install_code}
+ COMMAND ${CMAKE_COMMAND} -E chdir . \"${GLIB_COMPILE_SCHEMAS}\" \"${GSETTINGS_SCHEMAS_DIR}\"
+ )")
+ endif(_install_code)
+endmacro(add_gsettings_schemas)
+
+# This is called too early, when the schemas are not installed yet during `make install`
+#
+# compile_gsettings_schemas()
+# Optionally (based on ENABLE_SCHEMAS_COMPILE) recompiles schemas at the destination folder
+# after install. It's necessary to call it as the last command in the toplevel CMakeLists.txt,
+# thus the compile runs when all the schemas are installed.
+#
+if(ENABLE_SCHEMAS_COMPILE)
+ add_custom_command(TARGET uninstall POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E chdir . "${GLIB_COMPILE_SCHEMAS}" "${GSETTINGS_SCHEMAS_DIR}"
+ COMMENT "Recompile GSettings schemas in '${GSETTINGS_SCHEMAS_DIR}'"
+ )
+endif(ENABLE_SCHEMAS_COMPILE)
+
+find_program(GLIB_COMPILE_RESOURCES glib-compile-resources)
+if(NOT GLIB_COMPILE_RESOURCES)
+ message(FATAL_ERROR "Cannot find glib-compile-resources, which is required to build ${PROJECT_NAME}")
+endif(NOT GLIB_COMPILE_RESOURCES)
+
+macro(glib_compile_resources _sourcedir _outputprefix _cname _inxml)
+ add_custom_command(
+ OUTPUT ${_outputprefix}.h
+ COMMAND ${GLIB_COMPILE_RESOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/${_inxml} --target=${_outputprefix}.h --sourcedir=${_sourcedir} --c-name ${_cname} --generate-header
+ DEPENDS ${_inxml} ${ARGN}
+ VERBATIM
+ )
+ add_custom_command(
+ OUTPUT ${_outputprefix}.c
+ COMMAND ${GLIB_COMPILE_RESOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/${_inxml} --target=${_outputprefix}.c --sourcedir=${_sourcedir} --c-name ${_cname} --generate-source
+ DEPENDS ${_inxml} ${ARGN}
+ VERBATIM
+ )
+endmacro(glib_compile_resources)
diff --git a/cmake/modules/GtkDoc.cmake b/cmake/modules/GtkDoc.cmake
new file mode 100644
index 0000000000..4aa286ae26
--- /dev/null
+++ b/cmake/modules/GtkDoc.cmake
@@ -0,0 +1,150 @@
+# GtkDoc.cmake
+#
+# Macros to support develper documentation build from sources with gtk-doc.
+#
+# add_gtkdoc(_module _namespace _deprecated_guards _srcdirsvar _depsvar _ignoreheadersvar)
+# Adds rules to build developer documentation using gtk-doc for some part.
+# Arguments:
+# _module - the module name, like 'camel'; it expects ${_part}-docs.sgml.in in the CMAKE_CURRENT_SOURCE_DIR
+# _namespace - namespace for symbols
+# _deprecated_guards - define name, which guards deprecated symbols
+# _srcdirsvar - variable with dirs where the source files are located
+# _depsvar - a variable with dependencies (targets)
+# _ignoreheadersvar - a variable with a set of header files to ignore
+#
+# It also adds custom target gtkdoc-rebuild-${_module}-sgml to rebuild the sgml.in
+# file based on the current sources.
+
+include(PrintableOptions)
+
+add_printable_option(ENABLE_GTK_DOC "Use gtk-doc to build documentation" OFF)
+
+if(NOT ENABLE_GTK_DOC)
+ return()
+endif(NOT ENABLE_GTK_DOC)
+
+find_program(GTKDOC_SCAN gtkdoc-scan)
+find_program(GTKDOC_MKDB gtkdoc-mkdb)
+find_program(GTKDOC_MKHTML gtkdoc-mkhtml)
+find_program(GTKDOC_FIXXREF gtkdoc-fixxref)
+
+if(NOT (GTKDOC_SCAN AND GTKDOC_MKDB AND GTKDOC_MKHTML AND GTKDOC_FIXXREF))
+ message(FATAL_ERROR "Cannot find all gtk-doc binaries, install them or use -DENABLE_GTK_DOC=OFF instead")
+ return()
+endif()
+
+if(NOT TARGET gtkdocs)
+ add_custom_target(gtkdocs ALL)
+endif(NOT TARGET gtkdocs)
+
+if(NOT TARGET gtkdoc-rebuild-sgmls)
+ add_custom_target(gtkdoc-rebuild-sgmls)
+endif(NOT TARGET gtkdoc-rebuild-sgmls)
+
+macro(add_gtkdoc _module _namespace _deprecated_guards _srcdirsvar _depsvar _ignoreheadersvar)
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/${_module}-docs.sgml.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${_module}-docs.sgml
+ @ONLY
+ )
+
+ set(OUTPUT_DOCDIR ${SHARE_INSTALL_DIR}/gtk-doc/html/${_module})
+
+ set(_ignore_headers)
+ foreach(_header ${${_ignoreheadersvar}})
+ set(_ignore_headers "${_ignore_headers} ${_header}")
+ endforeach(_header)
+
+ set(_filedeps)
+ set(_srcdirs)
+ foreach(_srcdir ${${_srcdirsvar}})
+ set(_srcdirs ${_srcdirs} --source-dir="${_srcdir}")
+ file(GLOB _files ${_srcdir}/*.h* ${_srcdir}/*.c*)
+ list(APPEND _filedeps ${_files})
+ endforeach(_srcdir)
+
+ set(_mkhtml_prefix "")
+ if(APPLE)
+ set(_mkhtml_prefix "${CMAKE_COMMAND} -E env XML_CATALOG_FILES=\"/usr/local/etc/xml/catalog\"")
+ endif(APPLE)
+
+ add_custom_command(OUTPUT html/index.html
+ COMMAND ${GTKDOC_SCAN}
+ --module=${_module}
+ --deprecated-guards="${_deprecated_guards}"
+ --ignore-headers="${_ignore_headers}"
+ --rebuild-sections
+ --rebuild-types
+ ${_srcdirs}
+
+ COMMAND ${GTKDOC_MKDB}
+ --module=${_module}
+ --name-space=${_namespace}
+ --main-sgml-file="${CMAKE_CURRENT_BINARY_DIR}/${_module}-docs.sgml"
+ --sgml-mode
+ --output-format=xml
+ ${_srcdirs}
+
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/html"
+
+ COMMAND ${CMAKE_COMMAND} -E chdir "${CMAKE_CURRENT_BINARY_DIR}/html" ${_mkhtml_prefix} ${GTKDOC_MKHTML} --path=.. ${_module} ../${_module}-docs.sgml
+
+ COMMAND ${GTKDOC_FIXXREF}
+ --module=${_module}
+ --module-dir=.
+ --extra-dir=..
+ --html-dir="${OUTPUT_DOCDIR}"
+
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_module}-docs.sgml"
+ ${_filedeps}
+ COMMENT "Generating ${_module} documentation"
+ )
+
+ add_custom_target(gtkdoc-${_module}
+ DEPENDS html/index.html
+ )
+
+ if(${_depsvar})
+ add_dependencies(gtkdoc-${_module} ${${_depsvar}})
+ endif(${_depsvar})
+
+ add_dependencies(gtkdocs gtkdoc-${_module})
+
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
+ DESTINATION ${OUTPUT_DOCDIR}
+ )
+
+ # ***************************************
+ # sgml.in file rebuild, unconditional
+ # ***************************************
+ add_custom_target(gtkdoc-rebuild-${_module}-sgml
+ COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+
+ COMMAND ${CMAKE_COMMAND} -E chdir "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+ ${GTKDOC_SCAN}
+ --module=${_module}
+ --deprecated-guards="${_deprecated_guards}"
+ --ignore-headers="${_ignore_headers}"
+ --rebuild-sections
+ --rebuild-types
+ ${_srcdirs}
+
+ COMMAND ${CMAKE_COMMAND} -E chdir "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+ ${GTKDOC_MKDB}
+ --module=${_module}
+ --name-space=${_namespace}
+ --main-sgml-file="${CMAKE_CURRENT_BINARY_DIR}/tmp/${_module}-docs.sgml"
+ --sgml-mode
+ --output-format=xml
+ ${_srcdirs}
+
+ COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/tmp/${_module}-docs.sgml ${CMAKE_CURRENT_SOURCE_DIR}/${_module}-docs.sgml.in
+
+ COMMAND ${CMAKE_COMMAND} -E echo "File '${CMAKE_CURRENT_SOURCE_DIR}/${_module}-docs.sgml.in' overwritten, make sure you replace generated strings with proper content before committing."
+ )
+
+ add_dependencies(gtkdoc-rebuild-sgmls gtkdoc-rebuild-${_module}-sgml)
+
+endmacro(add_gtkdoc)
diff --git a/cmake/modules/IconCache.cmake b/cmake/modules/IconCache.cmake
new file mode 100644
index 0000000000..065a44bcdd
--- /dev/null
+++ b/cmake/modules/IconCache.cmake
@@ -0,0 +1,74 @@
+# IconCache.cmake
+#
+# This is required here only to have defined target 'uninstall'
+# in the same directory.
+#
+# Macros:
+# add_icon_cache_files(_destdir _fileslistvar ...)
+# adds rules to install icons to icon cache directory with prefix _destdir;
+# the other arguments are one or more list variables with file names.
+
+include(UninstallTarget)
+
+macro(get_one_icon_component _instring _outvalue _outrest)
+ string(FIND "${_instring}" "_" _pos)
+ if(_pos EQUAL -1)
+ message(FATAL_ERROR "get_one_icon_component() failed to get one component from '${_instring}'")
+ endif(_pos EQUAL -1)
+
+ math(EXPR _posinc "${_pos}+1")
+
+ string(SUBSTRING "${_instring}" 0 ${_pos} ${_outvalue})
+ string(SUBSTRING "${_instring}" ${_posinc} -1 ${_outrest})
+endmacro(get_one_icon_component)
+
+macro(split_icon_components _infilename _outtheme _outcontext _outsize _outiconfile)
+ set(_rest "${_infilename}")
+
+ get_one_icon_component("${_rest}" ${_outtheme} _rest)
+ get_one_icon_component("${_rest}" ${_outcontext} _rest)
+ get_one_icon_component("${_rest}" ${_outsize} _rest)
+ set(${_outiconfile} "${_rest}")
+endmacro(split_icon_components)
+
+find_program(GTK_UPDATE_ICON_CACHE gtk-update-icon-cache)
+if(NOT GTK_UPDATE_ICON_CACHE)
+ message(WARNING "gtk-update-icon-cache not found. Make sure to call ${GTK_UPDATE_ICON_CACHE} -f -t \"${SHARE_INSTALL_DIR}/icons/hicolor\" after install and uninstall")
+endif(NOT GTK_UPDATE_ICON_CACHE)
+
+set(_update_icon_cache_cmd ${GTK_UPDATE_ICON_CACHE} -f -t "${SHARE_INSTALL_DIR}/icons/hicolor")
+
+macro(process_icons _destdir _fileslistvar _install_codevar)
+ foreach(srcfile IN LISTS ${_fileslistvar})
+ split_icon_components(${srcfile} theme context size iconfile)
+ install(FILES ${srcfile}
+ DESTINATION ${_destdir}/icons/${theme}/${size}/${context}
+ RENAME ${iconfile}
+ )
+ set(${_install_codevar} "${${_install_codevar}}
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different \"${CMAKE_CURRENT_SOURCE_DIR}/${srcfile}\" \"${_destdir}/icons/${theme}/${size}/${context}/${iconfile}\""
+ )
+ endforeach(srcfile)
+endmacro(process_icons)
+
+macro(add_icon_cache_files _destdir _fileslistvar)
+ set(_install_code)
+
+ foreach(_filesvar ${_fileslistvar} ${ARGN})
+ process_icons("${_destdir}" ${_filesvar} _install_code)
+ endforeach(_filesvar)
+
+ if(GTK_UPDATE_ICON_CACHE)
+ install(CODE
+ "execute_process(${_install_code}
+ COMMAND ${CMAKE_COMMAND} -E chdir . ${_update_icon_cache_cmd}
+ )")
+ endif(GTK_UPDATE_ICON_CACHE)
+endmacro(add_icon_cache_files)
+
+if(GTK_UPDATE_ICON_CACHE)
+ add_custom_command(TARGET uninstall POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E chdir . ${_update_icon_cache_cmd}
+ COMMENT "Updating icon cache in '${SHARE_INSTALL_DIR}/icons/hicolor'"
+ )
+endif(GTK_UPDATE_ICON_CACHE)
diff --git a/cmake/modules/InstalledTests.cmake b/cmake/modules/InstalledTests.cmake
new file mode 100644
index 0000000000..ec445539c0
--- /dev/null
+++ b/cmake/modules/InstalledTests.cmake
@@ -0,0 +1,88 @@
+# InstalledTests.cmake
+#
+# Adds option ENABLE_INSTALLED_TESTS and helper macros to manage
+# installed test. There are also set variables:
+# INSTALLED_TESTS_EXEC_DIR - where to store installed tests and eventually its data
+# INSTALLED_TESTS_META_DIR - where to store .test meta files for installed tests
+#
+# install_test_if_enabled(_test_target _type _environ)
+# Adds rules to install a test whose target is _test_target (the one
+# used for add_executable()), while the target name should match
+# the executable name. The _type and _environ are used for populating
+# the .test meta file.
+#
+# install_behave_tests_if_enabled(_testsvar _type _environ)
+# Adds rules to install the 'behave' tests as stored in _testsvar
+# in the current source directory.
+
+include(PrintableOptions)
+
+add_printable_option(ENABLE_INSTALLED_TESTS "Enable installed tests" OFF)
+
+set(INSTALLED_TESTS_EXEC_DIR ${privlibexecdir}/installed-tests)
+set(INSTALLED_TESTS_META_DIR ${SHARE_INSTALL_DIR}/installed-tests/${PROJECT_NAME})
+
+macro(install_test_if_enabled _test_target _type _environ)
+ if(ENABLE_INSTALLED_TESTS)
+ set(TEST_TYPE ${_type})
+ set(TEST_ENVIRONMENT)
+ if(NOT ${_environ} STREQUAL "")
+ set(TEST_ENVIRONMENT "env ${_environ} ")
+ endif(NOT ${_environ} STREQUAL "")
+
+ set(teststring "[Test]
+Type=${TEST_TYPE}
+Exec=${TEST_ENVIRONMENT}${INSTALLED_TESTS_EXEC_DIR}/${_test_target}
+"
+)
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${_test_target}.test "${teststring}")
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_test_target}.test
+ DESTINATION ${INSTALLED_TESTS_META_DIR}
+ )
+
+ install(TARGETS ${_test_target}
+ DESTINATION ${INSTALLED_TESTS_EXEC_DIR}
+ )
+ endif(ENABLE_INSTALLED_TESTS)
+endmacro(install_test_if_enabled)
+
+macro(install_behave_tests_if_enabled _testsvar _type _environ)
+ if(ENABLE_INSTALLED_TESTS)
+ set(TEST_TYPE ${_type})
+ set(TEST_ENVIRONMENT)
+ if(NOT ${_environ} STREQUAL "")
+ set(TEST_ENVIRONMENT "env ${_environ} ")
+ endif(NOT ${_environ} STREQUAL "")
+
+ file(GLOB BEHAVE_FEATURES ${CMAKE_CURRENT_SOURCE_DIR}/*.feature)
+ file(GLOB BEHAVE_STEP_DEFINITIONS ${CMAKE_CURRENT_SOURCE_DIR}/steps/*.py)
+ set(BEHAVE_COMMON_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/environment.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/common_steps.py
+ )
+
+ install(FILES ${BEHAVE_FEATURES} ${BEHAVE_COMMON_FILES}
+ DESTINATION ${INSTALLED_TESTS_EXEC_DIR}
+ )
+
+ install(FILES ${BEHAVE_STEP_DEFINITIONS}
+ DESTINATION ${INSTALLED_TESTS_EXEC_DIR}/steps/
+ )
+
+ foreach(_test ${${_testsvar}})
+ set(teststring "[Test]
+Type=${TEST_TYPE}
+Exec=${TEST_ENVIRONMENT}behave ${INSTALLED_TESTS_EXEC_DIR} -t ${_test} -k -f html -o ${_test}.html -f plain
+"
+)
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${_test}.test "${teststring}")
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_test}.test
+ DESTINATION ${INSTALLED_TESTS_META_DIR}
+ )
+ endforeach(_test)
+ endif(ENABLE_INSTALLED_TESTS)
+endmacro(install_behave_tests_if_enabled)
diff --git a/cmake/modules/PkgConfigEx.cmake b/cmake/modules/PkgConfigEx.cmake
new file mode 100644
index 0000000000..866fe7c074
--- /dev/null
+++ b/cmake/modules/PkgConfigEx.cmake
@@ -0,0 +1,90 @@
+# PkgConfigEx.cmake
+#
+# Extends CMake's PkgConfig module with commands:
+#
+# pkg_check_modules_for_option(_option_name _option_description _prefix _module0)
+#
+# which calls `pkg_check_modules(_prefix _module0)` and if <_prefix>_FOUND is False,
+# then prints an error with a hint to disaable the _option_name if needed.
+#
+# pkg_check_exists(_output_name _pkg)
+#
+# calls pkg-config --exists for _pkg and stores the result to _output_name.
+#
+# pkg_check_at_least_version(_output_name _pkg _version)
+#
+# calls pkg-config --at-least-version=_version for _pkg and stores the result to _output_name.
+#
+# pkg_check_exact_version(_output_name _pkg _version)
+#
+# calls pkg-config --exact-version=_version for _pkg and stores the result to _output_name.
+#
+# pkg_check_variable(_output_name _pkg _name)
+#
+# gets a variable named _name from package _pkg and stores the result into _output_name
+
+find_package(PkgConfig REQUIRED)
+
+macro(pkg_check_modules_for_option _option_name _option_description _prefix _module0)
+ pkg_check_modules(${_prefix} ${_module0} ${ARGN})
+
+ if(NOT ${_prefix}_FOUND)
+ message(FATAL_ERROR "Necessary libraries not found or not enough version. If you want to disable ${_option_description}, please use -D${_option_name}=OFF argument to cmake command.")
+ endif(NOT ${_prefix}_FOUND)
+endmacro()
+
+macro(pkg_check_exists _output_name _pkg)
+ execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --exists ${_pkg}
+ RESULT_VARIABLE ${_output_name})
+
+ # Negate the result, because 0 means 'found'
+ if(${_output_name})
+ set(${_output_name} OFF)
+ else(${_output_name})
+ set(${_output_name} ON)
+ endif(${_output_name})
+endmacro()
+
+macro(pkg_check_at_least_version _output_name _pkg _version)
+ execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --atleast-version=${_version} ${_pkg}
+ RESULT_VARIABLE ${_output_name})
+
+ # Negate the result, because 0 means 'found'
+ if(${_output_name})
+ set(${_output_name} OFF)
+ else(${_output_name})
+ set(${_output_name} ON)
+ endif(${_output_name})
+endmacro()
+
+macro(pkg_check_exact_version _output_name _pkg _version)
+ execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --exact-version=${_version} ${_pkg}
+ RESULT_VARIABLE ${_output_name})
+
+ # Negate the result, because 0 means 'found'
+ if(${_output_name})
+ set(${_output_name} OFF)
+ else(${_output_name})
+ set(${_output_name} ON)
+ endif(${_output_name})
+endmacro()
+
+function(pkg_check_variable _output_name _pkg _name)
+ execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${_name} ${_pkg}
+ OUTPUT_VARIABLE _pkg_result
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set("${_output_name}" "${_pkg_result}" CACHE STRING "pkg-config variable ${_name} of ${_pkg}")
+endfunction()
+
+macro(add_pkgconfig_file _input _output)
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/${_input}
+ ${CMAKE_CURRENT_BINARY_DIR}/${_output}
+ @ONLY
+ )
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_output}
+ DESTINATION ${LIB_INSTALL_DIR}/pkgconfig
+ )
+endmacro()
diff --git a/cmake/modules/PrintableOptions.cmake b/cmake/modules/PrintableOptions.cmake
new file mode 100644
index 0000000000..23ce356991
--- /dev/null
+++ b/cmake/modules/PrintableOptions.cmake
@@ -0,0 +1,74 @@
+# PrintableOptions.cmake
+#
+# Provides functions to manage printable otpions,
+# which can be printed at the end of the configuration
+#
+# add_printable_variable_bare(_name)
+# adds variable named _name to the list of prinable options
+#
+# add_printable_option(_name _description _default_value)
+# the same as option() commnd, only also notes this option for later printing
+#
+# add_printable_variable(_name _description _default_value)
+# sets a new cached STRING variable and adds it to the list of printable options
+#
+# add_printable_variable_path(_name _description _default_value)
+# sets a new cached PATH variable and adds it to the list of printable options
+#
+# print_build_options()
+# prints all the build options previously added with the above functions
+
+macro(add_printable_variable_bare _name)
+ if(_name STREQUAL "")
+ message(FATAL_ERROR "variable name cannot be empty")
+ endif(_name STREQUAL "")
+ list(APPEND _printable_options ${_name})
+endmacro()
+
+macro(add_printable_option _name _description _default_value)
+ if(_name STREQUAL "")
+ message(FATAL_ERROR "option name cannot be empty")
+ endif(_name STREQUAL "")
+ option(${_name} ${_description} ${_default_value})
+ add_printable_variable_bare(${_name})
+endmacro()
+
+macro(add_printable_variable _name _description _default_value)
+ if(_name STREQUAL "")
+ message(FATAL_ERROR "variable name cannot be empty")
+ endif(_name STREQUAL "")
+ set(${_name} ${_default_value} CACHE STRING ${_description})
+ add_printable_variable_bare(${_name})
+endmacro()
+
+macro(add_printable_variable_path _name _description _default_value)
+ if(_name STREQUAL "")
+ message(FATAL_ERROR "path variable name cannot be empty")
+ endif(_name STREQUAL "")
+ set(${_name} ${_default_value} CACHE PATH ${_description})
+ add_printable_variable_bare(${_name})
+endmacro()
+
+function(print_build_options)
+ message(STATUS "Configure options:")
+
+ set(max_len 0)
+ foreach(opt IN LISTS _printable_options)
+ string(LENGTH "${opt}" len)
+ if(max_len LESS len)
+ set(max_len ${len})
+ endif(max_len LESS len)
+ endforeach()
+ math(EXPR max_len "${max_len} + 2")
+
+ foreach(opt IN LISTS _printable_options)
+ string(LENGTH "${opt}" len)
+ set(str " ${opt} ")
+ foreach (IGNORE RANGE ${len} ${max_len})
+ set(str "${str}.")
+ endforeach ()
+ set(str "${str} ${${opt}}")
+
+ message(STATUS ${str})
+ endforeach()
+endfunction()
diff --git a/cmake/modules/SetupBuildFlags.cmake b/cmake/modules/SetupBuildFlags.cmake
new file mode 100644
index 0000000000..a7d2aa4172
--- /dev/null
+++ b/cmake/modules/SetupBuildFlags.cmake
@@ -0,0 +1,80 @@
+# SetupBuildFlags.cmake
+#
+# Setups compiler/linker flags, skipping those which are not supported.
+
+include(CheckCCompilerFlag)
+include(CheckCXXCompilerFlag)
+
+macro(setup_build_flags _maintainer_mode)
+ list(APPEND proposed_flags
+ -Werror-implicit-function-declaration
+ -Wformat
+ -Wformat-security
+ -Winit-self
+ -Wmissing-declarations
+ -Wmissing-noreturn
+ -Wpointer-arith
+ -Wredundant-decls
+ -Wundef
+ -Wwrite-strings
+ -no-undefined
+ -fno-strict-aliasing
+ )
+
+ if(_maintainer_mode)
+ list(APPEND proposed_flags
+ -Wall
+ -Wextra
+ -Wdeprecated-declarations
+ -Wmissing-include-dirs
+ )
+ else(_maintainer_mode)
+ list(APPEND proposed_flags
+ -Wno-deprecated-declarations
+ -Wno-missing-include-dir)
+ endif(_maintainer_mode)
+
+ list(APPEND proposed_c_flags
+ ${proposed_flags}
+ -Wdeclaration-after-statement
+ -Wno-missing-field-initializers
+ -Wno-sign-compare
+ -Wno-unused-parameter
+ -Wnested-externs
+ )
+
+ if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+ list(APPEND proposed_c_flags
+ -Wno-parentheses-equality
+ -Wno-format-nonliteral
+ )
+ endif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+
+ list(APPEND proposed_cxx_flags
+ ${proposed_flags}
+ -Wabi
+ -Wnoexcept
+ )
+
+ foreach(flag IN LISTS proposed_c_flags)
+ check_c_compiler_flag(${flag} c_flag_${flag}_supported)
+ if(c_flag_${flag}_supported)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ endif(c_flag_${flag}_supported)
+ unset(c_flag_${flag}_supported)
+ endforeach()
+
+ foreach(flag IN LISTS proposed_cxx_flags)
+ check_cxx_compiler_flag(${flag} cxx_flag_${flag}_supported)
+ if(cxx_flag_${flag}_supported)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ endif(cxx_flag_${flag}_supported)
+ unset(cxx_flag_${flag}_supported)
+ endforeach()
+
+ if(("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU"))
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
+ endif(("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU"))
+endmacro()
diff --git a/cmake/modules/UninstallTarget.cmake b/cmake/modules/UninstallTarget.cmake
new file mode 100644
index 0000000000..7ccfcf3947
--- /dev/null
+++ b/cmake/modules/UninstallTarget.cmake
@@ -0,0 +1,13 @@
+# UninstallTarget.cmake
+#
+# Defines a custom target named 'uninstall'
+
+if(NOT TARGET uninstall)
+ configure_file(
+ "${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+ "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+
+ add_custom_target(uninstall
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake)
+endif(NOT TARGET uninstall)
diff --git a/cmake/verify-news-file.sh b/cmake/verify-news-file.sh
new file mode 100755
index 0000000000..98d819102b
--- /dev/null
+++ b/cmake/verify-news-file.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+# Verifies that the NEWS file's first line contains correct version and date.
+# Requires arguments:
+# $1 ... the NEWS file name, preferably with full path
+# $2 ... expected version string, like "1.2.3"
+#
+# The date is expected in a form of YYYY-MM-DD of the current local time.
+# The NEWS line is in form of "PROJECTNAME VERSION DATE".
+#
+# The test can be skipped entirely when SKIP_NEWS_FILE_TEST=1 is set.
+
+FILENAME=$1
+EXPVERSION=$2
+
+if [ ! -f "$FILENAME" ]; then
+ echo "File '$FILENAME' does not exist" 1>&2
+ exit 1
+fi
+
+if [ -z "$EXPVERSION" ]; then
+ echo "Expected version argument not given or empty, use format '1.2.3'" 1>&2
+ exit 1
+fi
+
+NEWSLINE=`head --lines=1 "$FILENAME"`
+EXPDATE=`date +%Y-%m-%d`
+
+NEWSVERSION="${NEWSLINE#* }"
+NEWSDATE="${NEWSVERSION#* }"
+NEWSVERSION="${NEWSVERSION% *}"
+SUCCESS=1
+
+if [ "$NEWSVERSION" != "$EXPVERSION" ]; then
+ echo "Read NEWS version '$NEWSVERSION' doesn't match expected version '$EXPVERSION'" 1>&2
+ SUCCESS=0
+fi
+
+if [ "$NEWSDATE" != "$EXPDATE" ]; then
+ echo "Read NEWS date '$NEWSDATE' doesn't match expected date '$EXPDATE'" 1>&2
+ SUCCESS=0
+fi
+
+if [ "$SUCCESS" != "1" ]; then
+ if [ "$SKIP_NEWS_FILE_TEST" = "1" ]; then
+ echo "" 1>&2
+ echo "****************************************************************" 1>&2
+ echo "* Failed NEWS file test ignored due to SKIP_NEWS_FILE_TEST=1 *" 1>&2
+ echo "****************************************************************" 1>&2
+ echo "" 1>&2
+ exit 0
+ else
+ echo "(This test can be skipped when SKIP_NEWS_FILE_TEST=1 is set.)" 1>&2
+ fi
+ exit 1
+fi