project('OpenRC', 'c', version : '0.47', license: 'BSD-2', default_options : [ 'c_std=c99', 'prefix=/usr', 'warning_level=3', ], meson_version : '>=0.53.2') cc = meson.get_compiler('c') fs = import('fs') audit_dep = dependency('audit', required : get_option('audit')) if audit_dep.found() cc_audit_flags = '-DHAVE_AUDIT' else cc_audit_flags = [] endif if get_option('branding') != '' cc_branding_flags = '-DBRANDING=' + get_option('branding') else cc_branding_flags = [] endif libname = get_option('libdir').split('/')[-1] option_local_prefix = get_option('local_prefix') if option_local_prefix == '' local_prefix = get_option('prefix') / 'usr' / 'local' else local_prefix = option_local_prefix endif option_os = get_option('os') if option_os == '' uname = find_program('uname') r = run_command(uname, '-s', check: true) os = r.stdout().strip() os = '-'.join(os.split('/')) else os = option_os endif if os != 'Linux' kvm_dep = cc.find_library('kvm', required: true) else kvm_dep = [] endif pam_dep = dependency('pam', required: false) if not pam_dep.found() pam_dep = cc.find_library('pam', required: false) endif if pam_dep.found() and get_option('pam') cc_pam_flags = '-DHAVE_PAM' else cc_pam_flags = [] endif if not pam_dep.found() and get_option('pam') error('Pam was requested but could not be located') endif cap_dep = dependency('libcap', version: '>=2.33', required : get_option('capabilities')) if cap_dep.found() cc_cap_flags = '-DHAVE_CAP' else cc_cap_flags = [] endif option_pkg_prefix = get_option('pkg_prefix') if option_pkg_prefix == '' if os == 'Dragonfly' or os == 'FreeBSD' pkg_prefix = '/usr/local' elif os == 'GNU' or os == 'GNU-kFreeBSD' or os == 'Linux' pkg_prefix = '/usr' elif os == 'NetBSD' pkg_prefix = '/usr/pkg' endif else pkg_prefix = option_pkg_prefix endif if get_option('split-usr') == 'auto' split_usr = run_command('test', '-L', '/bin', check: false).returncode() != 0 else split_usr = get_option('split-usr') == 'true' endif rootprefix = get_option('rootprefix') rootprefix_default = fs.is_symlink('/bin') ? '/usr' : '/' if rootprefix == '' rootprefix = rootprefix_default endif bindir = rootprefix / get_option('bindir') libdir = rootprefix / get_option('libdir') libexecdir = get_option('libexecdir') if os == 'Linux' and libexecdir == 'libexec' libexecdir = 'lib' endif libexecdir = rootprefix / libexecdir rc_libexecdir = libexecdir / 'rc' rc_bindir = rc_libexecdir / 'bin' rc_sbindir = rc_libexecdir / 'sbin' rc_shdir = rc_libexecdir / 'sh' sbindir = rootprefix / get_option('sbindir') pamdir = get_option('sysconfdir') / 'pam.d' crypt_dep = [] selinux_dep = dependency('libselinux', required : get_option('selinux')) pam_misc_dep = [] if selinux_dep.found() cc_selinux_flags = '-DHAVE_SELINUX' if pam_dep.found() and get_option('pam') pam_misc_dep = dependency('pam_misc', required: false) if not pam_misc_dep.found() pam_misc_dep = cc.find_library('pam_misc', required: false) endif if not pam_misc_dep.found() and get_option('pam') error('Pam was requested but could not be located') endif else crypt_dep = dependency('libcrypt', required : false) if not crypt_dep.found() crypt_dep = cc.find_library('crypt', required : true) endif endif else cc_selinux_flags = [] endif termcap = get_option('termcap') if termcap != '' termcap_dep = dependency(termcap) termcap_flags = '-DHAVE_TERMCAP' else termcap_dep = [] termcap_flags = [] endif if get_option('buildtype').startswith('debug') cc_debug_flags = ['-DRC_DEBUG'] else cc_debug_flags = [] endif if os == 'Linux' or os == 'GNU-kFreeBSD' cc_os_flags = ['-D_DEFAULT_SOURCE'] elif os == 'FreeBSD' cc_os_flags = ['-D_BSD_SOURCE'] elif os == 'GNU' cc_os_flags = ['-D_DEFAULT_SOURCE', '-DMAXPATHLEN=4096', '-DPATH_MAX=4096'] endif # Try and use some good cc flags if we're building from git. We don't use # -pedantic as it will warn about our perfectly valid use of %m in our logger. # We should be using -Wredundant-decls, but our library hidden proto stuff gives # loads of warnings. I don't fully understand it (the hidden proto, not the # warning) so we just silence the warning. cc_warning_flags_test = [ '-Wcast-align', '-Wcast-qual', '-Wdeclaration-after-statement', '-Wformat=2', '-Winline', '-Wmissing-declarations', '-Wmissing-format-attribute', '-Wmissing-noreturn', '-Wmissing-prototypes', '-Wnested-externs', '-Wpointer-arith', '-Wsequence-point', '-Wshadow', '-Wwrite-strings', '-Werror=implicit-int', '-Werror=implicit-function-declaration', '-Werror=int-conversion', '-Werror=incompatible-function-pointer-types', ] cc_warning_flags = cc.get_supported_arguments(cc_warning_flags_test) cc_flags = [cc_debug_flags, cc_os_flags, cc_warning_flags] add_project_arguments(cc_flags, language : 'c') # Meson's has_function_attribute doesn't know about GCC's extended # version (with arguments), so we have to build a test program instead. malloc_attribute_test = '''#include __attribute__ ((malloc (free, 1))) int func() { return 0; } ''' if cc.compiles(malloc_attribute_test, name : 'malloc attribute with arguments') add_project_arguments('-DHAVE_MALLOC_EXTENDED_ATTRIBUTE', language: 'c') endif if cc.has_function('closefrom', prefix: '#define _GNU_SOURCE\n#include ') add_project_arguments('-DHAVE_CLOSEFROM', language: 'c') endif if cc.has_function('close_range', prefix: '#define _GNU_SOURCE\n#include ') and \ cc.has_header_symbol('unistd.h', 'CLOSE_RANGE_CLOEXEC', prefix: '#define _GNU_SOURCE') add_project_arguments('-DHAVE_CLOSE_RANGE_CLOEXEC', language: 'c') endif incdir = include_directories('src/shared') einfo_incdir = include_directories('src/libeinfo') rc_incdir = include_directories('src/librc') init_d_conf_data = configuration_data() init_d_conf_data.set('SBINDIR', sbindir) init_d_conf_data.set('PKG_PREFIX', pkg_prefix) init_d_conf_data.set('SYSCONFDIR', get_option('sysconfdir')) dl_dep = cc.find_library('dl', required: false) util_dep = cc.find_library('util', required: false) subdir('bash-completion') subdir('conf.d') subdir('etc') subdir('init.d') subdir('local.d') subdir('man') subdir('pkgconfig') subdir('sh') subdir('src') subdir('support') subdir('sysctl.d') subdir('test') subdir('zsh-completion') meson.add_install_script('tools/meson_runlevels.sh', os, get_option('newnet') ? 'yes' : 'no', rc_libexecdir, get_option('sysconfdir'), get_option('sysvinit') ? 'yes' : 'no') meson.add_install_script('tools/meson_final.sh', rc_libexecdir, sbindir, os, get_option('sysvinit') ? 'yes' : 'no')