| # Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| # file Copyright.txt or https://cmake.org/licensing for details. | |
| #[=======================================================================[.rst: | |
| FindODBC | |
| -------- | |
| .. versionadded:: 3.12 | |
| Find an Open Database Connectivity (ODBC) include directory and library. | |
| On Windows, when building with Visual Studio, this module assumes the ODBC | |
| library is provided by the available Windows SDK. | |
| On Unix, this module allows to search for ODBC library provided by | |
| unixODBC or iODBC implementations of ODBC API. | |
| This module reads hint about location of the config program: | |
| .. variable:: ODBC_CONFIG | |
| Location of odbc_config or iodbc-config program | |
| Otherwise, this module tries to find the config program, | |
| first from unixODBC, then from iODBC. | |
| If no config program found, this module searches for ODBC header | |
| and library in list of known locations. | |
| Imported targets | |
| ^^^^^^^^^^^^^^^^ | |
| This module defines the following :prop_tgt:`IMPORTED` targets: | |
| .. variable:: ODBC::ODBC | |
| Imported target for using the ODBC library, if found. | |
| Result variables | |
| ^^^^^^^^^^^^^^^^ | |
| .. variable:: ODBC_FOUND | |
| Set to true if ODBC library found, otherwise false or undefined. | |
| .. variable:: ODBC_INCLUDE_DIRS | |
| Paths to include directories listed in one variable for use by ODBC client. | |
| May be empty on Windows, where the include directory corresponding to the | |
| expected Windows SDK is already available in the compilation environment. | |
| .. variable:: ODBC_LIBRARIES | |
| Paths to libraries to linked against to use ODBC. | |
| May just a library name on Windows, where the library directory corresponding | |
| to the expected Windows SDK is already available in the compilation environment. | |
| .. variable:: ODBC_CONFIG | |
| Path to unixODBC or iODBC config program, if found or specified. | |
| Cache variables | |
| ^^^^^^^^^^^^^^^ | |
| For users who wish to edit and control the module behavior, this module | |
| reads hints about search locations from the following variables: | |
| .. variable:: ODBC_INCLUDE_DIR | |
| Path to ODBC include directory with ``sql.h`` header. | |
| .. variable:: ODBC_LIBRARY | |
| Path to ODBC library to be linked. | |
| These variables should not be used directly by project code. | |
| Limitations | |
| ^^^^^^^^^^^ | |
| On Windows, this module does not search for iODBC. | |
| On Unix, there is no way to prefer unixODBC over iODBC, or vice versa, | |
| other than providing the config program location using the ``ODBC_CONFIG``. | |
| This module does not allow to search for a specific ODBC driver. | |
| #]=======================================================================] | |
| # Define lists used internally | |
| set(_odbc_include_paths) | |
| set(_odbc_lib_paths) | |
| set(_odbc_lib_names) | |
| set(_odbc_required_libs_names) | |
| ### Try Windows Kits ########################################################## | |
| if(WIN32) | |
| # List names of ODBC libraries on Windows | |
| if(NOT MINGW) | |
| set(ODBC_LIBRARY odbc32.lib) | |
| else() | |
| set(ODBC_LIBRARY libodbc32.a) | |
| endif() | |
| set(_odbc_lib_names odbc32;) | |
| # List additional libraries required to use ODBC library | |
| if(MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") | |
| set(_odbc_required_libs_names odbccp32;ws2_32) | |
| elseif(MINGW) | |
| set(_odbc_required_libs_names odbccp32) | |
| endif() | |
| endif() | |
| ### Try unixODBC or iODBC config program ###################################### | |
| if (UNIX) | |
| find_program(ODBC_CONFIG | |
| NAMES odbc_config iodbc-config | |
| DOC "Path to unixODBC or iODBC config program") | |
| mark_as_advanced(ODBC_CONFIG) | |
| endif() | |
| if (UNIX AND ODBC_CONFIG) | |
| # unixODBC and iODBC accept unified command line options | |
| execute_process(COMMAND ${ODBC_CONFIG} --cflags | |
| OUTPUT_VARIABLE _cflags OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| execute_process(COMMAND ${ODBC_CONFIG} --libs | |
| OUTPUT_VARIABLE _libs OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| # Collect paths of include directories from CFLAGS | |
| separate_arguments(_cflags NATIVE_COMMAND "${_cflags}") | |
| foreach(arg IN LISTS _cflags) | |
| if("${arg}" MATCHES "^-I(.*)$") | |
| list(APPEND _odbc_include_paths "${CMAKE_MATCH_1}") | |
| endif() | |
| endforeach() | |
| unset(_cflags) | |
| # Collect paths of library names and directories from LIBS | |
| separate_arguments(_libs NATIVE_COMMAND "${_libs}") | |
| foreach(arg IN LISTS _libs) | |
| if("${arg}" MATCHES "^-L(.*)$") | |
| list(APPEND _odbc_lib_paths "${CMAKE_MATCH_1}") | |
| elseif("${arg}" MATCHES "^-l(.*)$") | |
| set(_lib_name ${CMAKE_MATCH_1}) | |
| string(REGEX MATCH "odbc" _is_odbc ${_lib_name}) | |
| if(_is_odbc) | |
| list(APPEND _odbc_lib_names ${_lib_name}) | |
| else() | |
| list(APPEND _odbc_required_libs_names ${_lib_name}) | |
| endif() | |
| unset(_lib_name) | |
| endif() | |
| endforeach() | |
| unset(_libs) | |
| endif() | |
| ### Try unixODBC or iODBC in include/lib filesystems ########################## | |
| if (UNIX AND NOT ODBC_CONFIG) | |
| # List names of both ODBC libraries, unixODBC and iODBC | |
| set(_odbc_lib_names odbc;iodbc;unixodbc;) | |
| endif() | |
| ### Find include directories ################################################## | |
| find_path(ODBC_INCLUDE_DIR | |
| NAMES sql.h | |
| PATHS ${_odbc_include_paths}) | |
| if(NOT ODBC_INCLUDE_DIR AND WIN32) | |
| set(ODBC_INCLUDE_DIR "") | |
| endif() | |
| ### Find libraries ############################################################ | |
| if(NOT ODBC_LIBRARY) | |
| find_library(ODBC_LIBRARY | |
| NAMES ${_odbc_lib_names} | |
| PATHS ${_odbc_lib_paths} | |
| PATH_SUFFIXES odbc) | |
| foreach(_lib IN LISTS _odbc_required_libs_names) | |
| find_library(_lib_path | |
| NAMES ${_lib} | |
| PATHS ${_odbc_lib_paths} # system parths or collected from ODBC_CONFIG | |
| PATH_SUFFIXES odbc) | |
| if(_lib_path) | |
| list(APPEND _odbc_required_libs_paths ${_lib_path}) | |
| endif() | |
| unset(_lib_path CACHE) | |
| endforeach() | |
| endif() | |
| # Unset internal lists as no longer used | |
| unset(_odbc_include_paths) | |
| unset(_odbc_lib_paths) | |
| unset(_odbc_lib_names) | |
| unset(_odbc_required_libs_names) | |
| ### Set result variables ###################################################### | |
| set(_odbc_required_vars ODBC_LIBRARY) | |
| if(NOT WIN32) | |
| list(APPEND _odbc_required_vars ODBC_INCLUDE_DIR) | |
| endif() | |
| include(FindPackageHandleStandardArgs) | |
| find_package_handle_standard_args(ODBC DEFAULT_MSG ${_odbc_required_vars}) | |
| unset(_odbc_required_vars) | |
| mark_as_advanced(ODBC_LIBRARY ODBC_INCLUDE_DIR) | |
| set(ODBC_INCLUDE_DIRS ${ODBC_INCLUDE_DIR}) | |
| list(APPEND ODBC_LIBRARIES ${ODBC_LIBRARY}) | |
| list(APPEND ODBC_LIBRARIES ${_odbc_required_libs_paths}) | |
| ### Import targets ############################################################ | |
| if(ODBC_FOUND) | |
| if(NOT TARGET ODBC::ODBC) | |
| if(IS_ABSOLUTE "${ODBC_LIBRARY}") | |
| add_library(ODBC::ODBC UNKNOWN IMPORTED) | |
| set_target_properties(ODBC::ODBC PROPERTIES | |
| IMPORTED_LINK_INTERFACE_LANGUAGES "C" | |
| IMPORTED_LOCATION "${ODBC_LIBRARY}") | |
| else() | |
| add_library(ODBC::ODBC INTERFACE IMPORTED) | |
| set_target_properties(ODBC::ODBC PROPERTIES | |
| IMPORTED_LIBNAME "${ODBC_LIBRARY}") | |
| endif() | |
| set_target_properties(ODBC::ODBC PROPERTIES | |
| INTERFACE_INCLUDE_DIRECTORIES "${ODBC_INCLUDE_DIR}") | |
| if(_odbc_required_libs_paths) | |
| set_property(TARGET ODBC::ODBC APPEND PROPERTY | |
| INTERFACE_LINK_LIBRARIES "${_odbc_required_libs_paths}") | |
| endif() | |
| endif() | |
| endif() | |
| unset(_odbc_required_libs_paths) |