- Source code: cmake/modules/PHP/SearchLibraries.cmake
Check if symbol exists in given header(s). If not found in default linked libraries (for example, C library), a given list of libraries is iterated and found library can be linked as needed.
Depending on the system, C functions can be located in one of the default linked
libraries when using the compiler, or they can be in separate system libraries
that need to be manually passed to the linker. The usual check_symbol_exists()
doesn't find them unless CMAKE_REQUIRED_LIBRARIES
is specified.
For example, math functions (math.h
) can be in the math library (m
);
however, some systems, like macOS, Windows, and Haiku, have them in the C
library. Linking the math library (-lm
) there isn't necessary. Additionally,
some systems might be in the process of moving functions from their dedicated
libraries to the C library. For example, illumos-based systems (-lnsl
...), and
similar.
The logic in this module is somehow following the Autoconf's AC_SEARCH_LIBS
.
Module exposes the following function:
php_search_libraries(
<symbol>
HEADERS <header>...
[LIBRARIES <library>...]
[VARIABLE <variable>]
[LIBRARY_VARIABLE <library_variable>]
[TARGET <target> [<PRIVATE|PUBLIC|INTERFACE>]]
[RECHECK_HEADERS]
)
Check that the <symbol>
is available after including the <header>
(or a list
of <headers>
), or if any library from the LIBRARY
list needs to be linked.
If <variable>
is given, check result is stored in an internal cache variable.
-
HEADERS
A header (or a list of headers) where to look for the symbol declaration. Headers are checked in iteration with
check_include_files()
and are appended to the list of found headers instead of a single header check. In some cases a header might not be self-contained (it requires including prior additional headers). For example, to be able to usearpa/nameser.h
on Solaris, the<sys/types.h>
header must be included before. -
LIBRARIES
If symbol is not found in the default libraries (C library), then the
LIBRARIES
list is iterated. Instead of using thecheck_library_exists()
orcheck_function_exists()
, thecheck_symbol_exists()
is used, since it also works when symbol might be a macro definition. It would not be found using the other two commands because they don't include required headers. -
VARIABLE
Name of a cache variable where the check result will be stored. Optional. If not given, the result will be stored in an internal automatically defined cache variable name.
-
LIBRARY_VARIABLE
When symbol is not found in the default libraries, the resulting library that contains the symbol is stored in this local variable name.
-
TARGET
If the
TARGET
is given, the resulting library is linked to a given<target>
with the scope ofPRIVATE
,PUBLIC
, orINTERFACE
. Behavior is homogeneous to:target_link_libraries(<target> [PRIVATE|PUBLIC|INTERFACE] <library>)
-
RECHECK_HEADERS
Enabling this option will recheck the header(s) by using specific
_PHP_SEARCH_LIBRARIES_HEADER_<HEADER_NAMES_H...>
cache variable names instead of the more commonHAVE_<HEADER_NAME>_H
. When checking headers in iteration, by default, theHAVE_<HEADER_NAME>_H
cache variables are defined, so the entire check is slightly more performant if header(s) have already been checked elsewhere in the application using thecheck_header_include()
. In most cases this won't be needed.
In the following example, the library containing dlopen
is linked to
php_config
target with the INTERFACE
scope when needed to use the dlopen
symbol. Cache variable HAVE_LIBDL
is set if dlopen
is found either in the
default system libraries or in one of the libraries set in the CMAKE_DL_LIBS
variable.
# CMakeLists.txt
# Include the module
include(PHP/SearchLibraries)
# Search and link library containing dlopen and dlclose .
php_search_libraries(
dlopen
HEADERS dlfcn.h
LIBRARIES ${CMAKE_DL_LIBS}
VARIABLE HAVE_LIBDL
TARGET php_config INTERFACE
)
The following variables may be set before calling this function to modify the way the check is run. See https://cmake.org/cmake/help/latest/module/CheckSymbolExists.html
CMAKE_REQUIRED_FLAGS
CMAKE_REQUIRED_DEFINITIONS
CMAKE_REQUIRED_INCLUDES
CMAKE_REQUIRED_LINK_OPTIONS
CMAKE_REQUIRED_LIBRARIES
CMAKE_REQUIRED_LINK_DIRECTORIES
CMAKE_REQUIRED_QUIET
-
If symbol declaration is missing in its belonging headers, it won't be found with this module. There are still rare cases of such functions on some systems (for example,
fdatasync()
on macOS). In such cases it is better to use other approaches, such as CMake'scheck_function_exists()
. -
If symbol is defined as a macro to a function that requires additional libraries linked, this module will find the symbol but won't find the required library. For example, the
dn_skipname()
on macOS is defined as a macro in<resolv.h>
and resolves to a functionres_9_dn_skipname()
that requires theresolv
library linked to work:#define dn_skipname res9_dn_skipname
As this is considered an architectural bug from this module point of view, in such cases it is better to use additional library check.