1project('gdk-pixbuf', 'c', 2 version: '2.40.0', 3 license: 'LGPLv2.1+', 4 default_options: [ 5 'buildtype=debugoptimized', 6 'warning_level=1', 7 'c_std=c99', 8 ], 9 meson_version: '>= 0.46.0') 10 11add_project_arguments([ '-D_POSIX_C_SOURCE=200809L', '-D_DEFAULT_SOURCE', '-D_XOPEN_SOURCE' ], language: 'c') 12 13cc = meson.get_compiler('c') 14host_system = host_machine.system() 15 16# Versioning 17gdk_pixbuf_version = meson.project_version() 18version_arr = gdk_pixbuf_version.split('.') 19gdk_pixbuf_version_major = version_arr[0].to_int() 20gdk_pixbuf_version_minor = version_arr[1].to_int() 21gdk_pixbuf_version_micro = version_arr[2].to_int() 22 23gdk_pixbuf_api_version = '2.0' 24gdk_pixbuf_binary_version = '2.10.0' 25 26gdk_pixbuf_api_name = '@0@-@1@'.format(meson.project_name(), gdk_pixbuf_api_version) 27 28if gdk_pixbuf_version_minor.is_odd() 29 gdk_pixbuf_interface_age = 0 30else 31 gdk_pixbuf_interface_age = gdk_pixbuf_version_micro 32endif 33 34gdk_pixbuf_binary_age = 100 * gdk_pixbuf_version_minor + gdk_pixbuf_version_micro 35 36# maintaining compatibility with the previous libtool versioning 37# current = binary - interface 38# revision = interface 39soversion = 0 40current = gdk_pixbuf_binary_age - gdk_pixbuf_interface_age 41revision = gdk_pixbuf_interface_age 42libversion = '@0@.@1@.@2@'.format(soversion, current, revision) 43age = gdk_pixbuf_binary_age - gdk_pixbuf_interface_age 44current_minus_age = current - age 45darwin_versions = ['@0@'.format(current + 1), '@0@.@1@'.format(current + 1, gdk_pixbuf_interface_age)] 46 47# Paths 48gdk_pixbuf_prefix = get_option('prefix') 49gdk_pixbuf_libdir = join_paths(gdk_pixbuf_prefix, get_option('libdir')) 50gdk_pixbuf_bindir = join_paths(gdk_pixbuf_prefix, get_option('bindir')) 51gdk_pixbuf_includedir = join_paths(gdk_pixbuf_prefix, get_option('includedir')) 52gdk_pixbuf_datadir = join_paths(gdk_pixbuf_prefix, get_option('datadir')) 53gdk_pixbuf_mandir = join_paths(gdk_pixbuf_prefix, get_option('mandir')) 54gdk_pixbuf_localedir = join_paths(gdk_pixbuf_prefix, get_option('localedir')) 55gdk_pixbuf_libexecdir = join_paths(gdk_pixbuf_prefix, get_option('libexecdir')) 56gdk_pixbuf_loaderdir = join_paths(gdk_pixbuf_libdir, 'gdk-pixbuf-@0@/@1@/loaders'.format(gdk_pixbuf_api_version, gdk_pixbuf_binary_version)) 57 58# Dependencies 59glib_req_version = '>= 2.38.0' 60glib_dep = dependency('glib-2.0', version: glib_req_version, 61 fallback : ['glib', 'libglib_dep']) 62gobject_dep = dependency('gobject-2.0', version: glib_req_version, 63 fallback : ['glib', 'libgobject_dep']) 64gmodule_dep = dependency('gmodule-no-export-2.0', version: glib_req_version, 65 fallback : ['glib', 'libgmodule_dep']) 66gio_dep = dependency('gio-2.0', version: glib_req_version, 67 fallback : ['glib', 'libgio_dep']) 68 69# Configurations 70gdk_pixbuf_conf = configuration_data() 71 72check_headers = [ 73 'unistd.h', 74 'sys/resource.h', 75 'sys/time.h' 76] 77 78foreach h: check_headers 79 if cc.has_header(h) 80 gdk_pixbuf_conf.set('HAVE_' + h.underscorify().to_upper(), 1) 81 endif 82endforeach 83 84# Look for the math library first, since we use it to test for round() and lrint() 85mathlib_dep = cc.find_library('m', required: false) 86 87# XXX: Remove the checks for round() and lrint() once GDK-Pixbuf is declared C99 88if cc.has_function('round', dependencies: mathlib_dep) 89 gdk_pixbuf_conf.set('HAVE_ROUND', 1) 90endif 91 92if cc.has_function('lrint', dependencies: mathlib_dep) 93 gdk_pixbuf_conf.set('HAVE_LRINT', 1) 94endif 95 96if cc.has_function('bind_textdomain_codeset', prefix: '#include <libintl.h>') 97 gdk_pixbuf_conf.set('HAVE_BIND_TEXTDOMAIN_CODESET', 1) 98endif 99 100if cc.has_function('setrlimit', prefix: '#include <sys/time.h>\n#include <sys/resource.h>') 101 gdk_pixbuf_conf.set('HAVE_SETRLIMIT', 1) 102endif 103 104# We use links() because sigsetjmp() is often a macro hidden behind other macros 105gdk_pixbuf_conf.set('HAVE_SIGSETJMP', 106 cc.links('''#define _POSIX_SOURCE 107 #include <setjmp.h> 108 int main (void) { 109 sigjmp_buf env; 110 sigsetjmp (env, 0); 111 return 0; 112 }''', name: 'sigsetjmp'), 113) 114 115# Common compiler and linker flags 116common_cflags = [] 117common_ldflags = [] 118 119if cc.get_id() == 'msvc' 120 # For Visual Studio, just force-include msvc_reommended_pragmas.h 121 # so that we silence unwanted noise and track potential issues 122 test_cflags = [] 123 add_project_arguments([ '-FImsvc_recommended_pragmas.h' ], language: 'c') 124elif cc.get_id() == 'gcc' or cc.get_id() == 'clang' 125 test_cflags = [ 126 '-Wpointer-arith', 127 '-Wformat=2', 128 '-Wstrict-prototypes', 129 '-Wnested-externs', 130 '-Wold-style-definition', 131 '-Wdeclaration-after-statement', 132 '-Wunused', 133 '-Wcast-align', 134 '-Wmissing-noreturn', 135 '-Wmissing-format-attribute', 136 '-Wlogical-op', 137 '-fno-strict-aliasing', 138 '-Wno-int-conversion', 139 '-Wno-uninitialized', 140 '-Wno-discarded-qualifiers', 141 '-Werror=implicit', 142 '-Werror=nonnull', 143 '-Werror=init-self', 144 '-Werror=main', 145 '-Werror=missing-braces', 146 '-Werror=sequence-point', 147 '-Werror=return-type', 148 '-Werror=trigraphs', 149 '-Werror=array-bounds', 150 '-Werror=write-strings', 151 '-Werror=address', 152 '-Werror=int-to-pointer-cast', 153 '-Werror=pointer-to-int-cast', 154 '-Werror=empty-body', 155 ] 156 157 # Ensure we have the correct bit packing on Windows 158 if host_system == 'windows' 159 test_cflags += '-mms-bitfields' 160 endif 161else 162 test_cflags = [] 163endif 164 165# Symbol visibility 166if get_option('default_library') != 'static' 167 if host_system == 'windows' 168 gdk_pixbuf_conf.set('DLL_EXPORT', true) 169 gdk_pixbuf_conf.set('_GDK_PIXBUF_EXTERN', '__declspec(dllexport) extern') 170 if cc.get_id() != 'msvc' 171 test_cflags += ['-fvisibility=hidden'] 172 endif 173 else 174 gdk_pixbuf_conf.set('_GDK_PIXBUF_EXTERN', '__attribute__((visibility("default"))) extern') 175 test_cflags += ['-fvisibility=hidden'] 176 endif 177endif 178 179common_cflags += cc.get_supported_arguments(test_cflags) 180 181if host_machine.system() == 'linux' 182 # Additional linker flags 183 test_ldflags = ['-Wl,-Bsymbolic', '-Wl,-z,relro', '-Wl,-z,now'] 184 common_ldflags += cc.get_supported_link_arguments(test_ldflags) 185 gdk_pixbuf_conf.set('OS_LINUX', 1) 186endif 187 188if host_machine.system() == 'darwin' 189 # Maintain compatibility with autotools on macOS 190 common_ldflags += [ '-compatibility_version', darwin_versions[0], '-current_version', darwin_versions[1]] 191 gdk_pixbuf_conf.set('OS_DARWIN', 1) 192endif 193 194# On non-Windows/macOS systems we always required shared-mime-info and GIO 195# shared_mime_dep = [] 196shared_mime_dep = [] 197if get_option('gio_sniffing') and host_system != 'windows' and host_system != 'darwin' 198 shared_mime_dep += dependency('shared-mime-info') 199 gdk_pixbuf_conf.set('GDK_PIXBUF_USE_GIO_MIME', 1) 200endif 201 202# Check if medialib is available 203medialib_dep = cc.find_library('mlib', required: false) 204if medialib_dep.found() 205 if cc.has_function('mlib_ImageSetStruct', dependencies: medialib_dep) 206 gdk_pixbuf_conf.set('USE_MEDIALIB', 1) 207 208 if cc.has_function('mlib_VideoColorRGBint_to_BGRAint', dependencies: medialib_dep) 209 gdk_pixbuf_conf.set('USE_MEDIALIB25', 1) 210 endif 211 else 212 medialib_dep = [] 213 endif 214endif 215 216gdk_pixbuf_deps = [ mathlib_dep, glib_dep, gobject_dep, gmodule_dep, gio_dep, 217 shared_mime_dep, medialib_dep ] 218 219# Check if we can build shared modules 220if gmodule_dep.type_name() == 'pkgconfig' 221 build_modules = gmodule_dep.get_pkgconfig_variable('gmodule_supported') == 'true' 222else 223 build_modules = subproject('glib').get_variable('g_module_impl') != '0' 224endif 225gdk_pixbuf_conf.set('USE_GMODULE', build_modules) 226 227# Check which loaders should be built into gdk-pixbuf 228builtin_loaders = get_option('builtin_loaders').split(',') 229 230# If 'all' is specified for builtin_loaders, build all 231# buildable loaders into gdk-pixbuf 232builtin_all_loaders = false 233if builtin_loaders == [ 'all' ] 234 builtin_all_loaders = true 235endif 236 237# Loader dependencies 238enabled_loaders = [] 239loaders_deps = [] 240 241if get_option('png') 242 # We have a vast selection of libpng versions to choose from 243 foreach png: [ 'libpng16', 'libpng15', 'libpng14', 'libpng13', 'libpng12', 'libpng10' ] 244 if not enabled_loaders.contains('png') 245 png_dep = dependency(png, required: false) 246 if png_dep.found() 247 enabled_loaders += 'png' 248 loaders_deps += png_dep 249 endif 250 endif 251 endforeach 252 253 if not enabled_loaders.contains('png') 254 if cc.get_id() == 'msvc' and cc.has_header('png.h') 255 # MSVC: First look for the DLL + import .lib build of libpng, 256 # which is normally libpngxx.lib, when libpng's pkg-config can't 257 # be found, which is quite normal on MSVC. 258 foreach png: [ 'libpng16', 'libpng15', 'libpng14', 'libpng12', 'libpng13', 'libpng10' ] 259 if not enabled_loaders.contains('png') 260 png_dep = cc.find_library(png, required: false) 261 if png_dep.found() 262 enabled_loaders += 'png' 263 loaders_deps += png_dep 264 endif 265 endif 266 endforeach 267 268 # If we still can't find libpng, try looking for the static libpng.lib, 269 # which means we need to ensure we have the static zlib .lib as well 270 if not enabled_loaders.contains('png') 271 png_dep = cc.find_library('libpng', required: false) 272 zlib_dep = cc.find_library('zlib', required: false) 273 if png_dep.found() and zlib_dep.found() 274 enabled_loaders += 'png' 275 loaders_deps += [ png_dep, zlib_dep ] 276 endif 277 endif 278 endif 279 280 # Finally, look for the dependency in a fallback subproject if allowed by 281 # the --wrap-mode option. We don't directly call subproject() here because 282 # that will bypass --wrap-mode and cause issues for distro packagers. 283 # See: https://mesonbuild.com/Reference-manual.html#dependency 284 if not png_dep.found() 285 png_dep = dependency('', required: false, fallback: ['libpng', 'png_dep']) 286 if png_dep.found() 287 enabled_loaders += 'png' 288 loaders_deps += png_dep 289 endif 290 endif 291 endif 292endif 293 294# On Windows, check whether we are building the native Windows loaders 295# (it is an "all-or-nothing" option for BMP, EMF, GIF, ICO, JPEG, TIFF and WMF) 296# Note that we currently do not use the native Windows loaders to handle PNG and 297# JPEG2000 images 298if host_system == 'windows' 299 native_windows_loaders = get_option('native_windows_loaders') 300else 301 native_windows_loaders = false 302endif 303 304if native_windows_loaders 305 loaders_deps += cc.find_library('gdiplus') 306 loaders_deps += cc.find_library('ole32') 307 enabled_loaders += 'gdiplus' 308endif 309 310# Don't check and build the jpeg loader if native_windows_loaders is true 311if get_option('jpeg') and not native_windows_loaders 312 if cc.has_header('jpeglib.h') 313 jpeg_dep = cc.find_library('jpeg', required: false) 314 if cc.get_id() == 'msvc' and not jpeg_dep.found() 315 # The IJG JPEG library builds the .lib file as libjpeg.lib in its MSVC build system, 316 # so look for it as well when jpeg.lib cannot be found 317 jpeg_dep = cc.find_library('libjpeg', required: false) 318 endif 319 if jpeg_dep.found() and cc.has_function('jpeg_destroy_decompress', dependencies: jpeg_dep) 320 enabled_loaders += 'jpeg' 321 loaders_deps += jpeg_dep 322 323 gdk_pixbuf_conf.set('HAVE_PROGRESSIVE_JPEG', 324 cc.has_function('jpeg_simple_progression', 325 dependencies: jpeg_dep)) 326 endif 327 endif 328endif 329 330# Don't check and build the tiff loader if native_windows_loaders is true 331if get_option('tiff') and not native_windows_loaders 332 tiff_dep = dependency('libtiff-4', required: false) 333 if not tiff_dep.found() 334 # Fallback when no pkg-config file is found for libtiff on MSVC, which is quite normal 335 if cc.get_id() == 'msvc' and cc.has_header('tiff.h') 336 # First look for the DLL builds of libtiff, then the static builds 337 tiff_dep = cc.find_library('libtiff_i', required: false) 338 339 if not tiff_dep.found() 340 # For the static lib, zlib and libjpeg .lib's have been looked for first, and 341 # they are optional for libtiff 342 tiff_dep = cc.find_library('libtiff', required: false) 343 endif 344 endif 345 endif 346 if tiff_dep.found() 347 enabled_loaders += 'tiff' 348 loaders_deps += tiff_dep 349 endif 350endif 351 352jasper_extra_cflags = [] 353 354if get_option('jasper') 355 has_jasper_header = false 356 357 if cc.get_id() == 'msvc' 358 # We must define JAS_WIN_MSVC_BUILD before including jasper/jasper.h on MSVC 359 jasper_msvc_macro = 'JAS_WIN_MSVC_BUILD' 360 has_jasper_header = cc.has_header('jasper/jasper.h', prefix: '#define @0@'.format(jasper_msvc_macro)) 361 jasper_extra_cflags = [ '-D@0@'.format(jasper_msvc_macro) ] 362 else 363 has_jasper_header = cc.has_header('jasper/jasper.h') 364 endif 365 366 if has_jasper_header 367 jasper_dep = cc.find_library('jasper', required: false) 368 if not jasper_dep.found() 369 if cc.get_id() == 'msvc' 370 # on MSVC, we need to look for libjasper.lib if jasper.lib is not found, 371 # which corresponds to what libjasper's MSVC projects produce 372 jasper_dep = cc.find_library('libjasper', required: false) 373 endif 374 endif 375 if jasper_dep.found() and cc.has_function('jas_init', dependencies: jasper_dep) 376 enabled_loaders += 'jasper' 377 loaders_deps += jasper_dep 378 endif 379 endif 380endif 381 382# Determine whether we enable application bundle relocation support, and we use 383# this always on Windows 384if host_system == 'windows' 385 relocatable = true 386else 387 relocatable = get_option('relocatable') 388endif 389 390if relocatable 391 add_project_arguments([ '-DGDK_PIXBUF_RELOCATABLE' ], language: 'c') 392endif 393 394gdk_pixbuf_conf.set_quoted('GETTEXT_PACKAGE', meson.project_name()) 395 396configure_file(output: 'config.h', configuration: gdk_pixbuf_conf) 397add_project_arguments([ '-DHAVE_CONFIG_H=1' ], language: 'c') 398 399root_inc = include_directories('.') 400 401# Auxiliary scripts 402gen_resources = find_program('build-aux/gen-resources.py') 403gen_installed_test = find_program('build-aux/gen-installed-test.py') 404gen_thumbnailer = find_program('build-aux/gen-thumbnailer.py') 405 406gnome = import('gnome') 407 408subdir('gdk-pixbuf') 409 410gdkpixbuf_xlib_inc = [] 411if get_option('x11') 412 x11_dep = dependency('x11') 413 subdir('contrib/gdk-pixbuf-xlib') 414endif 415 416# i18n 417subdir('po') 418 419if not meson.is_cross_build() 420 subdir('thumbnailer') 421endif 422 423# Documentation 424subdir('docs') 425 426if not meson.is_cross_build() 427 # On Visual Studio, we don't normally have a shell interpreter, so use a .bat 428 if cc.get_id() == 'msvc' 429 meson.add_install_script('build-aux/post-install.bat', 430 gdk_pixbuf_bindir, 431 gdk_pixbuf_libdir, 432 gdk_pixbuf_binary_version, 433 ) 434 else 435 meson.add_install_script('build-aux/post-install.sh', 436 gdk_pixbuf_bindir, 437 gdk_pixbuf_libdir, 438 gdk_pixbuf_binary_version, 439 ) 440 endif 441endif 442 443summary = [ 444 '', 445 'GDK-Pixbuf @0@'.format(meson.project_version()), 446 '==================', 447 ' prefix: @0@'.format(gdk_pixbuf_prefix), 448 ' libdir: @0@'.format(gdk_pixbuf_libdir), 449 ' datadir: @0@'.format(gdk_pixbuf_datadir), 450 ' libexecdir: @0@'.format(gdk_pixbuf_libexecdir), 451 '', 452 ' enabled loaders: @0@'.format(' '.join(enabled_loaders)), 453 '', 454 ' documentation: @0@'.format(get_option('docs')), 455 ' man pages: @0@'.format(get_option('man')), 456 ' introspection: @0@'.format(get_option('gir')), 457 ' x11: @0@'.format(get_option('x11')), 458 ' installed tests: @0@'.format(get_option('installed_tests')), 459 ' relocatable: @0@'.format(get_option('relocatable')), 460 '', 461] 462message('\n'.join(summary)) 463