Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: add a meson build configuration #1910

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b552e46
build: add a meson build configuration
oscarbenjamin Apr 7, 2024
ebf835e
Add missing headers
oscarbenjamin Apr 8, 2024
de1b284
build: actually install libflint
oscarbenjamin Apr 8, 2024
6ae0116
build: use release as the default buildtype
oscarbenjamin Apr 8, 2024
8de98ab
build: build fft_small and assembly with meson
oscarbenjamin Apr 11, 2024
d0e2f70
build: build some tests with meson
oscarbenjamin Apr 11, 2024
1554223
build: fix tests and add -Dtests=enabled option
oscarbenjamin Apr 12, 2024
d6f1e87
build: make meson build files with meson_boostrap
oscarbenjamin Apr 13, 2024
e1132fa
build: generate build for fft_small and assembly
oscarbenjamin Apr 13, 2024
2996ea3
build: add dummy configure script
oscarbenjamin Apr 13, 2024
bccb239
build: fix paths in meson Makefile/configure
oscarbenjamin Apr 14, 2024
bc1ab5b
fix typo
oscarbenjamin Apr 14, 2024
ee38152
build: fix options in dummy configure script
oscarbenjamin Apr 14, 2024
0ae65c7
build: make a generated headers dir in build
oscarbenjamin Apr 14, 2024
27137bf
build: add variables to config.h and flint-config.h
oscarbenjamin Apr 14, 2024
daa719e
build: generate all built headers in meson build
oscarbenjamin Apr 14, 2024
27e2309
build: generate fmpz.c and config.m4 in meson build
oscarbenjamin Apr 14, 2024
b55d477
build: add config.m4.in
oscarbenjamin Apr 14, 2024
b52714f
build: add gmp_internals option to meson build
oscarbenjamin Apr 15, 2024
d88fba3
move mparam check after assembly
oscarbenjamin Apr 15, 2024
8d06fab
don't compile assembly if option disabled
oscarbenjamin Apr 15, 2024
faa848d
build: add pthread and tls options
oscarbenjamin Apr 15, 2024
726909c
build: add most options to meson build
oscarbenjamin Apr 16, 2024
a1a3424
build: Fix Makefile install dep in meson build
oscarbenjamin Apr 20, 2024
853cbee
build: Add make uninstall
oscarbenjamin Apr 20, 2024
b74cd3f
build: fix installing headers in meson build
oscarbenjamin Apr 20, 2024
3254724
build: disable avx2 and avx512 by default
oscarbenjamin Apr 20, 2024
4fbfde5
build: detect fft_small requirements in meson build
oscarbenjamin Apr 20, 2024
3ca5c2e
build: fix fft_small checking
oscarbenjamin Apr 20, 2024
88e6dad
Run config.guess to check for exact CPU
oscarbenjamin Jun 20, 2024
b27e820
Move detection script to config dir
oscarbenjamin Jun 20, 2024
97a96b5
Add CPU configuration tables to meson build
oscarbenjamin Jun 20, 2024
6c5d15d
Enable assembly based on exact_cpu in meson build
oscarbenjamin Jun 22, 2024
fa8fbff
Use exact_cpu to detect FLINT_KNOW_STRONG_ORDER
oscarbenjamin Jun 22, 2024
88baee4
Set FLINT_COVERAGE for coverage build
oscarbenjamin Jun 22, 2024
162be8e
Add --with-ntl in meson build
oscarbenjamin Jun 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ libtool
flint.pc
autom4te.cache/
config.m4
config.m4.in
src/flint-mparam.h
.gdb_history
vgcore.*
meson
meson.build
meson.options
31 changes: 31 additions & 0 deletions _meson_build/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
BUILDDIR = build.meson

all: setup
meson compile -C $(BUILDDIR)

setup: $(BUILDDIR)/.build-dir-created

$(BUILDDIR)/.build-dir-created:
meson setup $(BUILDDIR)
touch $(BUILDDIR)/.build-dir-created

clean:
rm -rf $(BUILDDIR)

install: setup
meson install -C $(BUILDDIR)

uninstall:
cd $(BUILDDIR) && ninja uninstall

test: setup
meson configure $(BUILDDIR) -Dtests=enabled
meson test -C $(BUILDDIR) --timeout-multiplier 10

coverage: setup
# Coverage tool e.g. gcovr needs to be installed *before* meson configure:
# pip install gcovr
meson configure $(BUILDDIR) -Dtests=enabled -Db_coverage=true
meson test -C $(BUILDDIR) --timeout-multiplier 10
cd $(BUILDDIR) && ninja coverage-html
# open $(BUILDDIR)/meson-logs/coveragereport/index.html
10 changes: 10 additions & 0 deletions _meson_build/bad_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* This is used to fail the build tests of someone tries to run them without
* enabling them in the build first.
*/
#include <stdio.h>

