build: Add meson build

This replicates most of the current autotools build.

Code coverage is omitted, it should be possible to use built-in
Meson functionality.

Valgrind for tests has not been added, instead it can run as
meson test --wrap='valgrind --leak-check=full --error-exitcode=1'

Change-Id: I5566a6c30630c486d22390e126899dbe4a6331ce
Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..c6c6fe9
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,147 @@
+project(
+    'libmctp', 'c',
+    meson_version: '>= 1.1',
+    version: '0.11',
+    default_options: [
+        'debug=true',
+        'optimization=g',
+        'warning_level=2',
+        'werror=true',
+        'tests=' + (meson.is_subproject() ? 'disabled' : 'enabled'),
+    ],
+)
+
+sources = [
+     'core.c',
+     'alloc.c',
+     'log.c',
+]
+
+headers = [
+    'libmctp.h',
+]
+
+serial_sources = [
+    'serial.c',
+    'crc-16-ccitt.c',
+]
+
+serial_headers = [
+    'libmctp-serial.h'
+]
+
+astlpc_sources = [
+    'astlpc.c',
+    'crc32.c',
+]
+
+astlpc_headers = [
+    'libmctp-astlpc.h',
+]
+
+libmctp_sources = sources
+libmctp_headers = headers
+
+if get_option('bindings').contains('serial')
+    libmctp_sources += serial_sources
+    libmctp_headers += serial_headers
+endif
+if get_option('bindings').contains('astlpc')
+    libmctp_sources += astlpc_sources
+    libmctp_headers += astlpc_headers
+endif
+
+compiler = meson.get_compiler('c')
+
+if get_option('default_alloc').require(
+    compiler.links('''
+        #include <stdlib.h>
+        void main()
+        {
+            free(malloc(4096));
+        }
+    ''')).allowed()
+    add_project_arguments('-DMCTP_DEFAULT_ALLOC', language : 'c')
+endif
+
+if get_option('fileio').require(
+    compiler.check_header('unistd.h') and compiler.check_header('fcntl.h')
+    ).allowed()
+    add_project_arguments('-DMCTP_HAVE_FILEIO', language : 'c')
+endif
+
+if get_option('syslog').require(
+    compiler.links('''
+        #include <stdarg.h>
+        #include <syslog.h>
+        void check_vsyslog(int level, const char *fmt, ...)
+        {
+            va_list ap;
+            va_start(ap, fmt);
+            vsyslog(0, fmt, ap);
+            va_end(ap);
+        }
+        void main()
+        {
+            check_vsyslog(0, "\n");
+        }
+        ''')).allowed()
+    add_project_arguments('-DMCTP_HAVE_SYSLOG', language : 'c')
+endif
+
+if get_option('stdio').require(
+    compiler.links('''
+        #include <stdarg.h>
+        #include <stdio.h>
+        void check_vsyslog(const char *fmt, ...)
+        {
+            va_list ap;
+            va_start(ap, fmt);
+            vprintf(fmt, ap);
+            va_end(ap);
+        }
+        void main()
+        {
+            check_vsyslog("\n");
+        }
+        ''')).allowed()
+    add_project_arguments('-DMCTP_HAVE_STDIO', language : 'c')
+endif
+
+# pcap is necessary for mctp-demux-daemon to be functional
+pcap_dep = dependency('libpcap', required: false)
+
+systemd_dep = dependency('systemd', required: false)
+libsystemd_dep = dependency('libsystemd', required: false)
+
+libmctp_include_dir = include_directories('.', is_system: true)
+libmctp = library('mctp',
+    libmctp_sources,
+    include_directories: libmctp_include_dir,
+    version: meson.project_version(),
+    install: true,
+)
+install_headers(libmctp_headers)
+
+if systemd_dep.found()
+    unitdir = systemd_dep.get_variable(pkgconfig: 'systemdsystemunitdir')
+    install_data('systemd/system/mctp-demux.service', install_dir: unitdir)
+    install_data('systemd/system/mctp-demux.socket', install_dir: unitdir)
+endif
+
+import('pkgconfig').generate(libmctp,
+    name: 'libmctp',
+    description: 'MCTP protocol implementation',
+    version: meson.project_version(),
+)
+
+libmctp_dep = declare_dependency(
+    include_directories: libmctp_include_dir,
+    link_with: libmctp,
+)
+
+subdir('utils')
+
+if get_option('tests').allowed()
+    subdir('tests')
+endif
diff --git a/meson.options b/meson.options
new file mode 100644
index 0000000..f919ad8
--- /dev/null
+++ b/meson.options
@@ -0,0 +1,33 @@
+option(
+    'tests',
+    type: 'feature',
+    value: 'enabled',
+    description: 'Build tests'
+)
+option(
+    'bindings',
+    type: 'array',
+    description: 'Bindings to include',
+    choices: ['serial', 'astlpc'],
+    value: ['serial', 'astlpc'],
+)
+option(
+    'default_alloc',
+    type: 'feature',
+    description: 'Use libc malloc and free for heap memory',
+)
+option(
+    'stdio',
+    type: 'feature',
+    description: 'Support logging to stdio',
+)
+option(
+    'fileio',
+    type: 'feature',
+    description: 'Support interfaces based on file-descriptors',
+)
+option(
+    'syslog',
+    type: 'feature',
+    description: 'Support logging to syslog',
+)
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000..4ca52a0
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,28 @@
+
+tests = [
+    'test_eid',
+    'test_seq',
+    'test_bridge',
+    'test_cmds',
+    'test_core',
+    ]
+
+if get_option('bindings').contains('serial')
+    tests += 'test_serial'
+endif
+if get_option('bindings').contains('astlpc')
+    tests += 'test_astlpc'
+endif
+
+test_include_dirs = [include_directories('.'), libmctp_include_dir]
+foreach t : tests
+    test(
+        t,
+        executable(
+            t,
+            [t + '.c', 'test-utils.c'],
+            include_directories: test_include_dirs,
+            dependencies: [libmctp_dep],
+        ),
+    )
+endforeach
diff --git a/utils/meson.build b/utils/meson.build
new file mode 100644
index 0000000..ae03af8
--- /dev/null
+++ b/utils/meson.build
@@ -0,0 +1,32 @@
+demux_sources = ['mctp-demux-daemon.c']
+demux_args = []
+demux_dep = [libmctp_dep, pcap_dep, libsystemd_dep]
+# While mctp-demux-daemon will build without pcap, it won't
+# be functional.
+# TODO only build mctp-demux-daemon when pcap is available.
+if pcap_dep.found()
+    demux_args += '-DHAVE_PCAP'
+    demux_sources += 'mctp-capture.c'
+endif
+
+demux = executable('mctp-demux-daemon',
+    demux_sources,
+    include_directories: libmctp_include_dir,
+    dependencies: demux_dep,
+    c_args: demux_args,
+    install: true,
+)
+
+pipe = executable('mctp-pipe',
+    'mctp-pipe.c',
+    include_directories: libmctp_include_dir,
+    dependencies: [libmctp_dep],
+    install: false,
+)
+
+mctp_in = executable('mctp-in',
+    'mctp-in.c',
+    include_directories: libmctp_include_dir,
+    dependencies: [libmctp_dep],
+    install: false,
+)