]> git.proxmox.com Git - mirror_lxc.git/blobdiff - meson.build
Merge pull request #4287 from hallyn/2023-03-10/dbus
[mirror_lxc.git] / meson.build
index 21eba6d1ebf2155a8296bb0a9ee1690819ee597c..cb6f17fa4c58791982df138e5d5984336868cd37 100644 (file)
@@ -10,7 +10,7 @@ project(
         'b_lto=true',
         'b_lto_mode=thin',
         'b_colorout=always',
-        'b_asneeded=true',
+        'b_asneeded=false',
         'b_pie=true',
         'b_staticpic=true',
         'c_std=gnu11',
@@ -22,6 +22,9 @@ cc = meson.get_compiler('c')
 pkgconfig = import('pkgconfig')
 pkgconfig_libs = []
 
+liblxc_dependencies = []
+oss_fuzz_dependencies = []
+
 # Version.
 liblxc_version = '1.7.0'
 version_data = configuration_data()
@@ -85,6 +88,11 @@ srcconf = configuration_data()
 srcconf.set('_GNU_SOURCE', true)
 srcconf.set('_FILE_OFFSET_BITS', 64)
 srcconf.set('__STDC_FORMAT_MACROS', true)
+
+## This is a hack to prevent any inclusion ofr linux/mount.h which causes
+## conflicts with sys/mount.h all over the place
+srcconf.set('_LINUX_MOUNT_H', true)
+
 srcconf.set_quoted('APPARMOR_CACHE_DIR', lxcapparmorcachedir)
 srcconf.set_quoted('LIBEXECDIR', libexecdir)
 srcconf.set_quoted('LOGPATH', lxclogpath)
@@ -117,14 +125,18 @@ conf.set('SYSCONFDIR', sysconfdir)
 
 # Set sysconfdir
 fs = import('fs')
-if fs.is_dir('/etc/sysconfig')
+distrosysconfdir = get_option('distrosysconfdir')
+if distrosysconfdir != ''
+    distrosysconfdir = join_paths(sysconfdir, distrosysconfdir)
+    conf.set('LXC_DISTRO_SYSCONF', distrosysconfdir)
+elif fs.is_dir('/etc/sysconfig')
     distrosysconfdir = join_paths(sysconfdir, 'sysconfig')
     conf.set('LXC_DISTRO_SYSCONF', distrosysconfdir)
 elif fs.is_dir('/etc/default')
     distrosysconfdir = join_paths(sysconfdir, 'default')
     conf.set('LXC_DISTRO_SYSCONF', distrosysconfdir)
 else
-    distrosysconfdir = ''
+    error('"distrosysconfdir" is not set')
 endif
 
 # Cross-compile on Android.
@@ -151,7 +163,7 @@ want_oss_fuzz = get_option('oss-fuzz')
 want_seccomp = get_option('seccomp')
 want_thread_safety = get_option('thread-safety')
 want_memfd_rexec = get_option('memfd-rexec')
-want_sd_bus = get_option('sd-bus')
+want_dbus = get_option('dbus')
 
 srcconf.set_quoted('DEFAULT_CGROUP_PATTERN', cgrouppattern)
 if coverity
@@ -177,7 +189,6 @@ possible_cc_flags = [
     '-Wstrict-prototypes',
     '-fno-strict-aliasing',
     '-fstack-clash-protection',
-    '-fstack-protector-strong',
     '--param=ssp-buffer-size=4',
     '--mcet -fcf-protection',
     '-Werror=implicit-function-declaration',
@@ -210,13 +221,19 @@ possible_cc_flags = [
 ]
 
 possible_link_flags = [
+    '-Wl,--no-as-needed',
     '-Wl,--gc-sections',
     '-Wl,-z,relro',
     '-Wl,-z,now',
-    '-Wl,-fuse-ld=gold',
     '-fstack-protector',
+    '-fstack-protector-strong',
 ]
 
+# The gold linker fails with a bus error on sparc64
+if build_machine.cpu_family() != 'sparc64'
+    possible_link_flags += '-Wl,-fuse-ld=gold'
+endif
+
 if sanitize == 'none'
     possible_link_flags += '-Wl,--warn-common'
 endif
@@ -251,53 +268,21 @@ if want_io_uring
     if cc.has_function('io_uring_prep_poll_add', prefix: '#include <liburing.h>', dependencies: liburing) == false
         error('liburing version does not support IORING_POLL_ADD_MULTI')
     endif
+    pkgconfig_libs += liburing
+    liblxc_dependencies += liburing
 
     srcconf.set10('HAVE_LIBURING', true)
 else
     srcconf.set10('HAVE_LIBURING', false)
 endif
 
-if not want_sd_bus.disabled()
-    has_sd_bus = true
-    sd_bus_optional = want_sd_bus.auto()
-
-    libsystemd = dependency('libsystemd', required: not sd_bus_optional)
-    if not libsystemd.found()
-        if not sd_bus_optional
-            error('missing required libsystemd dependency')
-        endif
-
-        has_sd_bus = false
-    endif
-
-    if not cc.has_header('systemd/sd-bus.h')
-        if not sd_bus_optional
-            error('libsystemd misses required systemd/sd-bus.h header')
-        endif
-
-        has_sd_bus = false
-    endif
-
-    if not cc.has_header('systemd/sd-event.h')
-        if not sd_bus_optional
-            error('libsystemd misses required systemd/sd-event.h header')
-        endif
-
-        has_sd_bus = false
-    endif
-
-    if not cc.has_function('sd_bus_call_method_asyncv', prefix: '#include <systemd/sd-bus.h>', dependencies: libsystemd) 
-        if not sd_bus_optional
-            error('libsystemd misses required sd_bus_call_method_asyncv function')
-        endif
-
-        has_sd_bus = false
-    endif
-
-    srcconf.set10('HAVE_LIBSYSTEMD', has_sd_bus)
+if want_dbus
+    libdbus = dependency('dbus-1', required: true)
+    pkgconfig_libs += libdbus
+    liblxc_dependencies += libdbus
+    srcconf.set10('HAVE_DBUS', libdbus.found())
 else
-    has_sd_bus = false
-    srcconf.set10('HAVE_LIBSYSTEMD', false)
+    srcconf.set10('HAVE_DBUS', false)
 endif
 
 ## Time EPOCH.
@@ -309,20 +294,17 @@ if time_epoch == '' and git.found() and run_command('test', '-e', '.git', check:
     # If we're in a git repository, use the creation time of the latest git tag.
     latest_tag = run_command(git, 'describe', '--abbrev=0', '--tags', check: false).stdout().strip()
     if latest_tag != ''
-      time_epoch = run_command(git, 'log', '--no-show-signature', '-1', '--format=%at', latest_tag, check: true).stdout()
+      time_epoch = run_command(git, 'log', '--no-show-signature', '-1', '--format=%at', latest_tag, check: true).stdout().strip()
     endif
 endif
 
 # Fallback to current epoch.
 if time_epoch == ''
-    time_epoch = run_command(date, '+%s', check: true).stdout()
+    time_epoch = run_command(date, '+%s', check: true).stdout().strip()
 endif
 generate_date = run_command(date, '--utc', '--date=@' + time_epoch, '+%Y-%m-%d', check: true).stdout().strip()
 
 ## Manpages.
-sgml2man = find_program('docbook2X2man', 'docbook2x-man', 'db2x_docbook2man', 'docbook2man', 'docbook-to-man', required: want_mans)
-docbook2man = find_program('docbook2man', required: false)
-
 docconf = configuration_data()
 docconf.set('builddir', '.')
 docconf.set('BINDIR', bindir)
@@ -337,20 +319,27 @@ docconf.set('LXCTEMPLATEDIR', lxctemplatedir)
 docconf.set('LXC_USERNIC_CONF', lxc_user_network_conf)
 docconf.set('LXC_USERNIC_DB', lxc_user_network_db)
 docconf.set('PACKAGE_VERSION', version_data.get('LXC_VERSION'))
-if sgml2man.found() and docbook2man.found() and sgml2man.full_path() == docbook2man.full_path()
-    docconf.set('docdtd', '"-//Davenport//DTD DocBook V3.0//EN"')
-else
-    docconf.set('docdtd', '"-//OASIS//DTD DocBook XML" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"')
+docconf.set('docdtd', '"-//OASIS//DTD DocBook XML" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"')
+sgml2man = find_program('docbook2X2man', 'docbook2x-man', 'db2x_docbook2man', 'docbook2man', 'docbook-to-man', required: false, version: '>=0.8')
+if not sgml2man.found()
+    sgml2man = find_program('docbook2man', required: false, version: '<0.8')
+    if sgml2man.found()
+        docconf.set('docdtd', '"-//Davenport//DTD DocBook V3.0//EN"')
+    elif want_mans
+        error('missing required docbook2x or docbook-utils dependency')
+    endif
 endif
 
 ## Threads.
 threads = dependency('threads')
+liblxc_dependencies += threads
 
 ## Seccomp.
 if want_seccomp
     libseccomp = dependency('libseccomp', required: false)
     srcconf.set10('HAVE_SECCOMP', libseccomp.found())
     pkgconfig_libs += libseccomp
+    liblxc_dependencies += libseccomp
     if libseccomp.found()
         if libseccomp.version().version_compare('>=2.5.0')
             # https://github.com/seccomp/libseccomp/commit/dead12bc788b259b148cc4d93b970ef0bd602b1a
@@ -377,7 +366,7 @@ if want_seccomp
         ]
 
             # We get -1 if the size cannot be determined
-            if cc.sizeof(decl, prefix: seccomp_headers, args: '-D_GNU_SOURCE') > 0
+            if cc.sizeof(decl, prefix: seccomp_headers, args: '-D_GNU_SOURCE', dependencies: libseccomp) > 0
                 srcconf.set10('HAVE_' + decl.underscorify().to_upper(), true)
             else
                 srcconf.set10('HAVE_' + decl.underscorify().to_upper(), false)
@@ -393,6 +382,7 @@ if want_selinux
     libselinux = dependency('libselinux', required: false)
     srcconf.set10('HAVE_SELINUX', libselinux.found())
     pkgconfig_libs += libselinux
+    liblxc_dependencies += libselinux
 else
     srcconf.set10('HAVE_SELINUX', false)
 endif
@@ -401,6 +391,8 @@ endif
 if want_apparmor
     libapparmor = dependency('libapparmor', required: false)
     srcconf.set10('HAVE_APPARMOR', libapparmor.found())
+    # We do not use the AppArmor library at runtime, so it's not in our pkg-config.
+    liblxc_dependencies += libapparmor
 else
     srcconf.set10('HAVE_APPARMOR', false)
 endif
@@ -410,6 +402,7 @@ if want_openssl
     libopenssl = dependency('openssl', required: false)
     srcconf.set10('HAVE_OPENSSL', libopenssl.found())
     pkgconfig_libs += libopenssl
+    liblxc_dependencies += libopenssl
 else
     srcconf.set10('HAVE_OPENSSL', false)
 endif
@@ -420,9 +413,13 @@ if want_capabilities
     if not libcap.found()
         # Compat with Ubuntu 14.04 which ships libcap w/o .pc file
         libcap = cc.find_library('cap', required: false)
+    else
+        have = cc.has_function('cap_get_file', dependencies: libcap, prefix: '#include <sys/capability.h>')
+        srcconf.set10('LIBCAP_SUPPORTS_FILE_CAPABILITIES', have)
     endif
     srcconf.set10('HAVE_LIBCAP', libcap.found())
     pkgconfig_libs += libcap
+    liblxc_dependencies += libcap
 
     libcap_static = dependency('libcap', required: false, static: true)
     if not libcap_static.found()
@@ -435,15 +432,19 @@ int main(int argc, char *argv[]) { return 0; };
 '''
     if libcap_static.found()
         libcap_static_linkable = cc.links(code, args: '-static', dependencies: libcap_static)
-        srcconf.set10('HAVE_STATIC_LIBCAP', libcap_static_linkable)
     else
-        srcconf.set10('HAVE_STATIC_LIBCAP', false)
+        libcap_static_linkable = false
     endif
+    srcconf.set10('HAVE_STATIC_LIBCAP', libcap_static_linkable)
 else
+    libcap_static = []
+    libcap_static_linkable = false
     srcconf.set10('HAVE_LIBCAP', false)
     srcconf.set10('HAVE_STATIC_LIBCAP', false)
 endif
 
+libutil = cc.find_library('util', required: false)
+
 if want_oss_fuzz
     srcconf.set10('FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION', true)
     srcconf.set10('RUN_ON_OSS_FUZZ', true)
@@ -459,11 +460,26 @@ srcconf.set10('HAVE_PAM', pam.found())
 pkgconfig_libs += pam
 
 ## Others.
-have = cc.has_function('strchrnul', prefix: '#include <string.h>', args: '-D_GNU_SOURCE')
-srcconf.set10('HAVE_STRCHRNUL', have)
+have = cc.has_function('fmemopen', prefix: '#include <stdio.h>', args: '-D_GNU_SOURCE')
+srcconf.set10('HAVE_FMEMOPEN', have)
 
-have = cc.has_function('openpty', prefix: '#include <pty.h>', args: '-D_GNU_SOURCE')
+have = cc.has_function('openpty', dependencies: libutil, prefix: '#include <pty.h>')
 srcconf.set10('HAVE_OPENPTY', have)
+if have
+    liblxc_dependencies += libutil
+    if want_oss_fuzz
+        oss_fuzz_dependencies += libutil
+    endif
+endif
+
+have = cc.has_function('pthread_setcancelstate', prefix: '#include <pthread.h>')
+srcconf.set10('HAVE_PTHREAD_SETCANCELSTATE', have)
+
+have = cc.has_function('rand_r')
+srcconf.set10('HAVE_RAND_R', have)
+
+have = cc.has_function('strchrnul', prefix: '#include <string.h>', args: '-D_GNU_SOURCE')
+srcconf.set10('HAVE_STRCHRNUL', have)
 
 have_func_strerror_r = cc.has_function('strerror_r', prefix: '#include <string.h>', args: '-D_GNU_SOURCE')
 srcconf.set10('HAVE_STRERROR_R', have_func_strerror_r)
@@ -538,6 +554,7 @@ foreach tuple: [
     ['sigdescr_np'],
     ['signalfd'],
     ['statx'],
+    ['statvfs'],
     ['strlcat'],
     ['strlcpy'],
     ['unshare'],
@@ -563,17 +580,15 @@ decl_headers = '''
 #include <uchar.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
-#include <linux/fs.h>
+#include <linux/if_link.h>
 #include <linux/types.h>
-#include <linux/openat2.h>
-#include <linux/sched.h>
 '''
 
 foreach decl: [
     '__aligned_u64',
-    'struct mount_attr',
-    'struct open_how',
     'struct clone_args',
+    'struct open_how',
+    'struct rtnl_link_stats64',
 ]
 
     # We get -1 if the size cannot be determined
@@ -591,8 +606,8 @@ foreach tuple: [
     ['struct seccomp_notif_sizes'],
     ['struct clone_args'],
     ['__aligned_u64'],
-    ['struct mount_attr'],
     ['struct open_how'],
+    ['struct rtnl_link_stats64'],
 ]
 
     if tuple.length() >= 2
@@ -610,6 +625,75 @@ foreach tuple: [
     endif
 endforeach
 
+decl_headers = '''
+#include <sys/mount.h>
+'''
+
+# We get -1 if the size cannot be determined
+if cc.sizeof('struct mount_attr', prefix: decl_headers, args: '-D_GNU_SOURCE') > 0
+    srcconf.set10('HAVE_' + 'struct mount_attr'.underscorify().to_upper(), true)
+    found_types += 'struct mount_attr (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'struct mount_attr'.underscorify().to_upper(), false)
+    missing_types += 'struct mount_attr (sys/mount.h)' endif
+
+## Check if sys/mount.h defines the fsconfig commands
+if cc.get_define('FSCONFIG_SET_FLAG', prefix: decl_headers) != ''
+    srcconf.set10('HAVE_' + 'FSCONFIG_SET_FLAG'.underscorify().to_upper(), true)
+    found_types += 'FSCONFIG_SET_FLAG (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'FSCONFIG_SET_FLAG'.underscorify().to_upper(), false)
+    missing_types += 'FSCONFIG_SET_FLAG (sys/mount.h)'
+endif
+
+if cc.get_define('FS_CONFIG_SET_STRING', prefix: decl_headers) != ''
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_STRING'.underscorify().to_upper(), true)
+    found_types += 'FS_CONFIG_SET_STRING (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_STRING'.underscorify().to_upper(), false)
+    missing_types += 'FS_CONFIG_SET_STRING (sys/mount.h)'
+endif
+
+if cc.get_define('FS_CONFIG_SET_BINARY', prefix: decl_headers) != ''
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_BINARY'.underscorify().to_upper(), true)
+    found_types += 'FS_CONFIG_SET_BINARY (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_BINARY'.underscorify().to_upper(), false)
+    missing_types += 'FS_CONFIG_SET_BINARY (sys/mount.h)'
+endif
+
+if cc.get_define('FS_CONFIG_SET_PATH_EMPTY', prefix: decl_headers) != ''
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_PATH_EMPTY'.underscorify().to_upper(), true)
+    found_types += 'FS_CONFIG_SET_PATH_EMPTY (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_PATH_EMPTY'.underscorify().to_upper(), false)
+    missing_types += 'FS_CONFIG_SET_PATH_EMPTY (sys/mount.h)'
+endif
+
+if cc.get_define('FS_CONFIG_SET_PATH_FD', prefix: decl_headers) != ''
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_PATH_FD'.underscorify().to_upper(), true)
+    found_types += 'FS_CONFIG_SET_PATH_FD (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_PATH_FD'.underscorify().to_upper(), false)
+    missing_types += 'FS_CONFIG_SET_PATH_FD (sys/mount.h)'
+endif
+
+if cc.get_define('FS_CONFIG_SET_CMD_CREATE', prefix: decl_headers) != ''
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_CMD_CREATE'.underscorify().to_upper(), true)
+    found_types += 'FS_CONFIG_SET_CMD_CREAT (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_CMD_CREATE'.underscorify().to_upper(), false)
+    missing_types += 'FS_CONFIG_SET_CMD_CREATE (sys/mount.h)'
+endif
+
+if cc.get_define('FS_CONFIG_SET_CMD_RECONFIGURE', prefix: decl_headers) != ''
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_CMD_RECONFIGURE'.underscorify().to_upper(), true)
+    found_types += 'FS_CONFIG_SET_CMD_RECONFIGURE (sys/mount.h)'
+else
+    srcconf.set10('HAVE_' + 'FS_CONFIG_SET_CMD_RECONFIGURE'.underscorify().to_upper(), false)
+    missing_types += 'FS_CONFIG_SET_CMD_RECONFIGURE (sys/mount.h)'
+endif
+
 ## Headers.
 foreach ident: [
     ['bpf',               '''#include <sys/syscall.h>
@@ -667,6 +751,7 @@ foreach ident: [
     ['setns',             '''#include <sched.h>'''],
     ['sigdescr_np',       '''#include <string.h>'''],
     ['signalfd',          '''#include <sys/signalfd.h>'''],
+    ['statvfs',           '''#include <sys/statvfs.h>'''],
     ['statx',             '''#include <sys/types.h>
                              #include <sys/stat.h>
                              #include <unistd.h>'''],
@@ -683,11 +768,10 @@ endforeach
 found_headers = []
 missing_headers = []
 foreach tuple: [
-    ['systemd/sd-bus.h'],
-    ['systemd/sd-event.h'],
     ['sys/resource.h'],
     ['sys/memfd.h'],
     ['sys/personality.h'],
+    ['sys/pidfd.h'],
     ['sys/signalfd.h'],
     ['sys/timerfd.h'],
     ['pty.h'],
@@ -722,7 +806,6 @@ foreach tuple: [
     ['pam'],
     ['openssl'],
     ['liburing'],
-    ['libsystemd'],
 ]
 
     if tuple.length() >= 2
@@ -763,44 +846,19 @@ liblxc_includes = include_directories(
     'src/lxc/cgroups',
     'src/lxc/storage')
 
+# Our static sub-project binaries don't (and in fact can't) link to our
+# dependencies directly, but need access to the headers when compiling (most
+# notably seccomp headers).
+liblxc_dependency_headers = []
+foreach dep: liblxc_dependencies
+    liblxc_dependency_headers += dep.partial_dependency(compile_args: true)
+endforeach
+
 # Early sub-directories.
 subdir('src/include')
 subdir('src/lxc')
 subdir('src/lxc/pam')
 
-# Library.
-liblxc_dependencies = [
-    threads,
-]
-
-if want_seccomp
-    liblxc_dependencies += libseccomp
-endif
-
-if want_capabilities
-    liblxc_dependencies += [libcap]
-endif
-
-if want_openssl
-    liblxc_dependencies += [libopenssl]
-endif
-
-if want_selinux
-    liblxc_dependencies += [libselinux]
-endif
-
-if want_apparmor
-    liblxc_dependencies += [libapparmor]
-endif
-
-if want_io_uring
-    liblxc_dependencies += [liburing]
-endif
-
-if has_sd_bus
-    liblxc_dependencies += [libsystemd]
-endif
-
 liblxc_link_whole = [liblxc_static]
 
 liblxc = shared_library(