FindBASIS.cmake
Go to the documentation of this file.
1 #.rst:
2 # FindBASIS
3 # ---------
4 #
5 # Find CMake Build system And Software Implementation Standard (BASIS)
6 # installation using the find_package command in CONFIG mode.
7 #
8 # Result variables::
9 #
10 # BASIS_FOUND - True if CMake BASIS was found.
11 # BASIS_VERSION - Version of found CMake BASIS installation.
12 # BASIS_VERSION_MAJOR - Major version number of found CMake BASIS installation.
13 # BASIS_VERSION_MINOR - Minor version number of found CMake BASIS installation.
14 # BASIS_VERSION_PATCH - Patch number of found CMake BASIS installation.
15 # BASIS_INCLUDE_DIRS - CMake BASIS Utilities include directories.
16 # BASIS_LIBRARY_DIRS - Link directories for CMake BASIS Utilities.
17 #
18 # By default, this module reads hints about search paths from variables::
19 #
20 # DEPENDS_BASIS_DIR - Either installation root or BASISConfig.cmake directory.
21 # BASIS_DIR - Directory containing the BASISConfig.cmake file.
22 # BASIS_ROOT - Root directory of CMake BASIS installation.
23 #
24 # This module considers the common ``BASIS_DIR`` and ``BASIS_ROOT`` CMake or environment
25 # variables to initialize the ``DEPENDS_BASIS_DIR`` cache entry. The ``DEPENDS_BASIS_DIR``
26 # is the non-internal cache entry visible in the CMake GUI. This variable can be set
27 # to either the installation prefix of CMake BASIS, i.e., the top-level directory,
28 # or the directory containing the ``BASISConfig.cmake`` file. It therefore is a hybrid
29 # of ``BASIS_ROOT`` and ``BASIS_DIR`` and replaces these. The common DEPENDS prefix
30 # for cache entries used to set the location of dependencies allows the grouping
31 # of these variables in the CMake GUI. This is a feature of basis_find_package.
32 # As this command is not available without having found a CMake BASIS installation before,
33 # this module can be used to replicate a subset of its functionality for finding BASIS.
34 
35 #=============================================================================
36 # Copyright 2016 Andreas Schuh
37 #
38 # Redistribution and use in source and binary forms, with or without
39 # modification, are permitted provided that the following conditions
40 # are met:
41 #
42 # * Redistributions of source code must retain the above copyright
43 # notice, this list of conditions and the following disclaimer.
44 #
45 # * Redistributions in binary form must reproduce the above copyright
46 # notice, this list of conditions and the following disclaimer in the
47 # documentation and/or other materials provided with the distribution.
48 #
49 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
52 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
53 # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
55 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
59 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 #=============================================================================
61 
62 # Set BASISConfig.cmake directory from installation prefix path
63 function (_basis_root_to_config_dir OUT IN)
64  if (IN)
65  if (WIN32)
66  set(${OUT} "${IN}/CMake" PARENT_SCOPE)
67  else ()
68  set(${OUT} "${IN}/lib/cmake/basis" PARENT_SCOPE)
69  endif ()
70  else ()
71  set(${OUT} "NOTFOUND" PARENT_SCOPE)
72  endif ()
73 endfunction ()
74 
75 # Set installation prefix path from BASISConfig.cmake directory
76 function (_basis_config_to_root_dir OUT IN)
77  if (IN)
78  if (WIN32)
79  string(REGEX REPLACE "/+CMake/*$" "" _prefix "${IN}")
80  else ()
81  string(REGEX REPLACE "/+lib/+cmake/+basis/*$" "" _prefix "${IN}")
82  endif ()
83  else ()
84  set(_prefix "NOTFOUND")
85  endif ()
86  set(${OUT} "${_prefix}" PARENT_SCOPE)
87 endfunction ()
88 
89 # Use more user friendly hybrid DEPENDS_BASIS_DIR cache variable which allows grouping
90 # of DEPENDS paths or custom named cache entry, but still consider BASIS_ROOT and
91 # BASIS_DIR as more common alternatives set in the user shell environment or on the
92 # CMake command line. The DEPENDS_<Package>_DIR is what CMake BASIS uses by default.
93 set (DEPENDS_BASIS_DIR "${DEPENDS_BASIS_DIR}" CACHE PATH
94  "Installation prefix of CMake BASIS or directory containing BASISConfig.cmake file."
95 )
96 
97 # Override DEPENDS_BASIS_DIR by alternative search path variable value if these
98 # were specified on the command line using the -D option. Note that these variables
99 # cannot be set in the CMake GUI because their type is changed here to INTERNAL.
100 # This has two reasons, firstly to not have duplicate variables with different
101 # names for the same purpose, and secondly to be able to recognize when their
102 # value is changed using the -D command line option of the cmake command.
103 if (BASIS_DIR AND (NOT DEFINED _BASIS_DIR OR (DEFINED _BASIS_DIR AND NOT "^${BASIS_DIR}$" STREQUAL "^${_BASIS_DIR}$")))
104  _basis_config_to_root_dir(_prefix "${BASIS_DIR}")
105  set_property(CACHE DEPENDS_BASIS_DIR PROPERTY VALUE "${_prefix}")
106 endif ()
107 if (BASIS_ROOT AND (NOT DEFINED _BASIS_ROOT OR (DEFINED _BASIS_ROOT AND NOT "^${BASIS_ROOT}$" STREQUAL "^${_BASIS_ROOT}$")))
108  set_property(CACHE DEPENDS_BASIS_DIR PROPERTY VALUE "${BASIS_ROOT}")
109 endif ()
110 
111 # Mark alternatives as internal cache entries
112 foreach (_var IN ITEMS BASIS_DIR BASIS_ROOT)
113  get_property(_cached CACHE ${_var} PROPERTY TYPE SET)
114  if (_cached)
115  set_property(CACHE ${_var} PROPERTY TYPE INTERNAL)
116  endif ()
117 endforeach ()
118 
119 # If still not set, use common environment variables to set DEPENDS_BASIS_DIR
120 if (NOT DEPENDS_BASIS_DIR)
121  foreach (_dir IN ITEMS "$ENV{BASIS_DIR}" "$ENV{BASIS_ROOT}")
122  if (_dir)
123  set_property(CACHE DEPENDS_BASIS_DIR PROPERTY VALUE "${_dir}")
124  break()
125  endif ()
126  endforeach ()
127 endif ()
128 
129 # Convert path to CMake style with forward slashes
130 file (TO_CMAKE_PATH "${DEPENDS_BASIS_DIR}" DEPENDS_BASIS_DIR)
131 
132 # Circumvent issue with CMake's find_package() interpreting these variables
133 # relative to the current binary directory instead of the top-level directory
134 if (DEPENDS_BASIS_DIR AND NOT IS_ABSOLUTE "${DEPENDS_BASIS_DIR}")
135  set (DEPENDS_BASIS_DIR "${CMAKE_BINARY_DIR}/${DEPENDS_BASIS_DIR}")
136 endif ()
137 
138 # Allow DEPENDS_BASIS_DIR to be set to either the root directory...
139 if (DEPENDS_BASIS_DIR)
140  list (INSERT CMAKE_PREFIX_PATH 0 "${DEPENDS_BASIS_DIR}")
141 endif ()
142 # ...or the directory containing the BASISConfig.cmake file
143 set(BASIS_DIR "${DEPENDS_BASIS_DIR}" CACHE INTERNAL "Directory containing BASISConfig.cmake file." FORCE)
144 
145 # Look for CMake BASIS installation
146 if (NOT BASIS_FIND_QUIETLY)
147  set(_msg "Looking for BASIS")
148  if (BASIS_FIND_VERSION)
149  set(_msg "${_msg} ${BASIS_FIND_VERSION}")
150  endif ()
151  if (BASIS_FIND_COMPONENTS)
152  set(_msg "${_msg} [${BASIS_FIND_COMPONENTS}]")
153  endif ()
154  message(STATUS "${_msg}...")
155 endif ()
156 
157 set(_argv)
158 if (BASIS_FIND_VERSION)
159  list(APPEND _argv ${BASIS_FIND_VERSION})
160 endif ()
161 if (BASIS_FIND_VERSION_EXACT)
162  list(APPEND _argv EXACT)
163 endif ()
164 set(_comps)
165 set(_comps_opt)
166 foreach (_comp IN LISTS BASIS_FIND_COMPONENTS)
167  if (BASIS_FIND_REQUIRED_${_component})
168  list(APPEND _comps ${_component})
169  else ()
170  list(APPEND _comps_opt ${_component})
171  endif ()
172 endforeach ()
173 if (_comps)
174  list(APPEND _argv COMPONENTS ${_comps})
175 endif ()
176 if (_comps_opt)
177  list(APPEND _argv OPTIONAL_COMPONENTS ${_comps_opt})
178 endif ()
179 
180 find_package(BASIS ${_argv} CONFIG QUIET)
181 
182 if (NOT BASIS_FIND_QUIETLY)
183  if (BASIS_FOUND)
184  if (BASIS_VERSION AND NOT BASIS_VERSION STREQUAL "0.0.0")
185  message(STATUS "Looking for BASIS... - found v${BASIS_VERSION}")
186  else ()
187  message(STATUS "Looking for BASIS... - found")
188  endif ()
189  else ()
190  message(STATUS "Looking for BASIS... - not found")
191  endif ()
192 endif ()
193 
194 # Make internal search path cache entries consistent with non-internal cache entry
195 if (BASIS_FOUND)
196  _basis_config_to_root_dir(_prefix "${BASIS_DIR}")
197 else ()
198  set(_prefix NOTFOUND)
199 endif ()
200 if (NOT "^DEPENDS_BASIS_DIR$" STREQUAL "^BASIS_DIR$")
201  set_property(CACHE BASIS_DIR PROPERTY TYPE INTERNAL)
202  set(_BASIS_DIR "${BASIS_DIR}" CACHE INTERNAL "Previous BASIS_DIR value" FORCE)
203 endif ()
204 get_property(_cached CACHE BASIS_ROOT PROPERTY TYPE SET)
205 if (_cached)
206  set_property(CACHE BASIS_ROOT PROPERTY VALUE "${_prefix}")
207 else ()
208  set(BASIS_ROOT "${_prefix}")
209 endif ()
210 if (NOT _cache MATCHES "^BASIS_(DIR|ROOT)$")
211  set_property(CACHE DEPENDS_BASIS_DIR PROPERTY VALUE "${_prefix}")
212 endif ()
213 
214 # Make internal cache copies of alternative search path variables
215 # so we can detect when a new value was specified using -D option
216 foreach (_var IN ITEMS BASIS_DIR BASIS_ROOT)
217  if (NOT "^DEPENDS_BASIS_DIR$" STREQUAL "^${_var}$")
218  get_property(_cached CACHE ${_var} PROPERTY TYPE SET)
219  if (_cached)
220  set(_${_var} "${${_var}}" CACHE INTERNAL "Previous value of ${_var} after last find_package(BASIS)" FORCE)
221  endif ()
222  endif ()
223 endforeach ()
224 
225 # Raise fatal error when CMake BASIS required but not found
226 if (BASIS_FIND_REQUIRED AND NOT BASIS_FOUND)
227  message(FATAL_ERROR "Could not find CMake BASIS! Please ensure that it is installed"
228  " in a standard system location or set DEPENDS_BASIS_DIR either"
229  " to the installation prefix of BASIS, i.e., the root directory,"
230  " or the directory containing the BASISConfig.cmake file.")
231 endif ()
232 
233 # Unset local variables
234 unset(_prefix)
235 unset(_argv)
236 unset(_comp)
237 unset(_comps)
238 unset(_comps_opt)
239 unset(_cached)
240 unset(_dir)
241 unset(_var)
242 unset(_msg)
path DEPENDS_BASIS_DIR
Definition: FindBASIS.cmake:95
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.
cmake _BASIS_DIR
cmake _msg
cmake DIR
cmake BASIS_ROOT
cmake VALUE
macro find_package()
Overloaded find_package() command.
cmake _prefix
cmake BASIS_DIR