meson.build 17.3 KB
Newer Older
1
project('gstreamer', 'c',
2
  version : '1.17.0.1',
Thibault Saunier's avatar
Thibault Saunier committed
3
  meson_version : '>= 0.48',
4 5 6 7 8
  default_options : [ 'warning_level=1',
                      'buildtype=debugoptimized' ])

gst_version = meson.project_version()
version_arr = gst_version.split('.')
9 10 11
gst_version_major = version_arr[0].to_int()
gst_version_minor = version_arr[1].to_int()
gst_version_micro = version_arr[2].to_int()
12
if version_arr.length() == 4
13
  gst_version_nano = version_arr[3].to_int()
14 15 16
else
  gst_version_nano = 0
endif
17
gst_version_is_dev = gst_version_minor % 2 == 1 and gst_version_micro < 90
18

19 20
host_system = host_machine.system()

21 22 23 24
apiversion = '1.0'
soversion = 0
# maintaining compatibility with the previous libtool versioning
# current = minor * 100 + micro
25 26 27
curversion = gst_version_minor * 100 + gst_version_micro
libversion = '@0@.@1@.0'.format(soversion, curversion)
osxversion = curversion + 1
28 29 30 31

prefix = get_option('prefix')

libexecdir = get_option('libexecdir')
32
helpers_install_dir = join_paths(libexecdir, 'gstreamer-1.0')
33 34 35

cc = meson.get_compiler('c')

36 37
cdata = configuration_data()

38 39 40 41
# Ignore several spurious warnings for things gstreamer 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
42 43 44 45 46 47
if cc.get_id() == 'msvc'
  add_project_arguments(
      '/wd4018', # implicit signed/unsigned conversion
      '/wd4146', # unary minus on unsigned (beware INT_MIN)
      '/wd4244', # lossy type conversion (e.g. double -> int)
      '/wd4305', # truncating type conversion (e.g. double -> float)
48
      cc.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
49
      language : 'c')
50
elif cc.has_link_argument('-Wl,-Bsymbolic-functions')
51 52
  # FIXME: Add an option for this if people ask for it
  add_project_link_arguments('-Wl,-Bsymbolic-functions', language : 'c')
53 54
endif

55
# Symbol visibility
56 57 58 59
have_visibility_hidden = false
if cc.get_id() == 'msvc'
  export_define = '__declspec(dllexport) extern'
elif cc.has_argument('-fvisibility=hidden')
60
  add_project_arguments('-fvisibility=hidden', language: 'c')
61 62 63 64
  export_define = 'extern __attribute__ ((visibility ("default")))'
  have_visibility_hidden = true
else
  export_define = 'extern'
65 66
endif

67 68 69
# Passing this through the command line would be too messy
cdata.set('GST_API_EXPORT', export_define)

70 71 72 73 74
# Disable strict aliasing
if cc.has_argument('-fno-strict-aliasing')
  add_project_arguments('-fno-strict-aliasing', language: 'c')
endif

75
# Define G_DISABLE_DEPRECATED for development versions
76 77
if gst_version_is_dev
  message('Disabling deprecated GLib API')
78 79 80
  add_project_arguments('-DG_DISABLE_DEPRECATED', language: 'c')
endif

81 82 83 84 85 86 87 88 89 90 91 92
cast_checks = get_option('gobject-cast-checks')
if cast_checks.disabled() or (cast_checks.auto() and not gst_version_is_dev)
  message('Disabling GLib cast checks')
  add_project_arguments('-DG_DISABLE_CAST_CHECKS', language: 'c')
endif

glib_asserts = get_option('glib-asserts')
if glib_asserts.disabled() or (glib_asserts.auto() and not gst_version_is_dev)
  message('Disabling GLib asserts')
  add_project_arguments('-DG_DISABLE_ASSERT', language: 'c')
endif

93 94 95 96 97 98
glib_checks = get_option('glib-checks')
if glib_checks.disabled() or (glib_checks.auto() and not gst_version_is_dev)
  message('Disabling GLib checks')
  add_project_arguments('-DG_DISABLE_CHECKS', language: 'c')
