File: SelectLibraryConfigurations.cmake

package info (click to toggle)
cmake 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 147,284 kB
  • sloc: ansic: 403,915; cpp: 290,772; sh: 4,102; python: 3,357; yacc: 3,106; lex: 1,189; f90: 532; asm: 471; lisp: 375; cs: 270; java: 266; fortran: 230; perl: 217; objc: 215; xml: 198; makefile: 97; javascript: 83; pascal: 63; tcl: 55; php: 25; ruby: 22
file content (185 lines) | stat: -rw-r--r-- 6,841 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file LICENSE.rst or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
SelectLibraryConfigurations
---------------------------

This module is intended for use in :ref:`Find Modules` and provides a
command to automatically set library variables when package is available
with multiple :ref:`Build Configurations`.

Load it in a CMake find module with:

.. code-block:: cmake

  include(SelectLibraryConfigurations)

Supported build configurations are ``Release`` and ``Debug`` as these are
the most common ones in such packages.

.. note::

  This module has been available since early versions of CMake, when the
  ``<PackageName>_LIBRARIES`` result variable was used for linking found
  packages.  When writing standard find modules, :ref:`Imported Targets` should
  be preferred.  In addition to or as an alternative to this module, imported
  targets provide finer control over linking through the
  :prop_tgt:`IMPORTED_CONFIGURATIONS` property.

Commands
^^^^^^^^

This module provides the following command:

.. command:: select_library_configurations

  Sets and adjusts library variables based on debug and release build
  configurations:

  .. code-block:: cmake

    select_library_configurations(<basename>)

  This command is a helper for setting the ``<basename>_LIBRARY`` and
  ``<basename>_LIBRARIES`` result variables when a library might be provided
  with multiple build configurations.

  The argument is:

  ``<basename>``
    The base name of the library, used as a prefix for variable names.  This is
    the name of the package as used in the ``Find<PackageName>.cmake`` module
    filename, or the component name, when find module provides them.

  Prior to calling this command the following cache variables should be set
  in the find module (for example, by the :command:`find_library` command):

  ``<basename>_LIBRARY_RELEASE``
    A cache variable storing the full path to the ``Release`` build of the
    library.  If not set or found, this command will set its value to
    ``<basename>_LIBRARY_RELEASE-NOTFOUND``.

  ``<basename>_LIBRARY_DEBUG``
    A cache variable storing the full path to the ``Debug`` build of the
    library.  If not set or found, this command will set its value to
    ``<basename>_LIBRARY_DEBUG-NOTFOUND``.

  This command then sets the following local result variables:

  ``<basename>_LIBRARY``
    A result variable that is set to the value of
    ``<basename>_LIBRARY_RELEASE`` variable if found, otherwise it is set to the
    value of ``<basename>_LIBRARY_DEBUG`` variable if found.  If both are found,
    the release library value takes precedence. If both are not found, it is set
    to value ``<basename>_LIBRARY-NOTFOUND``.

    If the :manual:`CMake Generator <cmake-generators(7)>` in use supports
    build configurations, then this variable will be a list of found libraries
    each prepended with the ``optimized`` or ``debug`` keywords specifying which
    library should be linked for the given configuration.  These keywords are
    used by the :command:`target_link_libraries` command.  If a build
    configuration has not been set or the generator in use does not support
    build configurations, then this variable value will not contain these
    keywords.

  ``<basename>_LIBRARIES``
    A result variable that is set to the same value as the
    ``<basename>_LIBRARY`` variable.

  .. note::

    The ``select_library_configurations()`` command should be called before
    handling standard find module arguments with
    :command:`find_package_handle_standard_args` to ensure that the
    ``<PackageName>_FOUND`` result variable is correctly set based on
    ``<basename>_LIBRARY`` or other related variables.

Examples
^^^^^^^^

Setting library variables based on the build configuration inside a find module
file:

.. code-block:: cmake
  :caption: ``FindFoo.cmake``

  # Find release and debug build of the library
  find_library(Foo_LIBRARY_RELEASE ...)
  find_library(Foo_LIBRARY_DEBUG ...)

  # Set Foo_LIBRARY and Foo_LIBRARIES result variables
  include(SelectLibraryConfigurations)
  select_library_configurations(Foo)

  # Set Foo_FOUND variable and print result message.
  include(FindPackageHandleStandardArgs)
  find_package_handle_standard_args(
    Foo
    REQUIRED_VARS Foo_LIBRARY ...
  )

When find module provides components with multiple build configurations:

.. code-block:: cmake
  :caption: ``FindFoo.cmake``

  include(SelectLibraryConfigurations)
  foreach(component IN LISTS Foo_FIND_COMPONENTS)
    # ...
    select_library_configurations(Foo_${component})
    # ...
  endforeach()

A project can then use this find module as follows:

.. code-block:: cmake
  :caption: ``CMakeLists.txt``

  find_package(Foo)
  target_link_libraries(project_target PRIVATE ${Foo_LIBRARIES})
  # ...
#]=======================================================================]

# This macro was adapted from the FindQt4 CMake module and is maintained by Will
# Dicharry <wdicharry@stellarscience.com>.

macro(select_library_configurations basename)
    if(NOT ${basename}_LIBRARY_RELEASE)
        set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.")
    endif()
    if(NOT ${basename}_LIBRARY_DEBUG)
        set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.")
    endif()

    get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
    if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND
           NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND
           ( _isMultiConfig OR CMAKE_BUILD_TYPE ) )
        # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
        # single-config generators, set optimized and debug libraries
        set( ${basename}_LIBRARY "" )
        foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE )
            list( APPEND ${basename}_LIBRARY optimized "${_libname}" )
        endforeach()
        foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG )
            list( APPEND ${basename}_LIBRARY debug "${_libname}" )
        endforeach()
    elseif( ${basename}_LIBRARY_RELEASE )
        set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
    elseif( ${basename}_LIBRARY_DEBUG )
        set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} )
    else()
        set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND")
    endif()

    set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" )

    if( ${basename}_LIBRARY )
        set( ${basename}_FOUND TRUE )
    endif()

    mark_as_advanced( ${basename}_LIBRARY_RELEASE
        ${basename}_LIBRARY_DEBUG
    )
endmacro()