diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 754925a4..a0586190 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,8 +9,11 @@ jobs: strategy: matrix: boost: + # Used by RMS 12.1 / Python 3.8 and later + - "1.74.0" + # newer versions of macOS (11+) / XCode (14+) have issues compiling Boost older than - "1.76.0" - # Used by RMS 14.2 / Python 11 and later + # Used by RMS 14.2 / Python 3.11 and later - "1.81.0" steps: diff --git a/README.md b/README.md index 16993737..8629acad 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ If you want to run with a predefined start seed, call `grf.seed(seed_value)` bef ## Building We use [`scikit-build-core`](https://scikit-build-core.readthedocs.io/en/latest/index.html) as the build tool, in order to use [`pyproject.toml`](https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/) to facilitate easier building while using [`cmake`](https://cmake.org) to build the C++ extension. -We also use [Boost.Python](https://www.boost.org/doc/libs/1_81_0/libs/python/doc/html/index.html) (version 1.76.0 for Python <=3.10 and 1.81.0 for newer versions). +We also use [Boost.Python](https://www.boost.org/doc/libs/1_81_0/libs/python/doc/html/index.html) (version 1.74.0 for Python <=3.9, 1.76.0 for Python <= 3.10, and 1.81.0 for newer versions). While compiling Boost, a python interpreter needs to be set. You may want to create a virtual environment before building `gaussianfft`. diff --git a/bin/fetch-boost.sh b/bin/fetch-boost.sh index 98cb322d..9f3dd228 100755 --- a/bin/fetch-boost.sh +++ b/bin/fetch-boost.sh @@ -163,6 +163,10 @@ extract_files_depending_on "boost/graph/adjacency_list.hpp" extract_files_depending_on "boost/graph/reverse_graph.hpp" # from libs/python/src/object/inheritance.cpp:17 extract_files_depending_on "boost/tuple/tuple_comparison.hpp" +# from ./boost/math/policies/policy.hpp:9 (in boost 1.74.0) +extract_files_depending_on "boost/mpl/list/list20.hpp" +extract_files_depending_on "boost/mpl/list/aux_/preprocessed/plain/list10.hpp" +extract_files_depending_on "boost/mpl/list/aux_/preprocessed/plain/list20.hpp" ## Filesystem extract_files libs/filesystem/build diff --git a/bin/find_boost_version.py b/bin/find_boost_version.py index 53c112dd..d236d481 100755 --- a/bin/find_boost_version.py +++ b/bin/find_boost_version.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +import argparse +import platform import sys from pathlib import Path @@ -6,9 +8,19 @@ PYTHON_VERSION = sys.version_info KNOWN_MINIMUMS = [ + {"python_version": (3, 6), "min_version": (1, 74, 0), "platform_system": "Linux"}, + {"python_version": (3, 6), "min_version": (1, 76, 0), "platform_system": "Darwin"}, + {"python_version": (3, 10), "min_version": (1, 76, 0), "platform_system": "Linux"}, {"python_version": (3, 11), "min_version": (1, 81, 0)}, ] +# These are known to cause problems on newer versions of Python and/or some OS-es +PROBLEMATIC_VERSIONS = [ + # Seem to not support Python 3.10 and newer + # It is also problematic to compile on macOS + (1, 74, 0), +] + ROOT = Path(__file__).parent @@ -23,19 +35,58 @@ def fixed_boost_version(): def dynamic_boost_version(): - version = (1, 76, 0) + version = (1, 74, 0) python_version = (PYTHON_VERSION.major, PYTHON_VERSION.minor) for constraint in KNOWN_MINIMUMS: if constraint["python_version"] <= python_version: - version = constraint["min_version"] + required_system = constraint.get("platform_system") + if required_system is None or required_system == platform.system(): + version = constraint["min_version"] return version +def parse_arguments(): + parser = argparse.ArgumentParser( + prog="find-relevant-boost-version", + description="Gives the appropriate version of Boost, based on gaussianfft's known run environments", + ) + parser.add_argument( + "-s", "--sdist", + action="store_true", + required=False, + help="Toggles if the version of Boost should be appropriate for inclusion in the source distribution", + ) + return parser.parse_args() + + def run(): + args = parse_arguments() + if args.sdist: + version = boost_version_for_sdist() + else: + version = boost_version_for_wheel() + sys.stdout.write('.'.join(map(str, version))) + + +def boost_version_for_sdist(): + python_version = (float('inf'), float('inf')) + boost_version = (0, 0, 0) + for constraint in KNOWN_MINIMUMS: + if python_version > constraint["python_version"] and constraint["min_version"] not in PROBLEMATIC_VERSIONS: + python_version = constraint["python_version"] + + for constraint in KNOWN_MINIMUMS: + if python_version == constraint["python_version"]: + if boost_version < constraint["min_version"]: + boost_version = constraint["min_version"] + return boost_version + + +def boost_version_for_wheel(): version = fixed_boost_version() if version is None: version = dynamic_boost_version() - sys.stdout.write('.'.join(map(str, version))) + return version if __name__ == '__main__': diff --git a/bin/prepare-sdist.sh b/bin/prepare-sdist.sh index 1e87af68..87774476 100755 --- a/bin/prepare-sdist.sh +++ b/bin/prepare-sdist.sh @@ -2,11 +2,12 @@ set -euo pipefail readonly ROOT_DIR="$(cd "$(dirname -- "$0")/.." >/dev/null; pwd -P)" +readonly PYTHON=${PYTHON:-python3} # Remove all, but the oldest supported version of boost # add that version to a file, which is read by `find_boost_version.py` -readonly boost_version="$(ls "$ROOT_DIR/sources/boost/" | sort -h | head -1)" +readonly boost_version="$("$PYTHON" "$ROOT_DIR/bin/find_boost_version.py" --sdist)" shopt -s extglob cd "$ROOT_DIR/sources/boost" diff --git a/cmake/boost.cmake b/cmake/boost.cmake index 0b41551a..b2664d5a 100644 --- a/cmake/boost.cmake +++ b/cmake/boost.cmake @@ -31,6 +31,14 @@ set(BUILD_PYTHON_SUPPORT ON) set(Boost_LIBRARY_DIR ${Boost_DIR}/stage/lib) if (NOT EXISTS ${Boost_LIBRARY_DIR}) message(STATUS "Compiling Boost") + if (APPLE AND ${BOOST_VERSION} STRLESS "1.76.0") + message(WARNING "There are known problems compiling Boost prior to 1.76.0 on newer versions of macOS") + # There is a problem with the C++11 check in tools/build/src/engine/build.sh + # for Boost 1.74.0 on macOS; the script does not add the necessary include directories for clang + # causing check_cxx11.cpp to fail by not finding + # This is not a problem in Boost 1.76.0 and newer + set(ENV{NO_CXX11_CHECK} "1") + endif () execute_process(COMMAND ${Boost_COMPILE_SCRIPT} ${BOOST_VERSION} COMMAND_ERROR_IS_FATAL ANY) else () message(STATUS "Reusing compiled boost libraries at ${Boost_LIBRARY_DIR}")