gdal/cmake/helpers/GdalGenerateConfig.cmake

300 строки
11 KiB
CMake

if ((NOT WIN32) OR MINGW)
set(split_libs_default ON)
else ()
set(split_libs_default OFF)
endif ()
option(GDAL_SPLIT_EXPORTED_LIBS "Split library path and name on export" ${split_libs_default})
# Join the list items and add double quotes around items which contain whitespace
function(gdal_join_and_quote _var)
set(string "")
foreach(item IN LISTS ${_var})
if("${item}" MATCHES " ")
set(item "\"${item}\"")
endif()
if(NOT "${string}" STREQUAL "")
string(APPEND string " ")
endif()
string(APPEND string "${item}")
endforeach()
set(${_var} "${string}" PARENT_SCOPE)
endfunction()
# Return a flat list of libs including target linking requirements.
function(gdal_flatten_link_libraries _result)
set(_libs "")
string(COMPARE EQUAL "${CMAKE_BUILD_TYPE}" "Debug" is_debug_build)
if(CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE IN_LIST DEBUG_CONFIGURATIONS)
set(is_debug_build TRUE)
endif()
while(ARGN)
list(GET ARGN 0 _lib)
list(REMOVE_AT ARGN 0)
if(_lib STREQUAL "debug")
if(NOT is_debug_build)
list(REMOVE_AT ARGN 0)
endif()
continue()
elseif(_lib STREQUAL "optimized")
if(is_debug_build)
list(REMOVE_AT ARGN 0)
endif()
continue()
elseif(_lib STREQUAL "general")
continue()
endif()
gdal_resolve_link_genex(_lib "${_lib}")
if(_lib)
list(APPEND _libs "${_lib}")
if(TARGET "${_lib}")
get_target_property(_link_libraries ${_lib} INTERFACE_LINK_LIBRARIES)
get_target_property(_type ${_lib} TYPE)
if(_link_libraries AND NOT TYPE STREQUAL "SHARED_LIBRARY")
list(INSERT ARGN 0 ${_link_libraries})
endif()
endif()
endif()
endwhile()
set(${_result} "${_libs}" PARENT_SCOPE)
endfunction()
# Resolve all generator expressions for the purpose of exporting linker flags.
function(gdal_resolve_link_genex _result _input)
while(_input MATCHES "^(.*)\\\$<([^:>]*):*([^>]*)>")
set(_match "${CMAKE_MATCH_0}")
set(_first "${CMAKE_MATCH_1}")
gdal_evaluate_link_genex(_second "${CMAKE_MATCH_2}" "${CMAKE_MATCH_3}")
string(REPLACE "${_match}" "${_first}${_second}" _input "${_input}")
endwhile()
set("${_result}" "${_input}" PARENT_SCOPE)
endfunction()
# Resolve a single generator expressions for the purpose of exporting linker flags.
function(gdal_evaluate_link_genex _result _keyword _params)
if(_keyword STREQUAL "1" OR _keyword STREQUAL "LINK_ONLY")
set(value "${_params}")
elseif(_keyword STREQUAL "CONFIG")
# Should use the target property, not the variable, but we don't track the target ATM
string(TOUPPER "${CMAKE_BUILD_TYPE}" current_config)
if(DEFINED "CMAKE_MAP_IMPORTED_CONFIG_${current_config}")
string(TOUPPER "${CMAKE_MAP_IMPORTED_CONFIG_${current_config}}" configs)
else()
set(configs "${current_config}")
endif()
if(_params IN_LIST configs)
set(value 1)
else()
set(value 0)
endif()
elseif(_keyword MATCHES "COMPILER_ID\$")
string(REPLACE "," ";" compiler_ids "${_params}")
if("${CMAKE_${_keyword}}" IN_LIST compiler_ids)
set(value 1)
else()
set(value 0)
endif()
elseif(_keyword STREQUAL "PLATFORM_ID")
string(REPLACE "," ";" platform_ids "${_params}")
if("${CMAKE_CXX_PLATFORM_ID}" IN_LIST "${platform_ids}")
set(value 1)
else()
set(value 0)
endif()
elseif(_keyword STREQUAL "NOT")
if(_params STREQUAL "0" OR _params STREQUAL "")
set(value 1)
else()
set(value 0)
endif()
elseif(_keyword STREQUAL "BOOL")
if("${_params}")
set(value 1)
else()
set(value 0)
endif()
elseif(_keyword STREQUAL "0")
set(value "")
else()
if(NOT _params STREQUAL "")
string(APPEND _keyword ":\${_params}")
endif()
message(WARNING "Dropping unsupported generator expression: '\$<${_params}>'")
set(value "")
endif()
set(${_result} "${value}" PARENT_SCOPE)
endfunction()
# Get a target property with respect to the current build type
function(gdal_get_target_property_for_config _result _target _property)
string(TOUPPER "${CMAKE_BUILD_TYPE}" current_config)
get_target_property(mapped_configs ${_target} MAP_IMPORTED_CONFIG_${current_config})
if (NOT mapped_configs AND NOT mapped_configs STREQUAL "" AND NOT current_config STREQUAL "")
set(mapped_configs "${current_config}")
endif ()
string(TOUPPER "${mapped_configs}" mapped_configs)
set(all_properties "")
foreach (mapped_config IN LISTS mapped_configs)
list(APPEND all_properties "${_property}_${mapped_config}")
endforeach()
list(APPEND all_properties "${_property}")
get_target_property(imported_configs ${_target} IMPORTED_CONFIGURATIONS)
foreach (imported_config IN LISTS imported_configs)
list(APPEND all_properties "${_property}_${imported_config}")
endforeach()
foreach(candidate_property IN LISTS all_properties)
get_target_property(value ${_target} ${candidate_property})
if(value)
break()
endif()
endforeach ()
set(${_result} "${value}" PARENT_SCOPE)
endfunction()
# Guess linker parameters (-L/osgeo -lproj) from file name (/osgeo/libproj.dll.a).
function(gdal_split_library_to_lflags _lib_flag _path_flag _input)
get_filename_component(_lib_name "${_input}" NAME)
foreach(_item IN ITEMS SHARED IMPORT STATIC)
set(_suffix "${CMAKE_${_item}_LIBRARY_SUFFIX}")
if(NOT _suffix)
continue()
endif()
string(FIND "${_lib_name}" "${_suffix}" _pos REVERSE)
if(_pos EQUAL "-1")
continue()
endif()
get_filename_component(_lib_dir "${_input}" DIRECTORY)
string(SUBSTRING "${_lib_name}" 0 "${_pos}" _name_we)
if(NOT "${_name_we}${_suffix}" STREQUAL _lib_name)
if(NOT _suffix STREQUAL ".so" OR NOT EXISTS "${_lib_dir}/${_name_we}${_suffix}")
continue()
endif()
endif()
set(_prefix "${CMAKE_${_item}_LIBRARY_PREFIX}")
if(_prefix)
string(FIND "${_name_we}" "${_prefix}" _pos)
else()
set(_pos 0)
endif()
if(_pos STREQUAL "0")
# Match
string(LENGTH "${_prefix}" _pos)
string(SUBSTRING "${_name_we}" "${_pos}" "-1" _lib_name)
set(${_lib_flag} "${CMAKE_LINK_LIBRARY_FLAG}${_lib_name}" PARENT_SCOPE)
if(_lib_dir AND NOT _lib_dir IN_LIST CMAKE_C_IMPLICIT_LINK_DIRECTORIES)
set(${_path_flag} "${CMAKE_LIBRARY_PATH_FLAG}${_lib_dir}" PARENT_SCOPE)
else()
set(${_path_flag} "" PARENT_SCOPE)
endif()
return()
endif()
endforeach()
# Fallback
set(${_lib_flag} "${_input}")
set(${_path_flag} "" PARENT_SCOPE)
endfunction()
# Get linker flags for cmake link libraries, with targets and generator
# expressions resolved for the current build type.
function(gdal_get_lflags _result)
gdal_flatten_link_libraries(_libs_in ${ARGN})
set(_libs_out "")
while(_libs_in)
list(GET _libs_in 0 _lib)
list(REMOVE_AT _libs_in 0)
if(TARGET "${_lib}")
get_property(_type TARGET ${_lib} PROPERTY TYPE)
if(_type STREQUAL "INTERFACE_LIBRARY")
continue()
endif()
set(_location "")
if(NOT _type STREQUAL "STATIC_LIBRARY")
gdal_get_target_property_for_config(_location "${_lib}" "IMPORTED_IMPLIB")
endif()
if(NOT _location)
gdal_get_target_property_for_config(_location "${_lib}" "IMPORTED_LOCATION")
endif()
if(_location)
set(_lib "${_location}")
endif()
endif()
set(_other "")
if(CMAKE_LIBRARY_PATH_FLAG STREQUAL "-L" AND _lib MATCHES "^-L")
set(_other "${_lib}")
set(_lib "")
elseif(_lib STREQUAL "-pthread")
# use _lib
elseif(CMAKE_LINK_LIBRARY_FLAG STREQUAL "-l" AND _lib MATCHES "^-l")
# use _lib
elseif(EXISTS "${_lib}")
if(GDAL_SPLIT_EXPORTED_LIBS)
gdal_split_library_to_lflags(_lib _other "${_lib}")
endif()
else()
set(_lib "${CMAKE_LINK_LIBRARY_FLAG}${_lib}")
endif()
if(_other AND NOT _other IN_LIST _libs_out)
list(APPEND _libs_out "${_other}")
endif()
if(_lib)
list(REMOVE_ITEM _libs_out "${_lib}")
list(APPEND _libs_out "${_lib}")
endif()
endwhile()
set(${_result} "${_libs_out}" PARENT_SCOPE)
endfunction()
# Generate gdal-config utility command and pkg-config module gdal.pc
function(gdal_generate_config)
set(one_value_keywords "TARGET;GLOBAL_PROPERTY;GDAL_CONFIG;PKG_CONFIG")
cmake_parse_arguments(PARSE_ARGV 0 arg "" "${one_value_keywords}" "")
if (ENABLE_GNM)
set(CONFIG_GNM_ENABLED "yes")
else ()
set(CONFIG_GNM_ENABLED "no")
endif ()
get_property(gdal_formats GLOBAL PROPERTY GDAL_FORMATS)
get_property(ogr_formats GLOBAL PROPERTY OGR_FORMATS)
string(REPLACE ";" " " CONFIG_FORMATS "${gdal_formats} ${ogr_formats}")
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CONFIG_PREFIX "/usr/local") # default
else()
set(CONFIG_PREFIX "${CMAKE_INSTALL_PREFIX}")
endif()
set(CONFIG_DATA "${CONFIG_PREFIX}/${GDAL_RESOURCE_PATH}")
set(CONFIG_CFLAGS "-I${CMAKE_INSTALL_FULL_INCLUDEDIR}")
gdal_join_and_quote(CONFIG_DATA)
gdal_join_and_quote(CONFIG_CFLAGS)
get_property(target_lib_name TARGET "${arg_TARGET}" PROPERTY OUTPUT_NAME)
set(CONFIG_LIBS "${CMAKE_LINK_LIBRARY_FLAG}${target_lib_name}")
if(NOT CONFIG_PREFIX IN_LIST CMAKE_C_IMPLICIT_LINK_LIBRARIES)
list(INSERT CONFIG_LIBS 0 "${CMAKE_LIBRARY_PATH_FLAG}${CMAKE_INSTALL_FULL_LIBDIR}")
endif()
gdal_join_and_quote(CONFIG_LIBS)
get_property(libs GLOBAL PROPERTY "${arg_GLOBAL_PROPERTY}")
if(NOT MSVC AND CMAKE_THREAD_LIBS_INIT)
list(APPEND libs ${CMAKE_THREAD_LIBS_INIT})
endif()
list(APPEND libs ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES})
if(CMAKE_C_IMPLICIT_LINK_LIBRARIES)
list(REMOVE_ITEM libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES})
endif()
gdal_get_lflags(CONFIG_DEP_LIBS ${libs})
gdal_join_and_quote(CONFIG_DEP_LIBS)
if(NOT BUILD_SHARED_LIBS)
# Make `--libs` simply work, even for static builds.
string(APPEND CONFIG_LIBS " ${CONFIG_DEP_LIBS}")
set(CONFIG_DEP_LIBS "")
endif()
gdal_join_and_quote(CONFIG_PREFIX)
configure_file("${GDAL_CMAKE_TEMPLATE_PATH}/gdal-config.in" "${arg_GDAL_CONFIG}" @ONLY)
configure_file("${GDAL_CMAKE_TEMPLATE_PATH}/gdal.pc.in" "${arg_PKG_CONFIG}" @ONLY)
endfunction()