# Makefile template for Sage packages: This Makefile is filled by the # ./configure script with information all of Sage's dependent packages (SPKGs), # including their names, their current versions, their dependencies, and some # classifications according to their installation priority ("standard", # "optional") and installation method ("normal", "pip", "script"). # # Finally, install and clean rules for each package are generated from the # templates at the end of this file. Because the templates may slightly # obscure the substance of the actual rules, this file can be debugged by # running: # # $ make -f build/make/Makefile -n DEBUG_RULES=1 # # This will not actually run any rules (the -n flag) but will print all the # rules generated from the templates. # Always use bash for make rules SHELL = @SHELL@ ifndef DEBUG_RULES # Check a variable that is only set in build/make/install, but not in sage-env, for example ifndef SAGE_PKGCONFIG # Set by build/bin/sage-sdist, which invokes the Makefile directly in # order to download upstream packages for distribution. ifndef SAGE_SPKG_COPY_UPSTREAM $(error This Makefile needs to be invoked by build/make/install) endif endif endif # Directory to keep track of which packages are installed - relative to installation prefix SPKG_INST_RELDIR = var/lib/sage/installed # Aliases for mutually exclusive standard packages selected at configure time TOOLCHAIN = @SAGE_TOOLCHAIN@ PYTHON = python3 MP_LIBRARY = gmp BLAS = openblas # pkgconfig files generated/installed at build time PCFILES = @SAGE_SYSTEM_FACADE_PC_FILES@ LN = ln SED = sed # In recursive invocations of make, remove "-jNUMJOBS" options that may # be in $(MAKE) when users follow the recommendations in our manuals. # We also get rid of excessive "Entering directory" messages. MAKE_REC = $(MAKE:-j%=) --no-print-directory # We need to be able to override this to support ./sage -i -c PKG SAGE_SPKG = sage-spkg # These are added to SAGE_SPKG in the call SAGE_SPKG_OPTIONS = @SAGE_SPKG_OPTIONS@ # Where the Sage distribution installs documentation. # set to empty if --disable-doc is used SAGE_DOCS = @SAGE_DOCS@ SAGE_DOCS_DISABLED_MESSAGE = This Sage build is configured with "configure --disable-doc", so building the documentation will not work. # Where the Sage distribution installs Python packages. # This can be overridden by 'make SAGE_VENV=/some/venv'. SAGE_VENV = @SAGE_VENV@ # Generate/install sage-specific .pc files. # see build/pkgs/gsl/spkg-configure.m4 $(SAGE_PKGCONFIG)/gsl.pc: -rm -f $@ @SAGE_GSL_PC_COMMAND@ # see build/pkgs/openblas/spkg-configure.m4 $(SAGE_PKGCONFIG)/openblas.pc $(SAGE_PKGCONFIG)/blas.pc $(SAGE_PKGCONFIG)/cblas.pc $(SAGE_PKGCONFIG)/lapack.pc: -rm -f $@ @SAGE_OPENBLAS_PC_COMMAND@ # Files to track installation of packages BUILT_PACKAGES = @SAGE_BUILT_PACKAGES@ DUMMY_PACKAGES = @SAGE_DUMMY_PACKAGES@ # Set to the path to Sage's GCC (if GCC is installed) to force rebuilds # of packages if GCC changed. # See m4/sage_spkg_collect.m4 and https://github.com/sagemath/sage/issues/24703 GCC_DEP = @SAGE_GCC_DEP@ # Versions of all the packages, in the format # # vers_<pkgname> = <pkgvers> @SAGE_PACKAGE_VERSIONS@ # Dependencies for all packages, in the format # # deps_<pkgname> = <dep1> <dep2> etc... @SAGE_PACKAGE_DEPENDENCIES@ # Installation trees for all packages, in the format: # # - for a non-Python package: # # trees_<pkgname1> = SAGE_LOCAL # # - for a Python package: # # trees_<pkgname2> = SAGE_VENV @SAGE_PACKAGE_TREES@ # All standard/optional/experimental installed packages (triggers the auto-update) OPTIONAL_INSTALLED_PACKAGES = @SAGE_OPTIONAL_INSTALLED_PACKAGES@ INSTALLED_PACKAGES = $(OPTIONAL_INSTALLED_PACKAGES) INSTALLED_PACKAGE_INSTS = \ $(foreach pkgname,$(INSTALLED_PACKAGES),$(inst_$(pkgname))) # All previously installed standard/optional/experimental packages that are to be uninstalled OPTIONAL_UNINSTALLED_PACKAGES = @SAGE_OPTIONAL_UNINSTALLED_PACKAGES@ UNINSTALLED_PACKAGES = $(OPTIONAL_UNINSTALLED_PACKAGES) UNINSTALLED_PACKAGES_UNINSTALLS = $(UNINSTALLED_PACKAGES:%=%-uninstall) # All packages which should be downloaded SDIST_PACKAGES = @SAGE_SDIST_PACKAGES@ # Packages that use the 'normal' build rules NORMAL_PACKAGES = @SAGE_NORMAL_PACKAGES@ # Packages that use the 'pip' package build rules PIP_PACKAGES = @SAGE_PIP_PACKAGES@ # Packages that use the 'script' package build rules SCRIPT_PACKAGES = @SAGE_SCRIPT_PACKAGES@ # Packages for which we build platform-independent wheels for PyPI PYPI_NOARCH_WHEEL_PACKAGES = \ sage_setup \ sagemath_environment \ # Packages for which we build wheels for PyPI PYPI_WHEEL_PACKAGES = $(PYPI_NOARCH_WHEEL_PACKAGES) \ sagemath_objects \ sagemath_repl \ sagemath_categories \ sagemath_bliss \ sagemath_mcqd \ sagemath_tdlib \ sagemath_coxeter3 \ sagemath_sirocco \ sagemath_meataxe # sage_docbuild is here, not in PYPI_WHEEL_PACKAGES, because it depends on sagelib WHEEL_PACKAGES = $(PYPI_WHEEL_PACKAGES) \ sage_conf \ sagelib \ sage_docbuild # Packages for which build sdists for PyPI PYPI_SDIST_PACKAGES = $(WHEEL_PACKAGES) # Generate the actual inst_<pkgname> variables; for each package that is # actually built this generates a line like: # # inst_<pkgname> = $(INST)/<pkgname>-<pkgvers> # # And for 'dummy' package that are not actually built/installed (e.g. because # configure determined we can use the package from the system): # # inst_<pkgname> = $(INST)/.dummy # # For example: # # inst_python3 = $(INST)/python3-$(vers_python3) # # inst_git = $(INST)/.dummy $(foreach pkgname,$(BUILT_PACKAGES),\ $(eval inst_$(pkgname) = $(foreach tree, $(trees_$(pkgname)), $(and $($(tree)), $($(tree))/$(SPKG_INST_RELDIR)/$(pkgname)-$(vers_$(pkgname)))))) $(foreach pkgname,$(DUMMY_PACKAGES),\ $(eval inst_$(pkgname) = $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/.dummy)) # Override this for pip packages, for which we do not keep an installation record # in addition to what pip is already doing. $(foreach pkgname,$(PIP_PACKAGES),\ $(eval inst_$(pkgname) = $(pkgname))) # Dummy target for packages which are not installed $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/.dummy: touch $@ # Filtered by installation tree $(foreach tree,SAGE_LOCAL SAGE_VENV SAGE_DOCS, \ $(eval $(tree)_INSTALLED_PACKAGE_INSTS = \ $(foreach pkgname,$(INSTALLED_PACKAGES), \ $(if $(findstring $(tree),$(trees_$(pkgname))), \ $(inst_$(pkgname))))) \ $(eval $(tree)_UNINSTALLED_PACKAGE_UNINSTALLS = \ $(foreach pkgname,$(INSTALLED_PACKAGES), \ $(if $(findstring $(tree),$(trees_$(pkgname))), \ $(inst_$(pkgname)))))) ############################################################################### # Silent rules # https://www.gnu.org/software/automake/manual/html_node/Automake-Silent-Rules.html ifeq ($(V), 0) AM_V_at = @ else AM_V_at = endif # Issue #33125: Handle make options -n, -t, -q ifeq ($(strip $(foreach flag,n t q,$(findstring $(flag),$(filter-out --%,$(MAKEFLAGS))))),) PLUS = + else PLUS = endif # List of targets that can be run (in addition to names of packages) using `sage -i` or `sage -f` # These should generally have an associated -uninstall target for `sage -f` to # work correctly SAGE_I_TARGETS = sagelib doc # Tell make not to look for files with these names: .PHONY: all all-sage all-toolchain all-build all-sageruntime \ all-start build-start toolchain toolchain-deps base-toolchain \ pypi-sdists pypi-noarch-wheels pypi-wheels wheels \ sagelib \ doc doc-html doc-html-jsmath doc-html-mathjax doc-pdf \ doc-uninstall \ python3_venv _clean-broken-gcc PYTHON_FOR_VENV = @PYTHON_FOR_VENV@ PYTHON_MINOR = @PYTHON_MINOR@ SAGE_VENV_FLAGS = @SAGE_VENV_FLAGS@ ifneq ($(PYTHON_FOR_VENV),) # Special rule for making the Python virtualenv from the system Python (Python # 3 only). $(PYTHON) is set in Makefile to python3_venv. # Thus $(inst_python3_venv) will an (order-only) dependency of every Python package. # # TODO: If we reconfigure to build our own Python after having used the system # Python, files installed to create the virtualenv should be *removed*. That # could either be done here by the makefile, or in an spkg-preinst for python3 ifeq ($(PYTHON),python3) PYTHON = python3_venv endif inst_python3_venv = $(SAGE_VENV)/$(SPKG_INST_RELDIR)/python3_venv-3.$(PYTHON_MINOR)-$(subst /,-,$(PYTHON_FOR_VENV))$(findstring --system-site-packages,$(SAGE_VENV_FLAGS)) $(SAGE_VENV)/$(SPKG_INST_RELDIR): mkdir -p "$@" $(inst_python3_venv): | $(SAGE_VENV)/$(SPKG_INST_RELDIR) $(PYTHON_FOR_VENV) $(SAGE_ROOT)/build/bin/sage-venv $(SAGE_VENV_FLAGS) "$(SAGE_VENV)" rm -f "$(SAGE_VENV)/$(SPKG_INST_RELDIR)"/python3_venv-* touch "$@" endif # Build everything and start Sage. # Note that we put the "doc" target first in the rule below because # the doc build takes the most time and should be started as soon as # possible. all-start: toolchain-deps +$(MAKE_REC) all-sage-docs all-sage # Build everything except the documentation all-build: toolchain-deps +$(MAKE_REC) all-sage # This used to do run "sage-starts" script, now it's just an alias build-start: all-build # The preliminary build phase: toolchain. base-toolchain: _clean-broken-gcc +$(MAKE_REC) toolchain # All targets except for the documentation all-sage: \ $(SAGE_LOCAL_INSTALLED_PACKAGE_INSTS) $(SAGE_LOCAL_UNINSTALLED_PACKAGES_UNINSTALLS) \ $(SAGE_VENV_INSTALLED_PACKAGE_INSTS) $(SAGE_VENV_UNINSTALLED_PACKAGES_UNINSTALLS) # Same but filtered by installation trees: all-build-local: toolchain-deps +$(MAKE_REC) all-sage-local all-sage-local: $(SAGE_LOCAL_INSTALLED_PACKAGE_INSTS) $(SAGE_LOCAL_UNINSTALLED_PACKAGES_UNINSTALLS) all-build-venv: toolchain-deps +$(MAKE_REC) all-sage-venv all-sage-venv: $(SAGE_VENV_INSTALLED_PACKAGE_INSTS) $(SAGE_VENV_UNINSTALLED_PACKAGES_UNINSTALLS) all-build-docs: toolchain-deps +$(MAKE_REC) all-sage-docs all-sage-docs: $(SAGE_DOCS_INSTALLED_PACKAGE_INSTS) $(SAGE_DOCS_UNINSTALLED_PACKAGES_UNINSTALLS) # Download all packages which should be inside an sdist tarball (the -B # option to make forces all targets to be built unconditionally) download-for-sdist: +env SAGE_INSTALL_FETCH_ONLY=yes $(MAKE_REC) -B SAGERUNTIME= \ $(SDIST_PACKAGES) # TOOLCHAIN consists of dependencies determined by configure. # These are built before anything else. toolchain: $(foreach pkgname,$(TOOLCHAIN),$(inst_$(pkgname))) $(PCFILES) # Build all packages that GCC links against serially, otherwise this # leads to race conditions where some library which is used by GCC gets # reinstalled. Since system GCCs might use Sage's libraries, we do this # unconditionally. We still use the dependency checking from $(MAKE), # so this will not trigger useless rebuilds. # See #14168 and #14232. # # Note: This list consists of only the *runtime* dependencies of the toolchain. TOOLCHAIN_DEPS = $(MP_LIBRARY) mpfr mpc TOOLCHAIN_DEP_INSTS = \ $(foreach pkgname,$(TOOLCHAIN_DEPS),$(inst_$(pkgname))) toolchain-deps: +@for target in $(TOOLCHAIN_DEP_INSTS); do \ echo $(MAKE_REC) $$target; \ $(MAKE_REC) $$target; \ done all-toolchain: base-toolchain +$(MAKE_REC) toolchain-deps # Shorthand for a list of packages sufficient for building and installing # typical Python packages from source. Wheel packages only need pip. PYTHON_TOOLCHAIN = setuptools pip setuptools_scm wheel flit_core hatchling python_build # Issue #32056: Avoid installed setuptools leaking into the build of python3 by uninstalling it. # It will have to be reinstalled anyway because of its dependency on $(PYTHON). python3-SAGE_LOCAL-no-deps: setuptools-clean python3-SAGE_VENV-no-deps: setuptools-clean # Everything needed to start up Sage using "./sage". Of course, not # every part of Sage will work. It does not include Maxima for example. SAGERUNTIME = sagelib $(inst_ipython) $(inst_pexpect) all-sageruntime: toolchain-deps +$(MAKE_REC) $(SAGERUNTIME) ############################################################################### # Building the documentation ############################################################################### # You can choose to have the built HTML version of the documentation link to # the PDF version. To do so, you need to build both the HTML and PDF versions. # To have the HTML version link to the PDF version, do # # $ ./sage --docbuild all html # $ ./sage --docbuild all pdf # # For more information on the docbuild utility, do # # $ ./sage --docbuild -H doc: doc-html # All doc-building is delegated to the script packages # sagemath_doc_html, sagemath_doc_pdf doc-html: sagemath_doc_html # 'doc-html-no-plot': build docs without building the graphics coming # from the '.. plot' directive, in case you want to save a few # megabytes of disk space. Run 'make doc-clean' first because the # presence of graphics is cached in the built documentation. doc-html-no-plot: (cd $(SAGE_ROOT) && $(MAKE) doc-clean) +$(MAKE_REC) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-plot" doc-html # Using mathjax is actually the only options, but we keep # this target for backwards compatibility. doc-html-mathjax: doc-html # Also Keep target 'doc-html-jsmath' for backwards compatibility. doc-html-jsmath: doc-html-mathjax doc-pdf: sagemath_doc_pdf doc-uninstall: rm -rf "$(SAGE_SHARE)/doc/sage" # Special target for cleaning up a broken GCC install detected by configure # This should check for the .clean-broken-gcc stamp, and if found clean # everything up along with the stamp file itself. This target is then run # as a prerequisite to installing any other packages. _clean-broken-gcc: @if [ -f "$(SAGE_ROOT)/build/make/.clean-broken-gcc" ]; then \ rm -f "$(SAGE_LOCAL)/bin/gcc"; \ rm -f "$(SAGE_LOCAL)/gcc-"*; \ rm -f "$(SAGE_LOCAL)/bin/g++"; \ rm -f "$(SAGE_SPKG_INST)/gcc-"*; \ rm -f "$(SAGE_ROOT)/build/make/.clean-broken-gcc"; \ echo "Cleaned up old broken GCC install"; \ fi # Implicit rules for uninstalling packages that no longer exist in the source tree. %-SAGE_LOCAL-uninstall: @package=$@; \ package=$${package%%-*}; \ if [ -d '$(SAGE_LOCAL)' ]; then \ sage-spkg-uninstall $$package; \ fi %-SAGE_VENV-uninstall: @package=$@; \ package=$${package%%-*}; \ if [ -d '$(SAGE_VENV)' ]; then \ sage-spkg-uninstall $$package $(SAGE_VENV); \ fi %-uninstall: @package=$@; \ package=$${package%%-*}; \ $(MAKE) $$package-SAGE_LOCAL-uninstall $$package-SAGE_VENV-uninstall %-installcheck: @stampfile=$@; \ stampfile=$${stampfile%-installcheck}; \ if [ -s $$stampfile ]; then \ echo >&2 "# Checking $$stampfile"; \ tree=$${stampfile%%/$(SPKG_INST_RELDIR)/*}; \ package_with_version=$${stampfile##*/}; \ package=$${package_with_version%%-*}; \ if ! $(SAGE_VENV)/bin/python3 $(SAGE_ROOT)/build/bin/sage-spkg-installcheck --verbose $$package $$tree; then \ case "$$tree" in \ "$(SAGE_LOCAL)") echo " make $$package-SAGE_LOCAL-uninstall;";; \ "$(SAGE_VENV)") echo " make $$package-SAGE_VENV-uninstall;";; \ *) echo " ./sage --buildsh -c \"sage-spkg-uninstall $$package $$tree\";";; \ esac; \ fi; \ fi; list-broken-packages: auditwheel_or_delocate @fix_broken_packages=$$($(MAKE) -s $(patsubst %,%-installcheck,$(wildcard $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/* $(SAGE_VENV)/$(SPKG_INST_RELDIR)/*))); \ if [ -n "$$fix_broken_packages" ]; then \ echo >&2 ; \ echo >&2 "Uninstall broken packages by typing:"; \ echo >&2 ; \ echo >&2 "$$fix_broken_packages"; \ fi pypi-sdists: $(PYPI_SDIST_PACKAGES:%=%-sdist) @echo "Built sdists are in upstream/" # Ensuring wheels are present, even for packages that may have been installed # as editable. Until we have better uninstallation of script packages, we # just remove the timestamps, which will lead to rebuilds of the packages. pypi-noarch-wheels: for a in $(PYPI_NOARCH_WHEEL_PACKAGES); do \ rm -f $(SAGE_VENV)/var/lib/sage/installed/$$a-*; \ done $(MAKE_REC) SAGE_EDITABLE=no SAGE_WHEELS=yes $(PYPI_NOARCH_WHEEL_PACKAGES) @echo "Built wheels are in venv/var/lib/sage/wheels/" pypi-wheels: for a in $(PYPI_WHEEL_PACKAGES); do \ rm -f $(SAGE_VENV)/var/lib/sage/installed/$$a-*; \ done $(MAKE_REC) SAGE_EDITABLE=no SAGE_WHEELS=yes $(PYPI_WHEEL_PACKAGES) @echo "Built wheels are in venv/var/lib/sage/wheels/" wheels: for a in $(WHEEL_PACKAGES); do \ rm -f $(SAGE_VENV)/var/lib/sage/installed/$$a-*; \ done $(MAKE_REC) SAGE_EDITABLE=no SAGE_WHEELS=yes $(WHEEL_PACKAGES) @echo "Built wheels are in venv/var/lib/sage/wheels/" pypi-wheels-check: $(PYPI_WHEEL_PACKAGES:%=%-check) #============================================================================== # Setting SAGE_CHECK... variables #============================================================================== ifeq "$(origin SAGE_CHECK)" "undefined" SAGE_CHECK := no endif define SET_SAGE_CHECK $(eval SAGE_CHECK_$(1) := $(2)) endef # Set defaults $(foreach pkgname, $(NORMAL_PACKAGES) $(SCRIPT_PACKAGES),\ $(eval $(call SET_SAGE_CHECK,$(pkgname),$(SAGE_CHECK)))) # Parsing the SAGE_CHECK_PACKAGES variable: # - if this contains "!pkg", set SAGE_CHECK_pkg=no. # - if this contains "?pkg", set SAGE_CHECK_pkg=warn. # - if this contains "pkg", set SAGE_CHECK_pkg=yes. # # We check this now and export SAGE_CHECK_pkg for # dependencies and the Makefile rules. # # Since Python's self-tests seem to fail on all platforms, we disable # its test suite by default. # meson_python 0.10.0 fails on some platforms, so we reduce it to warnings. # However, if SAGE_CHECK=warn, we do not do that. SAGE_CHECK_PACKAGES_DEFAULT_yes := !python3,?meson_python SAGE_CHECK_PACKAGES_DEFAULT_warn := SAGE_CHECK_PACKAGES_DEFAULT_no := comma := , ifeq "$(origin SAGE_CHECK_PACKAGES)" "undefined" SAGE_CHECK_PACKAGES := $(SAGE_CHECK_PACKAGES_DEFAULT_$(SAGE_CHECK)) endif SAGE_CHECK_PACKAGES_sep := $(subst $(comma), ,$(SAGE_CHECK_PACKAGES)) SAGE_CHECK_PACKAGES_sep := $(subst :, ,$(SAGE_CHECK_PACKAGES_sep)) $(foreach clause, $(SAGE_CHECK_PACKAGES_sep), \ $(if $(findstring !,$(clause)), \ $(eval $(call SET_SAGE_CHECK,$(subst !,,$(clause)),no)), \ $(if $(findstring ?,$(clause)), \ $(eval $(call SET_SAGE_CHECK,$(subst ?,,$(clause)),warn)), \ $(eval $(call SET_SAGE_CHECK,$(clause),yes))))) debug-check: @echo $(foreach pkgname, $(NORMAL_PACKAGES) $(SCRIPT_PACKAGES), SAGE_CHECK_$(pkgname) = $(SAGE_CHECK_$(pkgname))) #============================================================================== # Rules generated from pkgs/<package>/dependencies files #============================================================================== # Define a function for generating the list of a package's dependencies # as $(inst_<pkgname>) variables. For example, takes: # # deps_cysignals = python3 cython pari | pip # # to: # # $(inst_python3) $(inst_cython) $(inst_pari) | $(inst_pip) # # If some value in the dependencies list is not a package name (e.g. it is # the name of some arbitrary file, or it is the '|' symbol) then it is just # used verbatim. # # As a special case, also adds a special variable GCC_DEP for all packages # except for gcc itself. See the definition of GCC_DEP above # # Positional arguments: # $(1): package name pkg_deps = \ $(if $(filter gcc,$(1)),,$$(GCC_DEP))\ $(foreach dep,$(deps_$(1)),\ $(if $(value inst_$(dep)),$$(inst_$(dep)),$(dep))) # ============================= normal packages ============================== # Generate build rules for 'normal' packages; this template is used to generate # rules in the form: # # $(INST)/<pkgname>-<pkgvers>: <dependencies> # $(MAKE) $(1)-no-deps # # <pkgname>: $(INST)/<pkgname>-<pkgvers> # # <pkgname>-build-deps: <dependencies> # # <pkgname>-no-deps: # +$(AM_V_at)sage-logger -p '$(SAGE_SPKG) <pkgname>-<pkgvers>' '$(SAGE_LOGS)/<pkgname>-<pkgvers>.log' # # <pkgname>-uninstall: # sage-spkg-uninstall <pkgname> '$(SAGE_LOCAL)' # # So <pkgname>-build-deps installs just the dependencies, while # <pkgname>-no-deps tries to install the package without its # dependencies. This is currently used in SAGE_SRC/bin/sage when # running 'sage -b' to build the Sage library. # # For example, for python3 this will expand to: # # $(INST)/python3-3.7.3: $(inst_readline) $(inst_sqlite) $(inst_libpng) $(inst_xz) $(inst_libffi) # +$(AM_V_at)sage-logger -p '$(SAGE_SPKG) python3-3.7.3' '$(SAGE_LOGS)/python3-3.7.3.log' # # python3: $(INST)/python3-3.7.3 # # python3-uninstall: # sage-spkg-uninstall python3 '$(SAGE_LOCAL)' # # Note: In these rules the $(INST)/<pkgname>-<pkgvers> target is used # explicitly, rather than expanding the $(inst_<pkgname>) variable, since # it may expand to $(INST)/.dummy for packages that were not configured # for installation by default. However, we wish to be able to manually # install those packages later. # # For packages listed in $(TOOLCHAIN_DEPS) we also pass --keep-existing to # sage-spkg, and --keep-files to sage-spkg-uninstall since those packages can # have a recursive self-dependency, and should not be deleted while upgrading. # See Issue #25857 # Positional arguments: # $(1): package name # $(2): package version # $(3): package dependencies # $(4): package tree variable define NORMAL_PACKAGE_templ ########################################## $(1)-build-deps: $(3) $$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2): $(3) +$(MAKE_REC) $(1)-$(4)-no-deps $(1): $$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2) $(1)-ensure: $(inst_$(1)) $(1)-$(4)-no-deps: +@if [ -z '$$($(4))' ]; then \ echo "Error: The installation tree $(4) has been disabled" 2>&1; \ echo "$$($(4)_DISABLED_MESSAGE)" 2>&1; \ exit 1; \ else \ sage-logger -p 'SAGE_CHECK=$$(SAGE_CHECK_$(1)) PATH=$$(SAGE_SRC)/bin:$$($(4))/bin:$$$$PATH $$(SAGE_SPKG) $$(SAGE_SPKG_OPTIONS) \ $(if $(filter $(1),$(TOOLCHAIN_DEPS)),--keep-existing) \ $(1)-$(2) $$($(4))' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ fi $(1)-no-deps: $(1)-$(4)-no-deps $(1)-$(4)-check: $(PLUS)@sage-logger -p 'PATH=$$(SAGE_SRC)/bin:$$($(4))/bin:$$$$PATH $$(SAGE_SPKG) --check-only $(1)-$(2) $$($(4))' '$$(SAGE_LOGS)/$(1)-$(2).log' $(1)-check: $(1)-$(4)-check $(1)-$(4)-uninstall: if [ -d '$$($(4))' ]; then \ sage-spkg-uninstall $(if $(filter $(1),$(TOOLCHAIN_DEPS)),--keep-files) \ $(1) '$$($(4))'; \ fi $(1)-uninstall: $(1)-$(4)-uninstall $(1)-clean: $(1)-uninstall .PHONY: $(1) $(1)-$(4)-uninstall $(1)-uninstall $(1)-clean $(1)-build-deps $(1)-no-deps endef ################################################################# $(foreach pkgname, $(NORMAL_PACKAGES),\ $(foreach tree, $(trees_$(pkgname)), \ $(eval $(call NORMAL_PACKAGE_templ,$(pkgname),$(vers_$(pkgname)),\ $(call pkg_deps,$(pkgname)),$(tree))))) ifdef DEBUG_RULES $(info # Rules for standard packages) $(foreach pkgname, $(NORMAL_PACKAGES),\ $(foreach tree, $(trees_$(pkgname)), \ $(info $(call NORMAL_PACKAGE_templ,$(pkgname),$(vers_$(pkgname)),\ $(call pkg_deps,$(pkgname)),$(tree))))) endif # ================================ pip packages =============================== # Generate build rules for 'pip' packages; this template is used to generate # two rules in the form: # # <pkgname>: <dependencies> # $(AM_V_at)sage-logger -p 'sage --pip install ...' '$(SAGE_LOGS)/<pkgname>.log' # # <pkgname>-uninstall: # -sage --pip uninstall -y ... # Positional arguments: # $(1): package name # $(2): package dependencies define PIP_PACKAGE_templ $(1)-build-deps: $(2) $(1): $(2) +$(MAKE_REC) $(1)-no-deps $(1)-ensure: $(inst_$(1)) $(1)-no-deps: $(AM_V_at)sage-logger -p 'sage --pip install -r "$$(SAGE_ROOT)/build/pkgs/$(1)/requirements.txt"' '$$(SAGE_LOGS)/$(1).log' $(1)-uninstall: -sage --pip uninstall --isolated --yes --no-input -r '$$(SAGE_ROOT)/build/pkgs/$(1)/requirements.txt' $(1)-clean: $(1)-uninstall .PHONY: $(1) $(1)-uninstall $(1)-clean $(1)-build-deps $(1)-no-deps endef $(foreach pkgname,$(PIP_PACKAGES),\ $(eval $(call PIP_PACKAGE_templ,$(pkgname),$(call pkg_deps,$(pkgname))))) ifdef DEBUG_RULES $(info # Rules for pip packages) $(foreach pkgname,$(PIP_PACKAGES),\ $(info $(call PIP_PACKAGE_templ,$(pkgname),$(call pkg_deps,$(pkgname))))) endif # ============================= script packages ============================== # Generate build rules for 'script' packages; this template is used to generate # three rules in the form: # # $(INST)/<pkgname>-<pkgvers>: <dependencies> # $(AM_V_at)cd '$SAGE_ROOT' && \\ # . '$SAGE_ROOT/src/bin/sage-env-config' && \\ # . '$SAGE_ROOT/src/bin/sage-env' && \\ # . '$SAGE_ROOT/build/bin/sage-build-env-config' && \\ # . '$SAGE_ROOT/build/bin/sage-build-env' && \\ # sage-logger -p '$SAGE_ROOT/build/pkgs/<pkgname>/spkg-install' '$(SAGE_LOGS)/<pkgname>.log' # # <pkgname>: $(INST)/<pkgname>-<pkgvers> # # <pkgname>-uninstall: # -$(AM_V_at)cd '$SAGE_ROOT' && \\ # . '$SAGE_ROOT/src/bin/sage-env-config' && \\ # . '$SAGE_ROOT/src/bin/sage-env' && \\ # . '$SAGE_ROOT/build/bin/sage-build-env-config' && \\ # . '$SAGE_ROOT/build/bin/sage-build-env' && \\ # '$SAGE_ROOT/build/pkgs/$PKG_NAME/spkg-uninstall' # Positional arguments: # $(1): package name # $(2): package version # $(3): package dependencies # $(4): package tree variable define SCRIPT_PACKAGE_templ $(1)-build-deps: $(3) $$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2): $(3) +$(MAKE_REC) $(1)-$(4)-no-deps $(1): $$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2) $(1)-ensure: $(inst_$(1)) $(1)-$(4)-no-deps: $(PLUS)@if [ -z '$$($(4))' ]; then \ echo "Error: The installation tree $(4) has been disabled" 2>&1; \ echo "$$($(4)_DISABLED_MESSAGE)" 2>&1; \ exit 1; \ else \ rm -rf '$$($(4))/var/lib/sage/scripts/$(1)'; \ cd '$$(SAGE_ROOT)/build/pkgs/$(1)' && \ . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env' && \ . '$$(SAGE_ROOT)/build/bin/sage-build-env-config' && \ . '$$(SAGE_ROOT)/build/bin/sage-build-env' && \ SAGE_CHECK=$$(SAGE_CHECK_$(1)) \ sage-logger -p 'SAGE_CHECK=$$(SAGE_CHECK_$(1)) PATH=$$(SAGE_SRC)/bin:$$($(4))/bin:$$$$PATH $$(SAGE_SPKG) $$(SAGE_SPKG_OPTIONS) \ $(if $(filter $(1),$(TOOLCHAIN_DEPS)),--keep-existing) \ $(1)-$(2) $$($(4))' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ fi $(1)-no-deps: $(1)-$(4)-no-deps $(1)-$(4)-check: $(PLUS)@sage-logger -p 'PATH=$$(SAGE_SRC)/bin:$$($(4))/bin:$$$$PATH $$(SAGE_SPKG) --check-only $(1)-$(2) $$($(4))' '$$(SAGE_LOGS)/$(1)-$(2).log' $(1)-check: $(1)-$(4)-check $(1)-$(4)-uninstall: if [ -d '$$($(4))' ]; then \ sage-spkg-uninstall $(if $(filter $(1),$(TOOLCHAIN_DEPS)),--keep-files) \ $(1) '$$($(4))'; \ fi $(1)-uninstall: $(1)-$(4)-uninstall $(1)-clean: $(1)-uninstall $(1)-sdist: FORCE python_build sage_setup cython $(AM_V_at) cd '$$(SAGE_ROOT)' && \ . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env' && \ '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-src' # Recursive tox invocation # Setting SAGE_SPKG_WHEELS is for the benefit of sagelib's tox.ini $(1)-tox-%: FORCE $(AM_V_at)cd '$$(SAGE_ROOT)/build/pkgs/$(1)/src' && \ . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env' && \ SAGE_SPKG_WHEELS=$$(SAGE_VENV)/var/lib/sage/wheels \ tox -v -v -v -e $$* .PHONY: $(1) $(1)-uninstall $(1)-clean $(1)-build-deps $(1)-no-deps $(1)-clean endef $(foreach pkgname,$(SCRIPT_PACKAGES),\ $(foreach tree, $(trees_$(pkgname)), \ $(eval $(call SCRIPT_PACKAGE_templ,$(pkgname),$(vers_$(pkgname)),$(call pkg_deps,$(pkgname)),$(tree))))) ifdef DEBUG_RULES $(info # Rules for script packages) $(foreach pkgname,$(SCRIPT_PACKAGES),\ $(foreach tree, $(trees_$(pkgname)), \ $(info $(call SCRIPT_PACKAGE_templ,$(pkgname),$(vers_$(pkgname)),$(call pkg_deps,$(pkgname)),$(tree))))) endif # sagelib depends on this so that its install script is always executed FORCE: # Use this target to list common targets of this Makefile (in particular for # installation with `sage -i`. list: @for pkg in $(SAGE_I_TARGETS) $(NORMAL_PACKAGES) $(PIP_PACKAGES) $(SCRIPT_PACKAGES); do\ echo $$pkg;\ done .PHONY: list