diff options
Diffstat (limited to 'meson.build')
-rw-r--r-- | meson.build | 487 |
1 files changed, 487 insertions, 0 deletions
diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..95895300 --- /dev/null +++ b/meson.build @@ -0,0 +1,487 @@ +project('pacman', + 'c', + version : '5.1.0', + license : 'GPLv2+', + default_options : [ + 'c_std=gnu99', + 'prefix=/usr', + 'sysconfdir=/etc', + 'localstatedir=/var', + ], + meson_version : '>= 0.47') + +libalpm_version = '11.0.1' + +cc = meson.get_compiler('c') + +# commandline options +PREFIX = get_option('prefix') +DATAROOTDIR = join_paths(PREFIX, get_option('datarootdir')) +SYSCONFDIR = join_paths(PREFIX, get_option('sysconfdir')) +LOCALSTATEDIR = join_paths(PREFIX, get_option('localstatedir')) +LOCALEDIR = join_paths(PREFIX, get_option('localedir')) +ROOTDIR = get_option('root-dir') +BINDIR = join_paths(PREFIX, get_option('bindir')) +MANDIR = join_paths(PREFIX, get_option('mandir')) +BUILDSCRIPT = get_option('buildscript') +LIBMAKEPKGDIR = join_paths(PREFIX, DATAROOTDIR, 'makepkg') +PKGDATADIR = join_paths(PREFIX, DATAROOTDIR, meson.project_name()) + +PYTHON = import('python').find_installation('python3') +M4 = find_program('m4') +SED = find_program('sed') +DU = find_program('du') +LDCONFIG = get_option('ldconfig') +MESON_MAKE_SYMLINK = join_paths(meson.source_root(), 'build-aux/meson-make-symlink.sh') + +BASH = find_program('bash4', 'bash') +if BASH.found() + bash_version = run_command(BASH, '-c', 'IFS=.; echo "${BASH_VERSINFO[*]:0:3}"').stdout() + + have_bash = bash_version.version_compare('>= 4.4.0') +endif +if not have_bash + error('bash >= 4.4.0 is required for pacman scripts.') +endif + +bashcompletion = dependency('bash-completion', required : false) +if bashcompletion.found() + BASHCOMPDIR = bashcompletion.get_pkgconfig_variable('completionsdir') +else + BASHCOMPDIR = join_paths(DATAROOTDIR, 'bash-completion/completions') +endif + +if get_option('use-git-version') + PACKAGE_VERSION = run_command( + find_program('git'), + 'describe', + '--abbrev=4', + '--dirty').stdout().strip().strip('v') +else + PACKAGE_VERSION = meson.project_version() +endif + +conf = configuration_data() +conf.set('_GNU_SOURCE', true) +conf.set_quoted('PACKAGE', meson.project_name()) +conf.set_quoted('PACKAGE_VERSION', PACKAGE_VERSION) +conf.set_quoted('LOCALEDIR', LOCALEDIR) +conf.set_quoted('SCRIPTLET_SHELL', get_option('scriptlet-shell')) +conf.set_quoted('LDCONFIG', LDCONFIG) +conf.set_quoted('LIB_VERSION', meson.project_version()) +conf.set_quoted('SYSHOOKDIR', join_paths(DATAROOTDIR, 'libalpm/hooks/')) +conf.set_quoted('CONFFILE', join_paths(SYSCONFDIR, 'pacman.conf')) +conf.set_quoted('DBPATH', join_paths(LOCALSTATEDIR, 'lib/pacman')) +conf.set_quoted('GPGDIR', join_paths(SYSCONFDIR, 'pacman.d/gnupg')) +conf.set_quoted('LOGFILE', join_paths(LOCALSTATEDIR, 'log/pacman.log')) +conf.set_quoted('CACHEDIR', join_paths(LOCALSTATEDIR, 'cache/pacman/pkg')) +conf.set_quoted('HOOKDIR', join_paths(SYSCONFDIR, 'pacman.d/hooks/')) +conf.set_quoted('ROOTDIR', ROOTDIR) + +if get_option('i18n') + if not cc.has_function('ngettext') + error('ngettext not found but NLS support requested') + endif + conf.set('ENABLE_NLS', 1) +endif + +# dependencies +libarchive = dependency('libarchive', + version : '>=3.0.0', + static : get_option('buildstatic')) + +libcurl = dependency('libcurl', + version : '>=7.32.0', + required : get_option('curl'), + static : get_option('buildstatic')) +conf.set('HAVE_LIBCURL', libcurl.found()) + +want_gpgme = get_option('gpgme') +gpgme_config = find_program('gpgme-config', required : want_gpgme) +if not want_gpgme.disabled() and gpgme_config.found() + gpgme_version = run_command(gpgme_config, '--version').stdout().strip() + + needed_gpgme_version = '>=1.3.0' + have = gpgme_version.version_compare(needed_gpgme_version) + if want_gpgme.enabled() and not have + error('gpgme @0@ is needed for GPG signature support'.format(needed_gpgme_version)) + endif + + gpgme_libs = [ + cc.find_library('gpgme', required : have, + dirs : [get_option('gpgme-libdir')]), + cc.find_library('gpg-error', required : have, + dirs : [get_option('gpgme-libdir')]), + cc.find_library('assuan', required : have, + dirs : [get_option('gpgme-libdir')]), + ] + + conf.set('HAVE_LIBGPGME', have) +else + gpgme_libs = [] + conf.set('HAVE_LIBGPGME', false) +endif + +want_crypto = get_option('crypto') +if want_crypto == 'openssl' + libcrypto = dependency('libcrypto', static : get_option('buildstatic')) + if not libcrypto.found() + error('openssl support requested but not found') + endif + crypto_provider = libcrypto + conf.set10('HAVE_LIBSSL', true) +elif want_crypto == 'nettle' + libnettle = dependency('nettle', static : get_option('buildstatic')) + if not libnettle.found() + error('nettle support requested but not found') + endif + crypto_provider = libnettle + conf.set10('HAVE_LIBNETTLE', true) +else + error('unhandled crypto value @0@'.format(want_crypto)) +endif + +foreach header : [ + 'mntent.h', + 'sys/mnttab.h', + 'sys/mount.h', + 'sys/param.h', + 'sys/statvfs.h', + 'sys/types.h', + 'sys/ucred.h', + 'termios.h', + ] + if cc.has_header(header) + conf.set('HAVE_' + header.underscorify().to_upper(), true) + endif +endforeach + +foreach sym : [ + 'dup2', + 'fork', + 'getcwd', + 'getmntent', + 'getmntinfo', + 'gettimeofday', + 'memmove', + 'memset', + 'mkdir', + 'realpath', + 'regcomp', + 'rmdir', + 'setenv', + 'setlocale', + 'strcasecmp', + 'strchr', + 'strcspn', + 'strdup', + 'strerror', + 'strndup', + 'strnlen', + 'strnlen', + 'strrchr', + 'strsep', + 'strsep', + 'strstr', + 'strtol', + 'swprintf', + 'tcflush', + 'tcflush', + 'uname', + 'wcwidth', + ] + have = cc.has_function(sym, args : '-D_GNU_SOURCE') + conf.set10('HAVE_' + sym.to_upper(), have) +endforeach + +foreach member : [ + ['struct stat', 'st_blksize', '''#include <sys/stat.h>'''], + ['struct statvfs', 'f_flag', '''#include <sys/statvfs.h>'''], + ['struct statfs', 'f_flags', '''#include <sys/param.h> + #include <sys/mount.h>'''], + ] + have = cc.has_member(member[0], member[1], prefix : member[2]) + conf.set('HAVE_' + '_'.join([member[0], member[1]]).underscorify().to_upper(), have) +endforeach + +if conf.has('HAVE_STRUCT_STATVFS_F_FLAG') + conf.set('FSSTATSTYPE', 'struct statvfs') +elif conf.has('HAVE_STRUCT_STATFS_F_FLAGS') + conf.set('FSSTATSTYPE', 'struct statfs') +endif + +if get_option('buildtype') == 'debug' + extra_cflags = [ + '-Wcast-align', + '-Wclobbered', + '-Wempty-body', + '-Wfloat-equal', + '-Wformat-nonliteral', + '-Wformat-security', + '-Wignored-qualifiers', + '-Winit-self', + '-Wlogical-op', + '-Wmissing-declarations', + '-Wmissing-field-initializers', + '-Wmissing-parameter-type', + '-Wmissing-prototypes', + '-Wold-style-declaration', + '-Woverride-init', + '-Wpointer-arith', + '-Wredundant-decls', + '-Wshadow', + '-Wsign-compare', + '-Wstrict-aliasing', + '-Wstrict-overflow=5', + '-Wstrict-prototypes', + '-Wtype-limits', + '-Wuninitialized', + '-Wunused-but-set-parameter', + '-Wunused-parameter', + '-Wwrite-strings', + ] + add_project_arguments(cc.get_supported_arguments(extra_cflags), language : 'c') + + conf.set('PACMAN_DEBUG', 1) +endif + +config_h = configure_file( + output : 'config.h', + configuration : conf) +add_project_arguments('-include', 'config.h', language : 'c') + +default_duflags = ' -sk --apparent-size' +default_sedinplaceflags = ' --follow-symlinks -i' +inodecmd = 'stat -c \'%i %n\'' +ownercmd = 'stat -c \'%u:%g\'' +modecmd = 'stat -c \'%a\'' +strip_binaries = '--strip-all' +strip_shared = '--strip-unneeded' +strip_static = '--strip-debug' + +os = host_machine.system() +if os.startswith('darwin') + inodecmd = '/usr/bin/stat -f \'%i %n\'' + ownercmd = '/usr/bin/stat -f \'%u:%g\'' + modecmd = '/usr/bin/stat -f \'%lp\'' + default_sedinplaceflags = ' -i \'\'' + default_duflags = ' -sk' + strip_binaries = '' + strip_shared = '-s' + strip_static = '-s' +elif os.contains('bsd') or os == 'dragonfly' + inodecmd = 'stat -f \'%i %n\'' + ownercmd = 'stat -f \'%u:%g\'' + modecmd = 'stat -f \'%lp\'' + default_sedinplaceflags = ' -i \'\'' + default_duflags = ' -sk' +endif + +duflags = get_option('duflags') +if duflags == 'autodetect' + duflags = default_duflags +endif + +sedinplaceflags = get_option('sedinplaceflags') +if sedinplaceflags == 'auto' + sedinplaceflags = default_sedinplaceflags +endif + +chost = run_command(cc, '-dumpmachine').stdout().strip() +carch = chost.split('-')[0] + +# annoyingly, we have to maintain two sets of configuration_data which is +# largely identical, but which distinguishes between quoting needs. +substs = configuration_data() +substs.set('SED', SED.path()) +substs.set('M4', M4.path()) +substs.set('CARCH', carch) +substs.set('CHOST', chost) +substs.set('PKGEXT', get_option('pkg-ext')) +substs.set('SRCEXT', get_option('src-ext')) +substs.set('ROOTDIR', ROOTDIR) +substs.set('LOCALEDIR', LOCALEDIR) +substs.set('sysconfdir', SYSCONFDIR) +substs.set('localstatedir', LOCALSTATEDIR) +substs.set('PKGDATADIR', PKGDATADIR) +substs.set('PREFIX', PREFIX) +substs.set('BASH', BASH.path()) +substs.set('PACKAGE_VERSION', PACKAGE_VERSION) +substs.set('PACKAGE_NAME', meson.project_name()) +substs.set('BUILDSCRIPT', BUILDSCRIPT) +substs.set('TEMPLATE_DIR', get_option('makepkg-template-dir')) +substs.set('DEBUGSUFFIX', get_option('debug-suffix')) +substs.set('INODECMD', inodecmd) +substs.set('OWNERCMD', ownercmd) +substs.set('MODECMD', modecmd) +substs.set('SEDINPLACEFLAGS', sedinplaceflags) +substs.set('SEDPATH', SED.path()) +substs.set('DUFLAGS', duflags) +substs.set('DUPATH', DU.path()) +substs.set('LIBMAKEPKGDIR', LIBMAKEPKGDIR) +substs.set('STRIP_BINARIES', strip_binaries) +substs.set('STRIP_SHARED', strip_shared) +substs.set('STRIP_STATIC', strip_static) + +subdir('lib/libalpm') +subdir('src/common') +subdir('src/pacman') +subdir('src/util') +subdir('scripts') + +# Internationalization +if get_option('i18n') + i18n = import('i18n') + subdir('lib/libalpm/po') + subdir('src/pacman/po') + subdir('scripts/po') +endif + +want_doc = get_option('doc') +ASCIIDOC = find_program('asciidoc', required : want_doc) +A2X = find_program('a2x', required : want_doc) +build_doc = A2X.found() and not want_doc.disabled() +if build_doc + subdir('doc') +endif + +includes = include_directories('src/common', 'lib/libalpm') + +libcommon = static_library( + 'common', + libcommon_sources, + include_directories : includes, + install : false) + +libalpm = library( + 'alpm', + libalpm_sources, + version : libalpm_version, + include_directories : includes, + dependencies : [crypto_provider, libarchive, libcurl] + gpgme_libs, + link_with : [libcommon], + install : true) + +install_headers( + 'lib/libalpm/alpm.h', + 'lib/libalpm/alpm_list.h') + +# TODO: libs.private seem quite wrong here +pkgconfig = import('pkgconfig') +pkgconfig.generate( + libalpm, + name : 'libalpm', + description : 'Arch Linux package management library', + version : libalpm_version, + url : 'http://www.archlinux.org/pacman/') + +pacman_bin = executable( + 'pacman', + pacman_sources, + include_directories : includes, + link_with : [libalpm, libcommon], + dependencies : [libarchive], + install : true, +) + +executable( + 'pacman-conf', + pacman_conf_sources, + include_directories : includes, + link_with : [libalpm], + install : true, +) + +executable( + 'cleanupdelta', + cleanupdelta_sources, + include_directories : includes, + link_with : [libalpm], + install : true, +) + +executable( + 'testpkg', + testpkg_sources, + include_directories : includes, + link_with : [libalpm], + install : true, +) + +executable( + 'vercmp', + vercmp_sources, + include_directories : includes, + link_with : [libalpm], + install : true, +) + +configure_file( + input : 'etc/makepkg.conf.in', + output : 'makepkg.conf', + configuration : substs, + install_dir : SYSCONFDIR) + +configure_file( + input : 'etc/pacman.conf.in', + output : 'pacman.conf', + configuration : substs, + install_dir : SYSCONFDIR) + +install_data( + 'proto/PKGBUILD-split.proto', + 'proto/PKGBUILD-vcs.proto', + 'proto/PKGBUILD.proto', + 'proto/proto.install', + install_dir : join_paths(DATAROOTDIR, 'pacman')) + +TEST_ENV = environment() +TEST_ENV.set('PMTEST_SCRIPTLIB_DIR', join_paths(meson.source_root(), 'scripts/library/')) +TEST_ENV.set('PMTEST_LIBMAKEPKG_DIR', join_paths(meson.build_root(), 'scripts/libmakepkg/')) +TEST_ENV.set('PMTEST_UTIL_DIR', meson.build_root() + '/') +TEST_ENV.set('PMTEST_SCRIPT_DIR', join_paths(meson.build_root(), 'scripts/')) + +subdir('test/pacman') +subdir('test/scripts') +subdir('test/util') + +message('\n '.join([ + '@0@ @1@'.format(meson.project_name(), meson.project_version()), + 'Build information:', + ' prefix : @0@'.format(PREFIX), + ' sysconfdir : @0@'.format(SYSCONFDIR), + ' conf file : @0@'.format(join_paths(SYSCONFDIR, 'pacman.conf')), + ' localstatedir : @0@'.format(LOCALSTATEDIR), + ' database dir : @0@'.format(join_paths(LOCALSTATEDIR, 'lib/pacman/')), + ' cache dir : @0@'.format(join_paths(LOCALSTATEDIR, 'cache/pacman/pkg/')), + ' compiler : @0@ @1@'.format(cc.get_id(), cc.version()), + '', + ' Architecture : @0@'.format(carch), + ' Host Type : @0@'.format(chost), + ' File inode command : @0@'.format(inodecmd), + ' File owner command : @0@'.format(ownercmd), + ' File mode command : @0@'.format(modecmd), + ' Directory size command : @0@ @1@'.format(DU.path(), duflags), + ' In-place sed command : @0@ @1@'.format(SED.path(), sedinplaceflags), + ' libalpm version : @0@'.format(libalpm_version), + ' pacman version : @0@'.format(PACKAGE_VERSION), + '', + 'Directory and file information:', + ' root working directory : @0@'.format(ROOTDIR), + ' package extension : @0@'.format(get_option('pkg-ext')), + ' source pkg extension : @0@'.format(get_option('src-ext')), + ' build script name : @0@'.format(BUILDSCRIPT), + ' template directory : @0@'.format(get_option('makepkg-template-dir')), + '', + 'Compilation options:', + ' i18n support : @0@'.format(get_option('i18n')), + ' Build docs : @0@'.format(build_doc), + ' debug build : @0@'.format(get_option('buildtype') == 'debug'), + ' Use libcurl : @0@'.format(conf.get('HAVE_LIBCURL')), + ' Use GPGME : @0@'.format(conf.get('HAVE_LIBGPGME')), + ' Use OpenSSL : @0@'.format(conf.has('HAVE_LIBSSL') and + conf.get('HAVE_LIBSSL') == 1), + ' Use nettle : @0@'.format(conf.has('HAVE_LIBNETTLE') and + conf.get('HAVE_LIBNETTLE') == 1), + '', +])) |