endif

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
cdata.set_quoted('GST_API_VERSION', apiversion)
cdata.set_quoted('GST_DATADIR', join_paths(prefix, get_option('datadir')))
cdata.set_quoted('LOCALEDIR', join_paths(prefix, get_option('localedir')))
cdata.set_quoted('LIBDIR', join_paths(prefix, get_option('libdir')))
cdata.set_quoted('GST_API_VERSION', '1.0')
cdata.set_quoted('GETTEXT_PACKAGE', 'gstreamer-1.0')
cdata.set_quoted('GST_LICENSE', 'LGPL')
cdata.set_quoted('PACKAGE', 'gstreamer')
cdata.set_quoted('PACKAGE_NAME', 'GStreamer')
cdata.set_quoted('PACKAGE_STRING', 'GStreamer @0@'.format(gst_version))
cdata.set_quoted('PACKAGE_TARNAME', 'gstreamer')
cdata.set_quoted('PACKAGE_BUGREPORT', 'http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer')
cdata.set_quoted('PACKAGE_URL', '')
cdata.set_quoted('PACKAGE_VERSION', gst_version)
cdata.set_quoted('PLUGINDIR', join_paths(get_option('prefix'), get_option('libdir'), 'gstreamer-1.0'))
cdata.set_quoted('VERSION', gst_version)
cdata.set_quoted('GST_PLUGIN_SCANNER_INSTALLED', join_paths(prefix, helpers_install_dir, 'gst-plugin-scanner'))
cdata.set_quoted('GST_PTP_HELPER_INSTALLED', join_paths(prefix, helpers_install_dir, 'gst-ptp-helper'))
117 118
cdata.set_quoted('GST_PLUGIN_SUBDIR', get_option('libdir'),
  description: 'plugin directory path component, used to find plugins on relocatable builds on windows')
119 120
cdata.set_quoted('GST_PLUGIN_SCANNER_SUBDIR', libexecdir,
  description: 'libexecdir path component, used to find plugin-scanner on relocatable builds on windows')
121
cdata.set('GST_DISABLE_OPTION_PARSING', not get_option('option-parsing'))
122

123 124 125 126 127 128 129 130 131
mem_align_opt = get_option('memory-alignment')
if mem_align_opt == 'malloc'
  cdata.set('MEMORY_ALIGNMENT_MALLOC', 1)
elif mem_align_opt == 'pagesize'
  cdata.set('MEMORY_ALIGNMENT_PAGESIZE', 1)
else
  cdata.set('MEMORY_ALIGNMENT', mem_align_opt.to_int())
endif

132
if ['darwin', 'ios'].contains(host_system)
133 134 135
  cdata.set_quoted('GST_EXTRA_MODULE_SUFFIX', '.dylib')
endif

136 137 138 139 140 141 142
if gst_version_nano > 0
    # Have GST_ERROR message printed when running from git
    cdata.set('GST_LEVEL_DEFAULT', 'GST_LEVEL_ERROR')
else
    cdata.set('GST_LEVEL_DEFAULT', 'GST_LEVEL_NONE')
endif

143
# GStreamer package name and origin url
144
gst_package_name = get_option('package-name')
145 146
if gst_package_name == ''
  if gst_version_nano == 0
147
    gst_package_name = 'GStreamer source release'
148
  elif gst_version_nano == 1
149
    gst_package_name = 'GStreamer git'
150
  else
151
    gst_package_name = 'GStreamer prerelease'
152 153
  endif
endif
154
cdata.set_quoted('GST_PACKAGE_NAME', gst_package_name)
155
cdata.set_quoted('GST_PACKAGE_ORIGIN', get_option('package-origin'))
156

