From b230b69539c1ec84c425da9808dceb5b13a37bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Mon, 13 Sep 2010 19:24:53 +0200 Subject: Initial commit --- cmake/FindGTK2.cmake | 546 +++++++++++++++++++++++++++++++++++++++++++ cmake/FindGettext.cmake | 105 +++++++++ cmake/FindGtkDoc.cmake | 366 +++++++++++++++++++++++++++++ cmake/ProcessArguments.cmake | 140 +++++++++++ 4 files changed, 1157 insertions(+) create mode 100644 cmake/FindGTK2.cmake create mode 100644 cmake/FindGettext.cmake create mode 100644 cmake/FindGtkDoc.cmake create mode 100644 cmake/ProcessArguments.cmake (limited to 'cmake') diff --git a/cmake/FindGTK2.cmake b/cmake/FindGTK2.cmake new file mode 100644 index 0000000..39beae9 --- /dev/null +++ b/cmake/FindGTK2.cmake @@ -0,0 +1,546 @@ +# - FindGTK2.cmake +# This module can find the GTK2 widget libraries and several of its other +# optional components like gtkmm, glade, and glademm. +# +# NOTE: If you intend to use version checking, CMake 2.6.2 or later is +# required. +# +# Specify one or more of the following components +# as you call this find module. See example below. +# +# gtk +# gtkmm +# glade +# glademm +# +# The following variables will be defined for your use +# +# GTK2_FOUND - Were all of your specified components found? +# GTK2_INCLUDE_DIRS - All include directories +# GTK2_LIBRARIES - All libraries +# +# GTK2_VERSION - The version of GTK2 found (x.y.z) +# GTK2_MAJOR_VERSION - The major version of GTK2 +# GTK2_MINOR_VERSION - The minor version of GTK2 +# GTK2_PATCH_VERSION - The patch version of GTK2 +# +# Optional variables you can define prior to calling this module: +# +# GTK2_DEBUG - Enables verbose debugging of the module +# GTK2_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced +# +#================= +# Example Usage: +# +# Call find_package() once, here are some examples to pick from: +# +# Require GTK 2.6 or later +# find_package(GTK2 2.6 REQUIRED gtk) +# +# Require GTK 2.10 or later and Glade +# find_package(GTK2 2.10 REQUIRED gtk glade) +# +# Search for GTK/GTKMM 2.8 or later +# find_package(GTK2 2.8 COMPONENTS gtk gtkmm) +# +# if(GTK2_FOUND) +# include_directories(${GTK2_INCLUDE_DIRS}) +# add_executable(mygui mygui.cc) +# target_link_libraries(mygui ${GTK2_LIBRARIES}) +# endif() +# + +#============================================================================= +# Copyright 2009 Kitware, Inc. +# Copyright 2008-2009 Philip Lowman +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt 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 distributed this file outside of CMake, substitute the full +# License text for the above reference.) + +# Version 0.7 (3/22/09) +# * Checked into CMake CVS +# * Added versioning support +# * Module now defaults to searching for GTK if COMPONENTS not specified. +# * Added HKCU prior to HKLM registry key and GTKMM specific environment +# variable as per mailing list discussion. +# * Added lib64 to include search path and a few other search paths where GTK +# may be installed on Unix systems. +# * Switched to lowercase CMake commands +# * Prefaced internal variables with _GTK2 to prevent collision +# * Changed internal macros to functions +# * Enhanced documentation +# Version 0.6 (1/8/08) +# Added GTK2_SKIP_MARK_AS_ADVANCED option +# Version 0.5 (12/19/08) +# Second release to cmake mailing list + +#============================================================= +# _GTK2_GET_VERSION +# Internal function to parse the version number in gtkversion.h +# _OUT_major = Major version number +# _OUT_minor = Minor version number +# _OUT_micro = Micro version number +# _gtkversion_hdr = Header file to parse +#============================================================= +function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr) + file(READ ${_gtkversion_hdr} _contents) + if(_contents) + string(REGEX REPLACE ".*#define GTK_MAJOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_major} "${_contents}") + string(REGEX REPLACE ".*#define GTK_MINOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_minor} "${_contents}") + string(REGEX REPLACE ".*#define GTK_MICRO_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_micro} "${_contents}") + + if(NOT ${_OUT_major} MATCHES "[0-9]+") + message(FATAL_ERROR "Version parsing failed for GTK2_MAJOR_VERSION!") + endif() + if(NOT ${_OUT_minor} MATCHES "[0-9]+") + message(FATAL_ERROR "Version parsing failed for GTK2_MINOR_VERSION!") + endif() + if(NOT ${_OUT_micro} MATCHES "[0-9]+") + message(FATAL_ERROR "Version parsing failed for GTK2_MICRO_VERSION!") + endif() + + set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE) + set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE) + set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE) + else() + message(FATAL_ERROR "Include file ${_gtkversion_hdr} does not exist") + endif() +endfunction() + +#============================================================= +# _GTK2_FIND_INCLUDE_DIR +# Internal function to find the GTK include directories +# _var = variable to set +# _hdr = header file to look for +#============================================================= +function(_GTK2_FIND_INCLUDE_DIR _var _hdr) + + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "_GTK2_FIND_INCLUDE_DIR( ${_var} ${_hdr} )") + endif() + + set(_relatives + # FIXME + glibmm-2.4 + glib-2.0 + atk-1.0 + atkmm-1.6 + cairo + cairomm-1.0 + gdkmm-2.4 + giomm-2.4 + gtk-2.0 + gtkmm-2.4 + libglade-2.0 + libglademm-2.4 + pango-1.0 + pangomm-1.4 + sigc++-2.0 + ) + + set(_suffixes) + foreach(_d ${_relatives}) + list(APPEND _suffixes ${_d}) + list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include + endforeach() + + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "include suffixes = ${_suffixes}") + endif() + + find_path(${_var} ${_hdr} + PATHS + /usr/local/lib64 + /usr/local/lib + /usr/lib64 + /usr/lib + /opt/gnome/include + /opt/gnome/lib + /opt/openwin/include + /usr/openwin/lib + $ENV{GTKMM_BASEPATH}/include + $ENV{GTKMM_BASEPATH}/lib + [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/include + [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib + [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/include + [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib + PATH_SUFFIXES + ${_suffixes} + ) + + if(${_var}) + set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE) + if(NOT GTK2_SKIP_MARK_AS_ADVANCED) + mark_as_advanced(${_var}) + endif() + endif() + +endfunction(_GTK2_FIND_INCLUDE_DIR) + +#============================================================= +# _GTK2_FIND_LIBRARY +# Internal function to find libraries packaged with GTK2 +# _var = library variable to create +#============================================================= +function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version) + + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "_GTK2_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )") + endif() + + # Not GTK versions per se but the versions encoded into Windows + # import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example) + # Also the MSVC libraries use _ for . (this is handled below) + set(_versions 2.20 2.18 2.16 2.14 2.12 + 2.10 2.8 2.6 2.4 2.2 2.0 + 1.20 1.18 1.16 1.14 1.12 + 1.10 1.8 1.6 1.4 1.2 1.0) + + set(_library) + set(_library_d) + + set(_library ${_lib}) + + if(_expand_vc) + # Add vc80/vc90 midfixes + if(MSVC80) + set(_library ${_library}-vc80) + set(_library_d ${_library}-d) + elseif(MSVC90) + set(_library ${_library}-vc90) + set(_library_d ${_library}-d) + endif() + endif() + + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "After midfix addition = ${_library} and ${_library_d}") + endif() + + set(_lib_list) + set(_libd_list) + if(_append_version) + foreach(_ver ${_versions}) + list(APPEND _lib_list "${_library}-${_ver}") + list(APPEND _libd_list "${_library_d}-${_ver}") + endforeach() + else() + set(_lib_list ${_library}) + set(_libd_list ${_library_d}) + endif() + + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "library list = ${_lib_list} and library debug list = ${_libd_list}") + endif() + + # For some silly reason the MSVC libraries use _ instead of . + # in the version fields + if(_expand_vc AND MSVC) + set(_no_dots_lib_list) + set(_no_dots_libd_list) + foreach(_l ${_lib_list}) + string(REPLACE "." "_" _no_dots_library ${_l}) + list(APPEND _no_dots_lib_list ${_no_dots_library}) + endforeach() + # And for debug + set(_no_dots_libsd_list) + foreach(_l ${_libd_list}) + string(REPLACE "." "_" _no_dots_libraryd ${_l}) + list(APPEND _no_dots_libd_list ${_no_dots_libraryd}) + endforeach() + + # Copy list back to original names + set(_lib_list ${_no_dots_lib_list}) + set(_libd_list ${_no_dots_libd_list}) + endif() + + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "While searching for ${_var}, our proposed library list is ${_lib_list}") + endif() + + find_library(${_var} + NAMES ${_lib_list} + PATHS + /opt/gnome/lib + /opt/gnome/lib64 + /usr/openwin/lib + /usr/openwin/lib64 + $ENV{GTKMM_BASEPATH}/lib + [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib + [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib + ) + + if(_expand_vc AND MSVC) + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}") + endif() + + find_library(${_var}_DEBUG + NAMES ${_libd_list} + PATHS + $ENV{GTKMM_BASEPATH}/lib + [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib + [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib + ) + + if(${_var} AND ${_var}_DEBUG) + if(NOT GTK2_SKIP_MARK_AS_ADVANCED) + mark_as_advanced(${_var}_DEBUG) + endif() + set(GTK2_LIBRARIES ${GTK2_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG}) + set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE) + endif() + else() + if(NOT GTK2_SKIP_MARK_AS_ADVANCED) + mark_as_advanced(${_var}) + endif() + set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}}) + set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE) + # Set debug to release + set(${_var}_DEBUG ${${_var}}) + set(${_var}_DEBUG ${${_var}} PARENT_SCOPE) + endif() +endfunction(_GTK2_FIND_LIBRARY) + +#============================================================= + +# +# main() +# + +set(GTK2_FOUND) +set(GTK2_INCLUDE_DIRS) +set(GTK2_LIBRARIES) + +if(NOT GTK2_FIND_COMPONENTS) + # Assume they only want GTK + set(GTK2_FIND_COMPONENTS gtk) +endif() + +# +# If specified, enforce version number +# +if(GTK2_FIND_VERSION) + cmake_minimum_required(VERSION 2.6.2) + set(GTK2_FAILED_VERSION_CHECK true) + if(GTK2_DEBUG) + message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " + "Searching for version ${GTK2_FIND_VERSION}") + endif() + _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h) + if(GTK2_GTK_INCLUDE_DIR) + _GTK2_GET_VERSION(GTK2_MAJOR_VERSION + GTK2_MINOR_VERSION + GTK2_PATCH_VERSION + ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h) + set(GTK2_VERSION + ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION}) + if(GTK2_FIND_VERSION_EXACT) + if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION) + set(GTK2_FAILED_VERSION_CHECK false) + endif() + else() + if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION OR + GTK2_VERSION VERSION_GREATER GTK2_FIND_VERSION) + set(GTK2_FAILED_VERSION_CHECK false) + endif() + endif() + else() + # If we can't find the GTK include dir, we can't do version checking + if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY) + message(FATAL_ERROR "Could not find GTK2 include directory") + endif() + return() + endif() + + if(GTK2_FAILED_VERSION_CHECK) + if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY) + if(GTK2_FIND_VERSION_EXACT) + message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, version ${GTK2_FIND_VERSION} is needed exactly.") + else() + message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, at least version ${GTK2_FIND_VERSION} is required") + endif() + endif() + + # If the version check fails, exit out of the module here + return() + endif() +endif() + +# +# Find all components +# + +foreach(_GTK2_component ${GTK2_FIND_COMPONENTS}) + if(_GTK2_component STREQUAL "gtk") + + _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h) + _GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h) + _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true) + _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h) + _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-x11 false true) + _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-win32 false true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h) + _GTK2_FIND_LIBRARY (GTK2_CAIRO_LIBRARY cairo false false) + + _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h) + _GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h) + _GTK2_FIND_LIBRARY (GTK2_ATK_LIBRARY atk false true) + + #elseif(_GTK2_component STREQUAL "gdk_pixbuf") + #_GTK2_FIND_INCLUDE_DIR(GTK2_GDKPIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h) + #_GTK2_FIND_LIBRARY (GTK2_GDKPIXBUF_LIBRARY gdk_pixbuf false true) + + elseif(_GTK2_component STREQUAL "gtkmm") + + _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h) + _GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h) + _GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h) + _GTK2_FIND_LIBRARY (GTK2_GTKMM_LIBRARY gtkmm true true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h) + _GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h) + _GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h) + _GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h) + _GTK2_FIND_LIBRARY (GTK2_GIOMM_LIBRARY giomm true true) + + _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h) + _GTK2_FIND_LIBRARY (GTK2_ATKMM_LIBRARY atkmm true true) + + elseif(_GTK2_component STREQUAL "glade") + + _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h) + _GTK2_FIND_LIBRARY (GTK2_GLADE_LIBRARY glade false true) + + elseif(_GTK2_component STREQUAL "glademm") + + _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM_INCLUDE_DIR libglademm.h) + _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h) + _GTK2_FIND_LIBRARY (GTK2_GLADEMM_LIBRARY glademm true true) + + else() + message(FATAL_ERROR "Unknown GTK2 component ${_component}") + endif() +endforeach() + +# +# Solve for the GTK2 version if we haven't already +# +if(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR) + _GTK2_GET_VERSION(GTK2_MAJOR_VERSION + GTK2_MINOR_VERSION + GTK2_PATCH_VERSION + ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h) + set(GTK2_VERSION ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION}) +endif() + +# +# Try to enforce components +# + +set(_GTK2_did_we_find_everything true) # This gets set to GTK2_FOUND + +include(FindPackageHandleStandardArgs) + +foreach(_GTK2_component ${GTK2_FIND_COMPONENTS}) + string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER) + + if(_GTK2_component STREQUAL "gtk") + FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found." + GTK2_GTK_LIBRARY + GTK2_GTK_INCLUDE_DIR + + GTK2_GLIB_INCLUDE_DIR + GTK2_GLIBCONFIG_INCLUDE_DIR + GTK2_GLIB_LIBRARY + + GTK2_GDK_INCLUDE_DIR + GTK2_GDKCONFIG_INCLUDE_DIR + GTK2_GDK_LIBRARY + ) + elseif(_GTK2_component STREQUAL "gtkmm") + FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found." + GTK2_GTKMM_LIBRARY + GTK2_GTKMM_INCLUDE_DIR + GTK2_GTKMMCONFIG_INCLUDE_DIR + + GTK2_GLIBMM_INCLUDE_DIR + GTK2_GLIBMMCONFIG_INCLUDE_DIR + GTK2_GLIBMM_LIBRARY + + GTK2_GDKMM_INCLUDE_DIR + GTK2_GDKMMCONFIG_INCLUDE_DIR + GTK2_GDKMM_LIBRARY + ) + elseif(_GTK2_component STREQUAL "glade") + FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found." + GTK2_GLADE_LIBRARY + GTK2_GLADE_INCLUDE_DIR + ) + elseif(_GTK2_component STREQUAL "glademm") + FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glademm library was not found." + GTK2_GLADEMM_LIBRARY + GTK2_GLADEMM_INCLUDE_DIR + GTK2_GLADEMMCONFIG_INCLUDE_DIR + ) + endif() + + if(NOT GTK2_${_COMPONENT_UPPER}_FOUND) + set(_GTK2_did_we_find_everything false) + endif() +endforeach() + +if(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED) + set(GTK2_FOUND true) +else() + # Unset our variables. + set(GTK2_FOUND false) + set(GTK2_VERSION) + set(GTK2_VERSION_MAJOR) + set(GTK2_VERSION_MINOR) + set(GTK2_VERSION_PATCH) + set(GTK2_INCLUDE_DIRS) + set(GTK2_LIBRARIES) +endif() + +if(GTK2_INCLUDE_DIRS) + list(REMOVE_DUPLICATES GTK2_INCLUDE_DIRS) +endif() + diff --git a/cmake/FindGettext.cmake b/cmake/FindGettext.cmake new file mode 100644 index 0000000..4f8e6fb --- /dev/null +++ b/cmake/FindGettext.cmake @@ -0,0 +1,105 @@ +# - Find GNU gettext tools +# This module looks for the GNU gettext tools. This module defines the +# following values: +# GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool. +# GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool. +# GETTEXT_FOUND: True if gettext has been found. +# +# Additionally it provides the following macros: +# GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] file1 ... fileN ) +# This will create a target "${PROJECT_NAME}_translations" which will +# convert the given input po files into the binary output mo file. +# If the ALL option is used, the translations will also be created +# when building the default target. + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# Copyright 2010 Přemysl Janouch +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Kitware nor the names of contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDERS 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. +#============================================================================= + +find_program (GETTEXT_MSGMERGE_EXECUTABLE msgmerge) + +find_program (GETTEXT_MSGFMT_EXECUTABLE msgfmt) + +macro (GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg) + # Make it a real variable, so we can modify it here. + set (_firstPoFile "${_firstPoFileArg}") + + set (_gmoFiles) + get_filename_component (_potBasename ${_potFile} NAME_WE) + get_filename_component (_absPotFile ${_potFile} ABSOLUTE) + + set (_addToAll) + if (${_firstPoFile} STREQUAL "ALL") + set (_addToAll "ALL") + set (_firstPoFile) + endif (${_firstPoFile} STREQUAL "ALL") + + foreach (_currentPoFile ${_firstPoFile} ${ARGN}) + get_filename_component (_absFile ${_currentPoFile} ABSOLUTE) + get_filename_component (_abs_PATH ${_absFile} PATH) + get_filename_component (_lang ${_absFile} NAME_WE) + set (_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo) + + # msgmerge versions older than 0.11 don't actually support --update + # and --backup, let's try to workaround that (tested on 0.10.40). + execute_process (COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} -V + OUTPUT_VARIABLE _msgmergeVersion) + string (REGEX MATCH "0[.][0-9]+" _msgmergeVersion ${_msgmergeVersion}) + if ("${_msgmergeVersion}" MATCHES "[.]10|[.][0-9]") + set (_msgmergeParams --quiet -s + ${_absFile} -o ${_absFile} ${_absPotFile}) + else ("${_msgmergeVersion}" MATCHES "[.]10|[.][0-9]") + set (_msgmergeParams --quiet --update --backup=none -s + ${_absFile} ${_absPotFile}) + endif ("${_msgmergeVersion}" MATCHES "[.]10|[.][0-9]") + + add_custom_command ( + OUTPUT ${_gmoFile} + COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} ${_msgmergeParams} + COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile} + DEPENDS ${_absPotFile} ${_absFile} + ) + + install (FILES ${_gmoFile} DESTINATION + share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo) + set (_gmoFiles ${_gmoFiles} ${_gmoFile}) + endforeach (_currentPoFile) + + add_custom_target (${PROJECT_NAME}_translations ${_addToAll} + DEPENDS ${_gmoFiles}) +endmacro (GETTEXT_CREATE_TRANSLATIONS) + +if (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE) + set (GETTEXT_FOUND TRUE) +else (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE) + set (GETTEXT_FOUND FALSE) + if (GetText_REQUIRED) + message (FATAL_ERROR "GetText not found") + endif (GetText_REQUIRED) +endif (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE) + + diff --git a/cmake/FindGtkDoc.cmake b/cmake/FindGtkDoc.cmake new file mode 100644 index 0000000..97d849b --- /dev/null +++ b/cmake/FindGtkDoc.cmake @@ -0,0 +1,366 @@ +# - Finding gtk-doc and building documentation +# This module provides the following function: +# +# GTK_DOC_RUN ( +# [ALL] +# [MODULE ] +# [WORKING_DIR ] +# SOURCE_DIRS ... +# [IGNORE_FILES ...] +# [{SGML | XML} [ []] +# [HTML ]] +# ) +# +# The function creates a target named _gtkdocize +# which will build the documentation as specified by parameters. +# +# ALL - always build the target +# MODULE - the name of the module +# CMAKE_PROJECT_NAME by default +# WORKING_DIR - path to the working directory +# CMAKE_CURRENT_BINARY_DIR by default +# SOURCE_DIRS - documentation sources +# IGNORE_FILES - ignore these files in the process +# SGML - make SGML output in the spec. directory +# XML - make XML output in the spec. directory +# HTML - make HTML output in the spec. directory +# (requires either SGML or XML) +# +# Also creates these virtual symbolic outputs if appropriate: +# _gtkdocize_scan +# _gtkdocize_scan_rebuild_types +# _gtkdocize_scan_rebuild_sections +# _gtkdocize_mkdb +# _gtkdocize_mkhtml +# +# + +#============================================================================= +# Copyright Přemysl Janouch 2010 +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 COPYRIGHT HOLDERS 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. +#============================================================================= + +# Useful resources +# ================ +# +# /usr/share/cmake-2.8/Modules/readme.txt +# +# Autotools stack +# - /usr/share/aclocal/gtk-doc.m4 +# - /usr/share/gtk-doc/data/gtk-doc{.notmpl}.make +# +# gtk+-2.0, glib-2.0, totem, ... packages -- docs subdir etc. +# +# Python wrapper -- useful resource +# - http://bjourne.webfactional.com/browser/gtkimageview/gtkdoc.py +# +# Overview of the process +# - http://library.gnome.org +# /devel/gtk-doc-manual/stable/howdoesgtkdocwork.html.en +# +# Documenting +# - http://live.gnome.org/DocumentationProject/GtkDoc +# - http://library.gnome.org +# /devel/gtk-doc-manual/stable/documenting_syntax.html.en +# - http://library.gnome.org +# /devel/gtk-doc-manual/stable/metafiles.html.en +# +# TODO +# ==== +# - Since it doesn't work without the full Unix environment, +# it might be actually proper to use pkg-config +# +# - _gtkdocize_scangobj +# - _gtkdocize_mktmpl +# - _gtkdocize_fixxref +# - Content files (included by the main SGML file) +# + + +find_program (GTK_DOC_SCAN_EXECUTABLE "gtkdoc-scan") +find_program (GTK_DOC_SCANGOBJ_EXECUTABLE "gtkdoc-scangobj") +find_program (GTK_DOC_MKTMPL_EXECUTABLE "gtkdoc-mktmpl") +find_program (GTK_DOC_MKDB_EXECUTABLE "gtkdoc-mkdb") +find_program (GTK_DOC_MKHTML_EXECUTABLE "gtkdoc-mkhtml") +find_program (GTK_DOC_FIXXREF_EXECUTABLE "gtkdoc-fixxref") + +set (GTK_DOC_FOUND TRUE) +if (NOT GTK_DOC_SCAN_EXECUTABLE) + set (GTK_DOC_FOUND FALSE) +endif (NOT GTK_DOC_SCAN_EXECUTABLE) + +if (GtkDoc_FIND_REQUIRED AND NOT GTK_DOC_FOUND) + message (FATAL_ERROR "gtk-doc NOT found") +endif (GtkDoc_FIND_REQUIRED AND NOT GTK_DOC_FOUND) + + +include (ProcessArguments) + +function (GTK_DOC_RUN) + # Parse arguments given to this function + set (__names ALL MODULE WORKING_DIR) + set (__need NO NO NO) + set (__want 0 1 1) + set (__more NO NO NO) + set (__skip 0 0 0) + + list (APPEND __names SOURCE_DIRS IGNORE_FILES SGML XML HTML) + list (APPEND __need YES NO NO NO NO) + list (APPEND __want 1 1 0 0 1) + list (APPEND __more YES YES YES YES YES) + list (APPEND __skip 0 0 1 0 0) + + set (__argv ${ARGV}) + PROCESS_ARGUMENTS (__argv __names __need __want __more __skip "_opt_") + + # Further process the arguments + if (_opt_all) + set (_all ALL) + else (_opt_all) + set (_all) + endif (_opt_all) + + if (_opt_module) + set (_module_name ${_opt_module_param}) + else (_opt_module) + set (_module_name ${CMAKE_PROJECT_NAME}) + endif (_opt_module) + + if (_opt_working_dir) + set (_working_dir ${_opt_working_dir_param}) + else (_opt_working_dir) + set (_working_dir ${CMAKE_CURRENT_BINARY_DIR}) + endif (_opt_working_dir) + + set (_source_dirs) + foreach (_dir ${_opt_source_dirs_param}) + list (APPEND _source_dirs "--source-dir" "${_dir}") + endforeach (_dir ${_opt_source_dirs_param}) + + set (_ignores) + if (_opt_ignore_files) + foreach (_file ${_opt_ignore_files_param}) + set (_ignores "${_ignores} ${_file}") + endforeach (_file ${_opt_ignore_files_param}) + string (STRIP "${_ignores}" _ignores) + endif (_opt_ignore_files) + + if (_opt_sgml) + set (_mkdb_format "sgml") + set (_mkdb_options "${_opt_sgml_param}") + elseif (_opt_xml) + set (_mkdb_format "xml") + set (_mkdb_options "${_opt_xml_param}") + else (_opt_sgml) + set (_mkdb_format OFF) + endif (_opt_sgml) + + if (_mkdb_format) + set (_mkdb_driver ${_working_dir}/${_module_name}-docs.${_mkdb_format}) + list (LENGTH _mkdb_options _length) + if (${_length} GREATER 0) + list (GET _mkdb_options 0 _mkdb_output_dir) + list (REMOVE_AT _mkdb_options 0) + else (${_length} GREATER 0) + set (_mkdb_output_dir ${_working_dir}/${_mkdb_format}) + endif (${_length} GREATER 0) + endif (_mkdb_format) + + # The basic target name + set (_target_name ${_module_name}_gtkdocize) + + # Scan the source files + set (_scan_target_base + # These files are created if they don't exist + # ${_working_dir}/${_module_name}.types + # ${_working_dir}/${_module_name}-sections.txt + # ${_working_dir}/${_module_name}-overrides.txt + ${_working_dir}/${_module_name}-decl.txt + ${_working_dir}/${_module_name}-decl-list.txt + COMMAND ${GTK_DOC_SCAN_EXECUTABLE} + --module=${_module_name} + ${_source_dirs} "--ignore-headers=${_ignores}" + --output-dir=${_working_dir}) + add_custom_command ( + OUTPUT ${_target_name}_scan + ${_scan_target_base} + COMMENT "Calling gtkdoc-scan" VERBATIM) + + # Special target to force rebuild of ${_module_name}.types + add_custom_command ( + OUTPUT ${_target_name}_scan_rebuild_types + ${_scan_target_base} --rebuild-types + COMMENT "Calling gtkdoc-scan to rebuild types" VERBATIM) + add_custom_target (${_target_name}_rebuild_types + DEPENDS ${_target_name}_scan_rebuild_types) + + # Special target to force rebuild of ${_module_name}-sections.txt + add_custom_command ( + OUTPUT ${_target_name}_scan_rebuild_sections + ${_scan_target_base} --rebuild-sections + COMMENT "Calling gtkdoc-scan to rebuild sections" VERBATIM) + add_custom_target (${_target_name}_rebuild_sections + DEPENDS ${_target_name}_scan_rebuild_sections) + + set_source_files_properties ( + ${_target_name}_scan + ${_target_name}_scan_rebuild_types + ${_target_name}_scan_rebuild_sections + PROPERTIES SYMBOLIC TRUE) + + # gtkdoc-scangobj + # + # gtkdoc-scangobj builds and runs an inspection program. You must + # tell it how to do that by running it + # + # CC=.. CFLAGS=.. LD=.. LDFLAGS=.. RUN=.. gtkdoc-scangobj + # + # where the variables contain the right compiler, linker and their flags + # to build a program using your library. See the source of + # gtkdoc-scangobj around line containing `Compiling scanner' if you want + # to know how exactly are the variables used. + + # gtkdoc-mktmpl + # + # See: cd /usr/share/gtk-doc/data/ + # && diff -u gtk-doc.make gtk-doc.notmpl.make + # + # add_custom_command ( + # OUTPUT ${_working_dir}/${_module_name}-unused.txt + # ${_working_dir}/tmpl.stamp + ## This file is updated with unused templates + ## ${_tmpl_dir}/${_module_name}-unused.sgml + ## The directory is created if it didn't exist + ## ${_tmpl_dir} + # COMMAND ${GTK_DOC_MKTMPL_EXECUTABLE} + # --module=${_module_name} + # --output-dir=${_tmpl_dir} + # WORKING_DIRECTORY ${_working_dir} + # COMMENT "Calling gtkdoc-mktmpl" VERBATIM) + + # Create XML or SGML files + if (_mkdb_format) + add_custom_command ( + OUTPUT ${_target_name}_mkdb + ${_mkdb_output_dir} + ${_working_dir}/sgml.stamp + ${_working_dir}/${_module_name}-undeclared.txt + ${_working_dir}/${_module_name}-undocumented.txt + ${_working_dir}/${_module_name}-unused.txt + # --outputallsymbols --outputsymbolswithoutsince + # ${_working_dir}/${_module_name}-symbols.txt + # ${_working_dir}/${_module_name}-nosince.txt + COMMAND ${GTK_DOC_MKDB_EXECUTABLE} + --module=${_module_name} + ${_source_dirs} "--ignore-files=${_ignores}" + --output-format=${_mkdb_format} + --output-dir=${_mkdb_output_dir} + ${_mkdb_options} --main-sgml-file=${_mkdb_driver} + DEPENDS ${_target_name}_scan + WORKING_DIRECTORY ${_working_dir} + COMMENT "Calling gtkdoc-mkdb" VERBATIM) + + set_source_files_properties (${_target_name}_mkdb + PROPERTIES SYMBOLIC TRUE) + set (_top_output ${_target_name}_mkdb) + else (_mkdb_format) + set (_top_output ${_target_name}_scan) + endif (_mkdb_format) + + # Create HTML documentation + if (_opt_html) + if (NOT _mkdb_format) + message (FATAL_ERROR "Given HTML but neither XML nor SGML") + endif (NOT _mkdb_format) + + list (GET _opt_html_param 0 _html_output_dir) + list (REMOVE_AT _opt_html_param 0) + + add_custom_command ( + OUTPUT ${_target_name}_mkhtml + ${_html_output_dir}/../html.stamp + # We probably don't want this to be removed either + # ${_html_output_dir} + COMMAND ${CMAKE_COMMAND} -E make_directory ${_html_output_dir} + COMMAND ${CMAKE_COMMAND} -E chdir ${_html_output_dir} + ${GTK_DOC_MKHTML_EXECUTABLE} + ${_module_name} ${_mkdb_driver} ${_opt_html_param} + DEPENDS ${_target_name}_mkdb + COMMENT "Calling gtkdoc-mkhtml" VERBATIM) + + set_source_files_properties (${_target_name}_mkhtml + PROPERTIES SYMBOLIC TRUE) + set (_top_output ${_target_name}_mkhtml) + endif (_opt_html) + + # gtkdoc-fixxref + # ? copy ${_html_output_dir} to CMAKE_BINARY_DIR, + # run gtkdoc-fixxref in there and install the directory + # -> FIXXREF [INSTALL] + # + #? set (_fixxref_dir ${CMAKE_CURRENT_BINARY_DIR}/html-fixxref) + # add_custom_command ( + # OUTPUT ${_target_name}_fixxref + #? ${_fixxref_dir} + #? COMMAND ${CMAKE_COMMAND} -E remove_directory ${_fixxref_dir} + #? COMMAND ${CMAKE_COMMAND} -E copy_directory + #? ${_html_output_dir} ${_fixxref_dir} + # COMMAND ${GTK_DOC_FIXXREF_EXECUTABLE} + # --module=${_module_name} + # --module-dir=${_html_output_dir} + #? --module-dir=${_fixxref_dir} + # DEPENDS ${_html_output_dir} + # WORKING_DIRECTORY ${_working_dir} + # COMMENT "Calling gtkdoc-fixxref" VERBATIM) + #? install (DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html-fixxref/ + #? DESTINATION share/gtk-doc/html/${_module_name}) + #& COMPONENT docs) -- see CPack component install + + # gtkdoc-rebase -- how to do this? + # + # Probably omit this because source tarball cannot be hooked + # to do some action before. + # -> Custom dist target? + # add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) + # -> ${_html_output_dir} could contain online links by default, + # then it could be copied to binary dir and rebased to relative + # * Looks like a very good idea, can work even without gtk-doc + # -> Or it can be first xreffed in the binary dir and then + # converted to online links in ${_html_output_dir} + # * Which one of those should be installed? + # The one in the binary directory or should the + # ${_html_output_dir} be rebased? + # * A rebasing custom command may create the binary directory + # if it doesn't exist + # + # When creating the source tarball for distribution, + # gtkdoc-rebase turns all external links into web-links. + # When installing distributed (pregenerated) docs the same + # application will try to turn links back to local links + # (where those docs are installed). + + add_custom_target (${_target_name} ${_all} + DEPENDS ${_top_output}) +endfunction (GTK_DOC_RUN) + + diff --git a/cmake/ProcessArguments.cmake b/cmake/ProcessArguments.cmake new file mode 100644 index 0000000..1fafe26 --- /dev/null +++ b/cmake/ProcessArguments.cmake @@ -0,0 +1,140 @@ +# - Parse the arguments in ARGS. +# This module provides the following macro: +# PROCESS_ARGUMENTS (ARGS NAMES NEED WANT MORE SKIP [PREFIX]) +# +# ARGS - the list of arguments +# NAMES - a list of accepted option names, in order +# NEED - a list of boolean values specifying whether the corresponding +# options are required +# WANT - a list of integer values specifying how many arguments +# the corresponding options require +# MORE - a list of boolean values specifying whether the corresponding +# options accept more arguments than they want +# SKIP - a list of integer values for skipping control +# PREFIX - output variables prefix, "_" by default +# +# If an option is present, ${PREFIX}${lower cased name of the option} +# will be set to TRUE. If it's got any parameters, they will be stored +# in ${PREFIX}${lower case name of the option}_param. +# +# All the lists are indirect and the arguments to this macro +# specify names of the lists within the current scope. +# + +#============================================================================= +# Copyright Přemysl Janouch 2010 +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 COPYRIGHT HOLDERS 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. +#============================================================================= + +macro (PROCESS_ARGUMENTS ARGS NAMES NEED WANT MORE SKIP) + # Get the prefix + if ("${ARGN}" STREQUAL "") + set (__pa_prefix "_") + else ("${ARGN}" STREQUAL "") + set (__pa_value ${ARGN}) + list (GET __pa_value 0 __pa_prefix) + endif ("${ARGN}" STREQUAL "") + + # By default, no parameters have been read + foreach (__pa_value ${${NAMES}}) + string (TOLOWER ${__pa_value} __pa_value) + set (${__pa_prefix}${__pa_value} FALSE) + set (${__pa_prefix}${__pa_value}_param) + endforeach (__pa_value) + + # Find the first required option or -1 + list (FIND ${NEED} "YES" __pa_need) + + # Currently processed option + set (__pa_cur "") + # Index of the option + set (__pa_cur_index -1) + # In lowercase, prefixed with an underscore + set (__pa_cur_base "") + # How many arguments we want for this option + set (__pa_want 0) + # Do we accept additional arguments? + set (__pa_more FALSE) + # The next expected index minus one + set (__pa_cur_nextmm -1) + + foreach (__pa_arg ${${ARGS}}) + list (FIND ${NAMES} ${__pa_arg} __pa_found) + + # Found an option name + if (${__pa_found} GREATER ${__pa_cur_nextmm}) + # Missing arguments + if (${__pa_want} GREATER 0) + message (FATAL_ERROR "Argument(s) required for ${__pa_cur}") + # Missing option + elseif (${__pa_need} GREATER -1 + AND ${__pa_found} GREATER ${__pa_need}) + list (GET ${NAMES} ${__pa_need} __pa_value) + message (FATAL_ERROR "Option ${__pa_value} needed") + endif (${__pa_want} GREATER 0) + + set (__pa_cur ${__pa_arg}) + set (__pa_cur_index ${__pa_found}) + string (TOLOWER ${__pa_arg} __pa_value) + set (__pa_cur_base "${__pa_prefix}${__pa_value}") + + list (GET ${WANT} ${__pa_found} __pa_want) + list (GET ${MORE} ${__pa_found} __pa_more) + + # Skipping control + list (GET ${SKIP} ${__pa_found} __pa_value) + math (EXPR __pa_cur_nextmm "${__pa_found} + ${__pa_value}") + + # Option found + set (${__pa_cur_base} TRUE) + + # Since we read it, it's not needed anymore + if (${__pa_found} EQUAL ${__pa_need}) + list (INSERT ${NEED} ${__pa_need} "NO") + math (EXPR __pa_value "${__pa_need} + 1") + list (REMOVE_AT ${NEED} ${__pa_value}) + + list (FIND ${NEED} "YES" __pa_need) + endif (${__pa_found} EQUAL ${__pa_need}) + # Storing the required parameters for the current option + elseif (${__pa_want} GREATER 0) + list (APPEND ${__pa_cur_base}_param ${__pa_arg}) + math (EXPR __pa_want "${__pa_want} - 1") + # Storing optional parameters for the current option + elseif (__pa_more) + list (APPEND ${__pa_cur_base}_param ${__pa_arg}) + else (${__pa_found} GREATER ${__pa_cur_nextmm}) + message (FATAL_ERROR "Unexpected ${__pa_arg}") + endif (${__pa_found} GREATER ${__pa_cur_nextmm}) + endforeach (__pa_arg ${${ARGS}}) + + # Missing arguments at the end of list + if (${__pa_want} GREATER 0) + message (FATAL_ERROR "Argument(s) required for ${__pa_cur}") + # Missing options at the end of list + elseif (${__pa_need} GREATER -1) + list (GET ${NAMES} ${__pa_need} __pa_value) + message (FATAL_ERROR "Option ${__pa_value} needed") + endif (${__pa_want} GREATER 0) +endmacro (PROCESS_ARGUMENTS) + -- cgit v1.2.3