meson.build 67.5 KB
Newer Older
1
project('glib', 'c', 'cpp',
2
  version : '2.61.1',
3
  meson_version : '>= 0.48.0',
4
  default_options : [
5
    'buildtype=debugoptimized',
6 7 8 9
    'warning_level=1',
    'c_std=gnu89'
  ]
)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
10 11

cc = meson.get_compiler('c')
12
cxx = meson.get_compiler('cpp')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
13

14 15
cc_can_run = not meson.is_cross_build() or meson.has_exe_wrapper()

16 17 18 19 20
if cc.get_id() == 'msvc'
  # Ignore several spurious warnings for things glib does very commonly
  # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
  # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
  # NOTE: Only add warnings here if you are sure they're spurious
21 22
  add_project_arguments('/wd4035', '/wd4715', '/wd4116',
    '/wd4046', '/wd4068', '/wo4090', '/FImsvc_recommended_pragmas.h',language : 'c')
23 24 25
  # Disable SAFESEH with MSVC for plugins and libs that use external deps that
  # are built with MinGW
  noseh_link_args = ['/SAFESEH:NO']
26 27
  # Set the input and exec encoding to utf-8, like is the default with GCC
  add_project_arguments(cc.get_supported_arguments(['/utf-8']), language: 'c')
28 29 30 31
else
  noseh_link_args = []
  # -mms-bitfields vs -fnative-struct ?
endif
Jussi Pakkanen's avatar
Jussi Pakkanen committed
32

33
host_system = host_machine.system()
34

35
glib_version = meson.project_version()
Patrick Griffis's avatar
Patrick Griffis committed
36
glib_api_version = '2.0'
37
version_arr = glib_version.split('.')
38 39 40 41 42 43
major_version = version_arr[0].to_int()
minor_version = version_arr[1].to_int()
micro_version = version_arr[2].to_int()

interface_age = minor_version.is_odd() ? 0 : micro_version
binary_age = 100 * minor_version + micro_version
44 45 46 47

soversion = 0
# Maintain compatibility with previous libtool versioning
# current = minor * 100 + micro
48 49 50
current = binary_age - interface_age
library_version = '@0@.@1@.@2@'.format(soversion, current, interface_age)
darwin_versions = [current + 1, '@0@.@1@'.format(current + 1, interface_age)]
51 52 53 54 55 56 57 58

configinc = include_directories('.')
glibinc = include_directories('glib')
gobjectinc = include_directories('gobject')
gmoduleinc = include_directories('gmodule')
gioinc = include_directories('gio')

glib_prefix = get_option('prefix')
59
glib_bindir = join_paths(glib_prefix, get_option('bindir'))
60
glib_libdir = join_paths(glib_prefix, get_option('libdir'))
Xavier Claessens's avatar
Xavier Claessens committed
61
glib_libexecdir = join_paths(glib_prefix, get_option('libexecdir'))
62 63 64
glib_datadir = join_paths(glib_prefix, get_option('datadir'))
glib_pkgdatadir = join_paths(glib_datadir, 'glib-2.0')
glib_includedir = join_paths(glib_prefix, get_option('includedir'))
65 66 67 68
glib_giomodulesdir = get_option('gio_module_dir')
if glib_giomodulesdir == ''
  glib_giomodulesdir = join_paths(glib_libdir, 'gio', 'modules')
endif
69

70
glib_pkgconfigreldir = join_paths(glib_libdir, 'pkgconfig')
71

Xavier Claessens's avatar
Xavier Claessens committed
72 73 74 75
installed_tests_metadir = join_paths(glib_datadir, 'installed-tests', meson.project_name())
installed_tests_execdir = join_paths(glib_libexecdir, 'installed-tests', meson.project_name())
installed_tests_enabled = get_option('installed_tests')
installed_tests_template = files('template.test.in')
76
installed_tests_template_tap = files('template-tap.test.in')
Xavier Claessens's avatar
Xavier Claessens committed
77

78 79
add_project_arguments('-D_GNU_SOURCE', language: 'c')

80 81
# Disable strict aliasing;
# see https://bugzilla.gnome.org/show_bug.cgi?id=791622
82 83 84
if cc.has_argument('-fno-strict-aliasing')
  add_project_arguments('-fno-strict-aliasing', language: 'c')
endif
85

86 87 88
########################
# Configuration begins #
########################
Jussi Pakkanen's avatar
Jussi Pakkanen committed
89 90 91
glib_conf = configuration_data()
glibconfig_conf = configuration_data()

92 93 94 95
# accumulated list of defines as we check for them, so we can easily
# use them later in test programs (autoconf does this automatically)
glib_conf_prefix = ''

Jussi Pakkanen's avatar
Jussi Pakkanen committed
96 97 98
glib_conf.set('GLIB_MAJOR_VERSION', major_version)
glib_conf.set('GLIB_MINOR_VERSION', minor_version)
glib_conf.set('GLIB_MICRO_VERSION', micro_version)
99 100
glib_conf.set('GLIB_INTERFACE_AGE', interface_age)
glib_conf.set('GLIB_BINARY_AGE', binary_age)
101
glib_conf.set_quoted('GETTEXT_PACKAGE', 'glib20')
102
glib_conf.set_quoted('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new')
103 104 105 106 107
glib_conf.set_quoted('PACKAGE_NAME', 'glib')
glib_conf.set_quoted('PACKAGE_STRING', 'glib @0@'.format(meson.project_version()))
glib_conf.set_quoted('PACKAGE_TARNAME', 'glib')
glib_conf.set_quoted('PACKAGE_URL', '')
glib_conf.set_quoted('PACKAGE_VERSION', meson.project_version())
Jussi Pakkanen's avatar
Jussi Pakkanen committed
108
glib_conf.set('ENABLE_NLS', 1)
109

110 111 112
# used by the .rc.in files
glibconfig_conf.set('LT_CURRENT_MINUS_AGE', soversion)