157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
# These are only needed/used by the ABI tests
host_defines = [
  [ 'x86', 'HAVE_CPU_I386' ],
  [ 'x86_64', 'HAVE_CPU_X86_64' ],
  [ 'arm', 'HAVE_CPU_ARM' ],
  [ 'aarch64', 'HAVE_CPU_AARCH64' ],
  [ 'mips', 'HAVE_CPU_MIPS' ],
  [ 'powerpc', 'HAVE_CPU_PPC' ],
  [ 'powerpc64', 'HAVE_CPU_PPC64' ],
  [ 'alpha', 'HAVE_CPU_ALPHA' ],
  [ 'sparc', 'HAVE_CPU_SPARC' ],
  [ 'ia64', 'HAVE_CPU_IA64' ],
  [ 'hppa', 'HAVE_CPU_HPPA' ],
  [ 'm68k', 'HAVE_CPU_M68K' ],
  [ 's390', 'HAVE_CPU_S390' ],
]
foreach h : host_defines
  if h.get(0) == host_machine.cpu()
    cdata.set(h.get(1), 1)
  endif
endforeach
# FIXME: should really be called HOST_CPU or such
179
cdata.set_quoted('TARGET_CPU', host_machine.cpu())
180

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
check_headers = [
  'dlfcn.h',
  'inttypes.h',
  'memory.h',
  'poll.h',
  'stdint.h',
  'stdio_ext.h',
  'strings.h',
  'string.h',
  'sys/param.h',
  'sys/poll.h',
  'sys/prctl.h',
  'sys/socket.h',
  'sys/stat.h',
  'sys/times.h',
  'sys/time.h',
  'sys/types.h',
  'sys/utsname.h',
  'sys/wait.h',
  'ucontext.h',
  'unistd.h',
  'valgrind/valgrind.h',
  'sys/resource.h',
204 205
]

206
if host_system == 'windows'
207
  check_headers += ['winsock2.h']
208 209 210
endif

foreach h : check_headers
211 212 213
  if cc.has_header(h)
    define = 'HAVE_' + h.underscorify().to_upper()
    cdata.set(define, 1)
214 215 216
  endif
endforeach

217
if cc.has_member('struct tm', 'tm_gmtoff', prefix : '#include <time.h>')
218 219 220
  cdata.set('HAVE_TM_GMTOFF', 1)
endif

221 222 223 224 225 226 227
check_functions = [
  'gmtime_r',
  'sigaction',
  'getrusage',
  'fseeko',
  'ftello',
  'poll',
228
  'ppoll',
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
  'pselect',
  'getpagesize',
  'clock_gettime',
  # These are needed by libcheck
  'getline',
  'mkstemp',
  'alarm',
  'gettimeofday',
]

foreach f : check_functions
  if cc.has_function(f)
    define = 'HAVE_' + f.underscorify().to_upper()
    cdata.set(define, 1)
  endif
endforeach

246 247
if cc.has_function('localtime_r', prefix : '#include<time.h>')
  cdata.set('HAVE_LOCALTIME_R', 1)
248 249
  # Needed by libcheck
  cdata.set('HAVE_DECL_LOCALTIME_R', 1)
250 251
endif

252
if cc.links('''#include <pthread.h>
253 254 255 256
               int main() {
                 pthread_setname_np("example"); return 0;
               }''', name : 'pthread_setname_np(const char*)')
  cdata.set('HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID', 1)
257 258 259 260 261 262 263 264 265 266 267 268 269
endif

# Check for posix timers and the monotonic clock
time_prefix = '#include <time.h>\n'
if cdata.has('HAVE_UNISTD_H')
  time_prefix += '#include <unistd.h>'
endif

posix_timers_src = time_prefix + '''
#if !defined(_POSIX_TIMERS) || _POSIX_TIMERS < 0 || !defined(CLOCK_REALTIME)
#error Either _POSIX_TIMERS or CLOCK_REALTIME not defined
#endif
'''
270
if cc.compiles(posix_timers_src, name : 'posix timers from time.h')
271 272 273 274 275 276 277 278
  cdata.set('HAVE_POSIX_TIMERS', 1)
endif

