mirror of
https://github.com/Kitware/CMake.git
synced 2025-05-08 14:29:03 +08:00

- Synced module documentation with other similar find modules. - Added examples section describing module usage, highlighting the imported target, and how to override ODBC configuration through cache variables on Unix-like systems. Some exotic or custom ODBC implementations might sometimes need such steps.
274 lines
8.5 KiB
CMake
274 lines
8.5 KiB
CMake
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
# file LICENSE.rst or https://cmake.org/licensing for details.
|
|
|
|
#[=======================================================================[.rst:
|
|
FindODBC
|
|
--------
|
|
|
|
.. versionadded:: 3.12
|
|
|
|
Finds the Open Database Connectivity (ODBC) library, which implements a standard
|
|
API for accessing database systems. ODBC enables applications to communicate
|
|
with different database management systems (DBMS) using a common set of
|
|
functions. Communication with a specific database is handled through ODBC
|
|
drivers, which the library loads at runtime.
|
|
|
|
On Windows, when building with Visual Studio, this module assumes the ODBC
|
|
library is provided by the available Windows SDK.
|
|
|
|
On Unix-like systems, this module searches for ODBC library provided by unixODBC
|
|
or iODBC implementations of ODBC API. By default, this module looks for the
|
|
ODBC config program to determine the ODBC library and include directory, first
|
|
from unixODBC, then from iODBC. If no config program is found, it searches for
|
|
ODBC header and library in standard locations.
|
|
|
|
Imported Targets
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
This module provides the following :ref:`Imported Targets`:
|
|
|
|
``ODBC::ODBC``
|
|
Target encapsulating the ODBC usage requirements, available if ODBC is found.
|
|
|
|
Result Variables
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
This module defines the following variables:
|
|
|
|
``ODBC_FOUND``
|
|
Boolean indicating whether ODBC is found.
|
|
|
|
``ODBC_INCLUDE_DIRS``
|
|
Include directories containing headers needed to use ODBC.
|
|
|
|
``ODBC_LIBRARIES``
|
|
Libraries needed to link against to use ODBC.
|
|
|
|
Cache Variables
|
|
^^^^^^^^^^^^^^^
|
|
|
|
The following cache variables may also be set:
|
|
|
|
``ODBC_INCLUDE_DIR``
|
|
The path to the directory containing ``sql.h`` and other ODBC headers. May be
|
|
empty on Windows, where the include directory corresponding to the expected
|
|
Windows SDK is already available in the compilation environment.
|
|
|
|
``ODBC_LIBRARY``
|
|
The path to the ODBC library or a library name. On Windows, this may be only
|
|
a library name, because the library directory corresponding to the expected
|
|
Windows SDK is already available in the compilation environment.
|
|
|
|
``ODBC_CONFIG``
|
|
The path to the ODBC config program if found or specified. For example,
|
|
``odbc_config`` for unixODBC, or ``iodbc-config`` for iODBC.
|
|
|
|
Limitations
|
|
^^^^^^^^^^^
|
|
|
|
* On Windows, this module does not search for iODBC.
|
|
* On Unix-like systems, there is no built-in mechanism to prefer unixODBC over
|
|
iODBC, or vice versa. To bypass this limitation, explicitly set the
|
|
``ODBC_CONFIG`` variable to the path of the desired ODBC config program.
|
|
* This module does not support searching for or selecting a specific ODBC
|
|
driver.
|
|
|
|
Examples
|
|
^^^^^^^^
|
|
|
|
Finding and using ODBC
|
|
""""""""""""""""""""""
|
|
|
|
Finding ODBC and linking it to a project target:
|
|
|
|
.. code-block:: cmake
|
|
:caption: CMakeLists.txt
|
|
|
|
find_package(ODBC)
|
|
target_link_libraries(project_target PRIVATE ODBC::ODBC)
|
|
|
|
Finding a custom ODBC installation on Unix-like systems
|
|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
|
|
|
The following examples are for Unix-like systems and demonstrate how to set hint
|
|
and cache variables during the CMake configuration phase to help this module
|
|
find a custom ODBC implementation (e.g. one not supported by default).
|
|
|
|
To specify the installation prefix using :variable:`CMAKE_PREFIX_PATH`:
|
|
|
|
.. code-block:: console
|
|
|
|
$ cmake -D CMAKE_PREFIX_PATH=/path/to/odbc-installation -B build
|
|
|
|
Or using the dedicated :variable:`ODBC_ROOT <<PackageName>_ROOT>` variable:
|
|
|
|
.. code-block:: console
|
|
|
|
$ cmake -D ODBC_ROOT=/path/to/odbc-installation -B build
|
|
|
|
To manually specify the ODBC config program, if available, so that the ODBC
|
|
installation can be automatically determined based on the config tool:
|
|
|
|
.. code-block:: console
|
|
|
|
$ cmake -D ODBC_CONFIG=/path/to/odbc/bin/odbc-config -B build
|
|
|
|
To manually specify the ODBC library and include directory:
|
|
|
|
.. code-block:: console
|
|
|
|
$ cmake \
|
|
-D ODBC_LIBRARY=/path/to/odbc/lib/libodbc.so \
|
|
-D ODBC_INCLUDE_DIR=/path/to/odbc/include \
|
|
-B build
|
|
#]=======================================================================]
|
|
|
|
# Define internal variables
|
|
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 paths 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 variables 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)
|