-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
GdalGenerateConfig.cmake
338 lines (318 loc) · 12.8 KB
/
GdalGenerateConfig.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
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)
# For gdal.pc libdir variable. Not strictly needed, but quite standard
# to have one in a .pc
if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
if( "${CMAKE_INSTALL_LIBDIR}" MATCHES "^${CONFIG_PREFIX}.*")
file(RELATIVE_PATH _rel_path "${CONFIG_PREFIX}" "${CMAKE_INSTALL_LIBDIR}")
set(CONFIG_LIBDIR "\${exec_prefix}/${_rel_path}")
else()
set(CONFIG_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
endif()
else()
set(CONFIG_LIBDIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
endif()
gdal_join_and_quote(CONFIG_LIBDIR)
# For gdal.pc includedir variable. Not strictly needed, but quite standard
# to have one in a .pc
if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
if( "${CMAKE_INSTALL_INCLUDEDIR}" MATCHES "^${CONFIG_PREFIX}.*")
file(RELATIVE_PATH _rel_path "${CONFIG_PREFIX}" "${CMAKE_INSTALL_INCLUDEDIR}")
set(CONFIG_INCLUDEDIR "\${exec_prefix}/${_rel_path}")
else()
set(CONFIG_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
endif()
else()
set(CONFIG_INCLUDEDIR "\${exec_prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()
gdal_join_and_quote(CONFIG_INCLUDEDIR)
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)
# For gdal-config --plugindir
set(CONFIG_PLUGINDIR "${INSTALL_PLUGIN_FULL_DIR}")
gdal_join_and_quote(CONFIG_PLUGINDIR)
# Create apps/gdal-config with execution rights from gdal-config.in
get_filename_component(GDAL_CONFIG_DIR "${arg_GDAL_CONFIG}" DIRECTORY)
file(MAKE_DIRECTORY "${GDAL_CONFIG_DIR}.tmp")
configure_file("${GDAL_CMAKE_TEMPLATE_PATH}/gdal-config.in" "${GDAL_CONFIG_DIR}.tmp/gdal-config" @ONLY)
file(COPY "${GDAL_CONFIG_DIR}.tmp/gdal-config"
DESTINATION "${GDAL_CONFIG_DIR}"
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
configure_file("${GDAL_CMAKE_TEMPLATE_PATH}/gdal.pc.in" "${arg_PKG_CONFIG}" @ONLY)
endfunction()