int main() {
printf("No tests run. Need to enable building tests with meson configure -Dtests=enabled\n");
return 1;
}
21 changes: 21 additions & 0 deletions _meson_build/config.m4.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
dnl config.m4. Generated automatically by configure.
changequote(<,>)
ifdef(<__CONFIG_M4_INCLUDED__>,,<
define(<TEXT>, <.text>)
define(<DATA>, <.data>)
define(<LABEL_SUFFIX>, <:>)
define(<GLOBL>, <.globl>)
define(<GLOBL_ATTR>, <>)
define(<GSYM_PREFIX>, <_>)
define(<RODATA>, < .section __TEXT,__const>)
define(<TYPE>, <>)
define(<SIZE>, <>)
define(<LSYM_PREFIX>, @LSYM_PREFIX@)
define(<ALIGN_LOGARITHMIC>,<yes>)
>)
changequote(`,')
ifdef(`__CONFIG_M4_INCLUDED__',,`
include(`../src/mpn_extras/asm-defs.m4')
include(`../src/mpn_extras/arm64/darwin.m4')
')
define(`__CONFIG_M4_INCLUDED__')
217 changes: 217 additions & 0 deletions _meson_build/configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
#!/usr/bin/env python

from os.path import join, abspath, dirname
import sys
import shutil
from subprocess import check_call
from argparse import ArgumentParser


def enable_disable_to_do(args, feature):
"""Translate --enable-foo=no etc to foo=True/False/None"""
enable = getattr(args, 'enable_' + feature)
disable = getattr(args, 'disable_' + feature)
if enable is not None and disable is not None:
msg = 'Cannot use --enable-{} and --disable-{} together'
raise ValueError(msg.format(feature, feature))
if enable is not None:
return enable == 'yes'
if disable is not None:
return disable == 'no'
return None


def run_command(cmd):
print('-' * 80)
print('$', ' '.join(cmd))
print('-' * 80)
check_call(cmd)


def enabled_disabled(value):
if value is True:
return 'enabled'
elif value is False:
return 'disabled'
else:
raise ValueError('Invalid value: ' + value)


def true_false(value):
if value is True:
return 'true'
elif value is False:
return 'false'
else:
raise ValueError('Invalid value: ' + str(value))


def add_feature_option(parser, feature):
parser.add_argument('--enable-' + feature, help='Enable ' + feature,
choices=['yes', 'no', 'auto'], nargs='?', const='yes', action='store')
parser.add_argument('--disable-' + feature, help='Disable ' + feature,
choices=['yes', 'no', 'auto'], nargs='?', const='yes', action='store')


def add_with_option(parser, libname, default):
parser.add_argument('--with-' + libname, help=f'Link to {libname}',
default=default, const=True, nargs='?')


parser = ArgumentParser(description='Configure FLINT for building with meson')

parser.add_argument('--build-dir', default='build.meson', help='Build directory')

parser.add_argument('--prefix', default=None, help='Installation prefix')
parser.add_argument('--bindir', default=None, help='Binary directory')
parser.add_argument('--libdir', default=None, help='Library directory')
parser.add_argument('--includedir', default=None, help='Include directory')

parser.add_argument('--build', default=None, help='Not supported...')
parser.add_argument('--host', default=None, help='Not supported...')

add_feature_option(parser, 'shared')
add_feature_option(parser, 'static')

add_feature_option(parser, 'libtool-lock')
add_feature_option(parser, 'pthread')
add_feature_option(parser, 'reentrant')
add_feature_option(parser, 'thread-safe')
add_feature_option(parser, 'assert')
add_feature_option(parser, 'coverage')
add_feature_option(parser, 'debug')
add_feature_option(parser, 'dependency-tracking')
add_feature_option(parser, 'pretty-tests')

add_feature_option(parser, 'gmp-internals')
add_feature_option(parser, 'assembly')
add_feature_option(parser, 'avx2')
add_feature_option(parser, 'avx512')

add_with_option(parser, 'gmp', default=True)
add_with_option(parser, 'mpfr', default=True)
add_with_option(parser, 'ntl', default=False)

parser.add_argument('--with-blas', default=None, help='Not supported...')
parser.add_argument('--with-gc', default=None, help='Not supported...')


def get_meson_command_from_configure_args(args):
"""
Translate e.g.
./configure --prefix=/opt/foo --enable-assembly=no
to
meson setup build --prefix=/opt/foo -Dassembly=disabled
Raise ValueError if modifying an option is not supported.
"""
args = parser.parse_args(args)

setup_args = []

if args.bindir is not None:
setup_args.append('--bindir=' + args.bindir)
if args.libdir is not None:
setup_args.append('--libdir=' + args.libdir)
else:
setup_args.append('--libdir=lib')
if args.includedir is not None:
setup_args.append('--includedir=' + args.includedir)
if args.prefix is not None:
setup_args.append('--prefix=' + args.prefix)

do_shared = enable_disable_to_do(args, 'shared')
do_static = enable_disable_to_do(args, 'static')

do_libtool_lock = enable_disable_to_do(args, 'libtool_lock')
do_pthread = enable_disable_to_do(args, 'pthread')
do_reentrant = enable_disable_to_do(args, 'reentrant')
do_thread_safe = enable_disable_to_do(args, 'thread_safe')
do_assert = enable_disable_to_do(args, 'assert')
do_coverage = enable_disable_to_do(args, 'coverage')
do_debug = enable_disable_to_do(args, 'debug')
do_dependency_tracking = enable_disable_to_do(args, 'dependency_tracking')
do_pretty_tests = enable_disable_to_do(args, 'pretty_tests')

do_gmp_internals = enable_disable_to_do(args, 'gmp_internals')
do_assembly = enable_disable_to_do(args, 'assembly')
do_avx2 = enable_disable_to_do(args, 'avx2')
do_avx512 = enable_disable_to_do(args, 'avx512')

if do_shared is None:
do_shared = True
if do_static is None:
do_static = False

if do_shared and not do_static:
pass
elif not do_shared and do_static:
setup_args.append('--default-library=static')
elif do_shared and do_static:
setup_args.append('--default-library=both')
else:
raise ValueError('Cannot disable both shared and static libraries')

if do_debug is True:
setup_args.append('--buildtype=debugoptimized')

if do_libtool_lock is not None:
setup_args.append('-Dlibtool_lock=' + 'disabled')
if do_pthread is not None:
setup_args.append('-Dpthread=' + enabled_disabled(do_pthread))
if do_reentrant is not None:
setup_args.append('-Dreentrant=' + enabled_disabled(do_reentrant))
if do_thread_safe is not None:
setup_args.append('-Dthread_safe=' + enabled_disabled(do_thread_safe))
if do_assert is not None:
setup_args.append('-Dassert=' + enabled_disabled(do_assert))
if do_coverage is not None:
setup_args.append('-Db_coverage=' + true_false(do_coverage))
if do_dependency_tracking is not None:
pass # Meson always does dependency tracking with Ninja
if do_pretty_tests is not None:
setup_args.append('-Dpretty_tests=' + enabled_disabled(do_pretty_tests))

if do_gmp_internals is not None:
setup_args.append('-Dgmp_internals=' + enabled_disabled(do_gmp_internals))

if do_assembly is not None:
setup_args.append('-Dassembly=' + enabled_disabled(do_assembly))

if do_avx2 is False or do_avx512 is False:
setup_args.append('-Dfft_small=' + 'disabled')
elif do_avx2 is True or do_avx512 is True:
setup_args.append('-Dfft_small=' + 'enabled')

for lib in ['gmp', 'mpfr', 'gc', 'ntl', 'blas']:
val = getattr(args, 'with_' + lib)
if isinstance(val, str):
setup_args.append('--pkg-config-path=' + join(val, 'lib', 'pkgconfig'))

if args.with_ntl:
setup_args.append('-Dntl=enabled')

if args.with_blas is not None:
raise ValueError('--with-blas is not supported')
if args.with_gc is not None:
raise ValueError('--with-gc is not supported')

cmd = ['meson', 'setup', args.build_dir] + setup_args
return cmd, args


def main(*args):
cmd, args = get_meson_command_from_configure_args(args)
# The default behaviour of ./configure is to basically wipe out the build.
# Everything is then rebuilt from scratch. We will do the same here to
# match the semantics of configure which does not preserve any settings
# from one run of configure to the next. When using meson directly, it is
# better not to do this because the files might not need to be rebuilt.
shutil.rmtree(args.build_dir, ignore_errors=True)
run_command(cmd)
# The Makefile uses this to check if project is configured
with open(join(args.build_dir, '.build-dir-created'), 'w') as f:
pass


if __name__ == '__main__':
sys.exit(main(*sys.argv[1:]))
Loading
Loading