monotonic_clock_src = time_prefix + '''
#if !defined(_POSIX_MONOTONIC_CLOCK) || _POSIX_MONOTONIC_CLOCK < 0 || !defined(CLOCK_MONOTONIC)
#error Either _POSIX_MONOTONIC_CLOCK or CLOCK_MONOTONIC not defined
#endif
'''
279
if cc.compiles(monotonic_clock_src, name : 'monotonic clock from time.h')
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
  cdata.set('HAVE_MONOTONIC_CLOCK', 1)
endif

# Check for __uint128_t (gcc) by checking for 128-bit division
uint128_t_src = '''int main() {
static __uint128_t v1 = 100;
static __uint128_t v2 = 10;
static __uint128_t u;
u = v1 / v2;
}'''
if cc.compiles(uint128_t_src, name : '__uint128_t available')
  cdata.set('HAVE_UINT128_T', 1)
endif

# All supported platforms have long long now
cdata.set('HAVE_LONG_LONG', 1)

297 298 299 300 301 302 303 304
# We only want to use the __declspec(dllexport/import) dance in GST_EXPORT when
# building with MSVC
if cc.get_id() == 'msvc'
  cdata.set('GSTCONFIG_BUILT_WITH_MSVC', 1)
else
  cdata.set('GSTCONFIG_BUILT_WITH_MSVC', 0)
endif

305
# -------------------------------------------------------------------------------------
306
# config.h things needed by libcheck
307
# -------------------------------------------------------------------------------------
308
if cc.has_function('getpid')
309
  cdata.set('HAVE_GETPID', 1)
310 311 312
elif host_system == 'windows' and cc.has_function('_getpid')
  cdata.set('HAVE_PROCESS_H', 1) # Used by gstreamer too
  cdata.set('HAVE__GETPID', 1)
313
endif
314
if cc.has_function('strdup')
315
  cdata.set('HAVE_DECL_STRDUP', 1)
316
elif host_system == 'windows' and cc.has_function('_strdup')
317 318
  cdata.set('HAVE__STRDUP', 1) # Windows (MSVC)
endif
319
if host_system != 'windows'
320 321 322 323 324
  cdata.set('HAVE_FORK', 1)
else
  # libcheck requires HAVE_FORK to be 0 when fork() is not available
  cdata.set('HAVE_FORK', 0)
endif
325
if cc.has_function('strsignal')
326 327
  cdata.set('HAVE_DECL_STRSIGNAL', 1)
endif
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
# Check for availability of types
if not cc.has_type('clockid_t', prefix : '#include <time.h>')
  cdata.set('clockid_t', 'int')
endif
if not cc.has_type('timer_t', prefix : '#include <time.h>')
  cdata.set('timer_t', 'int')
endif
if not cc.has_members('struct timespec', 'tv_sec', 'tv_nsec',
		      prefix : '#include <time.h>')
  cdata.set('STRUCT_TIMESPEC_DEFINITION_MISSING', 1)
endif
if not cc.has_members('struct itimerspec', 'it_interval', 'it_value',
		      prefix : '#include <time.h>')
  cdata.set('STRUCT_ITIMERSPEC_DEFINITION_MISSING', 1)
endif
343

344 345
# Platform deps; only ws2_32 and execinfo for now
platform_deps = []
346
if host_system == 'windows'
347 348 349
  platform_deps = [cc.find_library('ws2_32')]
endif

350
backtrace_deps = []
351
unwind_dep = dependency('libunwind', required : get_option('libunwind'))
352
dw_dep = dependency('libdw', required: get_option('libdw'))
353 354
dbghelp_dep = dependency('DbgHelp', required : get_option('dbghelp'))
backtrace_deps = [unwind_dep, dw_dep, dbghelp_dep]
355 356 357 358 359 360 361 362
backtrace_source_info = false
backtrace_minimal = false
# MSVC debug stack trace support
if host_system == 'windows' and dbghelp_dep.found()
  cdata.set('HAVE_DBGHELP', 1)
  backtrace_source_info = true
