diff --git a/bin/activate.fish b/bin/activate.fish new file mode 100644 index 00000000..67616315 --- /dev/null +++ b/bin/activate.fish @@ -0,0 +1,5 @@ +# This file should be sourced, not run +set -al C_INCLUDE_PATH $PWD/.local/include +set -al LIBRARY_PATH $PWD/.local/lib +set -al LD_LIBRARY_PATH $PWD/.local/lib +set -al PYTHONPATH $PWD/src diff --git a/bin/activate b/bin/activate.sh similarity index 79% rename from bin/activate rename to bin/activate.sh index 83f5d452..caac9fd4 100644 --- a/bin/activate +++ b/bin/activate.sh @@ -1,3 +1,4 @@ +# This file should be sourced, not run export C_INCLUDE_PATH=$(pwd)/.local/include export LIBRARY_PATH=$(pwd)/.local/lib export LD_LIBRARY_PATH=$(pwd)/.local/lib diff --git a/bin/build_dependencies_unix.fish b/bin/build_dependencies_unix.fish new file mode 100755 index 00000000..1e9c50e4 --- /dev/null +++ b/bin/build_dependencies_unix.fish @@ -0,0 +1,389 @@ +#!/usr/bin/env fish +# +# Build local installs of python-flint's dependencies. This should be run +# before attempting to build python-flint itself. + +# There is no equivalent in fish AFAIK +# set -o errexit + +# ------------------------------------------------------------------------- # +# # +# Supported options: # +# # +# --jobs - run NUM jobs in parallel [default=3] # +# --host - set the host (target) for GMP build # +# --patch-gmp-arm64 - apply patch to GMP for OSX arm64 # +# --gmp gmp - build based on GMP (default) # +# --gmp mpir - build based on MPIR (no longer works) # +# ------------------------------------------------------------------------- # + +set NUM_CORES 3 +set SKIP_GMP no +set SKIP_MPFR no + +set USE_GMP gmp +set PATCH_GMP_ARM64 no +set BUILD_ARB no + +while test (count $argv) -gt 0 + set key $argv[1] + echo "key: $key" + switch "$key" + case -h --help + echo "bin/download_dependencies.sh [options]" + echo + echo "Build local installs of python-flint's dependencies." + echo + echo "Supported options:" + echo " --help - show this help message" + echo " --cores - set number of cores to use (default: 3)" + echo " --host - set the host (target) for GMP build" + echo " --skip-gmp - skip building GMP" + echo " --skip-mpfr - skip building MPFR" + echo + echo "Legacy options:" + echo " --gmp gmp - build based on GMP (default)" + echo " --gmp mpir - build based on MPIR (no longer works)" + echo " --patch-gmp-arm64 - apply patch to GMP 6.2.1 for OSX arm64" + echo " --arb - build Arb (only needed for flint < 3.0.0)" + echo + exit + case -j --jobs --cores + # e.g. --jobs 4 + # or --jobs 16 + set NUM_CORES "$argv[2]" + set argv $argv[3..-1] + case --host + # e.g. --host x86_64-unknown-linux-gnu + # or --host x86_64-apple-darwin + set HOST_ARG "$argv[2]" + set argv $argv[3..-1] + case --gmp + # e.g. --gmp gmp or --gmp mpir + # The mpir build no longer works because the download fails. + set USE_GMP "$argv[2]" + if test "$USE_GMP" != "gmp" -a "$USE_GMP" != "mpir" + echo "--gmp option should be gmp or mpir" + exit 1 + end + set argv $argv[3..-1] + case --arb + # With flint >= 3.0.0 Arb is included so we do not need to build it + # separately. Pass --arb if building for older versions of flint. + set BUILD_ARB yes + set argv $argv[2..-1] + case --skip-gmp + # If you already have a local install of GMP you can pass --skip-gmp + # to skip building it. + set SKIP_GMP yes + set argv $argv[2..-1] + case --skip-mpfr + # If you already have a local install of MPFR you can pass --skip-mpfr + # to skip building it. + set SKIP_MPFR yes + set argv $argv[2..-1] + case --patch-gmp-arm64 + # Needed only for GMP 6.2.1 on OSX arm64 (Apple M1) hardware + # As of GMP 6.3.0 this patch is no longer needed + set PATCH_GMP_ARM64 yes + set argv $argv[2..-1] + case --use-gmp-github-mirror + set argv $argv[2..-1] + case "*" + echo "unrecognised argument:" $key + exit 1 + end +end + +# ------------------------------------------------------------------------- # +# # +# The build_variables.sh script sets variables specifying the versions to # +# use for all dependencies and also the PREFIX variable. # +# # +# ------------------------------------------------------------------------- # + +source bin/build_variables.fish + +echo "=== Parameters ===" +echo "NUM_CORES: $NUM_CORES" +echo "PREFIX: $PREFIX" + +cd $PREFIX +mkdir -p src +cd src + +# ------------------------------------------------------------------------- # +# # +# Now build all dependencies. # +# # +# ------------------------------------------------------------------------- # + +if test "$USE_GMP" = "gmp" + + # ----------------------------------------------------------------------- # + # # + # GMP # + # # + # ----------------------------------------------------------------------- # + + if test "$SKIP_GMP" = "yes" + echo + echo -------------------------------------------- + echo " skipping GMP" + echo -------------------------------------------- + echo + else + echo + echo -------------------------------------------- + echo " building GMP" + echo -------------------------------------------- + echo + + if test "$USE_GMP_GITHUB_MIRROR" = "yes" + # Needed in GitHub Actions because it is blocked from gmplib.org + git clone https://github.com/oscarbenjamin/gmp_mirror.git + cp gmp_mirror/gmp-$GMPVER.tar.xz . + else + curl -O https://gmplib.org/download/gmp/gmp-$GMPVER.tar.xz + end + + tar xf gmp-$GMPVER.tar.xz + cd gmp-$GMPVER + + # + # See https://github.com/aleaxit/gmpy/issues/350 + # + # We need to patch GMP for OSX arm64 (Apple M1) hardware. This patch is + # from the GMP repo but was applied after the release of GMP 6.2.1. + # This patch is no longer needed for GMP 6.3.0. + # + if test "$PATCH_GMP_ARM64" = "yes" + echo + echo -------------------------------------------- + echo " patching GMP" + echo -------------------------------------------- + patch -N -Z -p0 < ../../../bin/patch-arm64.diff + end + + # Show the output of configfsf.guess + chmod +x configfsf.guess + ./configfsf.guess + + ./configure --prefix=$PREFIX \ + --enable-fat \ + --enable-shared=yes \ + --enable-static=no \ + --host=$HOST_ARG + make -j"$NUM_CORES" + make install + + cd .. + + end + + set FLINTARB_WITHGMP "-DGMP_INCLUDE_DIRS=$PREFIX" + +else + + # ----------------------------------------------------------------------- # + # # + # YASM (needed to build MPIR) # + # # + # ----------------------------------------------------------------------- # + + curl -O http://www.tortall.net/projects/yasm/releases/yasm-$YASMVER.tar.gz + tar xf yasm-$YASMVER.tar.gz + cd yasm-$YASMVER + ./configure --prefix=$PREFIX + make -j"$NUM_CORES" + make install + cd .. + + # ----------------------------------------------------------------------- # + # # + # MPIR # + # # + # ----------------------------------------------------------------------- # + + # + # The mpir.org domain has expired and no longer hosts the source code so the + # call to curl below will fail. + # We could try to download from https://github.com/wbhart/mpir/releases. + # + # Ultimately it seems that MPIR is no longer maintained though so for now + # this remains unfixed. + # + + echo "MPIR build of python_flint is no longer supported" + exit 1 + + # curl -O http://mpir.org/mpir-$MPIRVER.tar.bz2 + # tar xf mpir-$MPIRVER.tar.bz2 + # cd mpir-$MPIRVER + # ./configure --prefix=$PREFIX \ + # --with-yasm=$PREFIX/bin/yasm \ + # --enable-fat \ + # --enable-shared=yes \ + # --enable-static=no \ + # --enable-gmpcompat + # make -j"$NUM_CORES" + # make install + # cd .. + # + # set FLINTARB_WITHGMP "--with-mpir=$PREFIX" + +end + +# ------------------------------------------------------------------------- # +# # +# MPFR # +# # +# ------------------------------------------------------------------------- # + +if test "$SKIP_MPFR" = "yes" + echo + echo -------------------------------------------- + echo " skipping MPFR" + echo -------------------------------------------- + echo +else + echo + echo -------------------------------------------- + echo " building MPFR" + echo -------------------------------------------- + echo + + curl -O https://ftp.gnu.org/gnu/mpfr/mpfr-$MPFRVER.tar.gz + tar xf mpfr-$MPFRVER.tar.gz + cd mpfr-$MPFRVER + ./configure --prefix=$PREFIX \ + --with-gmp=$PREFIX \ + --enable-shared=yes \ + --enable-static=no + make -j"$NUM_CORES" + make install + cd .. +end + +# ------------------------------------------------------------------------- # +# # +# FLINT # +# # +# ------------------------------------------------------------------------- # + +echo +echo -------------------------------------------- +echo " building Flint" +echo -------------------------------------------- +echo + +# Use Ninja if it is installed (fish users exclusive feature) +echo -n "Checking if ninja is available..." +if command -q ninja + set NINJA_FLAG "-GNinja" + echo "Yes" +else + echo "No" +end + +# Use mold if it is installed (fish users exclusive feature) +# Please make sure the compiler versions are up to date +echo -n "Checking if mold is available..." +if command -q mold + set MOLD_C_FLAGS "-DCMAKE_C_FLAGS=\"-fuse-ld=mold\"" + set MOLD_CXX_FLAGS "-DCMAKE_CXX_FLAGS=\"-fuse-ld=mold\"" + echo "Yes" +else + echo "No" +end + +curl -O -L https://www.flintlib.org/flint-$FLINTVER.tar.gz +tar xf flint-$FLINTVER.tar.gz +cd flint-$FLINTVER + # I can't get ./bootstrap to work with fish + mkdir build + cd build + # I don't know how to translate --disable-static + cmake .. \ + -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DMPFR_INCLUDE_DIRS=$PREFIX/include \ + $FLINTARB_WITHGMP \ + $MOLD_C_FLAGS \ + $MOLD_CXX_FLAGS \ + $NINJA_FLAG + cmake --build . -j "$NUM_CORES" + cmake --build . --target install +cd .. + +# ------------------------------------------------------------------------- # +# # +# ARB # +# # +# ------------------------------------------------------------------------- # + +if test "$BUILD_ARB" = "yes" + + echo + echo -------------------------------------------- + echo " building Arb" + echo -------------------------------------------- + echo + + curl -O -L https://github.com/fredrik-johansson/arb/archive/refs/tags/$ARBVER.tar.gz + mv $ARBVER.tar.gz arb-$ARBVER.tar.gz + tar xf arb-$ARBVER.tar.gz + cd arb-$ARBVER + ./configure --prefix=$PREFIX \ + --with-flint=$PREFIX \ + $FLINTARB_WITHGMP \ + --with-mpfr=$PREFIX \ + --disable-static + make -j"$NUM_CORES" + make install + # + # Set PATH so that DLLs are picked up on Windows. + # + fish_add_path $PREFIX/lib + fish_add_path $PREFIX/bin + set ARB_TEST_MULTIPLIER 0.1 + # Skip Arb tests now because they are slow. + # make check + cd .. +end + +# ------------------------------------------------------------------------- # +# # +# Done! # +# # +# ------------------------------------------------------------------------- # + +echo +echo ----------------------------------------------------------------------- +echo +echo Build dependencies for python-flint compiled as shared libraries in: +echo $PREFIX +echo +echo Versions: + +if test "$SKIP_GMP" = "yes" + echo "GMP: skipped" +else if test "$USE_GMP" = "gmp" + echo "GMP: $GMPVER" +else + echo "MPIR: $MPIRVER" +end + +if test "$SKIP_MPFR" = "yes" + echo "MPFR: skipped" +else + echo "MPFR: $MPFRVER" +end + +echo "Flint: $FLINTVER" + +if test "$BUILD_ARB" = "yes" + echo "Arb: $ARBVER" +end +echo +echo ----------------------------------------------------------------------- +echo diff --git a/bin/build_inplace.fish b/bin/build_inplace.fish new file mode 100755 index 00000000..542ed7e8 --- /dev/null +++ b/bin/build_inplace.fish @@ -0,0 +1,5 @@ +#!/usr/bin/env fish +# +# Build the flint._flint module in place. + +C_INCLUDE_PATH=.local/include/ LIBRARY_PATH=.local/lib/ python setup.py build_ext --inplace diff --git a/bin/build_variables.fish b/bin/build_variables.fish new file mode 100644 index 00000000..1d6aca44 --- /dev/null +++ b/bin/build_variables.fish @@ -0,0 +1,24 @@ +#!/usr/bin/env fish +# +# Create a local directory .local to be used as --prefix when building +# local installs of python-flint's dependencies. This also sets the PREFIX +# shell variable and environment variables giving the versions to use for each +# dependency. This script should be sourced rather than executed e.g.: +# +# $ source bin/build_variables.sh +# +# This is used implicitly by the other build scripts and does not need to be +# executed directly. + +set PREFIX $PWD/.local +mkdir -p $PREFIX + +set ARBVER 2.23.0 # Not needed with flint > 3.0.0 (Arb is included in flint) + +set YASMVER 1.3.0 # Only needed for MPIR +set MPIRVER 3.0.0 # MPIR build no longer works (not clear where to download from) + +# These are the actual dependencies used (at least by default): +set GMPVER 6.3.0 +set MPFRVER 4.1.0 +set FLINTVER 3.0.0-alpha1 diff --git a/bin/coverage.fish b/bin/coverage.fish new file mode 100755 index 00000000..3f719fe8 --- /dev/null +++ b/bin/coverage.fish @@ -0,0 +1,37 @@ +#!/usr/bin/env fish +# +# Note: cython's Cython/Coverage.py fails for pyx files that are included in +# other pyx files. This gives the following error: +# +# $ coverage report -m +# Plugin 'Cython.Coverage.Plugin' did not provide a file reporter for +# '.../python-flint/src/flint/fmpz.pyx'. +# +# A patch to the file is needed: +# +# --- Coverage.py.backup 2022-12-09 17:36:35.387690467 +0000 +# +++ Coverage.py 2022-12-09 17:08:06.282516837 +0000 +# @@ -172,7 +172,9 @@ class Plugin(CoveragePlugin): +# else: +# c_file, _ = self._find_source_files(filename) +# if not c_file: +# - return None +# + c_file = os.path.join(os.path.dirname(filename), 'pyflint.c') +# + if not os.path.exists(c_file): +# + return None +# rel_file_path, code = self._read_source_lines(c_file, filename) +# if code is None: +# return None # no source found +# +# + +source bin/activate.fish + +set PYTHON_FLINT_COVERAGE true + +python setup.py build_ext --inplace + +coverage run -m flint.test $argv + +#coverage report -m +coverage html diff --git a/bin/coverage.sh b/bin/coverage.sh index eeb30f96..17e08d2c 100755 --- a/bin/coverage.sh +++ b/bin/coverage.sh @@ -27,7 +27,7 @@ set -o errexit -source bin/activate +source bin/activate.sh export PYTHON_FLINT_COVERAGE=true diff --git a/bin/run_me.fish b/bin/run_me.fish new file mode 100755 index 00000000..a87cec72 --- /dev/null +++ b/bin/run_me.fish @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +echo "================================================================================" +echo "Ref: https://github.com/flintlib/python-flint/issues/60#issuecomment-1682728914" +echo +echo "This folder contains useful scripts for development. To begin, set up" +echo "environment variables by running \`source bin/activate.fish\` (not executing the" +echo "script!), then build dependencies such as gmp and flint by" +echo "\`bin/build_dependencies_unix.fish\`." +echo +echo "Now to (re-)build \`python-flint\`, simply run \`bin/build_inplace.fish\`, which" +echo "places the extension modules right at \`src/flint\`. You can import by e.g." +echo +echo " >>> import flint" +echo " >>> print(flint.types.nmod.nmod(17, 5))" +echo +echo "Or run the tests from the command line:" +echo +echo " $ python -m flint.test" +echo "================================================================================" diff --git a/bin/run_me.sh b/bin/run_me.sh new file mode 100755 index 00000000..5585ae58 --- /dev/null +++ b/bin/run_me.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +echo "================================================================================" +echo "Ref: https://github.com/flintlib/python-flint/issues/60#issuecomment-1682728914" +echo +echo "This folder contains useful scripts for development. To begin, set up" +echo "environment variables by running \`source bin/activate.fish\` (not executing the" +echo "script!), then build dependencies such as gmp and flint by" +echo "\`bin/build_dependencies_unix.fish\`." +echo +echo "Now to build \`python-flint\`, simply run \`bin/build_inplace.fish\`, which" +echo "places the extension modules right at \`src/flint\`. You can import by e.g." +echo +echo " >>> import flint" +echo " >>> print(flint.types.nmod.nmod(17, 5))" +echo +echo "Or run the tests from the command line:" +echo +echo " $ python -m flint.test" +echo "================================================================================"