113
glib_conf.set('_GNU_SOURCE', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
114

115 116 117 118 119
if host_system == 'windows'
  # Poll doesn't work on devices on Windows
  glib_conf.set('BROKEN_POLL', true)
endif

120 121 122 123 124 125 126 127
if host_system == 'windows' and cc.get_id() != 'msvc'
  # FIXME: Ideally we shouldn't depend on this on Windows and should use
  # 64 bit capable Windows API that also works with MSVC.
  # The autotools build did set this for mingw and while meson sets it
  # for gcc/clang by default, it doesn't do so on Windows.
  glib_conf.set('_FILE_OFFSET_BITS', 64)
endif

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
# Check for GNU visibility attributes
g_have_gnuc_visibility = cc.compiles('''
  void
  __attribute__ ((visibility ("hidden")))
       f_hidden (void)
  {
  }
  void
  __attribute__ ((visibility ("internal")))
       f_internal (void)
  {
  }
  void
  __attribute__ ((visibility ("protected")))
       f_protected (void)
  {
  }
  void
  __attribute__ ((visibility ("default")))
       f_default (void)
  {
  }
  int main (void)
  {
    f_hidden();
    f_internal();
    f_protected();
    f_default();
    return 0;
  }
  ''',
  # Not supported by MSVC, but MSVC also won't support visibility,
  # so it's OK to pass -Werror explicitly. Replace with
  # override_options : 'werror=true' once that is supported
  args: ['-Werror'],
  name : 'GNU C visibility attributes test')

if g_have_gnuc_visibility
  glibconfig_conf.set('G_HAVE_GNUC_VISIBILITY', '1')
endif

169
# Detect and set symbol visibility
170
glib_hidden_visibility_args = []
171
if get_option('default_library') != 'static'
LRN's avatar
LRN committed
172
  if host_system == 'windows' or host_system == 'cygwin'
173 174 175
    glib_conf.set('DLL_EXPORT', true)
    if cc.get_id() == 'msvc'
      glib_conf.set('_GLIB_EXTERN', '__declspec(dllexport) extern')
176
    elif cc.has_argument('-fvisibility=hidden')
177
      glib_conf.set('_GLIB_EXTERN', '__attribute__((visibility("default"))) __declspec(dllexport) extern')
178
      glib_hidden_visibility_args = ['-fvisibility=hidden']
179
    endif
180
  elif cc.has_argument('-fvisibility=hidden')
181
    glib_conf.set('_GLIB_EXTERN', '__attribute__((visibility("default"))) extern')
182
    glib_hidden_visibility_args = ['-fvisibility=hidden']
183 184 185
  endif
endif

186 187 188 189 190
if host_system == 'windows' and get_option('default_library') == 'static'
    glibconfig_conf.set('GLIB_STATIC_COMPILATION', '1')
    glibconfig_conf.set('GOBJECT_STATIC_COMPILATION', '1')
endif

LRN's avatar
LRN committed
191 192 193 194 195 196
# Cygwin glib port maintainers made it clear
# (via the patches they apply) that they want no
# part of glib W32 code, therefore we do not define
# G_PLATFORM_WIN32 for host_system == 'cygwin'.
# This makes G_PLATFORM_WIN32 a synonym for
# G_OS_WIN32.
197
if host_system == 'windows'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
198
  glib_os = '''#define G_OS_WIN32
199
#define G_PLATFORM_WIN32'''
LRN's avatar
LRN committed
200
elif host_system == 'cygwin'
201
  glib_os = '''#define G_OS_UNIX
LRN's avatar
LRN committed
202
#define G_WITH_CYGWIN'''
Jussi Pakkanen's avatar
Jussi Pakkanen committed
203 204 205 206 207
else
  glib_os = '#define G_OS_UNIX'
endif
glibconfig_conf.set('glib_os', glib_os)

208 209 210 211
# We need to know the build type to determine what .lib files we need on Visual Studio
# for dependencies that don't normally come with pkg-config files for Visual Studio builds
buildtype = get_option('buildtype')

212 213 214 215 216 217 218 219 220
glib_debug_cflags = []
if buildtype.startswith('debug')
  glib_debug_cflags += ['-DG_ENABLE_DEBUG']
elif buildtype == 'release'
  glib_debug_cflags += ['-DG_DISABLE_CAST_CHECKS']
endif

add_project_arguments(glib_debug_cflags, language: 'c')

221 222 223
# check for header files

headers = [
224
  'alloca.h',
225 226
  'crt_externs.h',
  'dirent.h', # MSC does not come with this by default
227
  'float.h',
228
  'fstab.h',
229
  'grp.h',
230 231 232 233 234 235 236
  'inttypes.h',
  'limits.h',
  'linux/magic.h',
  'locale.h',
  'mach/mach_time.h',
  'memory.h',
  'mntent.h',
237
  'poll.h',
238 239
  'pwd.h',
  'sched.h',
240
  'spawn.h',
241 242 243 244
  'stdint.h',
  'stdlib.h',
  'string.h',
  'strings.h',
245
  'sys/auxv.h',
246 247 248 249 250 251 252
  'sys/event.h',
  'sys/filio.h',
  'sys/inotify.h',
  'sys/mkdev.h',
  'sys/mntctl.h',
  'sys/mnttab.h',
  'sys/mount.h',
253 254 255 256
  'sys/param.h',
  'sys/resource.h',
  'sys/select.h',
  'sys/statfs.h',
257
  'sys/stat.h',
258
  'sys/statvfs.h',
259
  'sys/sysctl.h',
260
  'sys/time.h', # MSC does not come with this by default
261
  'sys/times.h',
262 263 264 265 266
  'sys/types.h',
  'sys/uio.h',
  'sys/vfs.h',
  'sys/vfstab.h',
  'sys/vmount.h',
267
  'sys/wait.h',
268
  'termios.h',
269 270
  'unistd.h',
  'values.h',
271
  'wchar.h',
272
  'xlocale.h',
273 274 275
]

foreach h : headers
276 277 278 279
  if cc.has_header(h)
    define = 'HAVE_' + h.underscorify().to_upper()
    glib_conf.set(define, 1)
    glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(define)
280 281 282
  endif
endforeach

283 284 285 286 287 288 289
# FIXME: Use cc.check_header from Meson 0.47.
# FreeBSD includes a malloc.h which always throw compilation error.
if cc.compiles('#include <malloc.h>', name : 'malloc.h')
  glib_conf.set('HAVE_MALLOC_H', 1)
  glib_conf_prefix = glib_conf_prefix + '#define HAVE_MALLOC_H 1\n'
endif

290 291 292 293
if cc.has_header('linux/netlink.h')
  glib_conf.set('HAVE_NETLINK', 1)
endif

294
if glib_conf.has('HAVE_LOCALE_H')
295
  if cc.has_header_symbol('locale.h', 'LC_MESSAGES')
296 297
    glib_conf.set('HAVE_LC_MESSAGES', 1)
  endif
Jussi Pakkanen's avatar
Jussi Pakkanen committed
298
endif
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317

struct_stat_blkprefix = '''
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
'''

struct_members = [
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
  [ 'stat', 'st_mtimensec' ],
  [ 'stat', 'st_mtim.tv_nsec' ],
  [ 'stat', 'st_atimensec' ],
  [ 'stat', 'st_atim.tv_nsec' ],
  [ 'stat', 'st_ctimensec' ],
  [ 'stat', 'st_ctim.tv_nsec' ],
  [ 'stat', 'st_birthtime' ],
  [ 'stat', 'st_birthtimensec' ],
  [ 'stat', 'st_birthtim' ],
  [ 'stat', 'st_birthtim.tv_nsec' ],
  [ 'stat', 'st_blksize', struct_stat_blkprefix ],
  [ 'stat', 'st_blocks', struct_stat_blkprefix ],
  [ 'statfs', 'f_fstypename', struct_stat_blkprefix ],
  [ 'statfs', 'f_bavail', struct_stat_blkprefix ],
  [ 'dirent', 'd_type', '''#include <sys/types.h>
                           #include <dirent.h>''' ],
334 335 336 337
  [ 'statvfs', 'f_basetype', '#include <sys/statvfs.h>' ],
  [ 'statvfs', 'f_fstypename', '#include <sys/statvfs.h>' ],
  [ 'tm', 'tm_gmtoff', '#include <time.h>' ],
  [ 'tm', '__tm_gmtoff', '#include <time.h>' ],
338 339 340 341
]

foreach m : struct_members
  header_check_prefix = glib_conf_prefix
342 343
  if m.length() == 3
    header_check_prefix = header_check_prefix + m[2]
344 345 346 347
  else
    header_check_prefix = header_check_prefix + '#include <sys/stat.h>'
  endif
  if cc.has_member('struct ' + m[0], m[1], prefix : header_check_prefix)
348 349 350
    define = 'HAVE_STRUCT_@0@_@1@'.format(m[0].to_upper(), m[1].underscorify().to_upper())
    glib_conf.set(define, 1)
    glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(define)
351 352 353 354
  else
  endif
endforeach

355 356
# Compiler flags
if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
357
  warning_c_args = [
358 359
    '-Wall',
    '-Wduplicated-branches',
360
    '-Wimplicit-fallthrough',
361
    '-Wmisleading-indentation',
362
    '-Wstrict-prototypes',
363
    '-Wunused',
364 365
    # Due to maintained deprecated code, we do not want to see unused parameters
    '-Wno-unused-parameter',
366 367 368
    # Due to pervasive use of things like GPOINTER_TO_UINT(), we do not support
    # building with -Wbad-function-cast.
    '-Wno-bad-function-cast',
369
    '-Wno-cast-function-type',
370 371 372
    # Due to function casts through (void*) we cannot support -Wpedantic:
    # https://wiki.gnome.org/Projects/GLib/CompilerRequirements#Function_pointer_conversions.
    '-Wno-pedantic',
373 374 375 376 377 378 379 380
    '-Werror=declaration-after-statement',
    '-Werror=format=2',
    '-Werror=implicit-function-declaration',
    '-Werror=init-self',
    '-Werror=missing-include-dirs',
    '-Werror=missing-prototypes',
    '-Werror=pointer-arith',
  ]
381
  warning_c_link_args = [
382 383 384
    '-Wl,-z,nodelete',
  ]
  if get_option('bsymbolic_functions')
385
    warning_c_link_args += ['-Wl,-Bsymbolic-functions']
386
  endif
387
else
388 389
  warning_c_args = []
  warning_c_link_args = []
390 391
endif

392
add_project_arguments(cc.get_supported_arguments(warning_c_args), language: 'c')
393 394 395 396 397 398 399

# FIXME: We cannot build some of the GResource tests with -z nodelete, which
# means we cannot use that flag in add_project_link_arguments(), and must add
# it to the relevant targets manually. We do the same with -Bsymbolic-functions
# because that is what the autotools build did.
# See https://github.com/mesonbuild/meson/pull/3520 for a way to eventually
# improve this.
400
glib_link_flags = cc.get_supported_link_arguments(warning_c_link_args)
401

402
# Windows Support (7+)
403 404 405 406
if host_system == 'windows'
  glib_conf.set('_WIN32_WINNT', '0x0601')
endif

407
functions = [
408 409 410
  'endmntent',
  'endservent',
  'fallocate',
411 412
  'fchmod',
  'fchown',
413 414
  'fdwalk',
  'fsync',
415
  'getauxval',
416
  'getc_unlocked',
417
  'getfsstat',
418 419 420 421
  'getgrgid_r',
  'getmntent_r',
  'getpwuid_r',
  'getresuid',
422 423
  'getvfsstat',
  'gmtime_r',
424 425 426 427 428 429 430 431 432 433
  'hasmntopt',
  'inotify_init1',
  'issetugid',
  'kevent',
  'kqueue',
  'lchmod',
  'lchown',
  'link',
  'localtime_r',
  'lstat',
434
  'mbrtowc',
435 436
  'memalign',
  'mmap',
437
  'newlocale',
438 439 440 441 442 443 444 445 446 447 448
  'pipe2',
  'poll',
  'prlimit',
  'readlink',
  'recvmmsg',
  'sendmmsg',
  'setenv',
  'setmntent',
  'strerror_r',
  'strnlen',
  'strsignal',
449 450 451
  'strtod_l',
  'strtoll_l',
  'strtoull_l',
452 453 454 455 456 457 458 459 460 461 462
  'symlink',
  'timegm',
  'unsetenv',
  'uselocale',
  'utimes',
  'valloc',
  'vasprintf',
  'vsnprintf',
  'wcrtomb',
  'wcslen',
  'wcsnlen',
463 464
  'sysctlbyname',
  '_NSGetEnviron',
465 466 467
]

if glib_conf.has('HAVE_SYS_STATVFS_H')
468
  functions += ['statvfs']
469 470
else
  have_func_statvfs = false
Jussi Pakkanen's avatar
Jussi Pakkanen committed
471
endif
472
if glib_conf.has('HAVE_SYS_STATFS_H') or glib_conf.has('HAVE_SYS_MOUNT_H')
473
  functions += ['statfs']
474 475
else
  have_func_statfs = false
Jussi Pakkanen's avatar
Jussi Pakkanen committed
476
endif
477

478 479 480 481
if host_system == 'windows'
  iphlpapi_dep = cc.find_library('iphlpapi')
  iphlpapi_funcs = ['if_nametoindex', 'if_indextoname']
  foreach ifunc : iphlpapi_funcs
482 483 484
    iphl_prefix =  '''#define _WIN32_WINNT @0@
      #include <winsock2.h>
      #include <iphlpapi.h>'''.format(glib_conf.get('_WIN32_WINNT'))
485
    if cc.has_function(ifunc,
486
                       prefix : iphl_prefix,
487 488 489 490 491 492 493 494 495 496 497 498 499
                       dependencies : iphlpapi_dep)
      idefine = 'HAVE_' + ifunc.underscorify().to_upper()
      glib_conf.set(idefine, 1)
      glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(idefine)
      set_variable('have_func_' + ifunc, true)
    else
      set_variable('have_func_' + ifunc, false)
    endif
  endforeach
else
  functions += ['if_indextoname', 'if_nametoindex']
endif

500
# AIX splice is something else
501
if host_system != 'aix'
502
  functions += ['splice']
Jussi Pakkanen's avatar
Jussi Pakkanen committed
503
endif
504 505

foreach f : functions
506 507 508 509 510
  if cc.has_function(f)
    define = 'HAVE_' + f.underscorify().to_upper()
    glib_conf.set(define, 1)
    glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(define)
    set_variable('have_func_' + f, true)
511
  else
512
    set_variable('have_func_' + f, false)
513 514 515
  endif
endforeach

516 517
# Check that stpcpy() is usable; must use header
if cc.has_function('stpcpy', prefix : '#include <string.h>')
518 519 520
  glib_conf.set('HAVE_STPCPY', 1)
endif

521 522
# Check that posix_memalign() is usable; must use header
if cc.has_function('posix_memalign', prefix : '#include <stdlib.h>')
523 524 525
  glib_conf.set('HAVE_POSIX_MEMALIGN', 1)
endif

526 527 528 529 530
# Check that posix_spawn() is usable; must use header
if cc.has_function('posix_spawn', prefix : '#include <spawn.h>')
  glib_conf.set('HAVE_POSIX_SPAWN', 1)
endif

531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
# Check whether strerror_r returns char *
if have_func_strerror_r
  if cc.compiles('''#define _GNU_SOURCE
                    #include <string.h>
                    int func (void) {
                      char error_string[256];
                      char *ptr = strerror_r (-2, error_string, 256);
                      char c = *strerror_r (-2, error_string, 256);
                      return c != 0 && ptr != (void*) 0L;
                    }
                 ''',
                 name : 'strerror_r() returns char *')
    glib_conf.set('STRERROR_R_CHAR_P', 1,
                  description: 'Defined if strerror_r returns char *')
  endif
endif

548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
# Special-case these functions that have alternative names on Windows/MSVC
if cc.has_function('snprintf') or cc.has_header_symbol('stdio.h', 'snprintf')
  glib_conf.set('HAVE_SNPRINTF', 1)
  glib_conf_prefix = glib_conf_prefix + '#define HAVE_SNPRINTF 1\n'
elif cc.has_function('_snprintf') or cc.has_header_symbol('stdio.h', '_snprintf')
  hack_define = '1\n#define snprintf _snprintf'
  glib_conf.set('HAVE_SNPRINTF', hack_define)
  glib_conf_prefix = glib_conf_prefix + '#define HAVE_SNPRINTF ' + hack_define
endif

if cc.has_function('strcasecmp')
  glib_conf.set('HAVE_STRCASECMP', 1)
  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP 1\n'
elif cc.has_function('_stricmp')
  hack_define = '1\n#define strcasecmp _stricmp'
  glib_conf.set('HAVE_STRCASECMP', hack_define)
  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP ' + hack_define
endif

if cc.has_function('strncasecmp')
  glib_conf.set('HAVE_STRNCASECMP', 1)
  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRNCASECMP 1\n'
elif cc.has_function('_strnicmp')
  hack_define = '1\n#define strncasecmp _strnicmp'
  glib_conf.set('HAVE_STRNCASECMP', hack_define)
  glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRNCASECMP ' + hack_define
endif

576 577 578 579
if cc.has_header_symbol('sys/sysmacros.h', 'major')
  glib_conf.set('MAJOR_IN_SYSMACROS', 1)
elif cc.has_header_symbol('sys/mkdev.h', 'major')
  glib_conf.set('MAJOR_IN_MKDEV', 1)
580 581
elif cc.has_header_symbol('sys/types.h', 'major')
  glib_conf.set('MAJOR_IN_TYPES', 1)
582 583
endif

584 585 586 587 588 589 590 591 592 593 594 595
if cc.has_header_symbol('dlfcn.h', 'RTLD_LAZY')
  glib_conf.set('HAVE_RTLD_LAZY', 1)
endif

if cc.has_header_symbol('dlfcn.h', 'RTLD_NOW')
  glib_conf.set('HAVE_RTLD_NOW', 1)
endif

if cc.has_header_symbol('dlfcn.h', 'RTLD_GLOBAL')
  glib_conf.set('HAVE_RTLD_GLOBAL', 1)
endif

LRN's avatar
LRN committed
596
have_rtld_next = false
597
if cc.has_header_symbol('dlfcn.h', 'RTLD_NEXT', args: '-D_GNU_SOURCE')
LRN's avatar
LRN committed
598 599 600 601
  have_rtld_next = true
  glib_conf.set('HAVE_RTLD_NEXT', 1)
endif

602 603 604 605 606 607 608 609 610 611
# Check whether to use statfs or statvfs
# Some systems have both statfs and statvfs, pick the most "native" for these
if have_func_statfs and have_func_statvfs
  # on solaris and irix, statfs doesn't even have the f_bavail field
  if not glib_conf.has('HAVE_STRUCT_STATFS_F_BAVAIL')
    have_func_statfs = false
  else
    # at least on linux, statfs is the actual syscall
    have_func_statvfs = false
  endif
Jussi Pakkanen's avatar
Jussi Pakkanen committed
612
endif
613 614 615 616 617 618
if have_func_statfs
  glib_conf.set('USE_STATFS', 1)
  stat_func_to_use = 'statfs'
elif have_func_statvfs
  glib_conf.set('USE_STATVFS', 1)
  stat_func_to_use = 'statvfs'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
619
else
620
  stat_func_to_use = 'neither'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
621
endif
622 623
message('Checking whether to use statfs or statvfs .. ' + stat_func_to_use)

624 625 626 627 628 629 630 631
if host_system == 'linux'
  if cc.has_function('mkostemp',
                     prefix: '''#define _GNU_SOURCE
                                #include <stdlib.h>''')
    glib_conf.set('HAVE_MKOSTEMP', 1)
  endif
endif

632
osx_ldflags = []
633
glib_have_os_x_9_or_later = false
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
glib_have_carbon = false
glib_have_cocoa = false
if host_system == 'darwin'
  add_languages('objc')
  objcc = meson.get_compiler('objc')

  osx_ldflags += ['-Wl,-framework,CoreFoundation']

  # Mac OS X Carbon support
  glib_have_carbon = objcc.compiles('''#include <Carbon/Carbon.h>
                                       #include <CoreServices/CoreServices.h>''',
                                    name : 'Mac OS X Carbon support')

  if glib_have_carbon
    glib_conf.set('HAVE_CARBON', true)
    osx_ldflags += '-Wl,-framework,Carbon'
    glib_have_os_x_9_or_later = objcc.compiles('''#include <AvailabilityMacros.h>
                                                  #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
                                                  #error Compiling for minimum OS X version before 10.9
                                                  #endif''',
                                               name : 'OS X 9 or later')
  endif
656

657 658 659 660 661 662
  # Mac OS X Cocoa support
  glib_have_cocoa = objcc.compiles('''#include <Cocoa/Cocoa.h>
                                      #ifdef GNUSTEP_BASE_VERSION
                                      #error "Detected GNUstep, not Cocoa"
                                      #endif''',
                                   name : 'Mac OS X Cocoa support')
663

664 665 666 667
  if glib_have_cocoa
    glib_conf.set('HAVE_COCOA', true)
    osx_ldflags += ['-Wl,-framework,Foundation', '-Wl,-framework,AppKit']
  endif
668

669 670 671 672
  # FIXME: libgio mix C and objC source files and there is no way to reliably
  # know which language flags it's going to use to link. Add to both languages
  # for now. See https://github.com/mesonbuild/meson/issues/3585.
  add_project_link_arguments(osx_ldflags, language : ['objc', 'c'])
673 674
endif

675 676 677 678 679 680 681 682 683
# Check for futex(2)
if cc.links('''#include <linux/futex.h>
               #include <sys/syscall.h>
               #include <unistd.h>
               int main (int argc, char ** argv) {
                 syscall (__NR_futex, NULL, FUTEX_WAKE, FUTEX_WAIT);
                 return 0;
               }''', name : 'futex(2) system call')
  glib_conf.set('HAVE_FUTEX', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
684
endif
685 686 687 688 689 690 691 692 693

# Check for eventfd(2)
if cc.links('''#include <sys/eventfd.h>
               #include <unistd.h>
               int main (int argc, char ** argv) {
                 eventfd (0, EFD_CLOEXEC);
                 return 0;
               }''', name : 'eventfd(2) system call')
  glib_conf.set('HAVE_EVENTFD', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
694
endif
695 696 697 698 699 700 701

clock_gettime_test_code = '''
  #include <time.h>
  struct timespec t;
  int main (int argc, char ** argv) {
    return clock_gettime(CLOCK_REALTIME, &t);
  }'''
702
librt = []
703 704 705 706
if cc.links(clock_gettime_test_code, name : 'clock_gettime')
  glib_conf.set('HAVE_CLOCK_GETTIME', 1)
elif cc.links(clock_gettime_test_code, args : '-lrt', name : 'clock_gettime in librt')
  glib_conf.set('HAVE_CLOCK_GETTIME', 1)
707
  librt = cc.find_library('rt')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
708
endif
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727

# if statfs() takes 2 arguments (Posix) or 4 (Solaris)
if have_func_statfs
  if cc.compiles(glib_conf_prefix + '''
                 #include <unistd.h>
                        #ifdef HAVE_SYS_PARAM_H
                        #include <sys/param.h>
                        #endif
                        #ifdef HAVE_SYS_VFS_H
                        #include <sys/vfs.h>
                        #endif
                        #ifdef HAVE_SYS_MOUNT_H
                        #include <sys/mount.h>
                        #endif
                        #ifdef HAVE_SYS_STATFS_H
                        #include <sys/statfs.h>
                        #endif
                        void some_func (void) {
                          struct statfs st;
728
                          statfs("/", &st);
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
                        }''', name : 'number of arguments to statfs() (n=2)')
    glib_conf.set('STATFS_ARGS', 2)
  elif cc.compiles(glib_conf_prefix + '''
                   #include <unistd.h>
                          #ifdef HAVE_SYS_PARAM_H
                          #include <sys/param.h>
                          #endif
                          #ifdef HAVE_SYS_VFS_H
                          #include <sys/vfs.h>
                          #endif
                          #ifdef HAVE_SYS_MOUNT_H
                          #include <sys/mount.h>
                          #endif
                          #ifdef HAVE_SYS_STATFS_H
                          #include <sys/statfs.h>
                          #endif
                          void some_func (void) {
                            struct statfs st;
747
                            statfs("/", &st, sizeof (st), 0);
748 749 750 751 752
                          }''', name : 'number of arguments to statfs() (n=4)')
    glib_conf.set('STATFS_ARGS', 4)
  else
    error('Unable to determine number of arguments to statfs()')
  endif
Jussi Pakkanen's avatar
Jussi Pakkanen committed
753
endif
754 755 756 757 758 759 760 761 762 763

# open takes O_DIRECTORY as an option
#AC_MSG_CHECKING([])
if cc.compiles('''#include <fcntl.h>
                  #include <sys/types.h>
                  #include <sys/stat.h>],
                  void some_func (void) {
                    open(0, O_DIRECTORY, 0);
                  }''', name : 'open() option O_DIRECTORY')
  glib_conf.set('HAVE_OPEN_O_DIRECTORY', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
764 765
endif

766
# Check whether there is a vsnprintf() function with C99 semantics installed.
767
# (similar tests to AC_FUNC_VSNPRINTF_C99)
768
# Check whether there is a snprintf() function with C99 semantics installed.
769 770 771
# (similar tests to AC_FUNC_SNPRINTF_C99)
# Check whether there is a printf() function with Unix98 semantics installed.
# (similar tests to AC_FUNC_PRINTF_UNIX98)
772 773
have_good_vsnprintf = false
have_good_snprintf = false
774
have_good_printf = false
775

776 777 778 779
if host_system == 'windows' and cc.get_id() == 'msvc'
  # Unfortunately the Visual Studio 2015+ implementations of C99-style
  # snprintf and vsnprintf don't seem to be quite good enough.
  # (Sorry, I don't know exactly what is the problem,
780
  # but it is related to floating point formatting and decimal point vs. comma.)
781 782 783 784
  # The simple tests in AC_FUNC_VSNPRINTF_C99 and AC_FUNC_SNPRINTF_C99 aren't
  # rigorous enough to notice, though.
  glib_conf.set('HAVE_C99_SNPRINTF', false)
  glib_conf.set('HAVE_C99_VSNPRINTF', false)
785
  glib_conf.set('HAVE_UNIX98_PRINTF', false)
786 787 788 789
else
  vsnprintf_c99_test_code = '''
#include <stdio.h>
#include <stdarg.h>
Jussi Pakkanen's avatar
Jussi Pakkanen committed
790

791 792 793 794 795 796
int
doit(char * s, ...)
{
  char buffer[32];
  va_list args;
  int r;
Jussi Pakkanen's avatar
Jussi Pakkanen committed
797

798 799 800
  va_start(args, s);
  r = vsnprintf(buffer, 5, s, args);
  va_end(args);
Jussi Pakkanen's avatar
Jussi Pakkanen committed
801

802 803
  if (r != 7)
    exit(1);
Jussi Pakkanen's avatar
Jussi Pakkanen committed
804

805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
  /* AIX 5.1 and Solaris seems to have a half-baked vsnprintf()
     implementation. The above will return 7 but if you replace
     the size of the buffer with 0, it borks! */
  va_start(args, s);
  r = vsnprintf(buffer, 0, s, args);
  va_end(args);

  if (r != 7)
    exit(1);

  exit(0);
}

int
main(void)
{
  doit("1234567");
  exit(1);
}'''

825 826 827 828 829 830 831 832 833
  if cc_can_run
    rres = cc.run(vsnprintf_c99_test_code, name : 'C99 vsnprintf')
    if rres.compiled() and rres.returncode() == 0
      glib_conf.set('HAVE_C99_VSNPRINTF', 1)
      have_good_vsnprintf = true
    endif
  else
      have_good_vsnprintf = meson.get_cross_property('have_c99_vsnprintf', false)
      glib_conf.set('HAVE_C99_VSNPRINTF', have_good_vsnprintf)
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
  endif

  snprintf_c99_test_code = '''
#include <stdio.h>
#include <stdarg.h>

int
doit()
{
  char buffer[32];
  va_list args;
  int r;

  r = snprintf(buffer, 5, "1234567");

  if (r != 7)
    exit(1);

  r = snprintf(buffer, 0, "1234567");

  if (r != 7)
    exit(1);

  r = snprintf(NULL, 0, "1234567");

  if (r != 7)
    exit(1);

  exit(0);
}
Jussi Pakkanen's avatar
Jussi Pakkanen committed
864

865 866 867 868 869 870 871
int
main(void)
{
  doit();
  exit(1);
}'''

872 873 874 875 876 877 878 879 880
  if cc_can_run
    rres = cc.run(snprintf_c99_test_code, name : 'C99 snprintf')
    if rres.compiled() and rres.returncode() == 0
      glib_conf.set('HAVE_C99_SNPRINTF', 1)
      have_good_snprintf = true
    endif
  else
      have_good_snprintf = meson.get_cross_property('have_c99_snprintf', false)
      glib_conf.set('HAVE_C99_SNPRINTF', have_good_snprintf)
881
  endif
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906

  printf_unix98_test_code = '''
#include <stdio.h>

int
main (void)
{
  char buffer[128];

  sprintf (buffer, "%2\$d %3\$d %1\$d", 1, 2, 3);
  if (strcmp ("2 3 1", buffer) == 0)
    exit (0);
  exit (1);
}'''

  if cc_can_run
    rres = cc.run(printf_unix98_test_code, name : 'Unix98 printf positional parameters')
    if rres.compiled() and rres.returncode() == 0
      glib_conf.set('HAVE_UNIX98_PRINTF', 1)
      have_good_printf = true
    endif
  else
      have_good_printf = meson.get_cross_property('have_unix98_printf', false)
      glib_conf.set('HAVE_UNIX98_PRINTF', have_good_printf)
  endif
Jussi Pakkanen's avatar
Jussi Pakkanen committed
907 908
endif

909
if host_system == 'windows'
910
  glib_conf.set_quoted('EXEEXT', '.exe')
911
else
912
  glib_conf.set('EXEEXT', '')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
913 914
endif

915 916 917
if have_good_vsnprintf and have_good_snprintf and have_good_printf
  # Our printf is 'good' only if vsnpintf()/snprintf()/printf() supports C99 well enough
  glib_conf.set('HAVE_GOOD_PRINTF', 1)
918 919 920 921
else
  glib_conf.set('HAVE_VASPRINTF', 1)
endif

922 923 924
glibconfig_conf.set('GLIB_USING_SYSTEM_PRINTF',
                    have_good_vsnprintf and have_good_snprintf and have_good_printf)

925 926
# Check whether the printf() family supports Unix98 %n$ positional parameters
# AC_FUNC_PRINTF_UNIX98
927
# Nothing uses HAVE_UNIX98_PRINTF
928

929

930 931 932 933 934
# Check for nl_langinfo and CODESET
if cc.links('''#include <langinfo.h>
               int main (int argc, char ** argv) {
                 char *codeset = nl_langinfo (CODESET);
                 return 0;
935 936
               }''', name : 'nl_langinfo and CODESET')
  glib_conf.set('HAVE_LANGINFO_CODESET', 1)
937
  glib_conf.set('HAVE_CODESET', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
938 939
endif

940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
# Check for nl_langinfo and LC_TIME parts that are needed in gdatetime.c
if cc.links('''#include <langinfo.h>
               int main (int argc, char ** argv) {
                 char *str;
                 str = nl_langinfo (PM_STR);
                 str = nl_langinfo (D_T_FMT);
                 str = nl_langinfo (D_FMT);
                 str = nl_langinfo (T_FMT);
                 str = nl_langinfo (T_FMT_AMPM);
                 str = nl_langinfo (MON_1);
                 str = nl_langinfo (ABMON_12);
                 str = nl_langinfo (DAY_1);
                 str = nl_langinfo (ABDAY_7);
                 return 0;
               }''', name : 'nl_langinfo (PM_STR)')
  glib_conf.set('HAVE_LANGINFO_TIME', 1)
endif
if cc.links('''#include <langinfo.h>
               int main (int argc, char ** argv) {
                 char *str;
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT1_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT2_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT3_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT4_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT5_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT6_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT7_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT8_MB);
                 str = nl_langinfo (_NL_CTYPE_OUTDIGIT9_MB);
                 return 0;
               }''', name : 'nl_langinfo (_NL_CTYPE_OUTDIGITn_MB)')
  glib_conf.set('HAVE_LANGINFO_OUTDIGIT', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
973 974
endif

975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
# Check for nl_langinfo and alternative month names
if cc.links('''#ifndef _GNU_SOURCE
              # define _GNU_SOURCE
              #endif
              #include <langinfo.h>
               int main (int argc, char ** argv) {
                 char *str;
                 str = nl_langinfo (ALTMON_1);
                 str = nl_langinfo (ALTMON_2);
                 str = nl_langinfo (ALTMON_3);
                 str = nl_langinfo (ALTMON_4);
                 str = nl_langinfo (ALTMON_5);
                 str = nl_langinfo (ALTMON_6);
                 str = nl_langinfo (ALTMON_7);
                 str = nl_langinfo (ALTMON_8);
                 str = nl_langinfo (ALTMON_9);
                 str = nl_langinfo (ALTMON_10);
                 str = nl_langinfo (ALTMON_11);
                 str = nl_langinfo (ALTMON_12);
                 return 0;
               }''', name : 'nl_langinfo (ALTMON_n)')
  glib_conf.set('HAVE_LANGINFO_ALTMON', 1)
endif

# Check for nl_langinfo and abbreviated alternative month names
if cc.links('''#ifndef _GNU_SOURCE
              # define _GNU_SOURCE
              #endif
              #include <langinfo.h>
               int main (int argc, char ** argv) {
                 char *str;
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
                 str = nl_langinfo (_NL_ABALTMON_1);
                 str = nl_langinfo (_NL_ABALTMON_2);
                 str = nl_langinfo (_NL_ABALTMON_3);
                 str = nl_langinfo (_NL_ABALTMON_4);
                 str = nl_langinfo (_NL_ABALTMON_5);
                 str = nl_langinfo (_NL_ABALTMON_6);
                 str = nl_langinfo (_NL_ABALTMON_7);
                 str = nl_langinfo (_NL_ABALTMON_8);
                 str = nl_langinfo (_NL_ABALTMON_9);
                 str = nl_langinfo (_NL_ABALTMON_10);
                 str = nl_langinfo (_NL_ABALTMON_11);
                 str = nl_langinfo (_NL_ABALTMON_12);
1018
                 return 0;
1019
               }''', name : 'nl_langinfo (_NL_ABALTMON_n)')
1020 1021 1022
  glib_conf.set('HAVE_LANGINFO_ABALTMON', 1)
endif

1023 1024 1025
# Check if C compiler supports the 'signed' keyword
if not cc.compiles('''signed char x;''', name : 'signed')
  glib_conf.set('signed', '/* NOOP */')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1026 1027
endif

1028
# Check if the ptrdiff_t type exists
1029
if cc.has_header_symbol('stddef.h', 'ptrdiff_t')
1030
  glib_conf.set('HAVE_PTRDIFF_T', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1031 1032
endif

1033 1034 1035 1036 1037 1038 1039 1040
# Check for sig_atomic_t type
if cc.links('''#include <signal.h>
               #include <sys/types.h>
               sig_atomic_t val = 42;
               int main (int argc, char ** argv) {
                 return val == 42 ? 0 : 1;
               }''', name : 'sig_atomic_t')
  glib_conf.set('HAVE_SIG_ATOMIC_T', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1041 1042
endif

1043
# Check if 'long long' works
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
# jm_AC_TYPE_LONG_LONG
if cc.compiles('''long long ll = 1LL;
                  int i = 63;
                  int some_func (void) {
                    long long llmax = (long long) -1;
                    return ll << i | ll >> i | llmax / ll | llmax % ll;
                  }''', name : 'long long')
  glib_conf.set('HAVE_LONG_LONG', 1)
  have_long_long = true
else
  have_long_long = false
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1055 1056
endif

1057 1058 1059 1060 1061 1062 1063
# Test whether the compiler supports the 'long double' type.
if cc.compiles('''/* The Stardent Vistra knows sizeof(long double), but does not support it.  */
                  long double foo = 0.0;
                  /* On Ultrix 4.3 cc, long double is 4 and double is 8.  */
                  int array [2*(sizeof(long double) >= sizeof(double)) - 1];''',
               name : 'long double')
  glib_conf.set('HAVE_LONG_DOUBLE', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1064 1065
endif

1066
# Test whether <stddef.h> has the 'wchar_t' type.
1067
if cc.has_header_symbol('stddef.h', 'wchar_t')
1068
  glib_conf.set('HAVE_WCHAR_T', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1069 1070
endif

1071
# Test whether <wchar.h> has the 'wint_t' type.
1072
if cc.has_header_symbol('wchar.h', 'wint_t')
1073
  glib_conf.set('HAVE_WINT_T', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1074 1075
endif

1076
found_uintmax_t = false
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1077

1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
# Define HAVE_INTTYPES_H_WITH_UINTMAX if <inttypes.h> exists,
# doesn't clash with <sys/types.h>, and declares uintmax_t.
# jm_AC_HEADER_INTTYPES_H
if cc.compiles('''#include <sys/types.h>
                  #include <inttypes.h>
                  void some_func (void) {
                    uintmax_t i = (uintmax_t) -1;
                  }''', name : 'uintmax_t in inttypes.h')
  glib_conf.set('HAVE_INTTYPES_H_WITH_UINTMAX', 1)
  found_uintmax_t = true
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1088
endif
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099

# Define HAVE_STDINT_H_WITH_UINTMAX if <stdint.h> exists,
# doesn't clash with <sys/types.h>, and declares uintmax_t.
# jm_AC_HEADER_STDINT_H
if cc.compiles('''#include <sys/types.h>
                  #include <stdint.h>
                  void some_func (void) {
                    uintmax_t i = (uintmax_t) -1;
                  }''', name : 'uintmax_t in stdint.h')
  glib_conf.set('HAVE_STDINT_H_WITH_UINTMAX', 1)
  found_uintmax_t = true
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1100 1101
endif

1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
# Define intmax_t to 'long' or 'long long'
# if it is not already defined in <stdint.h> or <inttypes.h>.
# For simplicity, we assume that a header file defines 'intmax_t' if and
# only if it defines 'uintmax_t'.
if found_uintmax_t
  glib_conf.set('HAVE_INTMAX_T', 1)
elif have_long_long
  glib_conf.set('intmax_t', 'long long')
else
  glib_conf.set('intmax_t', 'long')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1112 1113 1114 1115 1116 1117 1118
endif

char_size = cc.sizeof('char')
short_size = cc.sizeof('short')
int_size = cc.sizeof('int')
voidp_size = cc.sizeof('void*')
long_size = cc.sizeof('long')
1119 1120 1121 1122 1123
if have_long_long
  long_long_size = cc.sizeof('long long')
else
  long_long_size = 0
endif
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1124
sizet_size = cc.sizeof('size_t')
1125 1126 1127 1128 1129 1130
if cc.get_id() == 'msvc'
  ssizet_size = cc.sizeof('SSIZE_T', prefix : '#include <BaseTsd.h>')
else
  ssizet_size = cc.sizeof('ssize_t')
endif

1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
# Some platforms (Apple) hard-code int64_t to long long instead of
# using long on 64-bit architectures. This can cause type mismatch
# warnings when trying to interface with code using the standard
# library type. Test for the warnings and set gint64 to whichever
# works.
if long_long_size == long_size
  if cc.compiles('''#if defined(_AIX) && !defined(__GNUC__)
                    #pragma options langlvl=stdc99
                    #endif
                    #pragma GCC diagnostic error "-Wincompatible-pointer-types"
                    #include <stdint.h>
                    #include <stdio.h>
                    int main () {
                      int64_t i1 = 1;
                      long *i2 = &i1;
                      return 1;
                    }''', name : 'int64_t is long')
    int64_t_typedef = 'long'
  elif cc.compiles('''#if defined(_AIX) && !defined(__GNUC__)
                      #pragma options langlvl=stdc99
                      #endif
                      #pragma GCC diagnostic error "-Wincompatible-pointer-types"
                      #include <stdint.h>
                      #include <stdio.h>
                      int main () {
                        int64_t i1 = 1;
                        long long *i2 = &i1;
                        return 1;
                      }''', name : 'int64_t is long long')
    int64_t_typedef = 'long long'
  endif
endif

1164
int64_m = 'll'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1165 1166 1167 1168 1169
char_align = cc.alignment('char')
short_align = cc.alignment('short')
int_align = cc.alignment('int')
voidp_align = cc.alignment('void*')
long_align = cc.alignment('long')
1170 1171 1172
long_long_align = cc.alignment('long long')
# NOTE: We don't check for size of __int64 because long long is guaranteed to
# be 64-bit in C99, and it is available on all supported compilers
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
sizet_align = cc.alignment('size_t')

glib_conf.set('ALIGNOF_UNSIGNED_LONG', long_align)

glib_conf.set('SIZEOF_CHAR', char_size)
glib_conf.set('SIZEOF_INT', int_size)
glib_conf.set('SIZEOF_SHORT', short_size)
glib_conf.set('SIZEOF_LONG', long_size)
glib_conf.set('SIZEOF_LONG_LONG', long_long_size)
glib_conf.set('SIZEOF_SIZE_T', sizet_size)
1183
glib_conf.set('SIZEOF_SSIZE_T', ssizet_size)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1184
glib_conf.set('SIZEOF_VOID_P', voidp_size)
1185
glib_conf.set('SIZEOF_WCHAR_T', cc.sizeof('wchar_t', prefix: '#include <stddef.h>'))
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1186 1187 1188

if short_size == 2
  gint16 = 'short'
1189 1190 1191
  gint16_modifier='h'
  gint16_format='hi'
  guint16_format='hu'
1192 1193
elif int_size == 2
  gint16 = 'int'
1194 1195 1196
  gint16_modifier=''
  gint16_format='i'
  guint16_format='u'
1197 1198
else
  error('Compiler provides no native 16-bit integer type')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1199 1200
endif
glibconfig_conf.set('gint16', gint16)
1201 1202 1203
glibconfig_conf.set_quoted('gint16_modifier', gint16_modifier)
glibconfig_conf.set_quoted('gint16_format', gint16_format)
glibconfig_conf.set_quoted('guint16_format', guint16_format)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1204 1205 1206

if short_size == 4
  gint32 = 'short'
1207 1208 1209
  gint32_modifier='h'
  gint32_format='hi'
  guint32_format='hu'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1210
  guint32_align = short_align
1211 1212
elif int_size == 4
  gint32 = 'int'
1213 1214 1215
  gint32_modifier=''
  gint32_format='i'
  guint32_format='u'
1216 1217 1218
  guint32_align = int_align
elif long_size == 4
  gint32 = 'long'
1219 1220 1221
  gint32_modifier='l'
  gint32_format='li'
  guint32_format='lu'
1222 1223 1224
  guint32_align = long_align
else
  error('Compiler provides no native 32-bit integer type')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1225 1226
endif
glibconfig_conf.set('gint32', gint32)
1227 1228 1229
glibconfig_conf.set_quoted('gint32_modifier', gint32_modifier)
glibconfig_conf.set_quoted('gint32_format', gint32_format)
glibconfig_conf.set_quoted('guint32_format', guint32_format)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1230 1231 1232 1233
glib_conf.set('ALIGNOF_GUINT32', guint32_align)

if int_size == 8
  gint64 = 'int'
1234 1235 1236
  gint64_modifier=''
  gint64_format='i'
  guint64_format='u'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1237 1238 1239 1240
  glib_extension=''
  gint64_constant='(val)'
  guint64_constant='(val)'
  guint64_align = int_align
1241
elif long_size == 8 and (long_long_size != long_size or int64_t_typedef == 'long')
1242 1243
  gint64 = 'long'
  glib_extension=''
1244 1245 1246
  gint64_modifier='l'
  gint64_format='li'
  guint64_format='lu'
1247 1248 1249
  gint64_constant='(val##L)'
  guint64_constant='(val##UL)'
  guint64_align = long_align
1250
elif long_long_size == 8 and (long_long_size != long_size or int64_t_typedef == 'long long')
1251
  gint64 = 'long long'
1252
  glib_extension='G_GNUC_EXTENSION '
1253 1254 1255
  gint64_modifier=int64_m
  gint64_format=int64_m + 'i'
  guint64_format=int64_m + 'u'
1256 1257
  gint64_constant='(G_GNUC_EXTENSION (val##LL))'
  guint64_constant='(G_GNUC_EXTENSION (val##ULL))'
1258 1259 1260
  guint64_align = long_long_align
else
  error('Compiler provides no native 64-bit integer type')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1261
endif
1262
glibconfig_conf.set('glib_extension', glib_extension)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1263
glibconfig_conf.set('gint64', gint64)
1264 1265 1266
glibconfig_conf.set_quoted('gint64_modifier', gint64_modifier)
glibconfig_conf.set_quoted('gint64_format', gint64_format)
glibconfig_conf.set_quoted('guint64_format', guint64_format)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1267 1268 1269 1270
glibconfig_conf.set('gint64_constant', gint64_constant)
glibconfig_conf.set('guint64_constant', guint64_constant)
glib_conf.set('ALIGNOF_GUINT64', guint64_align)

1271
if host_system == 'windows'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1272
  glibconfig_conf.set('g_pid_type', 'void*')
1273
  glibconfig_conf.set_quoted('g_pid_format', 'p')
1274
  if host_machine.cpu_family() == 'x86_64'
1275
    glibconfig_conf.set_quoted('g_pollfd_format', '%#' + int64_m + 'x')
1276
  else
1277
    glibconfig_conf.set_quoted('g_pollfd_format', '%#x')
1278
  endif
1279
  glibconfig_conf.set('g_dir_separator', '\\\\')
1280
  glibconfig_conf.set('g_searchpath_separator', ';')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1281 1282
else
  glibconfig_conf.set('g_pid_type', 'int')
1283 1284
  glibconfig_conf.set_quoted('g_pid_format', 'i')
  glibconfig_conf.set_quoted('g_pollfd_format', '%d')
1285 1286
  glibconfig_conf.set('g_dir_separator', '/')
  glibconfig_conf.set('g_searchpath_separator', ':')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1287 1288 1289 1290
endif

if sizet_size == short_size
  glibconfig_conf.set('glib_size_type_define', 'short')
1291 1292 1293 1294
  glibconfig_conf.set_quoted('gsize_modifier', 'h')
  glibconfig_conf.set_quoted('gssize_modifier', 'h')
  glibconfig_conf.set_quoted('gsize_format', 'hu')
  glibconfig_conf.set_quoted('gssize_format', 'hi')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1295 1296 1297
  glibconfig_conf.set('glib_msize_type', 'SHRT')
elif sizet_size == int_size
  glibconfig_conf.set('glib_size_type_define', 'int')
1298 1299 1300 1301
  glibconfig_conf.set_quoted('gsize_modifier', '')
  glibconfig_conf.set_quoted('gssize_modifier', '')
  glibconfig_conf.set_quoted('gsize_format', 'u')
  glibconfig_conf.set_quoted('gssize_format', 'i')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1302 1303 1304
  glibconfig_conf.set('glib_msize_type', 'INT')
elif sizet_size == long_size
  glibconfig_conf.set('glib_size_type_define', 'long')
1305 1306 1307 1308
  glibconfig_conf.set_quoted('gsize_modifier', 'l')
  glibconfig_conf.set_quoted('gssize_modifier', 'l')
  glibconfig_conf.set_quoted('gsize_format', 'lu')
  glibconfig_conf.set_quoted('gssize_format', 'li')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1309 1310 1311
  glibconfig_conf.set('glib_msize_type', 'LONG')
elif sizet_size == long_long_size
  glibconfig_conf.set('glib_size_type_define', 'long long')
1312 1313 1314 1315
  glibconfig_conf.set_quoted('gsize_modifier', int64_m)
  glibconfig_conf.set_quoted('gssize_modifier', int64_m)
  glibconfig_conf.set_quoted('gsize_format', int64_m + 'u')
  glibconfig_conf.set_quoted('gssize_format', int64_m + 'i')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1316 1317 1318 1319 1320
  glibconfig_conf.set('glib_msize_type', 'INT64')
else
  error('Could not determine size of size_t.')
endif

1321 1322
if voidp_size == int_size
  glibconfig_conf.set('glib_intptr_type_define', 'int')
1323 1324 1325
  glibconfig_conf.set_quoted('gintptr_modifier', '')
  glibconfig_conf.set_quoted('gintptr_format', 'i')
  glibconfig_conf.set_quoted('guintptr_format', 'u')
1326 1327 1328 1329
  glibconfig_conf.set('glib_gpi_cast', '(gint)')
  glibconfig_conf.set('glib_gpui_cast', '(guint)')
elif voidp_size == long_size
  glibconfig_conf.set('glib_intptr_type_define', 'long')
1330 1331 1332
  glibconfig_conf.set_quoted('gintptr_modifier', 'l')
  glibconfig_conf.set_quoted('gintptr_format', 'li')
  glibconfig_conf.set_quoted('guintptr_format', 'lu')
1333 1334 1335 1336
  glibconfig_conf.set('glib_gpi_cast', '(glong)')
  glibconfig_conf.set('glib_gpui_cast', '(gulong)')
elif voidp_size == long_long_size
  glibconfig_conf.set('glib_intptr_type_define', 'long long')
1337 1338 1339
  glibconfig_conf.set_quoted('gintptr_modifier', int64_m)
  glibconfig_conf.set_quoted('gintptr_format', int64_m + 'i')
  glibconfig_conf.set_quoted('guintptr_format', int64_m + 'u')
1340 1341 1342 1343 1344 1345
  glibconfig_conf.set('glib_gpi_cast', '(gint64)')
  glibconfig_conf.set('glib_gpui_cast', '(guint64)')
else
  error('Could not determine size of void *')
endif

1346 1347 1348 1349
if long_size != 8 and long_long_size != 8 and int_size != 8
  error('GLib requires a 64-bit type. You might want to consider using the GNU C compiler.')
endif

1350 1351 1352 1353 1354
glibconfig_conf.set('gintbits', int_size * 8)
glibconfig_conf.set('glongbits', long_size * 8)
glibconfig_conf.set('gsizebits', sizet_size * 8)
glibconfig_conf.set('gssizebits', ssizet_size * 8)

1355
# XXX: https://gitlab.gnome.org/GNOME/glib/issues/1413
1356
if host_system == 'windows'
1357 1358 1359 1360 1361 1362 1363 1364 1365
  g_module_suffix = 'dll'
else
  g_module_suffix = 'so'
endif
glibconfig_conf.set('g_module_suffix', g_module_suffix)

glibconfig_conf.set('GLIB_MAJOR_VERSION', major_version)
glibconfig_conf.set('GLIB_MINOR_VERSION', minor_version)
glibconfig_conf.set('GLIB_MICRO_VERSION', micro_version)
1366
glibconfig_conf.set('GLIB_VERSION', glib_version)
1367

Jussi Pakkanen's avatar
Jussi Pakkanen committed
1368 1369 1370
glibconfig_conf.set('glib_void_p', voidp_size)
glibconfig_conf.set('glib_long', long_size)
glibconfig_conf.set('glib_size_t', sizet_size)
1371 1372
glibconfig_conf.set('glib_ssize_t', ssizet_size)
if host_machine.endian() == 'big'
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1373 1374 1375 1376 1377 1378 1379 1380 1381
  glibconfig_conf.set('g_byte_order', 'G_BIG_ENDIAN')
  glibconfig_conf.set('g_bs_native', 'BE')
  glibconfig_conf.set('g_bs_alien', 'LE')
else
  glibconfig_conf.set('g_byte_order', 'G_LITTLE_ENDIAN')
  glibconfig_conf.set('g_bs_native', 'LE')
  glibconfig_conf.set('g_bs_alien', 'BE')
endif

1382 1383 1384 1385
# === va_copy checks ===
# we currently check for all three va_copy possibilities, so we get
# all results in config.log for bug reports.

1386
va_copy_func = ''
1387 1388 1389
foreach try_func : [ '__va_copy', 'va_copy' ]
  if cc.compiles('''#include <stdarg.h>
                    #include <stdlib.h>
1390 1391 1392
                    #ifdef _MSC_VER
                    # include "msvc_recommended_pragmas.h"
                    #endif
1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
                    void f (int i, ...) {
                    va_list args1, args2;
                    va_start (args1, i);
                    @0@ (args2, args1);
                    if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
                      exit (1);
                    va_end (args1); va_end (args2);
                    }
                    int main() {
                      f (0, 42);
                      return 0;
                    }'''.format(try_func),
                    name : try_func + ' check')
    va_copy_func = try_func
  endif
endforeach
1409 1410 1411 1412 1413 1414
if va_copy_func != ''
  glib_conf.set('G_VA_COPY', va_copy_func)
  glib_vacopy = '#define G_VA_COPY ' + va_copy_func
else
  glib_vacopy = '/* #undef G_VA_COPY */'
endif
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431

va_list_val_copy_prog = '''
  #include <stdarg.h>
  #include <stdlib.h>
  void f (int i, ...) {
    va_list args1, args2;
    va_start (args1, i);
    args2 = args1;
    if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
      exit (1);
    va_end (args1); va_end (args2);
  }
  int main() {
    f (0, 42);
    return 0;
  }'''

1432 1433 1434 1435 1436
if cc_can_run
  rres = cc.run(va_list_val_copy_prog, name : 'va_lists can be copied as values')
  glib_va_val_copy = rres.returncode() == 0
else
  glib_va_val_copy = meson.get_cross_property('va_val_copy', true)
1437 1438 1439 1440
endif
if not glib_va_val_copy
  glib_vacopy = glib_vacopy + '\n#define G_VA_COPY_AS_ARRAY 1'
  glib_conf.set('G_VA_COPY_AS_ARRAY', 1)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1441
endif
1442
glibconfig_conf.set('glib_vacopy', glib_vacopy)
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1443

1444 1445 1446 1447 1448 1449 1450
# check for flavours of varargs macros
g_have_iso_c_varargs = cc.compiles('''
  void some_func (void) {
    int a(int p1, int p2, int p3);
    #define call_a(...) a(1,__VA_ARGS__)
    call_a(2,3);
  }''', name : 'ISO C99 varargs macros in C')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1451

1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464
if g_have_iso_c_varargs
  glibconfig_conf.set('g_have_iso_c_varargs', '''
#ifndef __cplusplus
# define G_HAVE_ISO_VARARGS 1
#endif''')
endif

g_have_iso_cxx_varargs = cxx.compiles('''
  void some_func (void) {
    int a(int p1, int p2, int p3);
    #define call_a(...) a(1,__VA_ARGS__)
    call_a(2,3);
  }''', name : 'ISO C99 varargs macros in C++')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1465

1466 1467 1468 1469 1470
if g_have_iso_cxx_varargs
  glibconfig_conf.set('g_have_iso_cxx_varargs', '''
#ifdef __cplusplus
# define G_HAVE_ISO_VARARGS 1
#endif''')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1471 1472
endif

1473 1474 1475 1476 1477 1478 1479
g_have_gnuc_varargs = cc.compiles('''
  void some_func (void) {
    int a(int p1, int p2, int p3);
    #define call_a(params...) a(1,params)
    call_a(2,3);
  }''', name : 'GNUC varargs macros')

Jussi Pakkanen's avatar
Jussi Pakkanen committed
1480 1481 1482 1483 1484 1485 1486 1487
if cc.has_header('alloca.h')
  glibconfig_conf.set('GLIB_HAVE_ALLOCA_H', true)
endif
has_syspoll = cc.has_header('sys/poll.h')
has_systypes = cc.has_header('sys/types.h')
if has_syspoll
  glibconfig_conf.set('GLIB_HAVE_SYS_POLL_H', true)
endif
1488
has_winsock2 = cc.has_header('winsock2.h')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1489 1490

if has_syspoll and has_systypes
1491 1492 1493
  poll_includes = '''
      #include<sys/poll.h>
      #include<sys/types.h>'''
1494
elif has_winsock2
1495
  poll_includes = '''
1496 1497
      #define _WIN32_WINNT @0@
      #include <winsock2.h>'''.format(glib_conf.get('_WIN32_WINNT'))
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1498
else
1499 1500
  # FIXME?
  error('FIX POLL* defines')
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1501 1502
endif

1503
poll_defines = [
1504 1505 1506 1507 1508 1509
  [ 'POLLIN', 'g_pollin', 1 ],
  [ 'POLLOUT', 'g_pollout', 4 ],
  [ 'POLLPRI', 'g_pollpri', 2 ],
  [ 'POLLERR', 'g_pollerr', 8 ],
  [ 'POLLHUP', 'g_pollhup', 16 ],
  [ 'POLLNVAL', 'g_pollnval', 32 ],
1510
]
1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527

if has_syspoll and has_systypes
  foreach d : poll_defines
    val = cc.compute_int(d[0], prefix: poll_includes)
    glibconfig_conf.set(d[1], val)
  endforeach
elif has_winsock2
  # Due to a missed bug in configure.ac the poll test
  # never succeeded on Windows and used some pre-defined
  # values as a fallback. Keep using them to maintain
  # ABI compatibility with autotools builds of glibs
  # and with *any* glib-using code compiled against them,
  # since these values end up in a public header glibconfig.h.
  foreach d : poll_defines
    glibconfig_conf.set(d[1], d[2])
  endforeach
endif
Jussi Pakkanen's avatar
Jussi Pakkanen committed
1528

1529 1530
# Internet address families
# FIXME: what about Cygwin (G_WITH_CYGWIN)
1531
if host_system == 'windows'
1532 1533
  inet_includes = '''
      #include <winsock2.h>'''
1534
else
1535 1536 1537
  inet_includes = '''
      #include <sys/types.h>
      #include <sys/socket.h>'''
1538 1539
endif

1540
inet_defines = [
1541 1542 1543 1544 1545 1546 1547
  [ 'AF_UNIX', 'g_af_unix' ],
  [ 'AF_INET', 'g_af_inet' ],
  [ 'AF_INET6', 'g_af_inet6' ],
  [ 'MSG_OOB', 'g_msg_oob' ],
  [ 'MSG_PEEK', 'g_msg_peek' ],
  [ 'MSG_DONTROUTE', 'g_msg_dontroute' ],
]
1548 1549
foreach d : inet_defines
  val = cc.compute_int(d[0], prefix: inet_includes)
1550 1551 1552 1553 1554
  glibconfig_conf.set(d[1], val)
endforeach

# We need a more robust approach here...
host_cpu_family = host_machine.cpu_family()
1555
if host_cpu_family == 'x86' or host_cpu_family == 'x86_64' or host_cpu_family == 's390' or host_cpu_family == 's390x' or host_cpu_family.startswith('arm') or host_cpu_family == 'aarch64' or host_cpu_family.startswith('crisv32') or host_cpu_family.startswith('etrax')
1556 1557 1558 1559
  glib_memory_barrier_needed = false
elif host_cpu_family.startswith('sparc') or host_cpu_family.startswith('alpha') or host_cpu_family.startswith('powerpc') or host_cpu_family == 'ia64'
  glib_memory_barrier_needed = true
else
1560
  warning('Unknown host cpu: ' + host_cpu_family)
1561 1562 1563