# DWARF stack trace support with libunwind and elf-utils
elif unwind_dep.found()
363 364 365
  cdata.set('HAVE_UNWIND', 1)
  if dw_dep.found()
    cdata.set('HAVE_DW', 1)
366
    backtrace_source_info = true
367
  endif
368 369
  backtrace_minimal = true
# Basic backtrace() stack trace support
370 371
elif cc.has_function('backtrace')
  cdata.set('HAVE_BACKTRACE', 1)
372 373 374 375 376 377 378 379 380
  backtrace_minimal = true
endif
# Print messages about what was enabled
if not backtrace_source_info
  if not backtrace_minimal
    message('NO support for stack traces.')
  else
    message('Minimal support for stack traces, no source info.')
  endif
381 382
endif

383 384 385 386 387 388 389 390 391 392
if cc.has_header('execinfo.h')
  if cc.has_function('backtrace', prefix : '#include <execinfo.h>')
    cdata.set('HAVE_BACKTRACE', 1)
  else
    execinfo_dep = cc.find_library('execinfo', required : false)
    if execinfo_dep.found() and cc.has_function('backtrace', prefix : '#include <execinfo.h>', dependencies : execinfo_dep)
      cdata.set('HAVE_BACKTRACE', 1)
      platform_deps += execinfo_dep
    endif
  endif
393 394
endif

395 396
gst_debug = get_option('gst_debug')
if not gst_debug
397 398 399
  add_project_arguments(['-Wno-unused'], language: 'c')
endif

400 401 402 403 404 405
warning_flags = [
  '-Wmissing-declarations',
  '-Wmissing-prototypes',
  '-Wredundant-decls',
  '-Wundef',
  '-Wwrite-strings',
406
  '-Wformat',
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
  '-Wformat-nonliteral',
  '-Wformat-security',
  '-Wold-style-definition',
  '-Winit-self',
  '-Wmissing-include-dirs',
  '-Waddress',
  '-Waggregate-return',
  '-Wno-multichar',
  '-Wdeclaration-after-statement',
  '-Wvla',
  '-Wpointer-arith',
]

foreach extra_arg : warning_flags
  if cc.has_argument (extra_arg)
    add_project_arguments([extra_arg], language: 'c')
  endif
endforeach

426 427 428 429 430 431 432 433 434 435 436
# Used by the gstutils test
gmp_dep = cc.find_library('gmp', required : false)
cdata.set('HAVE_GMP', gmp_dep.found())
gsl_dep = cc.find_library('gsl', required : false)
gslcblas_dep = cc.find_library('gslcblas', required : false)
cdata.set('HAVE_GSL', gsl_dep.found() and gslcblas_dep.found())
test_deps = [gmp_dep, gsl_dep, gslcblas_dep]

# Used by gstinfo.c
dl_dep = cc.find_library('dl', required : false)
cdata.set('HAVE_DLADDR', cc.has_function('dladdr', dependencies : dl_dep))
437
cdata.set('GST_ENABLE_EXTRA_CHECKS', get_option('extra-checks'))
438
cdata.set('USE_POISONING', get_option('poisoning'))
439 440 441 442 443 444

configinc = include_directories('.')
libsinc = include_directories('libs')
privinc = include_directories('gst')

# Find dependencies
445
glib_dep = dependency('glib-2.0', version : '>=2.44.0',
446 447 448 449 450
  fallback: ['glib', 'libglib_dep'])
gobject_dep = dependency('gobject-2.0',
  fallback: ['glib', 'libgobject_dep'])
gmodule_dep = dependency('gmodule-2.0',
  fallback: ['glib', 'libgmodule_dep'])
451
if host_system == 'windows'
452 453
    gio_dep = dependency('gio-2.0',
        fallback: ['glib', 'libgio_dep'])
454
else
455 456 457 458
    gio_dep = [dependency('gio-2.0',
                  fallback: ['glib', 'libgio_dep']),
               dependency('gio-unix-2.0',
                  fallback: ['glib', 'libgio_dep'])]
459
endif
Thibault Saunier's avatar
Thibault Saunier committed
460

