duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

ECMFindModuleHelpers.cmake (13540B)


      1 #.rst:
      2 # ECMFindModuleHelpers
      3 # --------------------
      4 #
      5 # Helper macros for find modules: ecm_find_package_version_check(),
      6 # ecm_find_package_parse_components() and
      7 # ecm_find_package_handle_library_components().
      8 #
      9 # ::
     10 #
     11 #   ecm_find_package_version_check(<name>)
     12 #
     13 # Prints warnings if the CMake version or the project's required CMake version
     14 # is older than that required by extra-cmake-modules.
     15 #
     16 # ::
     17 #
     18 #   ecm_find_package_parse_components(<name>
     19 #       RESULT_VAR <variable>
     20 #       KNOWN_COMPONENTS <component1> [<component2> [...]]
     21 #       [SKIP_DEPENDENCY_HANDLING])
     22 #
     23 # This macro will populate <variable> with a list of components found in
     24 # <name>_FIND_COMPONENTS, after checking that all those components are in the
     25 # list of KNOWN_COMPONENTS; if there are any unknown components, it will print
     26 # an error or warning (depending on the value of <name>_FIND_REQUIRED) and call
     27 # return().
     28 #
     29 # The order of components in <variable> is guaranteed to match the order they
     30 # are listed in the KNOWN_COMPONENTS argument.
     31 #
     32 # If SKIP_DEPENDENCY_HANDLING is not set, for each component the variable
     33 # <name>_<component>_component_deps will be checked for dependent components.
     34 # If <component> is listed in <name>_FIND_COMPONENTS, then all its (transitive)
     35 # dependencies will also be added to <variable>.
     36 #
     37 # ::
     38 #
     39 #   ecm_find_package_handle_library_components(<name>
     40 #       COMPONENTS <component> [<component> [...]]
     41 #       [SKIP_DEPENDENCY_HANDLING])
     42 #       [SKIP_PKG_CONFIG])
     43 #
     44 # Creates an imported library target for each component.  The operation of this
     45 # macro depends on the presence of a number of CMake variables.
     46 #
     47 # The <name>_<component>_lib variable should contain the name of this library,
     48 # and <name>_<component>_header variable should contain the name of a header
     49 # file associated with it (whatever relative path is normally passed to
     50 # '#include'). <name>_<component>_header_subdir variable can be used to specify
     51 # which subdirectory of the include path the headers will be found in.
     52 # ecm_find_package_components() will then search for the library
     53 # and include directory (creating appropriate cache variables) and create an
     54 # imported library target named <name>::<component>.
     55 #
     56 # Additional variables can be used to provide additional information:
     57 #
     58 # If SKIP_PKG_CONFIG, the <name>_<component>_pkg_config variable is set, and
     59 # pkg-config is found, the pkg-config module given by
     60 # <name>_<component>_pkg_config will be searched for and used to help locate the
     61 # library and header file.  It will also be used to set
     62 # <name>_<component>_VERSION.
     63 #
     64 # Note that if version information is found via pkg-config,
     65 # <name>_<component>_FIND_VERSION can be set to require a particular version
     66 # for each component.
     67 #
     68 # If SKIP_DEPENDENCY_HANDLING is not set, the INTERFACE_LINK_LIBRARIES property
     69 # of the imported target for <component> will be set to contain the imported
     70 # targets for the components listed in <name>_<component>_component_deps.
     71 # <component>_FOUND will also be set to false if any of the compoments in
     72 # <name>_<component>_component_deps are not found.  This requires the components
     73 # in <name>_<component>_component_deps to be listed before <component> in the
     74 # COMPONENTS argument.
     75 #
     76 # The following variables will be set:
     77 #
     78 # ``<name>_TARGETS``
     79 #   the imported targets
     80 # ``<name>_LIBRARIES``
     81 #   the found libraries
     82 # ``<name>_INCLUDE_DIRS``
     83 #   the combined required include directories for the components
     84 # ``<name>_DEFINITIONS``
     85 #   the "other" CFLAGS provided by pkg-config, if any
     86 # ``<name>_VERSION``
     87 #   the value of ``<name>_<component>_VERSION`` for the first component that
     88 #   has this variable set (note that components are searched for in the order
     89 #   they are passed to the macro), although if it is already set, it will not
     90 #   be altered
     91 #
     92 # Note that these variables are never cleared, so if
     93 # ecm_find_package_handle_library_components() is called multiple times with
     94 # different components (typically because of multiple find_package() calls) then
     95 # ``<name>_TARGETS``, for example, will contain all the targets found in any
     96 # call (although no duplicates).
     97 #
     98 # Since pre-1.0.0.
     99 
    100 #=============================================================================
    101 # Copyright 2014 Alex Merry <alex.merry@kde.org>
    102 #
    103 # Redistribution and use in source and binary forms, with or without
    104 # modification, are permitted provided that the following conditions
    105 # are met:
    106 #
    107 # 1. Redistributions of source code must retain the copyright
    108 #    notice, this list of conditions and the following disclaimer.
    109 # 2. Redistributions in binary form must reproduce the copyright
    110 #    notice, this list of conditions and the following disclaimer in the
    111 #    documentation and/or other materials provided with the distribution.
    112 # 3. The name of the author may not be used to endorse or promote products
    113 #    derived from this software without specific prior written permission.
    114 #
    115 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    116 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    117 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    118 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    119 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    120 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    121 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    122 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    123 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    124 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    125 
    126 include(CMakeParseArguments)
    127 
    128 macro(ecm_find_package_version_check module_name)
    129     if(CMAKE_VERSION VERSION_LESS 2.8.12)
    130         message(FATAL_ERROR "CMake 2.8.12 is required by Find${module_name}.cmake")
    131     endif()
    132     if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
    133         message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use Find${module_name}.cmake")
    134     endif()
    135 endmacro()
    136 
    137 macro(ecm_find_package_parse_components module_name)
    138     set(ecm_fppc_options SKIP_DEPENDENCY_HANDLING)
    139     set(ecm_fppc_oneValueArgs RESULT_VAR)
    140     set(ecm_fppc_multiValueArgs KNOWN_COMPONENTS DEFAULT_COMPONENTS)
    141     cmake_parse_arguments(ECM_FPPC "${ecm_fppc_options}" "${ecm_fppc_oneValueArgs}" "${ecm_fppc_multiValueArgs}" ${ARGN})
    142 
    143     if(ECM_FPPC_UNPARSED_ARGUMENTS)
    144         message(FATAL_ERROR "Unexpected arguments to ecm_find_package_parse_components: ${ECM_FPPC_UNPARSED_ARGUMENTS}")
    145     endif()
    146     if(NOT ECM_FPPC_RESULT_VAR)
    147         message(FATAL_ERROR "Missing RESULT_VAR argument to ecm_find_package_parse_components")
    148     endif()
    149     if(NOT ECM_FPPC_KNOWN_COMPONENTS)
    150         message(FATAL_ERROR "Missing KNOWN_COMPONENTS argument to ecm_find_package_parse_components")
    151     endif()
    152     if(NOT ECM_FPPC_DEFAULT_COMPONENTS)
    153         set(ECM_FPPC_DEFAULT_COMPONENTS ${ECM_FPPC_KNOWN_COMPONENTS})
    154     endif()
    155 
    156     if(${module_name}_FIND_COMPONENTS)
    157         set(ecm_fppc_requestedComps ${${module_name}_FIND_COMPONENTS})
    158 
    159         if(NOT ECM_FPPC_SKIP_DEPENDENCY_HANDLING)
    160             # Make sure deps are included
    161             foreach(ecm_fppc_comp ${ecm_fppc_requestedComps})
    162                 foreach(ecm_fppc_dep_comp ${${module_name}_${ecm_fppc_comp}_component_deps})
    163                     list(FIND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}" ecm_fppc_index)
    164                     if("${ecm_fppc_index}" STREQUAL "-1")
    165                         if(NOT ${module_name}_FIND_QUIETLY)
    166                             message(STATUS "${module_name}: ${ecm_fppc_comp} requires ${${module_name}_${ecm_fppc_comp}_component_deps}")
    167                         endif()
    168                         list(APPEND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}")
    169                     endif()
    170                 endforeach()
    171             endforeach()
    172         else()
    173             message(STATUS "Skipping dependency handling for ${module_name}")
    174         endif()
    175         list(REMOVE_DUPLICATES ecm_fppc_requestedComps)
    176 
    177         # This makes sure components are listed in the same order as
    178         # KNOWN_COMPONENTS (potentially important for inter-dependencies)
    179         set(${ECM_FPPC_RESULT_VAR})
    180         foreach(ecm_fppc_comp ${ECM_FPPC_KNOWN_COMPONENTS})
    181             list(FIND ecm_fppc_requestedComps "${ecm_fppc_comp}" ecm_fppc_index)
    182             if(NOT "${ecm_fppc_index}" STREQUAL "-1")
    183                 list(APPEND ${ECM_FPPC_RESULT_VAR} "${ecm_fppc_comp}")
    184                 list(REMOVE_AT ecm_fppc_requestedComps ${ecm_fppc_index})
    185             endif()
    186         endforeach()
    187         # if there are any left, they are unknown components
    188         if(ecm_fppc_requestedComps)
    189             set(ecm_fppc_msgType STATUS)
    190             if(${module_name}_FIND_REQUIRED)
    191                 set(ecm_fppc_msgType FATAL_ERROR)
    192             endif()
    193             if(NOT ${module_name}_FIND_QUIETLY)
    194                 message(${ecm_fppc_msgType} "${module_name}: requested unknown components ${ecm_fppc_requestedComps}")
    195             endif()
    196             return()
    197         endif()
    198     else()
    199         set(${ECM_FPPC_RESULT_VAR} ${ECM_FPPC_DEFAULT_COMPONENTS})
    200     endif()
    201 endmacro()
    202 
    203 macro(ecm_find_package_handle_library_components module_name)
    204     set(ecm_fpwc_options SKIP_PKG_CONFIG SKIP_DEPENDENCY_HANDLING)
    205     set(ecm_fpwc_oneValueArgs)
    206     set(ecm_fpwc_multiValueArgs COMPONENTS)
    207     cmake_parse_arguments(ECM_FPWC "${ecm_fpwc_options}" "${ecm_fpwc_oneValueArgs}" "${ecm_fpwc_multiValueArgs}" ${ARGN})
    208 
    209     if(ECM_FPWC_UNPARSED_ARGUMENTS)
    210         message(FATAL_ERROR "Unexpected arguments to ecm_find_package_handle_components: ${ECM_FPWC_UNPARSED_ARGUMENTS}")
    211     endif()
    212     if(NOT ECM_FPWC_COMPONENTS)
    213         message(FATAL_ERROR "Missing COMPONENTS argument to ecm_find_package_handle_components")
    214     endif()
    215 
    216     include(FindPackageHandleStandardArgs)
    217     find_package(PkgConfig)
    218     foreach(ecm_fpwc_comp ${ECM_FPWC_COMPONENTS})
    219         set(ecm_fpwc_dep_vars)
    220         set(ecm_fpwc_dep_targets)
    221         if(NOT SKIP_DEPENDENCY_HANDLING)
    222             foreach(ecm_fpwc_dep ${${module_name}_${ecm_fpwc_comp}_component_deps})
    223                 list(APPEND ecm_fpwc_dep_vars "${module_name}_${ecm_fpwc_dep}_FOUND")
    224                 list(APPEND ecm_fpwc_dep_targets "${module_name}::${ecm_fpwc_dep}")
    225             endforeach()
    226         endif()
    227 
    228         if(NOT ECM_FPWC_SKIP_PKG_CONFIG AND ${module_name}_${ecm_fpwc_comp}_pkg_config)
    229             pkg_check_modules(PKG_${module_name}_${ecm_fpwc_comp} QUIET
    230                               ${${module_name}_${ecm_fpwc_comp}_pkg_config})
    231         endif()
    232 
    233         find_path(${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
    234             NAMES ${${module_name}_${ecm_fpwc_comp}_header}
    235             HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_INCLUDE_DIRS}
    236             PATH_SUFFIXES ${${module_name}_${ecm_fpwc_comp}_header_subdir}
    237         )
    238         find_library(${module_name}_${ecm_fpwc_comp}_LIBRARY
    239             NAMES ${${module_name}_${ecm_fpwc_comp}_lib}
    240             HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_LIBRARY_DIRS}
    241         )
    242 
    243         set(${module_name}_${ecm_fpwc_comp}_VERSION "${PKG_${module_name}_${ecm_fpwc_comp}_VERSION}")
    244         if(NOT ${module_name}_VERSION)
    245             set(${module_name}_VERSION ${${module_name}_${ecm_fpwc_comp}_VERSION})
    246         endif()
    247 
    248         find_package_handle_standard_args(${module_name}_${ecm_fpwc_comp}
    249             FOUND_VAR
    250                 ${module_name}_${ecm_fpwc_comp}_FOUND
    251             REQUIRED_VARS
    252                 ${module_name}_${ecm_fpwc_comp}_LIBRARY
    253                 ${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
    254                 ${ecm_fpwc_dep_vars}
    255             VERSION_VAR
    256                 ${module_name}_${ecm_fpwc_comp}_VERSION
    257             )
    258 
    259         mark_as_advanced(
    260             ${module_name}_${ecm_fpwc_comp}_LIBRARY
    261             ${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
    262         )
    263 
    264         if(${module_name}_${ecm_fpwc_comp}_FOUND)
    265             list(APPEND ${module_name}_LIBRARIES
    266                         "${${module_name}_${ecm_fpwc_comp}_LIBRARY}")
    267             list(APPEND ${module_name}_INCLUDE_DIRS
    268                         "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}")
    269             set(${module_name}_DEFINITIONS
    270                     ${${module_name}_DEFINITIONS}
    271                     ${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS})
    272             if(NOT TARGET ${module_name}::${ecm_fpwc_comp})
    273                 add_library(${module_name}::${ecm_fpwc_comp} UNKNOWN IMPORTED)
    274                 set_target_properties(${module_name}::${ecm_fpwc_comp} PROPERTIES
    275                     IMPORTED_LOCATION "${${module_name}_${ecm_fpwc_comp}_LIBRARY}"
    276                     INTERFACE_COMPILE_OPTIONS "${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS}"
    277                     INTERFACE_INCLUDE_DIRECTORIES "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}"
    278                     INTERFACE_LINK_LIBRARIES "${ecm_fpwc_dep_targets}"
    279                 )
    280             endif()
    281             list(APPEND ${module_name}_TARGETS
    282                         "${module_name}::${ecm_fpwc_comp}")
    283         endif()
    284     endforeach()
    285     if(${module_name}_LIBRARIES)
    286         list(REMOVE_DUPLICATES ${module_name}_LIBRARIES)
    287     endif()
    288     if(${module_name}_INCLUDE_DIRS)
    289         list(REMOVE_DUPLICATES ${module_name}_INCLUDE_DIRS)
    290     endif()
    291     if(${module_name}_DEFINITIONS)
    292         list(REMOVE_DUPLICATES ${module_name}_DEFINITIONS)
    293     endif()
    294     if(${module_name}_TARGETS)
    295         list(REMOVE_DUPLICATES ${module_name}_TARGETS)
    296     endif()
    297 endmacro()