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()