461
mathlib = cc.find_library('m', required : false)
462 463 464
# Needed for timer_create/settime/delete
# Also provides clock_gettime in glibc < 2.17
rt_lib = cc.find_library('rt', required : false)
465

466
gir = find_program('g-ir-scanner', required : get_option('introspection'))
467 468
gnome = import('gnome')

469
build_gir = gir.found() and (not meson.is_cross_build() or get_option('introspection').enabled())
470

471
gir_init_section = [ '--add-init-section=extern void gst_init(gint*,gchar**);' + \
472
    'g_setenv("GST_REGISTRY_DISABLE", "yes", TRUE);' + \
473 474 475
    'g_setenv("GST_REGISTRY_1.0", "/no/way/this/exists.reg", TRUE);' + \
    'g_setenv("GST_PLUGIN_PATH_1_0", "", TRUE);' + \
    'g_setenv("GST_PLUGIN_SYSTEM_PATH_1_0", "", TRUE);' + \
476
    'gst_init(NULL,NULL);', '--quiet']
477 478

gst_c_args = ['-DHAVE_CONFIG_H']
479 480

# FIXME: This is only needed on windows and probably breaks when
481 482 483
# default_library = 'both'. We should add this flag to static_c_args instead
# when Meson supports it: https://github.com/mesonbuild/meson/issues/3304
if get_option('default_library') == 'static'
484 485 486
  gst_c_args += ['-DGST_STATIC_COMPILATION']
endif

487
# Used in gst/parse/meson.build and below
488
python3 = import('python').find_installation()
489

490 491
bashcomp_option = get_option('bash-completion')
bashcomp_dep = dependency('bash-completion', version : '>= 2.0', required : bashcomp_option)
492 493 494
bash_completions_dir = ''
bash_helpers_dir = ''

495 496 497
bashcomp_found = false
if bashcomp_dep.found()
  bashcomp_found = true
498
  bash_completions_dir = bashcomp_dep.get_pkgconfig_variable('completionsdir', define_variable: ['prefix', '.'])
499
  if bash_completions_dir == ''
500 501 502 503 504 505
    msg = 'Found bash-completion but the .pc file did not set \'completionsdir\'.'
    if bashcomp_option.enabled()
      error(msg)
    else
      message(msg)
    endif
506 507 508
    bashcomp_found = false
  endif

509
  bash_helpers_dir = bashcomp_dep.get_pkgconfig_variable('helpersdir', define_variable: ['prefix', '.'])
510
  if bash_helpers_dir == ''
511 512 513 514 515 516
    msg = 'Found bash-completion, but the .pc file did not set \'helpersdir\'.'
    if bashcomp_option.enabled()
      error(msg)
    else
      message(msg)
    endif
517 518 519 520
    bashcomp_found = false
  endif
endif

521 522 523 524 525 526 527 528 529
plugins_install_dir = join_paths(get_option('libdir'), 'gstreamer-1.0')

pkgconfig = import('pkgconfig')
plugins_pkgconfig_install_dir = join_paths(plugins_install_dir, 'pkgconfig')
if get_option('default_library') == 'shared'
  # If we don't build static plugins there is no need to generate pc files
  plugins_pkgconfig_install_dir = disabler()
endif

530 531 532
subdir('gst')
subdir('libs')
subdir('plugins')
533 534 535
if not get_option('tools').disabled()
  subdir('tools')
endif
536 537
subdir('pkgconfig')
subdir('tests')
538
subdir('data')
Thibault Saunier's avatar
Thibault Saunier committed
539
subdir('docs')
540

541
# xgettext is optional (on Windows for instance)
542 543
if find_program('xgettext', required : get_option('nls')).found()
  cdata.set('ENABLE_NLS', 1)
544 545 546
  subdir('po')
endif

547
configure_file(output : 'config.h', configuration : cdata)
548
run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")')
549
install_data('gst-element-check-1.0.m4', install_dir : join_paths(get_option('datadir'), 'aclocal'))