Commit 0e0f89d2 authored by Tim-Philipp Müller's avatar Tim-Philipp Müller 🐠 Committed by Olivier Crête

Add support for Meson build system

parent ed70ea09
......@@ -185,3 +185,6 @@ ar-lib
# Code coverage
lcov/
# Meson builddir
_build/
agent_headers = files([
'address.h',
'agent.h',
'candidate.h',
'debug.h',
'interfaces.h',
'pseudotcp.h',
])
install_headers(agent_headers, subdir : 'nice')
agent_include = include_directories('.')
agent_sources = files([
'address.c',
'agent.c',
'candidate.c',
'component.c',
'conncheck.c',
'debug.c',
'discovery.c',
'inputstream.c',
'interfaces.c',
'iostream.c',
'outputstream.c',
'pseudotcp.c',
'stream.c',
])
gnome = import('gnome')
agent_enum_types = gnome.mkenums_simple('agent-enum-types', sources : agent_headers)
agent_enum_types_c = agent_enum_types[0]
agent_enum_types_h = agent_enum_types[1]
libagent = static_library('agent',
agent_enum_types, agent_sources,
c_args: ['-DG_LOG_DOMAIN="libnice"'],
include_directories: nice_incs,
dependencies: nice_deps,
install: false)
docpath = join_paths(nice_datadir, 'gtk-doc', 'html')
ignore_headers = [
'conncheck.h',
'discovery.h',
'stream.h',
'component.h',
'agent-priv.h',
'iostream.h',
'inputstream.h',
'outputstream.h',
'gstnice.h',
'gstnicesrc.h',
'gstnicesink.h',
'md5.h',
'sha1.h',
'stunhmac.h',
'utils.h',
'rand.h',
'stun5389.h',
'stuncrc32.h',
'stund.h',
'agent-signals-marshal.h',
'win32_common.h',
]
gnome.gtkdoc('libnice',
main_xml: 'libnice-docs.xml',
namespace: 'nice',
mode: 'none',
src_dir: ['agent', 'stun'],
dependencies: libnice_dep,
scan_args: [
'--rebuild-types',
#'--deprecated-guards=G_DISABLE_DEPRECATED',
#'--ignore-decorators=' + '|'.join(ignore_decorators),
'--ignore-headers=' + ' '.join(ignore_headers),
],
html_assets: [
'states.png',
],
fixxref_args:[
'--html-dir=' + docpath,
],
mkdb_args: [ # not sure if these need to be specified explicitly here
'--xml-mode',
'--output-format=xml',
'--name-space=Nice',
],
install: true)
# If we ever need to regenerate this diagram.
# Since it’s not expected to change much, let’s not depend on GraphViz to
# build the docs (that's also why we don't use find_program('dot') here)
run_target('update-states.png',
command: ['dot',
'-Tpng',
'-o', join_paths(meson.current_source_dir(), 'states.png'),
'-Gsize=9.6,2.9!',
'-Gdpi=200',
files('states.gv')])
examples = ['simple-example', 'threaded-example', 'sdp-example']
foreach ex : examples
executable(ex, '@0@.c'.format(ex),
include_directories: nice_incs,
dependencies: [libnice_dep, glib_dep, gupnp_igd_dep],
install: false)
endforeach
gst_nice_sources = [
'gstnicesrc.c',
'gstnicesink.c',
'gstnice.c',
]
gst_nice_args = ['-DGST_USE_UNSTABLE_API']
libgstnice = library('gstnice',
gst_nice_sources,
c_args : gst_nice_args,
include_directories: nice_incs,
dependencies: [nice_deps, gst_dep],
link_with: libnice,
install_dir: join_paths(get_option('libdir'), 'gstreamer-1.0'),
install: true)
project('libnice', 'c',
version: '0.1.14.1',
meson_version : '>= 0.47.0',
default_options : ['warning_level=1', 'buildtype=debugoptimized'])
nice_version = meson.project_version()
version_arr = nice_version.split('.')
version_major = version_arr[0]
version_minor = version_arr[1]
version_micro = version_arr[2]
if version_arr.length() == 4
version_nano = version_arr[3]
else
version_nano = 0
endif
# maintain compatibility with the previous libtool versioning
soversion = 10
libversion = '10.6.2'
glib_req = '>= 2.44'
gnutls_req = '>= 2.12.0'
gupnp_igd_req = '>= 0.2.4'
gst_req = '>= 1.0.0'
nice_datadir = join_paths(get_option('prefix'), get_option('datadir'))
cc = meson.get_compiler('c')
syslibs = []
if host_machine.system() == 'windows'
syslibs += [cc.find_library('iphlpapi')]
syslibs += [cc.find_library('ws2_32')]
elif host_machine.system() == 'sunos'
add_project_arguments('-D_XOPEN_SOURCE=600', language: 'c')
add_project_arguments('-D__EXTENSIONS__=1', language: 'c')
# inet_pton() is only used by the tests
syslibs += [cc.find_library('nsl')]
if not cc.has_function('inet_pton')
libnsl = cc.find_library('nsl', required: false)
if libnsl.found() and cc.has_function('inet_pton', dependencies: libnsl)
syslibs += [libnsl]
endif
endif
if not cc.has_function('socket')
libsocket = cc.find_library('socket', required: false)
libinet = cc.find_library('inet', required: false)
if cc.has_function('socket', dependencies: libsocket)
syslibs += [libsocket]
elif cc.has_function('socket', dependencies: libinet)
syslibs += [libinet]
else
error('Could not find right library for socket() on Solaris')
endif
endif
endif
if not cc.has_function('clock_gettime')
librt = cc.find_library('rt', required: false)
if cc.has_function('clock_gettime', dependencies: librt)
syslibs += [librt]
else
error('Could not find right library for clock_gettime()')
endif
endif
glib_req_minmax_str = glib_req.split().get(1).underscorify()
add_project_arguments('-D_GNU_SOURCE',
'-DHAVE_CONFIG_H',
'-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_' + glib_req_minmax_str,
'-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_' + glib_req_minmax_str,
language: 'c')
cdata = configuration_data()
cdata.set_quoted('PACKAGE_STRING', meson.project_name())
cdata.set_quoted('PACKAGE_NAME', meson.project_name())
cdata.set_quoted('PACKAGE', meson.project_name())
cdata.set_quoted('VERSION', meson.project_version())
cdata.set('NICEAPI_EXPORT', true,
description: 'Public library function implementation')
# headers
foreach h : ['arpa/inet.h', 'net/in.h', 'netdb.h', 'ifaddrs.h']
if cc.has_header(h)
define = 'HAVE_' + h.underscorify().to_upper()
cdata.set(define, 1)
endif
endforeach
# functions
foreach f : ['poll', 'getifaddrs']
if cc.has_function(f)
define = 'HAVE_' + f.underscorify().to_upper()
cdata.set(define, 1)
endif
endforeach
if cc.has_argument('-fno-strict-aliasing')
add_project_arguments('-fno-strict-aliasing', language: 'c')
endif
# Extra compiler warnings (FIXME: not sure this makes sense to keep like this)
warning_level = get_option('warning_level').to_int()
werror = get_option('werror')
warnings = []
message('warning level: @0@'.format(warning_level))
message('werror enabled: @0@'.format(werror))
if warning_level >= 2
warnings += [
'-Wextra',
'-Wundef',
'-Wnested-externs',
'-Wwrite-strings',
'-Wpointer-arith',
'-Wmissing-declarations',
'-Wmissing-prototypes',
'-Wstrict-prototypes',
'-Wredundant-decls',
'-Wno-unused-parameter',
'-Wno-missing-field-initializers',
'-Wdeclaration-after-statement',
'-Wformat=2',
'-Wold-style-definition',
'-Wcast-align',
'-Wformat-nonliteral',
'-Wformat-security',
]
endif
if warning_level >= 3
warnings += [
'-Wsign-compare',
'-Wstrict-aliasing',
'-Wshadow',
'-Winline',
'-Wpacked',
'-Wmissing-format-attribute',
'-Winit-self',
'-Wredundant-decls',
'-Wmissing-include-dirs',
'-Wunused-but-set-variable',
'-Warray-bounds',
]
warnings += [
'-Wswitch-default',
'-Waggregate-return',
]
endif
if werror
warnings += [
'-Wno-suggest-attribute=format',
'-Wno-cast-function-type',
]
endif
foreach w : warnings
if cc.has_argument(w)
add_project_arguments(w, language: 'c')
endif
endforeach
# Dependencies
gnutls_dep = dependency('gnutls', version: gnutls_req)
glib_dep = dependency('gio-2.0', version: glib_req)
gthread_dep = dependency('gthread-2.0')
# GStreamer
gst_dep = dependency('gstreamer-base-1.0', version: gst_req,
required: get_option('gstreamer'),
fallback : ['gstreamer', 'gst_base_dep'])
cdata.set('HAVE_GSTREAMER', gst_dep.found(), description: 'Build GStreamer plugin')
# GUPnP IGD
gupnp_igd_dep = dependency('gupnp-igd-1.0', version: gupnp_igd_req, required: get_option('gupnp'))
cdata.set('HAVE_GUPNP', gupnp_igd_dep.found(), description: 'Use the GUPnP IGD library')
libm = cc.find_library('m', required: false)
nice_incs = include_directories('.', 'agent', 'random', 'socket', 'stun')
nice_deps = [glib_dep, gthread_dep, gnutls_dep, gupnp_igd_dep] + syslibs
ignored_iface_prefix = get_option('ignored-network-interface-prefix')
if ignored_iface_prefix != ''
cdata.set_quoted('IGNORED_IFACE_PREFIX', ignored_iface_prefix)
endif
subdir('agent')
subdir('stun')
subdir('socket')
subdir('random')
subdir('nice')
if gst_dep.found()
subdir('gst')
endif
if not get_option('gtk_doc').disabled()
subdir('docs/reference/libnice')
endif
if not get_option('tests').disabled()
subdir('tests')
endif
if not get_option('examples').disabled()
subdir('examples')
endif
configure_file(output : 'config.h', configuration : cdata)
option('gupnp', type: 'feature', value: 'auto',
description: 'Enable or disable GUPnP IGD support')
option('gstreamer', type: 'feature', value: 'auto',
description: 'Enable or disable build of GStreamer plugins')
option('ignored-network-interface-prefix', type: 'string', value: '',
description: 'Ignore network interfaces whose name starts with this string in the ICE connection check algorithm. For example, "virbr" to ignore virtual bridge interfaces added by virtd, which do not help in finding connectivity.')
# Common feature options
option('examples', type : 'feature', value : 'auto', yield : true,
description: 'Build examples')
option('tests', type : 'feature', value : 'auto', yield : true,
description: 'Enable or disable unit tests')
option('gtk_doc', type : 'feature', value : 'disabled', yield : true,
description: 'Generate API documentation with gtk-doc')
option('introspection', type : 'feature', value : 'auto', yield : true,
description : 'Generate gobject-introspection bindings')
#!/usr/bin/env python3
#
# gen-def.py LIBNICE.SYM
import os
import sys
try:
sym_file = sys.argv[1]
except:
print('Usage: gen-def.py SYM-FILE')
exit(-1)
f = open(os.path.join(sym_file), 'r')
print('EXPORTS')
for line in f:
print(' ' + line.strip())
f.close()
#!/usr/bin/env python3
#
# gen-map.py LIBNICE.SYM
import os
import sys
try:
sym_file = sys.argv[1]
except:
print('Usage: gen-map.py SYM-FILE')
exit(-1)
f = open(os.path.join(sym_file), 'r')
print('''libnice {
global:''')
for line in f:
print('\t' + line.strip() + ';')
print('''};
HIDDEN {
local:
*;
};''')
f.close()
......@@ -60,6 +60,7 @@ nice_agent_set_stream_tos
nice_candidate_copy
nice_candidate_equal_target
nice_candidate_free
nice_candidate_get_type
nice_candidate_new
nice_component_state_to_string
nice_debug_disable
......
nice_gen_sources = []
nice_link_args = []
# libnice.def
libnice_def = custom_target('libnice.def',
command: [find_program('gen-def.py'), '@INPUT@'],
input: 'libnice.sym',
output: 'libnice.def',
capture: true)
# map file
mapfile = custom_target('libnice.map',
command: [find_program('gen-map.py'), '@INPUT@'],
input: 'libnice.sym',
output: 'libnice.map',
capture: true)
# We need to check with a file that exists at configure time!
if cc.has_link_argument('-Wl,--version-script,@0@/libnice.ver'.format(meson.current_source_dir()))
nice_link_args += ['-Wl,--version-script,@0@'.format(mapfile.full_path())]
endif
libnice = library('nice',
link_whole: [libagent, libsocket, libstun, librandom],
version : libversion,
soversion : soversion,
vs_module_defs: libnice_def,
link_args: nice_link_args,
link_depends: mapfile,
install: true)
install_headers('nice.h', subdir: 'nice')
nice_include = include_directories('.')
# introspection
build_gir = not get_option('introspection').disabled() and get_option('default_library') != 'static'
if build_gir
nice_gen_sources += [
gnome.generate_gir(libnice,
sources : [agent_headers, agent_sources],
namespace : 'Nice',
nsversion : '0.1',
identifier_prefix : 'Nice',
symbol_prefix: 'nice',
export_packages: 'nice',
includes: ['GObject-2.0', 'Gio-2.0'],
extra_args: ['--accept-unprefixed'],
install: true)
]
endif
libnice_dep = declare_dependency(link_with : libnice,
include_directories : [agent_include, nice_include],
# Everything that uses libnice needs this built to compile
sources : nice_gen_sources)
# pkg-config file
pkg = import('pkgconfig')
upnp_enabled_string = gupnp_igd_dep.found() ? 'true' : 'false'
pkg.generate(libnice,
name: 'libnice',
filebase: 'nice',
subdirs: 'nice',
description: 'ICE library',
requires: glib_dep,
requires_private: [gthread_dep, gupnp_igd_dep, gnutls_dep, syslibs],
variables: ['upnp_enabled=@0@'.format(upnp_enabled_string)])
librandom = static_library('nice-random',
'random.c', 'random-glib.c',
c_args: ['-DG_LOG_DOMAIN="libnice-random"'],
include_directories: nice_incs,
dependencies: [glib_dep, gthread_dep],
install: false)
if not get_option('tests').disabled()
test_exe = executable('nice-random-test', 'test.c',
include_directories: nice_incs,
dependencies: [glib_dep, gthread_dep],
link_with: librandom)
test('nice-random', test_exe)
endif
socket_sources = [
'socket.c',
'udp-bsd.c',
'tcp-bsd.c',
'tcp-active.c',
'tcp-passive.c',
'pseudossl.c',
'socks5.c',
'http.c',
'udp-turn.c',
'udp-turn-over-tcp.c',
]
libsocket = static_library('socket', socket_sources,
c_args: ['-DG_LOG_DOMAIN="libnice-socket"'],
include_directories: nice_incs,
dependencies: nice_deps,
install: false)
stun_sources = [
'stunagent.c',
'stunmessage.c',
'stun5389.c',
'stuncrc32.c',
'rand.c',
'stunhmac.c',
'utils.c',
'debug.c',
'usages/ice.c',
'usages/bind.c',
'usages/turn.c',
'usages/timer.c',
]
install_headers(
'stunagent.h',
'stunmessage.h',
'win32_common.h', # installed unconditionally?!
'debug.h',
'constants.h', subdir: 'stun')
install_headers(
'usages/bind.h',
'usages/ice.h',
'usages/turn.h',
'usages/timer.h', subdir: 'stun/usages')
libstun = static_library('stun', stun_sources,
c_args: ['-DG_LOG_DOMAIN="libnice-stun"'],
include_directories: nice_incs,
dependencies: nice_deps,
install: false)
subdir('tools')
if not get_option('tests').disabled()
subdir('tests')
endif
#! /bin/sh
STUNC=../tools/stunbdc
STUND=../tools/stund
if test -n "${BUILT_WITH_MESON}"; then
STUNC=$1
STUND=$2
else
STUNC=../tools/stunbdc
STUND=../tools/stund
fi
cleanup() {
rm -f stund?.pid stund?.fail stunc?.log
}
trap cleanup EXIT
set -xe
......@@ -23,7 +34,7 @@ fi
echo "Using local UDP port number $PORT ..."
# Start the STUN test daemon if needed
rm -f stund?.pid stund?.fail stunc?.log
cleanup()
for v in 4 6; do
(($SHELL -c "echo \$\$ > stund$v.pid ; exec $STUND -$v $PORT") || \
......@@ -44,5 +55,3 @@ grep -e "^Mapped address: 127.0.0.1" stunc4.log || exit 4
if test -f stund6.fail; then exit 77; fi
grep -e "^Mapped address: ::1" stunc6.log || exit 6
rm -f stund?.fail stund?.pid stunc?.log
foreach t : ['parse', 'format', 'bind', 'conncheck', 'hmac']
test_name = 'test-@0@'.format(t)
exe = executable(test_name, test_name + '.c',
include_directories: nice_incs,
dependencies: syslibs,
link_with: libstun)
test(test_name, exe)
endforeach
# XXX: This test is broken and unused since 2007, ocrete knows about it
# If we enable it, we may want to put it in a separate suite that's only run on
# dist because it takes a long time to run since it tests stun timeouts.
if false and find_program('sh', required : false).found()
test('test-check-bind', find_program('check-bind.sh'),
timeout: 600,
env: 'BUILT_WITH_MESON=1',
args: [stunbdc_exe, stund_exe])
endif
stund_exe = executable('stund', 'stund.c',
include_directories: nice_incs,
link_with: libstun,
install: true)
stunbdc_exe = executable('stunbdc', 'stunbdc.c',
include_directories: nice_incs,
dependencies: syslibs,
link_with: libstun,
install: true)
......@@ -57,7 +57,6 @@
#ifndef _WIN32_COMMON_H
#define _WIN32_COMMON_H
#include "config.h"
#include <sys/types.h>
/* 7.18.1.1 Exact-width integer types */
......@@ -70,26 +69,21 @@ typedef unsigned uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
/* Using the [S]SIZE_T definitions from:
* http://msdn.microsoft.com/en-gb/library/windows/desktop/aa383751%28v=vs.85%29.aspx#SSIZE_T */
#ifndef HAVE_SIZE_T
#if defined(_WIN64)
/* size_t and ssize_t are not defined on Windows */
#ifndef size_t
# if defined(_WIN64)
typedef unsigned __int64 size_t;
#else
# else
typedef unsigned long size_t;
#endif
#endif /* !HAVE_SSIZE_T */
#ifndef HAVE_SSIZE_T
#if defined(_WIN64)
# endif
#endif /* !size_t */
#ifndef ssize_t
# if defined(_WIN64)
typedef signed __int64 ssize_t;
#else
# else
typedef signed long ssize_t;
#endif
#endif /* !HAVE_SSIZE_T */
typedef uint8_t bool;
#define true 1
#define false 0
# endif
#endif /* !ssize_t */
#endif /* _WIN32_COMMON_H */
#! /bin/sh
STUND=../stun/tools/stund
if test -n "${BUILT_WITH_MESON}"; then
STUND=$1
TEST_FULLMODE=$2
else
STUND=../stun/tools/stund
TEST_FULLMODE=./test-fullmode
fi
echo "Starting ICE full-mode with STUN unit test."
......@@ -15,13 +21,13 @@ pidfile=./stund.pid
export NICE_STUN_SERVER=127.0.0.1
export NICE_STUN_SERVER_PORT=3800
echo "Launching stund on port ${NICE_STUN_SERVER_PORT}."
echo "Launching $STUND on port ${NICE_STUN_SERVER_PORT}."
rm -f -- "$pidfile"
(sh -c "echo \$\$ > \"$pidfile\" && exec "$STUND" ${NICE_STUN_SERVER_PORT}") &
sleep 1
./test-fullmode
"${TEST_FULLMODE}"
error=$?
kill "$(cat "$pidfile")"
......
nice_tests = [
'test-pseudotcp',
'test-pseudotcp-fin',
'test-pseudotcp-fuzzy',
'test-bsd',
'test',
'test-address',
'test-add-remove-stream',
'test-build-io-stream',
'test-io-stream-thread',
'test-io-stream-closing-write',
'test-io-stream-closing-read',
'test-io-stream-cancelling',
'test-io-stream-pollable',
'test-send-recv',
'test-socket-is-based-on',
'test-priority',
'test-fullmode',
'test-different-number-streams',
'test-restart',
'test-fallback',
'test-thread',
'test-dribble',
'test-new-dribble',
'test-tcp',
'test-icetcp',
'test-credentials',
'test-turn',
'test-drop-invalid',
'test-nomination',
]
tenv = environment()
tenv.set('BUILT_WITH_MESON', '1')
foreach tname : nice_tests
if tname.startswith('test-io-stream') or tname.startswith('test-send-recv')
extra_src = ['test-io-stream-common.c']
else
extra_src = []
endif
exe = executable('nice-@0@'.format(tname),
'@0@.c'.format(tname), extra_src,
c_args: '-DG_LOG_DOMAIN="libnice-tests"',
include_directories: nice_incs,
dependencies: [nice_deps, libm],
link_with: [libagent, libstun, libsocket, librandom],
install: false)
set_variable(tname.underscorify(), exe)
test(tname, exe, env: tenv)
endforeach
if gst_dep.found()
gst_check = dependency('gstreamer-check-1.0', required: get_option('gstreamer'),
fallback : ['gstreamer', 'gst_check_dep'])
if gst_check.found()
exe = executable('nice-test-gstreamer',
'test-gstreamer.c', extra_src,
c_args: '-DG_LOG_DOMAIN="libnice-tests"',
include_directories: nice_incs,
dependencies: [nice_deps, gst_check, libm],
link_with: libnice,
install: false)
test('test-gstreamer', exe, env: tenv)
endif
endif
if find_program('sh', required : false).found()
dd = find_program('dd', required : false)
diff = find_program('diff', required : false)
if dd.found() and diff.found()