300 строки
11 KiB
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()
|