diff options
Diffstat (limited to 'reproduce/software/make')
-rw-r--r-- | reproduce/software/make/README.md | 2 | ||||
-rw-r--r-- | reproduce/software/make/atlas-multiple.mk | 4 | ||||
-rw-r--r-- | reproduce/software/make/atlas-single.mk | 4 | ||||
-rw-r--r-- | reproduce/software/make/basic.mk | 1068 | ||||
-rw-r--r-- | reproduce/software/make/build-rules.mk | 106 | ||||
-rw-r--r-- | reproduce/software/make/high-level.mk | 1347 | ||||
-rw-r--r-- | reproduce/software/make/python.mk | 849 | ||||
-rw-r--r-- | reproduce/software/make/r-cran.mk | 488 | ||||
-rw-r--r-- | reproduce/software/make/xorg.mk | 43 |
9 files changed, 2694 insertions, 1217 deletions
diff --git a/reproduce/software/make/README.md b/reproduce/software/make/README.md index 8d12d7a..00afef4 100644 --- a/reproduce/software/make/README.md +++ b/reproduce/software/make/README.md @@ -1,7 +1,7 @@ Software building instructions ------------------------------ -Copyright (C) 2019-2021 Mohammad Akhlaghi <mohammad@akhlaghi.org>\ +Copyright (C) 2019-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org>\ See the end of the file for license conditions. This directory contains Makefiles that are called by the high-level diff --git a/reproduce/software/make/atlas-multiple.mk b/reproduce/software/make/atlas-multiple.mk index e782578..6e7d415 100644 --- a/reproduce/software/make/atlas-multiple.mk +++ b/reproduce/software/make/atlas-multiple.mk @@ -3,12 +3,12 @@ # ------------------------------------------------------------------------ # !!!!! IMPORTANT NOTES !!!!! # -# This Makefile will be run during the initial `./project configure' +# This Makefile will be run during the initial './project configure' # script. It is not included into the reproduction pipe after that. # # ------------------------------------------------------------------------ # -# Copyright (C) 2019-2021 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2019-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> # # This Makefile is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/reproduce/software/make/atlas-single.mk b/reproduce/software/make/atlas-single.mk index 0934b66..2b68677 100644 --- a/reproduce/software/make/atlas-single.mk +++ b/reproduce/software/make/atlas-single.mk @@ -3,12 +3,12 @@ # ------------------------------------------------------------------------ # !!!!! IMPORTANT NOTES !!!!! # -# This Makefile will be run during the initial `./project configure' +# This Makefile will be run during the initial './project configure' # script. It is not included into the reproduction pipe after that. # # ------------------------------------------------------------------------ # -# Copyright (C) 2019-2021 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2019-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> # # This Makefile is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/reproduce/software/make/basic.mk b/reproduce/software/make/basic.mk index 0d114db..4b18c29 100644 --- a/reproduce/software/make/basic.mk +++ b/reproduce/software/make/basic.mk @@ -4,7 +4,7 @@ # ------------------------------------------------------------------------ # !!!!! IMPORTANT NOTES !!!!! # -# This Makefile will be run by the initial `./project configure' script. It +# This Makefile will be run by the initial './project configure' script. It # is not included into the project afterwards. # # This Makefile builds low-level and basic tools that are necessary in any @@ -21,8 +21,9 @@ # # ------------------------------------------------------------------------ # -# Copyright (C) 2018-2021 Mohammad Akhlaghi <mohammad@akhlaghi.org> -# Copyright (C) 2019-2021 Raul Infante-Sainz <infantesainz@gmail.com> +# Copyright (C) 2018-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2019-2025 Raul Infante-Sainz <infantesainz@gmail.com> +# Copyright (C) 2022-2025 Pedram Ashofteh Ardakani <pedramardakani@pm.me> # # This Makefile is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -38,7 +39,7 @@ # along with this Makefile. If not, see <http://www.gnu.org/licenses/>. # Top level environment -include reproduce/software/config/LOCAL.conf +include .build/software/config/LOCAL.conf include reproduce/software/make/build-rules.mk include reproduce/software/config/versions.conf include reproduce/software/config/checksums.conf @@ -48,22 +49,27 @@ include reproduce/software/config/checksums.conf include reproduce/software/config/urls.conf # Basic directories -lockdir = $(BDIR)/software/locks -tdir = $(BDIR)/software/tarballs -ddir = $(BDIR)/software/build-tmp -idir = $(BDIR)/software/installed -ibdir = $(BDIR)/software/installed/bin -ildir = $(BDIR)/software/installed/lib -ibidir = $(BDIR)/software/installed/version-info/proglib +lockdir = $(BDIR)/software/locks +tdir = $(BDIR)/software/tarballs +ddir = $(BDIR)/software/build-tmp +idir = $(BDIR)/software/installed +ibdir = $(BDIR)/software/installed/bin +ildir = $(BDIR)/software/installed/lib +iidir = $(BDIR)/software/installed/include +shsrcdir = "$(shell pwd)"/reproduce/software/shell +ibidir = $(BDIR)/software/installed/version-info/proglib # Ultimate Makefile target. GNU Nano (a simple and very light-weight text # editor) is installed by default, it is recommended to have it in the # 'basic.mk', so Maneaged projects can be edited on any system (even when -# there is no command-line text editor is available). +# there is no command-line text editor available). +# +# The recipe is '@echo > /dev/null' so Make does not print "make: Nothing +# to be done for 'all'." targets-proglib = low-level-links \ gcc-$(gcc-version) \ nano-$(nano-version) -all: $(foreach p, $(targets-proglib), $(ibidir)/$(p)) +all: $(foreach p, $(targets-proglib), $(ibidir)/$(p)); @echo > /dev/null # Define the shell environment # ---------------------------- @@ -86,21 +92,38 @@ export SHELL := $(ibdir)/dash export PATH := $(ibdir):$(PATH) export PKG_CONFIG_PATH := $(ildir)/pkgconfig export PKG_CONFIG_LIBDIR := $(ildir)/pkgconfig -export CPPFLAGS := -I$(idir)/include $(CPPFLAGS) \ - -Wno-nullability-completeness export LDFLAGS := $(rpath_command) -L$(ildir) $(LDFLAGS) +# Disable built-in rules (which are not needed here!) +.SUFFIXES: + +# See description of '-Wno-nullability-completeness' in +# 'reproduce/software/shell/configure.sh'. +ifeq ($(on_mac_os),yes) + noccwarnings=-Wno-nullability-completeness +endif +export CPPFLAGS := -I$(idir)/include $(CPPFLAGS) $(noccwarnings) + # This is the "basic" tools where we are relying on the host operating # system, but are slowly populating our basic software envirnoment. To run -# (system or template) programs, `LD_LIBRARY_PATH' is necessary, so here, +# (system or template) programs, 'LD_LIBRARY_PATH' is necessary, so here, # we'll first tell the programs to look into any possible pre-defined -# `LD_LIBRARY_PATH', then we'll add our own newly installed libraries. We +# 'LD_LIBRARY_PATH', then we'll add our own newly installed libraries. We # will also make sure that there is no "current directory" in it (by -# removing a starting or trailing `:' and any occurance of `::'. +# removing a starting or trailing ':' and any occurance of '::'. +# +# But first: in case LD_LIBRARY_PATH is empty, give it the default value of +# $(sys_library_sh_path) (which was the location of the libraries needed by +# the host's shell). This is because after we add the Maneage's library +# path, on some systems, no other libraries will be checked except those +# that are in 'LD_LIBRARY_PATH'. +ifeq ($(strip $(LD_LIBRARY_PATH)),) +export LD_LIBRARY_PATH=$(sys_library_sh_path) +endif export LD_LIBRARY_PATH := $(shell echo $(LD_LIBRARY_PATH):$(ildir) \ | sed -e's/::/:/g' -e's/^://' -e's/:$$//') -# RPATH is automatically written in macOS, so `DYLD_LIBRARY_PATH' is +# RPATH is automatically written in macOS, so 'DYLD_LIBRARY_PATH' is # ultimately redundant. But on some systems, even having a single value # causes crashs (see bug #56682). So we'll just give it no value at all. export DYLD_LIBRARY_PATH := @@ -117,17 +140,24 @@ export DYLD_LIBRARY_PATH := # Afer putting everything together, we use the first server as the # reference for all software if their '-url' variable isn't defined (in # 'reproduce/software/config/urls.conf'). -downloadwrapper = ./reproduce/analysis/bash/download-multi-try +downloadwrapper = ./reproduce/analysis/bash/download-multi-try.sh maneage_backup_urls := $(shell awk '!/^#/{printf "%s ", $$1}' \ reproduce/software/config/servers-backup.conf) backupservers_all = $(user_backup_urls) $(maneage_backup_urls) topbackupserver = $(word 1, $(backupservers_all)) backupservers = $(filter-out $(topbackupserver),$(backupservers_all)) - - - - +# When building in Apptainer containers, as of 2025-04-18, we need to +# configure Maneage as root (within the container). In such cases, we need +# to activate the 'FORCE_UNSAFE_CONFIGURE' environment variable to build +# some of the software. The 'if' statement is here to make sure we are in +# Apptainer: in other situations, the "unsafe" configure script shouldn't +# be activated. Note that this doesn't happen in Docker (where the Maneage +# source is in the same directory) because we build a non-root ('maneager' +# user there who executes the configure command. +unsafe-config = if [ $$(pwd) = "/home/maneager/source" ] \ + && [ $$(whoami) = root ]; then \ + export FORCE_UNSAFE_CONFIGURE=1; fi @@ -150,10 +180,10 @@ backupservers = $(filter-out $(topbackupserver),$(backupservers_all)) # # About ccache: ccache acts like a wrapper over the C compiler and is made # to avoid/speed-up compiling of identical files in a system (it is -# commonly used on large servers). It actually makes `gcc' or `g++' a +# commonly used on large servers). It actually makes 'gcc' or 'g++' a # symbolic link to itself so it can control them internally. So, for our # purpose here, it is very annoying and can cause many complications. We -# thus remove any part of PATH of that has `ccache' in it before making +# thus remove any part of PATH of that has 'ccache' in it before making # symbolic links to the programs we are not building ourselves. # # The double quotations after the starting 'export PATH' are necessary in @@ -172,9 +202,9 @@ makelink = origpath="$$PATH"; \ | tr '\n' :)"; \ if type $(1) > /dev/null 2> /dev/null; then \ if [ x$(3) = x ]; then \ - ln -sf "$$(realpath $$(which $(1)))" $(ibdir)/$(1); \ + ln -sf "$$(realpath $$(command -v $(1)))" $(ibdir)/$(1); \ else \ - ln -sf "$$(realpath $$(which $(1)))" $(ibdir)/$(3); \ + ln -sf "$$(realpath $$(command -v $(1)))" $(ibdir)/$(3); \ fi; \ else \ if [ "x$(strip $(2))" = xmandatory ]; then \ @@ -189,26 +219,27 @@ $(ibdir) $(ildir):; mkdir $@ $(ibidir)/low-level-links: $(ibidir)/grep-$(grep-version) \ | $(ibdir) $(ildir) - # Hardware specific +# Hardware specific $(call makelink,lp) # For printing, necessary for R. $(call makelink,lpr) # For printing, necessary for R. - # Mac OS specific +# Mac OS specific $(call makelink,mig) $(call makelink,xcrun) $(call makelink,sysctl) $(call makelink,sw_vers) + $(call makelink,codesign) $(call makelink,dsymutil) $(call makelink,install_name_tool) - # On Mac OS, libtool is different compared to GNU Libtool. The - # libtool we'll build in the high-level dependencies has the - # executable name `glibtool'. +# On Mac OS, libtool is different compared to GNU Libtool. The +# libtool we'll build in the high-level dependencies has the +# executable name 'glibtool'. $(call makelink,libtool) - # Necessary libraries: - # Libdl (for dynamic loading libraries at runtime) - # POSIX Threads library for multi-threaded programs. +# Necessary libraries: +# Libdl (for dynamic loading libraries at runtime) +# POSIX Threads library for multi-threaded programs. for l in dl pthread; do if [ -f /usr/lib/lib$$l.a ]; then for f in /usr/lib/lib$$l.*; do @@ -218,8 +249,12 @@ $(ibidir)/low-level-links: $(ibidir)/grep-$(grep-version) \ fi done - # We want this to be empty (so it doesn't interefere with the other - # files in `ibidir'. +# Useful tools: 'ldd' (list libraries linked by binary on GNU +# systems) + $(call makelink,ldd) + +# We want this to be empty (so it doesn't interefere with the other +# files in 'ibidir'. touch $@ @@ -236,11 +271,8 @@ $(ibidir)/low-level-links: $(ibidir)/grep-$(grep-version) \ # # The first set of programs to be built are those that we need to unpack # the source code tarballs of each program. We have already installed Lzip -# before calling 'basic.mk', so it is present and working. Hence we first -# build the Lzipped tarball of Gzip, then use our own Gzip to unpack the -# tarballs of the other compression programs. Once all the compression -# programs/libraries are complete, we build our own GNU Tar and continue -# with other software. +# before calling 'basic.mk', so it is present and working. So the only +# prerequisites of these (until reaching Tar) is the necessary directories. $(lockdir): | $(BDIR); mkdir $@ $(ibidir)/gzip-$(gzip-version): | $(ibdir) $(ildir) $(lockdir) tarball=gzip-$(gzip-version).tar.lz @@ -248,27 +280,27 @@ $(ibidir)/gzip-$(gzip-version): | $(ibdir) $(ildir) $(lockdir) $(call gbuild, gzip-$(gzip-version), static, , V=1) echo "GNU Gzip $(gzip-version)" > $@ -$(ibidir)/xz-$(xz-version): $(ibidir)/gzip-$(gzip-version) - tarball=xz-$(xz-version).tar.gz +$(ibidir)/xz-$(xz-version): | $(ibdir) $(ildir) $(lockdir) + tarball=xz-$(xz-version).tar.lz $(call import-source, $(xz-url), $(xz-checksum)) $(call gbuild, xz-$(xz-version), static) echo "XZ Utils $(xz-version)" > $@ -$(ibidir)/bzip2-$(bzip2-version): $(ibidir)/gzip-$(gzip-version) +$(ibidir)/bzip2-$(bzip2-version): | $(ibdir) $(ildir) $(lockdir) - # Download the tarball. - tarball=bzip2-$(bzip2-version).tar.gz +# Download the tarball. + tarball=bzip2-$(bzip2-version).tar.lz $(call import-source, $(bzip2-url), $(bzip2-checksum)) - # Bzip2 doesn't have a `./configure' script, and its Makefile - # doesn't build a shared library. So we can't use the `gbuild' - # function here and we need to take some extra steps (inspired - # from the GNU/Linux from Scratch (LFS) guide for Bzip2): - # 1) The `sed' call is for relative installed symbolic links. - # 2) The special Makefile-libbz2_so builds shared libraries. - # - # NOTE: the major version number appears in the final symbolic - # link. +# Bzip2 doesn't have a './configure' script, and its Makefile doesn't +# build a shared library. So we can't use the 'gbuild' function here +# and we need to take some extra steps (inspired from the GNU/Linux +# from Scratch (LFS) guide for Bzip2): +# +# 1) The 'sed' call is for relative installed symbolic links. +# 2) The special Makefile-libbz2_so builds shared libraries. +# +# NOTE: the major version number appears in the final symbolic link. tdir=bzip2-$(bzip2-version) if [ $(static_build) = yes ]; then makecommand="make LDFLAGS=-static" @@ -283,8 +315,9 @@ $(ibidir)/bzip2-$(bzip2-version): $(ibidir)/gzip-$(gzip-version) fi cd $(ddir) rm -rf $$tdir - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd $$tdir + $(shsrcdir)/prep-source.sh $(ibdir) sed -e 's@\(ln -s -f \)$$(PREFIX)/bin/@\1@' Makefile \ > Makefile.sed mv Makefile.sed Makefile @@ -296,38 +329,16 @@ $(ibidir)/bzip2-$(bzip2-version): $(ibidir)/gzip-$(gzip-version) cd .. rm -rf $$tdir cd $(ildir) - ln -fs libbz2.so.1.0 libbz2.so + ln -fs libbz2.so.$(bzip2-version) libbz2.so echo "Bzip2 $(bzip2-version)" > $@ -$(ibidir)/unzip-$(unzip-version): $(ibidir)/gzip-$(gzip-version) - tarball=unzip-$(unzip-version).tar.gz - v=$$(echo $(unzip-version) | sed -e's/\.//') - $(call import-source, $(unzip-url), $(unzip-checksum)) - $(call gbuild, unzip$$v, static,, \ - -f unix/Makefile generic \ - CFLAGS="-DBIG_MEM -DMMAP",,pwd, \ - -f unix/Makefile generic \ - BINDIR=$(ibdir) MANDIR=$(idir)/man/man1 ) - echo "Unzip $(unzip-version)" > $@ - -$(ibidir)/zip-$(zip-version): $(ibidir)/gzip-$(gzip-version) - tarball=zip-$(zip-version).tar.gz - v=$$(echo $(zip-version) | sed -e's/\.//') - $(call import-source, $(zip-url), $(zip-checksum)) - $(call gbuild, zip$$v, static,, \ - -f unix/Makefile generic \ - CFLAGS="-DBIG_MEM -DMMAP",,pwd, \ - -f unix/Makefile generic \ - BINDIR=$(ibdir) MANDIR=$(idir)/man/man1 ) - echo "Zip $(zip-version)" > $@ - # Some programs (like Wget and CMake) that use zlib need it to be dynamic # so they use our custom build. So we won't force a static-only build. # -# Note for a static-only build: Zlib's `./configure' doesn't use Autoconf's -# configure script, it just accepts a direct `--static' option. -$(ibidir)/zlib-$(zlib-version): $(ibidir)/gzip-$(gzip-version) - tarball=zlib-$(zlib-version).tar.gz +# Note for a static-only build: Zlib's './configure' doesn't use Autoconf's +# configure script, it just accepts a direct '--static' option. +$(ibidir)/zlib-$(zlib-version): | $(ibdir) $(ildir) $(lockdir) + tarball=zlib-$(zlib-version).tar.lz $(call import-source, $(zlib-url), $(zlib-checksum)) $(call gbuild, zlib-$(zlib-version)) echo "Zlib $(zlib-version)" > $@ @@ -339,16 +350,16 @@ $(ibidir)/zlib-$(zlib-version): $(ibidir)/gzip-$(gzip-version) # software to be built). $(ibidir)/tar-$(tar-version): \ $(ibidir)/xz-$(xz-version) \ - $(ibidir)/zip-$(zip-version) \ $(ibidir)/gzip-$(gzip-version) \ $(ibidir)/zlib-$(zlib-version) \ - $(ibidir)/bzip2-$(bzip2-version) \ - $(ibidir)/unzip-$(unzip-version) - # Since all later programs depend on Tar, the configuration will be - # stuck here, only making Tar. So its more efficient to built it on - # multiple threads (when the user's Make doesn't pass down the - # number of threads). - tarball=tar-$(tar-version).tar.gz + $(ibidir)/bzip2-$(bzip2-version) + +# Since all later programs depend on Tar, the configuration will hit +# a bottleneck here: only making Tar. So its more efficient to built +# it on multiple threads (even when the user's Make doesn't pass down +# the number of threads). + $(call unsafe-config) + tarball=tar-$(tar-version).tar.lz $(call import-source, $(tar-url), $(tar-checksum)) $(call gbuild, tar-$(tar-version), , , -j$(numthreads) V=1) echo "GNU Tar $(tar-version)" > $@ @@ -370,7 +381,7 @@ $(ibidir)/tar-$(tar-version): \ # a prerequisite (and forgetting in others causing bugs), we'll put it as a # dependancy of 'tar'. $(ibidir)/patchelf-$(patchelf-version): $(ibidir)/tar-$(tar-version) - tarball=patchelf-$(patchelf-version).tar.gz + tarball=patchelf-$(patchelf-version).tar.lz $(call import-source, $(patchelf-url), $(patchelf-checksum)) if [ x$(on_mac_os) = xyes ]; then echo "" > $@ @@ -395,75 +406,80 @@ $(ibidir)/patchelf-$(patchelf-version): $(ibidir)/tar-$(tar-version) # basic dependencies. # # Unfortunately Make needs dynamic linking in two instances: when loading -# objects (dynamically linked libraries), or when using the `getpwnam' +# objects (dynamically linked libraries), or when using the 'getpwnam' # function (for tilde expansion). The first can be disabled with -# `--disable-load', but unfortunately I don't know any way to fix the +# '--disable-load', but unfortunately I don't know any way to fix the # second. So, we'll have to build it dynamically for now. $(ibidir)/ncurses-$(ncurses-version): $(ibidir)/patchelf-$(patchelf-version) - tarball=ncurses-$(ncurses-version).tar.gz + tarball=ncurses-$(ncurses-version).tar.lz $(call import-source, $(ncurses-url), $(ncurses-checksum)) - # Delete the library that will be installed (so we can make sure - # the build process completed afterwards and reset the links). +# Delete the library that will be installed (so we can make sure the +# build process completed afterwards and reset the links). rm -f $(ildir)/libncursesw* - # Delete the (possibly existing) low-level programs that depend on - # `readline', and thus `ncurses'. Since these programs are actually - # used during the building of `ncurses', we need to delete them so - # the build process doesn't use the project's Bash and AWK, but the - # host's. +# Delete the (possibly existing) low-level programs that depend on +# 'readline', and thus 'ncurses'. Since these programs are actually +# used during the building of 'ncurses', we need to delete them so +# the build process doesn't use the project's Bash and AWK, but the +# host's. rm -f $(ibdir)/bash* $(ibdir)/awk* $(ibdir)/gawk* - # Standard build process. +# Standard build process. + export CFLAGS="-std=gnu17 $$CFLAGS" $(call gbuild, ncurses-$(ncurses-version), static, \ --with-shared --enable-rpath --without-normal \ --without-debug --with-cxx-binding \ --with-cxx-shared --enable-widec --enable-pc-files \ --with-pkg-config=$(ildir)/pkgconfig, -j$(numthreads)) - # Unfortunately there are many problems with `ncurses' using - # "normal" (or 8-bit) characters. The standard way that will work - # is to build it with wide character mode as you see above in the - # configuration (or the `w' prefix you see below). Also, most - # programs (and in particular Bash and AWK), first look for other - # (mostly obsolete) libraries like tinfo, which define the same - # symbols. The links below address both situations: we need to fool - # higher-level packages to find this library even if they aren't - # explicitly mentioning its name correctly (as a value to `-l' at - # link time in their configure scripts). - # - # This part is taken from the Arch GNU/Linux build script[1], then - # extended to Mac thanks to Homebrew's script [2]. - # - # [1] https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/ncurses - # [2] https://github.com/Homebrew/homebrew-core/blob/master/Formula/ncurses.rb - # - # Since we can't have comments, in the connected script, here is a - # summary: - # - # 1. We find the actual suffix of the library, from the file that - # is not a symbolic link (starting with `-' in the output of - # `ls -l'). - # - # 2. We make symbolic links to all the "ncurses", "ncurses++", - # "form", "panel" and "menu" libraries to point to their - # "wide" (character) library. - # - # 3. We make symbolic links to the "tic" and "tinfo" libraries to - # point to the same `libncursesw' library. - # - # 4. Some programs link with "curses" (not "ncurses", notice the - # starting "n"), so we'll also make links for these to point - # to the `libncursesw' library. - # - # 5. A link is made to also be able to include files from the - # `ncurses' headers. +# Unfortunately there are many problems with 'ncurses' using "normal" +# (or 8-bit) characters. The standard way that will work is to build +# it with wide character mode as you see above in the configuration +# (or the 'w' prefix you see below). Also, most programs (and in +# particular Bash and AWK), first look for other (mostly obsolete) +# libraries like tinfo, which define the same symbols. The links +# below address both situations: we need to fool higher-level +# packages to find this library even if they aren't explicitly +# mentioning its name correctly (as a value to '-l' at link time in +# their configure scripts). +# +# This part is taken from the Arch GNU/Linux build script[1], then +# extended to Mac thanks to Homebrew's script [2]. +# +# [1] https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/ncurses +# [2] https://github.com/Homebrew/homebrew-core/blob/master/Formula/ncurses.rb +# +# Since we can't have comments, in the connected script, here is a +# summary: +# +# 1. We find the actual suffix of the library, from the file that +# is not a symbolic link (starting with '-' in the output of 'ls +# -l'). +# +# 2. We make symbolic links to all the "ncurses", "ncurses++", +# "form", "panel" and "menu" libraries to point to their "wide" +# (character) library. +# +# 3. We make symbolic links to the "tic" and "tinfo" libraries to +# point to the same 'libncursesw' library. +# +# 4. Some programs link with "curses" (not "ncurses", notice the +# starting "n"), so we'll also make links for these to point to +# the 'libncursesw' library. +# +# 5. A link is made to also be able to include files from the +# 'ncurses' headers. +# +# 6. Top-level symbolic links are made for the 'include' (.h) files. +# if [ x$(on_mac_os) = xyes ]; then so="dylib"; else so="so"; fi if [ -f $(ildir)/libncursesw.$$so ]; then + unalias ls || true # avoid decorated 'ls' commands with extra characters sov=$$(ls -l $(ildir)/libncursesw* \ | awk '/^-/{print $$NF}' \ - | sed -e's|'$(ildir)/libncursesw.'||') + | sed -e "s;$(ildir)/libncursesw\.;;") cd "$(ildir)" for lib in ncurses ncurses++ form panel menu; do @@ -481,6 +497,11 @@ $(ibidir)/ncurses-$(ncurses-version): $(ibidir)/patchelf-$(patchelf-version) ln -fs $(ildir)/pkgconfig/ncursesw.pc pkgconfig/cursesw.pc ln -fs $(idir)/include/ncursesw $(idir)/include/ncurses + +# Add symbolic links for the ncursesw/*.h 'include' files +# so that they can be found in the top-level include/ directory. + cd "$(iidir)" + ln -fsv $(idir)/include/ncursesw/*.h . echo "GNU NCURSES $(ncurses-version)" > $@ else exit 1 @@ -488,7 +509,7 @@ $(ibidir)/ncurses-$(ncurses-version): $(ibidir)/patchelf-$(patchelf-version) $(ibidir)/readline-$(readline-version): \ $(ibidir)/ncurses-$(ncurses-version) - tarball=readline-$(readline-version).tar.gz + tarball=readline-$(readline-version).tar.lz $(call import-source, $(readline-url), $(readline-checksum)) $(call gbuild, readline-$(readline-version), static, \ --with-curses --disable-install-examples, \ @@ -496,12 +517,12 @@ $(ibidir)/readline-$(readline-version): \ echo "GNU Readline $(readline-version)" > $@ -# IMPORTANT: Even though we have enabled `rpath', Bash doesn't write the +# IMPORTANT: Even though we have enabled 'rpath', Bash doesn't write the # absolute adddress of the libraries it depends on! Therefore, if we -# configure Bash with `--with-installed-readline' (so the installed version +# configure Bash with '--with-installed-readline' (so the installed version # of Readline, that we build below as a prerequisite or AWK, is used) and -# you run `ldd $(ibdir)/bash' on the resulting binary, it will say that it -# is linking with the system's `readline'. But if you run that same command +# you run 'ldd $(ibdir)/bash' on the resulting binary, it will say that it +# is linking with the system's 'readline'. But if you run that same command # within a rule in this project, you'll see that it is indeed linking with # our own built readline. # @@ -509,11 +530,11 @@ $(ibidir)/readline-$(readline-version): \ # released as patches. Therefore we'll need to make our own fully-working # and updated tarball to build the proper version of Bash. You download and # apply them to the original tarball and make a new one with the following -# series of commands (just replace `NUMBER' with the total number of +# series of commands (just replace 'NUMBER' with the total number of # patches that you want to apply). # # $ number=NUMBER -# $ tar xf bash-5.0.tar.gz +# $ tar -xf bash-5.0.tar.gz # $ cd bash-5.0 # $ for i in $(seq 1 $number); do \ # pname=bash50-$(printf "%03d" $i); \ @@ -529,22 +550,22 @@ $(ibidir)/bash-$(bash-version): \ $(ibidir)/gettext-$(gettext-version) \ $(ibidir)/readline-$(readline-version) - # Download the tarball. +# Download the tarball. tarball=bash-$(bash-version).tar.lz $(call import-source, $(bash-url), $(bash-checksum)) - # Delete the (possibly) existing Bash executable in the project, - # let it use the default shell of the host. +# Delete the (possibly) existing Bash executable in the project, +# let it use the default shell of the host. rm -f $(ibdir)/bash - # Bash has many `--enable' features which are already enabled by - # default. As described in the manual, they are mainly useful when - # you disable them all with `--enable-minimal-config' and enable a - # subset using the `--enable' options. +# Bash has many '--enable' features which are already enabled by +# default. As described in the manual, they are mainly useful when +# you disable them all with '--enable-minimal-config' and enable a +# subset using the '--enable' options. if [ "x$(static_build)" = xyes ]; then stopt="--enable-static-link" else stopt="" fi; - export CFLAGS="$$CFLAGS \ + export CFLAGS="$$CFLAGS -std=gnu17 \ -DDEFAULT_PATH_VALUE='\"$(ibdir)\"' \ -DSTANDARD_UTILS_PATH='\"$(ibdir)\"' \ -DSYS_BASHRC='\"$(BASH_ENV)\"' " @@ -553,22 +574,20 @@ $(ibidir)/bash-$(bash-version): \ --with-curses=yes, \ -j$(numthreads)) - # Atleast on GNU/Linux systems, Bash doesn't include RPATH by - # default. So, we have to manually include it, currently we are - # only doing this on GNU/Linux systems (using the `patchelf' - # program). +# Atleast on GNU/Linux systems, Bash doesn't include RPATH by +# default. So, we have to manually include it, currently we are only +# doing this on GNU/Linux systems (using the 'patchelf' program). if [ -f $(ibdir)/patchelf ]; then $(ibdir)/patchelf --set-rpath $(ildir) $(ibdir)/bash; fi - # To be generic, some systems use the `sh' command to call the - # shell. By convention, `sh' is just a symbolic link to the - # preferred shell executable. So we'll define `$(ibdir)/sh' as a - # symbolic link to the Bash that we just built and installed. - # - # Just to be sure that the installation step above went well, - # before making the link, we'll see if the file actually exists - # there. +# To be generic, some systems use the 'sh' command to call the +# shell. By convention, 'sh' is just a symbolic link to the preferred +# shell executable. So we'll define '$(ibdir)/sh' as a symbolic link +# to the Bash that we just built and installed. +# +# Just to be sure that the installation step above went well, before +# making the link, we'll see if the file actually exists there. ln -fs $(ibdir)/bash $(ibdir)/sh echo "GNU Bash $(bash-version)" > $@ @@ -584,9 +603,9 @@ $(ibidir)/bash-$(bash-version): \ # Level 4: Most other programs # ---------------------------- -# In Perl, The `-shared' flag will cause problems while building on macOS, +# In Perl, The '-shared' flag will cause problems while building on macOS, # so we'll only use this configuration option when we are GNU/Linux -# systems. However, since the whole option must be used (which includes `=' +# systems. However, since the whole option must be used (which includes '=' # and empty space), its easier to define the variable as a Make variable # outside the recipe, not as a shell variable inside it. ifeq ($(on_mac_os),yes) @@ -595,7 +614,7 @@ else perl-conflddlflags = -Dlddlflags="-shared $$LDFLAGS" endif $(ibidir)/perl-$(perl-version): $(ibidir)/patchelf-$(patchelf-version) - tarball=perl-$(perl-version).tar.gz + tarball=perl-$(perl-version).tar.lz $(call import-source, $(perl-url), $(perl-checksum)) major_version=$$(echo $(perl-version) \ | sed -e's/\./ /g' \ @@ -605,8 +624,9 @@ $(ibidir)/perl-$(perl-version): $(ibidir)/patchelf-$(patchelf-version) | awk '{printf("%d.%d", $$1, $$2)}') cd $(ddir) rm -rf perl-$(perl-version) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd perl-$(perl-version) + $(shsrcdir)/prep-source.sh $(ibdir) ./Configure -des \ -Dusethreads \ -Duseshrplib \ @@ -615,7 +635,7 @@ $(ibidir)/perl-$(perl-version): $(ibidir)/patchelf-$(patchelf-version) -Dprivlib=$(idir)/share/perl$$major_version/core_perl \ -Darchlib=$(idir)/lib/perl$$major_version/$$base_version/core_perl \ -Dsitelib=$(idir)/share/perl$$major_version/site_perl \ - -Dsitearch=$(idir)/lib/perl$$major_version/$$basever/site_perl \ + -Dsitearch=$(idir)/lib/perl$$major_version/$$base_version/site_perl \ -Dvendorlib=$(idir)/share/perl$$major_version/vendor_perl \ -Dvendorarch=$(idir)/lib/perl$$major_version/$$base_version/vendor_perl \ -Dscriptdir=$(idir)/bin/core_perl \ @@ -627,7 +647,7 @@ $(ibidir)/perl-$(perl-version): $(ibidir)/patchelf-$(patchelf-version) -Dcccdlflags='-fPIC' \ $(perl-conflddlflags) \ -Dldflags="$$LDFLAGS" - make -j$(numthreads) + make -j$(numthreads) V=1 make install cd .. rm -rf perl-$(perl-version) @@ -641,17 +661,17 @@ $(ibidir)/perl-$(perl-version): $(ibidir)/patchelf-$(patchelf-version) # Coreutils # --------- # -# For some reason, Coreutils doesn't include `rpath' in its installed +# For some reason, Coreutils doesn't include 'rpath' in its installed # executables (even though it says that by default its included and that -# even when calling `--enable-rpath=yes'). So we have to manually add -# `rpath' to Coreutils' executables after the standard build is +# even when calling '--enable-rpath=yes'). So we have to manually add +# 'rpath' to Coreutils' executables after the standard build is # complete. # # One problem is that Coreutils installs many very basic executables which # might be in used by other programs. So we must make sure that when # Coreutils is being built, no other program is being built in # parallel. The solution to the many executables it installs is to make a -# fake installation (with `DESTDIR'), and get a list of the contents of the +# fake installation (with 'DESTDIR'), and get a list of the contents of the # directory to find the names. # # The echo after the PatchELF loop is to avoid a crash if the last @@ -664,32 +684,29 @@ $(ibidir)/coreutils-$(coreutils-version): \ $(ibidir)/perl-$(perl-version) \ $(ibidir)/openssl-$(openssl-version) - # Import, unpack and enter the source directory. - tarball=coreutils-$(coreutils-version).tar.xz +# Import, unpack and enter the source directory. + $(call unsafe-config) + tarball=coreutils-$(coreutils-version).tar.lz $(call import-source, $(coreutils-url), $(coreutils-checksum)) + +# Unpack and enter the source. cd $(ddir) rm -rf coreutils-$(coreutils-version) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd coreutils-$(coreutils-version) + $(shsrcdir)/prep-source.sh $(ibdir) - # Set the configure script to use our shell, note that we can't - # assume GNU SED here yet (it installs after Coreutils). - sed -e's|\#\! /bin/sh|\#\! $(ibdir)/bash|' \ - -e's|\#\!/bin/sh|\#\! $(ibdir)/bash|' \ - configure > configure-tmp - mv configure-tmp configure - chmod +x configure - - # Configure, build and install Coreutils. +# Configure, build and install Coreutils. ./configure --prefix=$(idir) SHELL=$(ibdir)/bash \ LDFLAGS="$(LDFLAGS)" CPPFLAGS="$(CPPFLAGS)" \ --disable-silent-rules --with-openssl=yes make SHELL=$(ibdir)/bash -j$(numthreads) make SHELL=$(ibdir)/bash install - # Fix RPATH if necessary. +# Fix RPATH if necessary. if [ -f $(ibdir)/patchelf ]; then make SHELL=$(ibdir)/bash install DESTDIR=junkinst + unalias ls || true # Not decorated 'ls' (with extra characters). instprogs=$$(ls junkinst/$(ibdir)) for f in $$instprogs; do $(ibdir)/patchelf --set-rpath $(ildir) $(ibdir)/$$f @@ -697,12 +714,35 @@ $(ibidir)/coreutils-$(coreutils-version): \ echo "PatchELF applied to all programs." fi - # Come back up to the unpacking directory, delete the source - # directory and write the final target. +# Come back up to the unpacking directory, delete the source +# directory and write the final target. cd .. rm -rf coreutils-$(coreutils-version) echo "GNU Coreutils $(coreutils-version)" > $@ +# Podlators +# +# POD is short for "Plain Old Documentation", that is the format used in +# Perl's documentation. Podlators provies two executables pod2man and +# pod2text convert this into the roff format (used in man pages) or pod2 It +# is used by some software like OpenSSL to create their man pages. +$(ibidir)/podlators-$(podlators-version): $(ibidir)/perl-$(perl-version) + tarball=podlators-$(podlators-version).tar.lz + $(call import-source, $(podlators-url), $(podlators-checksum)) + cd $(ddir) + rm -rf podlators-$(podlators-version) + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd podlators-$(podlators-version) + $(shsrcdir)/prep-source.sh $(ibdir) + perl Makefile.PL + make + make install + ln -sf $(ibdir)/site_perl/pod2man $(ibdir)/pod2man + ln -sf $(ibdir)/site_perl/pod2text $(ibdir)/pod2text + cd .. + rm -rf podlators-$(podlators-version) + echo "podlators $(podlators-version)" > $@ + # OpenSSL # # Until we find a nice and generic way to create an updated CA file in the @@ -710,26 +750,26 @@ $(ibidir)/coreutils-$(coreutils-version): \ # along with the other tarballs. $(idir)/etc:; mkdir $@ $(idir)/etc/ssl: | $(idir)/etc; mkdir $@ -$(ibidir)/openssl-$(openssl-version): $(ibidir)/perl-$(perl-version) \ +$(ibidir)/openssl-$(openssl-version): $(ibidir)/podlators-$(podlators-version) \ | $(idir)/etc/ssl - # First download the certificates and copy them into the - # installation directory. - tarball=cert.pem - $(call import-source, $(cert-url), $(cert-checksum)) - cp $(tdir)/cert.pem $(idir)/etc/ssl/cert.pem +# First download the certificates and copy them into the +# installation directory. + tarball=cert.pem-$(certpem-version) + $(call import-source, $(certpem-url), $(certpem-checksum)) + cp $(tdir)/cert.pem-$(certpem-version) $(idir)/etc/ssl/cert.pem - # Now download the OpenSSL tarball. - tarball=openssl-$(openssl-version).tar.gz +# Now download the OpenSSL tarball. + tarball=openssl-$(openssl-version).tar.lz $(call import-source, $(openssl-url), $(openssl-checksum)) - # According to OpenSSL's Wiki (link bellow), it can't automatically - # detect Mac OS's structure. It will need some help. So we'll use - # the `on_mac_os' Make variable that we defined in the configure - # script and help it with some extra configuration options and an - # environment variable. - # - # https://wiki.openssl.org/index.php/Compilation_and_Installation +# According to OpenSSL's Wiki (link bellow), it can't automatically +# detect Mac OS's structure. It will need some help. So we'll use the +# 'on_mac_os' Make variable that we defined in the configure script +# and help it with some extra configuration options and an +# environment variable. +# +# https://wiki.openssl.org/index.php/Compilation_and_Installation if [ x$(on_mac_os) = xyes ]; then export KERNEL_BITS=64 copt="shared no-ssl2 no-ssl3 enable-ec_nistp_64_gcc_128" @@ -743,29 +783,19 @@ $(ibidir)/openssl-$(openssl-version): $(ibidir)/perl-$(perl-version) \ --with-zlib-include=$(idir)/include, \ -j$(numthreads), , ./config ) - # Manually insert RPATH inside the two created libraries. +# Manually insert RPATH inside the two created libraries. if [ -f $(ibdir)/patchelf ]; then patchelf --set-rpath $(ildir) $(ildir)/libssl.so patchelf --set-rpath $(ildir) $(ildir)/libcrypto.so fi - # Bug 58263 (https://savannah.nongnu.org/bugs/?58263): In OpenSSL - # Version 1.1.1a (also checked in 1.1.1g), `openssl/ec.h' fails to - # include `openssl/openconf.h' on some OSs. The SED hack below - # inserts a hardwired element of `openssl/openconf.h' that is - # needed to include sections of code `f` that are deprecated in - # 1.2.0, but not yet in 1.1.1. This problem may be solved in - # version 1.2.x, so please check again in that bug. - mv -v $(idir)/include/openssl/ec.h $(idir)/include/openssl/ec.h.orig - sed -e 's,\(# include .openssl/opensslconf\.h.\),\1\n#ifndef DEPRECATEDIN_1_2_0\n#define DEPRECATEDIN_1_2_0(f) f;\n#endif\n,' \ - $(idir)/include/openssl/ec.h.orig > $(idir)/include/openssl/ec.h - - # Build the final target. +# Build the final target. echo "OpenSSL $(openssl-version)" > $@ + # Downloaders # ----------- @@ -774,13 +804,13 @@ $(ibidir)/openssl-$(openssl-version): $(ibidir)/perl-$(perl-version) \ # cURL can optionally link with many different network-related libraries on # the host system that we are not yet building in the template. Many of # these are not relevant to most science projects, so we are explicitly -# using `--without-XXX' or `--disable-XXX' so cURL doesn't link with +# using '--without-XXX' or '--disable-XXX' so cURL doesn't link with # them. Note that if it does link with them, the configuration will crash # when the library is updated/changed by the host, and the whole purpose of # this project is avoid dependency on the host as much as possible. $(ibidir)/curl-$(curl-version): $(ibidir)/coreutils-$(coreutils-version) - tarball=curl-$(curl-version).tar.gz + tarball=curl-$(curl-version).tar.lz $(call import-source, $(curl-url), $(curl-checksum)) $(call gbuild, curl-$(curl-version), , \ @@ -792,6 +822,8 @@ $(ibidir)/curl-$(curl-version): $(ibidir)/coreutils-$(coreutils-version) --without-librtmp \ --without-libidn2 \ --without-wolfssl \ + --without-nghttp2 \ + --without-nghttp3 \ --without-brotli \ --without-gnutls \ --without-cyassl \ @@ -799,6 +831,7 @@ $(ibidir)/curl-$(curl-version): $(ibidir)/coreutils-$(coreutils-version) --without-axtls \ --disable-ldaps \ --disable-ldap \ + --without-zstd \ --without-nss, V=1) if [ -f $(ibdir)/patchelf ]; then @@ -810,8 +843,8 @@ $(ibidir)/curl-$(curl-version): $(ibidir)/coreutils-$(coreutils-version) # GNU Wget # # Note that on some systems (for example GNU/Linux) Wget needs to explicity -# link with `libdl', but on others (for example Mac OS) it doesn't. We -# check this at configure time and define the `needs_ldl' variable. +# link with 'libdl', but on others (for example Mac OS) it doesn't. We +# check this at configure time and define the 'needs_ldl' variable. # # Also note that since Wget needs to load outside libraries dynamically, it # gives a segmentation fault when built statically. @@ -824,12 +857,12 @@ $(ibidir)/wget-$(wget-version): \ $(ibidir)/libiconv-$(libiconv-version) \ $(ibidir)/coreutils-$(coreutils-version) - # Download the tarball. +# Download the tarball. tarball=wget-$(wget-version).tar.lz $(call import-source, $(wget-url), $(wget-checksum)) - # We need to explicitly disable `libiconv', because of the - # `pkg-config' and `libiconv' problem. +# We need to explicitly disable 'libiconv', because of the +# 'pkg-config' and 'libiconv' problem. libs="-pthread" if [ x$(needs_ldl) = xyes ]; then libs="$$libs -ldl"; fi $(call gbuild, wget-$(wget-version), , \ @@ -860,15 +893,22 @@ $(ibidir)/wget-$(wget-version): \ # process of the higher-level programs and libraries. Note that during the # building of those higher-level programs (after this Makefile finishes), # there is no access to the system's PATH. +$(ibidir)/bison-$(bison-version): $(ibidir)/help2man-$(help2man-version) + tarball=bison-$(bison-version).tar.lz + $(call import-source, $(bison-url), $(bison-checksum)) + $(call gbuild, bison-$(bison-version), static, ,V=1 -j$(numthreads)) + echo "GNU Bison $(bison-version)" > $@ + $(ibidir)/diffutils-$(diffutils-version): \ $(ibidir)/coreutils-$(coreutils-version) - tarball=diffutils-$(diffutils-version).tar.xz + tarball=diffutils-$(diffutils-version).tar.lz $(call import-source, $(diffutils-url), $(diffutils-checksum)) $(call gbuild, diffutils-$(diffutils-version), static,,V=1) echo "GNU Diffutils $(diffutils-version)" > $@ $(ibidir)/file-$(file-version): $(ibidir)/coreutils-$(coreutils-version) - tarball=file-$(file-version).tar.gz + export CFLAGS="-std=c99 $$CFLAGS" + tarball=file-$(file-version).tar.lz $(call import-source, $(file-url), $(file-checksum)) $(call gbuild, file-$(file-version), static, \ --disable-libseccomp, V=1) @@ -876,7 +916,7 @@ $(ibidir)/file-$(file-version): $(ibidir)/coreutils-$(coreutils-version) $(ibidir)/findutils-$(findutils-version): \ $(ibidir)/coreutils-$(coreutils-version) - tarball=findutils-$(findutils-version).tar.xz + tarball=findutils-$(findutils-version).tar.lz $(call import-source, $(findutils-url), $(findutils-checksum)) $(call gbuild, findutils-$(findutils-version), static,,V=1) echo "GNU Findutils $(findutils-version)" > $@ @@ -886,19 +926,19 @@ $(ibidir)/gawk-$(gawk-version): \ $(ibidir)/mpfr-$(mpfr-version) \ $(ibidir)/coreutils-$(coreutils-version) - # Download the tarball. +# Download the tarball. tarball=gawk-$(gawk-version).tar.lz $(call import-source, $(gawk-url), $(gawk-checksum)) - # AWK doesn't include RPATH by default, so we'll have to manually - # include it using the `patchelf' program (which was a dependency - # of Bash). Just note that AWK produces two executables (for - # example `gawk-4.2.1' and `gawk') and a symbolic link `awk' to one - # of those executables. +# AWK doesn't include RPATH by default, so we'll have to manually +# include it using the 'patchelf' program (which was a dependency of +# Bash). Just note that AWK produces two executables (for example +# 'gawk-4.2.1' and 'gawk') and a symbolic link 'awk' to one of those +# executables. $(call gbuild, gawk-$(gawk-version), static, \ --with-readline=$(idir)) - # Correct the RPATH on systems that have installed patchelf. +# Correct the RPATH on systems that have installed patchelf. if [ -f $(ibdir)/patchelf ]; then if [ -f $(ibdir)/gawk ]; then $(ibdir)/patchelf --set-rpath $(ildir) $(ibdir)/gawk @@ -909,31 +949,38 @@ $(ibidir)/gawk-$(gawk-version): \ fi fi - # Build final target. +# Build final target. echo "GNU AWK $(gawk-version)" > $@ +$(ibidir)/help2man-$(help2man-version): \ + $(ibidir)/coreutils-$(coreutils-version) + tarball=help2man-$(help2man-version).tar.lz + $(call import-source, $(help2man-url), $(help2man-checksum)) + $(call gbuild, help2man-$(help2man-version), static, ,V=1) + echo "Help2man $(Help2man-version)" > $@ + $(ibidir)/libiconv-$(libiconv-version): \ $(ibidir)/pkg-config-$(pkgconfig-version) - tarball=libiconv-$(libiconv-version).tar.gz + tarball=libiconv-$(libiconv-version).tar.lz $(call import-source, $(libiconv-url), $(libiconv-checksum)) $(call gbuild, libiconv-$(libiconv-version), static) echo "GNU libiconv $(libiconv-version)" > $@ $(ibidir)/libunistring-$(libunistring-version): \ $(ibidir)/libiconv-$(libiconv-version) - tarball=libunistring-$(libunistring-version).tar.xz + tarball=libunistring-$(libunistring-version).tar.lz $(call import-source, $(libunistring-url), $(libunistring-checksum)) $(call gbuild, libunistring-$(libunistring-version), static,, \ -j$(numthreads)) echo "GNU libunistring $(libunistring-version)" > $@ $(ibidir)/libxml2-$(libxml2-version): $(ibidir)/patchelf-$(patchelf-version) - # The libxml2 tarball also contains Python bindings which are built - # and installed to a system directory by default. If you don't need - # the Python bindings, the easiest solution is to compile without - # Python support: `./configure --without-python'. If you really need - # the Python bindings, use `--with-python-install-dir=DIR' instead. - tarball=libxml2-$(libxml2-version).tar.gz +# The libxml2 tarball also contains Python bindings which are built +# and installed to a system directory by default. If you don't need +# the Python bindings, the easiest solution is to compile without +# Python support: './configure --without-python'. If you really need +# the Python bindings, use '--with-python-install-dir=DIR' instead. + tarball=libxml2-$(libxml2-version).tar.lz $(call import-source, $(libxml2-url), $(libxml2-checksum)) $(call gbuild, libxml2-$(libxml2-version), static, \ --without-python, V=1) @@ -956,7 +1003,7 @@ $(ibidir)/git-$(git-version): \ $(ibidir)/curl-$(curl-version) \ $(ibidir)/gettext-$(gettext-version) \ $(ibidir)/libiconv-$(libiconv-version) - tarball=git-$(git-version).tar.xz + tarball=git-$(git-version).tar.lz if [ x$(on_mac_os) = xyes ]; then export LDFLAGS="$$LDFLAGS -lcharset" fi @@ -971,27 +1018,40 @@ $(ibidir)/gmp-$(gmp-version): \ $(ibidir)/coreutils-$(coreutils-version) tarball=gmp-$(gmp-version).tar.lz $(call import-source, $(gmp-url), $(gmp-checksum)) + export CFLAGS="-std=gnu17 $$CFLAGS" $(call gbuild, gmp-$(gmp-version), static, \ --enable-cxx --enable-fat, \ - -j$(numthreads) ,make check) + -j$(numthreads)) echo "GNU Multiple Precision Arithmetic Library $(gmp-version)" > $@ # Less is useful with Git (to view the diffs within a minimal container) # and generally to view large files easily when the project is built in a # container with a minimal OS. $(ibidir)/less-$(less-version): $(ibidir)/ncurses-$(ncurses-version) - tarball=less-$(less-version).tar.gz + tarball=less-$(less-version).tar.lz $(call import-source, $(less-url), $(less-checksum)) - $(call gbuild, less-$(less-version), static,,-j$(numthreads)) + +# Without the '--with-regex=posix' option, the build will depend on +# PCRE (perl compatible regular expressions) which are not available +# on some systems/compilers and can cause a crash. Maneage was +# successfully built with the POSIX regular expression (regex), and +# 'less' is generally, an interactive software, not a batch-mode +# software (it is just added in 'basic.mk' because Git uses it to +# display things. Again, this is an interactive meta-operation in +# maneage (operations you only do when you are developing Maneage +# within Maneage interactively, and will not affect into the actual +# reproducible analysis!) + $(call gbuild, less-$(less-version), static, \ + --with-regex=posix,-j$(numthreads)) if [ -f $(ibdir)/patchelf ]; then $(ibdir)/patchelf --set-rpath $(ildir) $(ibdir)/less; fi echo "Less $(less-version)" > $@ # On Mac OS, libtool does different things, so to avoid confusion, we'll -# prefix GNU's libtool executables with `glibtool'. +# prefix GNU's libtool executables with 'glibtool'. $(ibidir)/libtool-$(libtool-version): $(ibidir)/m4-$(m4-version) - tarball=libtool-$(libtool-version).tar.xz + tarball=libtool-$(libtool-version).tar.lz $(call import-source, $(libtool-url), $(libtool-checksum)) $(call gbuild, libtool-$(libtool-version), static, \ --program-prefix=g, V=1 -j$(numthreads)) @@ -999,172 +1059,67 @@ $(ibidir)/libtool-$(libtool-version): $(ibidir)/m4-$(m4-version) echo "GNU Libtool $(libtool-version)" > $@ $(ibidir)/grep-$(grep-version): $(ibidir)/coreutils-$(coreutils-version) - tarball=grep-$(grep-version).tar.xz + tarball=grep-$(grep-version).tar.lz $(call import-source, $(grep-url), $(grep-checksum)) - $(call gbuild, grep-$(grep-version), static,,V=1) + $(call gbuild, grep-$(grep-version), static,, \ + -j$(numthreads) V=1) echo "GNU Grep $(grep-version)" > $@ -$(ibidir)/libbsd-$(libbsd-version): $(ibidir)/coreutils-$(coreutils-version) - tarball=libbsd-$(libbsd-version).tar.xz - $(call import-source, $(libbsd-url), $(libbsd-checksum)) - if [ x$(on_mac_os) = xyes ]; then - echo "" > $@ - else - $(call gbuild, libbsd-$(libbsd-version), static,,V=1) - echo "Libbsd $(libbsd-version)" > $@ - fi - -# We need to apply a patch to the M4 source to be used properly on macOS. -# The patch [1] was inspired by Homebrew's build instructions [1]. -# -# [1] https://raw.githubusercontent.com/macports/macports-ports/edf0ee1e2cf/devel/m4/files/secure_snprintf.patch -# [2] https://github.com/Homebrew/homebrew-core/blob/master/Formula/m4.rb -# # M4 doesn't depend on PatchELF, but just to be consistent with the # levels/phases introduced here (where the compressors are level 1, # PatchELF is level 2, and ...), we'll set it as a dependency. +# +# The '--with-syscmd-shell' is used as the default shell and if not given, +# 'm4' will use '/bin/sh' (which is not under Maneage control and can cause +# problems in 'high-level.mk' because it closes off the system's +# LD_LIBRARY_PATH and if the system's '/bin/sh' needs a special system +# library, the high-level programs will not be built). We are setting this +# default shell to Dash because M4 is built before our own Bash. Recall +# that Dash is built before we enter this Makefile. $(ibidir)/m4-$(m4-version): $(ibidir)/patchelf-$(patchelf-version) - tarball=m4-$(m4-version).tar.gz + tarball=m4-$(m4-version).tar.lz $(call import-source, $(m4-url), $(m4-checksum)) - cd $(ddir) - unpackdir=m4-$(m4-version) - rm -rf $$unpackdir - tar xf $(tdir)/$$tarball - mv m4-* $$unpackdir - cd $$unpackdir - if [ x$(on_mac_os) = xyes ]; then - sed 's|if !(((__GLIBC__ > 2|if !defined(__APPLE__) \&\& !(((__GLIBC__ > 2|' \ - lib/vasnprintf.c > lib/vasnprintf_edited.c - mv lib/vasnprintf_edited.c lib/vasnprintf.c - fi - ./configure --prefix=$(idir) LDFLAGS="$(LDFLAGS)" \ - CPPFLAGS="$(CPPFLAGS)" - make V=1 -j$(numthreads) - make V=1 install - cd .. - rm -rf $$unpackdir + export CFLAGS="-std=gnu17 $$CFLAGS" + $(call gbuild, m4-$(m4-version), static, \ + --with-syscmd-shell=$(ibdir)/dash, \ + -j$(numthreads) V=1) echo "GNU M4 $(m4-version)" > $@ -# Metastore is used (through a Git hook) to restore the source modification -# dates of files after a Git checkout. Another Git hook saves all file -# metadata just before a commit (to allow restoration after a -# checkout). Since this project is managed in Makefiles, file modification -# dates are critical to not having to redo the whole analysis after -# checking out between branches. -# -# Note that we aren't using the standard version of Metastore, but a fork -# of it that is maintained in this repository: -# https://gitlab.com/makhlaghi/metastore-fork -# -# Note that the prerequisites `coreutils', `gawk' and `sed' are not -# metastore oficial dependencies, but they are necessaries to run our steps -# before and after the installation. -# -# Libbsd is not necessary on macOS systems, because macOS is already a -# BSD-based distribution. But on GNU/Linux systems, it is necessary. -$(ibidir)/metastore-$(metastore-version): \ - $(ibidir)/sed-$(sed-version) \ - $(ibidir)/git-$(git-version) \ - $(ibidir)/gawk-$(gawk-version) \ - $(ibidir)/libbsd-$(libbsd-version) \ - $(ibidir)/coreutils-$(coreutils-version) - - # Download the tarball. - tarball=metastore-$(metastore-version).tar.gz - $(call import-source, $(metastore-url), $(metastore-checksum)) - - # Metastore doesn't have any `./configure' script. So we'll just - # call `pwd' as a place-holder for the `./configure' command. - # - # File attributes are also not available on some systems, since the - # main purpose here is modification dates (and not attributes), - # we'll also set the `NO_XATTR' flag. - # - # After installing Metastore, write the relevant hooks into this - # system's Git hooks, while setting the system-specific - # directories/files. - # - # Note that the metastore -O and -G options used in this template - # are currently only available in a fork of `metastore' hosted at: - # https://github.com/mohammad-akhlaghi/metastore - # - # Checking for presence of `.git'. When the project source is - # downloaded from a non-Git source (for example from arXiv), there - # is no `.git' directory to work with. So until we find a better - # solution, avoid the step to to add the Git hooks. - current_dir=$$(pwd); \ - $(call gbuild, metastore-$(metastore-version), static,, \ - NO_XATTR=1 V=1,,pwd,PREFIX=$(idir)) - - # Correct RPATH when necessary. - if [ -f $(ibdir)/patchelf ]; then - $(ibdir)/patchelf --set-rpath $(ildir) $(ibdir)/metastore - fi - - # If this project is being built in a directory version controlled - # by Git, copy the hooks into the Git configuation. - if [ -f $(ibdir)/metastore ]; then - if [ -d .git ]; then - user=$$(whoami) - group=$$(groups | awk '{print $$1}') - cd $$current_dir - for f in pre-commit post-checkout; do - sed -e's|@USER[@]|'$$user'|g' \ - -e's|@GROUP[@]|'$$group'|g' \ - -e's|@BINDIR[@]|$(ibdir)|g' \ - -e's|@TOP_PROJECT_DIR[@]|'$$current_dir'|g' \ - reproduce/software/shell/git-$$f > .git/hooks/$$f - chmod +x .git/hooks/$$f - done - fi - echo "Metastore (forked) $(metastore-version)" > $@ - else - echo; echo; echo - echo "*****************" - echo "metastore couldn't be installed!" - echo - echo "Its used for preserving timestamps on Git commits." - echo "Its useful for development, not simple running of " - echo "the project. So we won't stop the configuration " - echo "because it wasn't built." - echo "*****************" - echo "" > $@ - fi - $(ibidir)/mpfr-$(mpfr-version): $(ibidir)/gmp-$(gmp-version) - tarball=mpfr-$(mpfr-version).tar.xz + tarball=mpfr-$(mpfr-version).tar.lz $(call import-source, $(mpfr-url), $(mpfr-checksum)) - $(call gbuild, mpfr-$(mpfr-version), static, , , make check) + $(call gbuild, mpfr-$(mpfr-version), static) echo "GNU Multiple Precision Floating-Point Reliably $(mpfr-version)" > $@ $(ibidir)/pkg-config-$(pkgconfig-version): $(ibidir)/patchelf-$(patchelf-version) - # Download the tarball. - tarball=pkg-config-$(pkgconfig-version).tar.gz +# Download the tarball. + tarball=pkg-config-$(pkgconfig-version).tar.lz $(call import-source, $(pkgconfig-url), $(pkgconfig-checksum)) - # An existing `libiconv' can cause a conflict with `pkg-config', - # this is why `libiconv' depends on `pkg-config'. On a clean build, - # `pkg-config' is built first. But when we don't have a clean build - # (and `libiconv' exists) there will be a problem. So before - # re-building `pkg-config', we'll remove any installation of - # `libiconv'. +# An existing 'libiconv' can cause a conflict with 'pkg-config', this +# is why 'libiconv' depends on 'pkg-config'. On a clean build, +# 'pkg-config' is built first. But when we don't have a clean build +# (and 'libiconv' exists) there will be a problem. So before +# re-building 'pkg-config', we'll remove any installation of +# 'libiconv'. rm -f $(ildir)/libiconv* $(idir)/include/iconv.h - # Some Mac OS systems may have a version of the GNU C Compiler - # (GCC) installed that doesn't support some necessary features of - # building Glib (as part of pkg-config). So to be safe, for Mac - # systems, we'll make sure it will use LLVM's Clang. +# Some Mac OS systems may have a version of the GNU C Compiler (GCC) +# installed that doesn't support some necessary features of building +# Glib (as part of pkg-config). So to be safe, for Mac systems, we'll +# make sure it will use LLVM's Clang. if [ x$(on_mac_os) = xyes ]; then export compiler="CC=clang" else export compiler="" fi + export CFLAGS="-std=gnu17 $$CFLAGS" $(call gbuild, pkg-config-$(pkgconfig-version), static, \ $$compiler --with-internal-glib \ --with-pc-path=$(ildir)/pkgconfig, V=1) echo "pkg-config $(pkgconfig-version)" > $@ $(ibidir)/sed-$(sed-version): $(ibidir)/coreutils-$(coreutils-version) - tarball=sed-$(sed-version).tar.xz + tarball=sed-$(sed-version).tar.lz $(call import-source, $(sed-url), $(sed-checksum)) $(call gbuild, sed-$(sed-version), static,,V=1) echo "GNU Sed $(sed-version)" > $@ @@ -1172,7 +1127,18 @@ $(ibidir)/sed-$(sed-version): $(ibidir)/coreutils-$(coreutils-version) $(ibidir)/texinfo-$(texinfo-version): \ $(ibidir)/perl-$(perl-version) \ $(ibidir)/gettext-$(gettext-version) - tarball=texinfo-$(texinfo-version).tar.xz + +# Setting for the XS sub-package. "This is because in theory, the XS +# module could be built with a different compiler to the rest of the +# project, needing completely different flags" (part of [1]) +# +# [1] https://lists.gnu.org/archive/html/bug-texinfo/2022-08/msg00068.html + export PERL="$(ibdir)/perl" + export PERL_EXT_LDFLAGS="-L$(ildir)" + export PERL_EXT_CPPFLAGS="-I$(iidir)" + +# Basic build commands. + tarball=texinfo-$(texinfo-version).tar.lz $(call import-source, $(texinfo-url), $(texinfo-checksum)) $(call gbuild, texinfo-$(texinfo-version), static) if [ -f $(ibdir)/patchelf ]; then @@ -1182,14 +1148,14 @@ $(ibidir)/texinfo-$(texinfo-version): \ echo "GNU Texinfo $(texinfo-version)" > $@ $(ibidir)/which-$(which-version): $(ibidir)/coreutils-$(coreutils-version) - tarball=which-$(which-version).tar.gz + tarball=which-$(which-version).tar.lz $(call import-source, $(which-url), $(which-checksum)) $(call gbuild, which-$(which-version), static) echo "GNU Which $(which-version)" > $@ # GNU ISL is necessary to build GCC. $(ibidir)/isl-$(isl-version): $(ibidir)/gmp-$(gmp-version) - tarball=isl-$(isl-version).tar.bz2 + tarball=isl-$(isl-version).tar.lz $(call import-source, $(isl-url), $(isl-checksum)) if [ $(host_cc) = 1 ]; then echo "" > $@ @@ -1201,13 +1167,13 @@ $(ibidir)/isl-$(isl-version): $(ibidir)/gmp-$(gmp-version) # GNU MPC is necessary to build GCC. $(ibidir)/mpc-$(mpc-version): $(ibidir)/mpfr-$(mpfr-version) - tarball=mpc-$(mpc-version).tar.gz + tarball=mpc-$(mpc-version).tar.lz $(call import-source, $(mpc-url), $(mpc-checksum)) if [ $(host_cc) = 1 ]; then echo "" > $@ else $(call gbuild, mpc-$(mpc-version), static, , \ - -j$(numthreads), make check) + -j$(numthreads)) echo "GNU Multiple Precision Complex library" > $@ fi @@ -1224,33 +1190,35 @@ $(ibidir)/mpc-$(mpc-version): $(ibidir)/mpfr-$(mpfr-version) # ----------------------- # # The installation of Binutils can cause problems during the build of other -# programs (http://savannah.nongnu.org/bugs/?56294), but its necessary for +# programs since it provides the linker that is used to build them +# (http://savannah.nongnu.org/bugs/?56294). However, it is necessary for # GCC. Therefore, we'll set all other basic programs as Binutils -# prerequisite and GCC (the final basic target) ultimately just depends on -# Binutils. +# prerequisites, so GCC (the almost-final basic target) ultimately just +# depends on Binutils. $(ibidir)/binutils-$(binutils-version): \ - $(ibidir)/sed-$(sed-version) \ + $(ibidir)/git-$(git-version) \ $(ibidir)/isl-$(isl-version) \ $(ibidir)/mpc-$(mpc-version) \ - $(ibidir)/wget-$(wget-version) \ - $(ibidir)/grep-$(grep-version) \ + $(ibidir)/sed-$(sed-version) \ $(ibidir)/file-$(file-version) \ $(ibidir)/gawk-$(gawk-version) \ + $(ibidir)/grep-$(grep-version) \ + $(ibidir)/wget-$(wget-version) \ + $(ibidir)/bison-$(bison-version) \ $(ibidir)/which-$(which-version) \ - $(ibidir)/texinfo-$(texinfo-version) \ $(ibidir)/libtool-$(libtool-version) \ - $(ibidir)/metastore-$(metastore-version) \ - $(ibidir)/findutils-$(findutils-version) \ + $(ibidir)/texinfo-$(texinfo-version) \ + $(ibidir)/coreutils-$(coreutils-version) \ $(ibidir)/diffutils-$(diffutils-version) \ - $(ibidir)/coreutils-$(coreutils-version) + $(ibidir)/findutils-$(findutils-version) - # Download the tarball. +# Download the tarball. tarball=binutils-$(binutils-version).tar.lz $(call import-source, $(binutils-url), $(binutils-checksum)) - # Binutils' assembler (`as') and linker (`ld') will conflict with - # other compilers. So if we don't build our own compiler, we'll use - # the host opertating system's equivalents by just making links. +# Binutils' assembler ('as') and linker ('ld') will conflict with +# other compilers. So if we don't build our own compiler, we'll use +# the host opertating system's equivalents by just making links. if [ x$(on_mac_os) = xyes ]; then $(call makelink,as) $(call makelink,ar) @@ -1262,20 +1230,21 @@ $(ibidir)/binutils-$(binutils-version): \ echo "" > $@ else - # Build binutils with the standard 'gbuild' function. +# Build binutils with the standard 'gbuild' function. $(call gbuild, binutils-$(binutils-version), static, \ - --with-lib-path=$(sys_library_path), \ - -j$(numthreads) ) - - # The `ld' linker of Binutils needs several `*crt*.o' files from - # the host's GNU C Library to run. On some systems these object - # files aren't installed in standard places. We defined - # `LIBRARY_PATH' and that fixed the problem for many - # systems. However, some software (for example ImageMagick) - # over-write `LIBRARY_PATH', therefore there is no other way than - # to put a link to these necessary files in our local build - # directory. IMPORTANT NOTE: later, when we build the GNU C - # Library in the project, we should remove this step. + --with-lib-path=$(sys_library_path) \ + --enable-gprofng=no, \ + -j$(numthreads) V=1) + +# The 'ld' linker of Binutils needs several '*crt*.o' files from +# the host's GNU C Library to run. On some systems these object +# files aren't installed in standard places. We defined +# 'LIBRARY_PATH' and that fixed the problem for many +# systems. However, some software (for example ImageMagick) +# over-write 'LIBRARY_PATH', therefore there is no other way than +# to put a link to these necessary files in our local build +# directory. IMPORTANT NOTE: later, when we build the GNU C Library +# in the project, we should remove this step. if ! [ x"$(sys_library_path)" = x ]; then for f in $(sys_library_path)/*crt*.o; do b=$$($(ibdir)/basename $$f) @@ -1283,11 +1252,11 @@ $(ibidir)/binutils-$(binutils-version): \ done fi - # Write the final target. +# Write the final target. echo "GNU Binutils $(binutils-version)" > $@ fi -# We are having issues with `libiberty' (part of GCC) on Mac. So for now, +# We are having issues with 'libiberty' (part of GCC) on Mac. So for now, # GCC won't be built there. Since almost no natural science paper's # processing depends so strongly on the compiler used, for now, this isn't # a bad assumption, but we are indeed searching for a solution. @@ -1296,13 +1265,13 @@ $(ibidir)/binutils-$(binutils-version): \ # environment. So, we'll build GCC after building all the basic tools that # are often used in a configure and build scripts of GCC components. # -# Objective C and Objective C++ is necessary for installing `matplotlib'. +# Objective C and Objective C++ is necessary for installing 'matplotlib'. # # We are currently having problems installing GCC on macOS, so for the time # being, if the project is being run on a macOS, we'll just set a link. $(ibidir)/gcc-$(gcc-version): $(ibidir)/binutils-$(binutils-version) - # Function to let the users know what to do if build fails. +# Function to let the users know what to do if build fails. error_message() { echo; echo echo "_________________________________________________" @@ -1323,45 +1292,41 @@ $(ibidir)/gcc-$(gcc-version): $(ibidir)/binutils-$(binutils-version) echo; exit 1 } - # Download the tarball. - tarball=gcc-$(gcc-version).tar.xz +# Download the tarball. + tarball=gcc-$(gcc-version).tar.lz $(call import-source, $(gcc-url), $(gcc-checksum)) - # To avoid any previous build in '.local/bin' causing problems in - # this build/links of this GCC, we'll first delete all the possibly - # built/existing compilers in this project. Note that GCC also - # installs several executables like this 'x86_64-pc-linux-gnu-gcc', - # 'x86_64-pc-linux-gnu-gcc-ar' or 'x86_64-pc-linux-gnu-g++'. +# To avoid any previous build in '.local/bin' causing problems in +# this build/links of this GCC, we'll first delete all the possibly +# built/existing compilers in this project. Note that GCC also +# installs several executables like this 'x86_64-pc-linux-gnu-gcc', +# 'x86_64-pc-linux-gnu-gcc-ar' or 'x86_64-pc-linux-gnu-g++'. rm -f $(ibdir)/*g++ $(ibdir)/cpp $(ibdir)/gfortran rm -rf $(ildir)/gcc $(ildir)/libcc* $(ildir)/libgcc* rm -f $(ibdir)/*gcc* $(ibdir)/gcov* $(ibdir)/cc $(ibdir)/c++ rm -rf $(ildir)/libgfortran* $(ildir)/libstdc* rm $(idir)/x86_64* - # GCC builds is own libraries in '$(idir)/lib64'. But all other - # libraries are in '$(idir)/lib'. Since this project is only for a - # single architecture, we can trick GCC into building its libraries - # in '$(idir)/lib' by defining the '$(idir)/lib64' as a symbolic - # link to '$(idir)/lib'. +# Build (or set links) to GCC. if [ $(host_cc) = 1 ]; then - # Put links to the host's tools in '.local/bin'. Note that some - # macOS systems have both a native clang *and* a GNU C Compiler - # (note that this is different from the "normal" macOS situation - # where 'gcc' actually points to clang, here we mean when 'gcc' - # is actually the GNU C Compiler). - # - # In such cases, the GCC isn't complete and using it will cause - # problems when building high-level tools (for example openBLAS, - # rpcsvc-proto, CMake, xlsxio, Python or Matplotlib among - # others). To avoid such situations macOSs are configured like - # this: we'll simply set 'gcc' to point to 'clang' and won't set - # 'gcc' to point to the system's 'gcc'. - # - # Also, note that LLVM's clang doesn't have a C Pre-Processor. So - # we will only put a link to the host's 'cpp' if the system is - # not macOS. On macOS systems that have a real GCC installed, - # having GNU CPP in the project build directory is known to cause - # problems with 'libX11'. +# Put links to the host's tools in '.local/bin'. Note that some +# macOS systems have both a native clang *and* a GNU C Compiler +# (note that this is different from the "normal" macOS situation +# where 'gcc' actually points to clang, here we mean when 'gcc' is +# actually the GNU C Compiler). +# +# In such cases, the GCC isn't complete and using it will cause +# problems when building high-level tools (for example openBLAS, +# rpcsvc-proto, CMake, xlsxio, Python or Matplotlib among +# others). To avoid such situations macOSs are configured like +# this: we'll simply set 'gcc' to point to 'clang' and won't set +# 'gcc' to point to the system's 'gcc'. +# +# Also, note that LLVM's clang doesn't have a C Pre-Processor. So +# we will only put a link to the host's 'cpp' if the system is not +# macOS. On macOS systems that have a real GCC installed, having +# GNU CPP in the project build directory is known to cause problems +# with 'libX11'. $(call makelink,gfortran) if [ x$(on_mac_os) = xyes ]; then $(call makelink,clang) @@ -1374,52 +1339,121 @@ $(ibidir)/gcc-$(gcc-version): $(ibidir)/binutils-$(binutils-version) $(call makelink,g++) fi - # We also want to have the two 'cc' and 'c++' in the build - # directory that point to the selected compiler. With the checks - # above, 'gcc' and 'g++' will point to the proper compiler, so - # we'll use them to define 'cc' and 'c++'. +# We also want to have the two 'cc' and 'c++' in the build +# directory that point to the selected compiler. With the checks +# above, 'gcc' and 'g++' will point to the proper compiler, so +# we'll use them to define 'cc' and 'c++'. $(call makelink,gcc,,cc) $(call makelink,g++,,c++) - # Get the first line of the compiler's '--version' output and put - # that into the target (so we know want compiler was used). +# Get the first line of the compiler's '--version' output and put +# that into the target (so we know want compiler was used). ccinfo=$$(gcc --version | awk 'NR==1') echo "C compiler (""$$ccinfo"")" > $@ else - # Mark the current directory. +# Mark the current directory. current_dir=$$(pwd) - # We don't want '.local/lib' and '.local/lib64' to be separate. - ln -fs $(ildir) $(idir)/lib64 - - # By default we'll build GCC in the RAM to avoid building so many - # files and possibly harming the hard-drive or SSD. But if the - # RAM doesn't have enough space, we can't use it. - in_ram=$$(df $(ddir) \ - | awk 'NR==2{print ($$4>10000000) ? "yes" : "no"}'); \ +# By default 'ddir' (where GCC is decompressed and built) is in the +# RAM (on systems that support a '/dev/shm' RAM disk). This is done +# to avoid building so many small/temporary files and possibly +# harming the hard-drive or SSD. But if the RAM doesn't have enough +# space, we should use the hard-drive or SSD. During its build, +# GCC's build directory will become several gigabytes and the build +# also needs RAM. You can track the RAM usage of the system with a +# 1-second resolution (if no other RAM consuming program is running +# while building GCC) with the command below (example outputs can +# be seen in https://savannah.nongnu.org/task/index.php?16623). +# +# c=1; while true; do POSIXLY_CORRECT=1 df -P /dev/shm/maneage-* | awk 'NR==2{print '$c', $3}'; c=$((c+1)); sleep 1; done > mem-usage.txt +# asttable mem-usage.txt -c1,'arith $2 512 x 1024 / 1024 / 1024 /' -o mem.fits +# +# For POSIX portability and longevity (default sizes might change), +# we use the '-P' option, and we use the environment variable +# POSIXLY_CORRECT=1, so the 'block size' is 512 bytes. In this way, +# to get the actual GiB amount, multiply the value returned above +# by 512 (B/block), then divide by 1024^3 (B/GiB). +# +# To get the final value to use here, get the maximum used value +# after GCC is fully built and you have stopped the 'while true' +# command above. You can do this with the command below (assumes +# you have Gnuastro). +# +# aststatistics mem-usage.txt -c2 --maximum | asttable -c'arith $1 7000000 +' -Afixed -B0 +# +# The extra space is because we will assume an extra 3 GiB = 3GiB * +# 1024^3 (B/GiB) / 512 (B/block) = 6291456 blocks are necessary for +# the building (let's round it to 7000000!). +# +# Therefore, we need to make sure that the running system more than +# the necessary amount of space in the RAM. To do this, we use 'df' +# below. +# +# The 4th column of 'df' is the "available" space at the time of +# running, not the full space. So the 'RAM disk' that the OS +# will be using as "pretend" disk space (e.g. using 'tmpfs'; this +# is physically RAM, but appears as if it is disk space) +# during this stage of Maneage is accounted for. GCC is built +# alone - no other Maneage software is built at the same time as +# GCC - so this amount of RAM should be enough. + in_ram=$$(POSIXLY_CORRECT=1 df -P $(ddir) \ + | awk 'NR==2{print ($$4>26613216) ? "yes" : "no"}'); \ if [ $$in_ram = "yes" ]; then odir=$(ddir) else - odir=$(BDIR)/software/build-tmp-gcc + odir=$(BDIR)/software/build-tmp-gcc-due-to-lack-of-space if [ -d $$odir ]; then rm -rf $$odir; fi mkdir $$odir fi - # Go into the proper directory, unpack GCC and prepare the - # 'build' directory inside it for all the built files. +# Go into the directory to uncompress GCC. cd $$odir + +# Unpack GCC and prepare the 'build' directory inside it for all +# the built files. rm -rf gcc-$(gcc-version) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions if [ $$odir != $(ddir) ]; then ln -s $$odir/gcc-$(gcc-version) $(ddir)/gcc-$(gcc-version) fi cd gcc-$(gcc-version) + $(shsrcdir)/prep-source.sh $(ibdir) + +# Unfortunately binutils installs headers like 'ansidecl.h' that +# have been seen to conflict with GCC's internal versions of those +# headers. For example in the 'ansidecl.h' of Binutils 2.39, the +# 'PTR' macro isn't defined, while the same file in GCC 12.1.0 has +# defined it. Therefore, without this change, GCC will include the +# file installed from Binutils, not find what it needs and crash! +# Therefore, with the 'CPPFLAGS' modification below, we tell GCC to +# first look into its own 'include' directory before anything else. + export CPPFLAGS="-I$$(pwd)/include $(CPPFLAGS)" + +# In the GNU C Library 2.36 (which is more recent than GCC 12.1.0), +# the 'linux/mount.h' (loaded by 'linux/fs.h', which is loaded by +# 'libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp' +# in GCC) conflicts with 'sys/mount.h' which is directly loaded by +# the same file! This is a known conflict in glibc 2.36 (see +# [1]). As described in [1], one solution is the final job done in +# [2]. We therefore do this process here: 1) Not loading +# 'linux/fs.h', and adding the necessary macros directly. +# +# [1] https://sourceware.org/glibc/wiki/Release/2.36#Usage_of_.3Clinux.2Fmount.h.3E_and_.3Csys.2Fmount.h.3E +# [2] https://reviews.llvm.org/D129471 + sed -e's|\#include <linux/fs.h>||' \ + -e"s|FS_IOC_GETFLAGS;|_IOR('f', 1, long);|" \ + -e"s|FS_IOC_GETVERSION;|_IOR('v', 1, long);|" \ + -e"s|FS_IOC_SETFLAGS;|_IOW('f', 2, long);|" \ + -e"s|FS_IOC_SETVERSION;|_IOW('v', 2, long);|" \ + -i libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp + +# Set the build directory for the processing. mkdir build cd build - # Configure, build and install GCC, if any of three steps fails, - # the error message will be printed. +# Configure, build and install GCC, if any of three steps fails, +# the error message will be printed. if ! ../configure SHELL=$(ibdir)/bash \ --prefix=$(idir) \ --with-mpc=$(idir) \ @@ -1438,26 +1472,25 @@ $(ibidir)/gcc-$(gcc-version): $(ibidir)/binutils-$(binutils-version) --enable-languages=c,c++,fortran,objc,obj-c++ \ --disable-nls \ --disable-libada \ - --disable-multilib \ - --disable-multiarch; then error_message; fi + --disable-multilib; then error_message; fi if ! make SHELL=$(ibdir)/bash -j$(numthreads); then error_message; fi if ! make SHELL=$(ibdir)/bash install; then error_message; fi - # We need to manually fix the RPATH inside GCC's libraries, the - # programs built by GCC already have RPATH. +# We need to manually fix the RPATH inside GCC's libraries, the +# programs built by GCC already have RPATH. tempname=$$odir/gcc-$(gcc-version)/build/rpath-temp-copy if [ -f $(ibdir)/patchelf ]; then - # Go over all the installed GCC libraries (its executables are - # fine!). +# Go over all the installed GCC libraries (its executables are +# fine!). for f in $$(find $(idir)/libexec/gcc -type f) $(ildir)/libstdc++*; do - # Make sure this is a static library, copy it to a temporary - # name (to avoid any possible usage of the file while it is - # being corrected), and add RPATH inside of it and put the - # corrected file back in its place. In the case of the - # standard C++ library, we also need to manually insert a - # linking to libiconv. +# Make sure this is a static library, copy it to a temporary +# name (to avoid any possible usage of the file while it is +# being corrected), and add RPATH inside of it and put the +# corrected file back in its place. In the case of the standard +# C++ library, we also need to manually insert a linking to +# libiconv. if file $$f | grep -q "dynamically linked"; then cp $$f $$tempname patchelf --set-rpath $(ildir) $$tempname @@ -1471,8 +1504,8 @@ $(ibidir)/gcc-$(gcc-version): $(ibidir)/binutils-$(binutils-version) done fi - # Come back up to the un-packing directory and delete the GCC - # source directory. +# Come back up to the un-packing directory and delete the GCC +# source directory. cd ../.. rm -rf gcc-$(gcc-version) cd $$current_dir @@ -1481,11 +1514,11 @@ $(ibidir)/gcc-$(gcc-version): $(ibidir)/binutils-$(binutils-version) rm $(ddir)/gcc-$(gcc-version); fi - # Set 'cc' to point to 'gcc'. +# Set 'cc' to point to 'gcc'. ln -sf $(ibdir)/gcc $(ibdir)/cc ln -sf $(ibdir)/g++ $(ibdir)/c++ - # Write the final target. +# Write the final target. echo "GNU Compiler Collection (GCC) $(gcc-version)" > $@ fi @@ -1493,29 +1526,58 @@ $(ibidir)/gcc-$(gcc-version): $(ibidir)/binutils-$(binutils-version) +# Level 6: need re-compilation +# ---------------------------- +# +# The initial build of these was done with the host's settings, which will +# cause problems later when we completely close-off the host environment. +$(ibidir)/make-$(make-version): $(ibidir)/gcc-$(gcc-version) + tarball=make-$(make-version).tar.lz + $(call import-source, $(make-url), $(make-checksum)) + $(call gbuild, make-$(make-version), static, \ + --disable-dependency-tracking --without-guile) + echo "GNU Make $(make-version)" > $@ + +$(ibidir)/lzip-$(lzip-version): $(ibidir)/gcc-$(gcc-version) + tarball=lzip-$(lzip-version).tar + unpackdir=lzip-$(lzip-version) + cd $(ddir) + rm -rf $$unpackdir + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) + ./configure --build --check --installdir="$(ibdir)" + if [ -f $(ibdir)/patchelf ]; then + $(ibdir)/patchelf --set-rpath $(ildir) $(ibdir)/lzip; + fi + cd .. + rm -rf $$unpackdir + echo "Lzip $(lzip-version)" > $@ -# Level 6: Basic text editor +# Level 7: Basic text editor # -------------------------- # # If the project is built in a minimal environment, there is no text # editor, making it hard to work on the project. By default a minimal # (relatively user-friendly: GNU Nano) text editor will thus also be built -# at the end of the "basic" tools. More advanced editors are available as -# optional high-level programs. GNU Nano is a very light-weight and small -# command-line text editor (around 3.5 Mb after installation!). +# at the end of the "basic" tools. More advanced editors (for example Emacs +# and Vim) are available as optional high-level programs. GNU Nano is a +# very light-weight and small command-line text editor (around 3.5 Mb after +# installation!). # # The editor is a top-level target in the basic tools (given to # 'targets-proglib' above). Hence nothing depends on it, and it just # depends on GCC. This is done because some projects may choose to not have -# nano (and use their own optional high-level text editor). To do this, -# they just have to manually remove 'nano' from 'targets-proglib' above and +# nano (and use their own optional high-level text editor). To do this, you +# can just have to manually remove 'nano' from 'targets-proglib' above and # add their optional text editor in 'TARGETS.conf'. -$(ibidir)/nano-$(nano-version): $(ibidir)/gcc-$(gcc-version) - tarball=nano-$(nano-version).tar.xz +$(ibidir)/nano-$(nano-version): $(ibidir)/lzip-$(lzip-version) \ + $(ibidir)/make-$(make-version) + tarball=nano-$(nano-version).tar.lz $(call import-source, $(nano-url), $(nano-checksum)) $(call gbuild, nano-$(nano-version), static) echo "GNU Nano $(nano-version)" > $@ diff --git a/reproduce/software/make/build-rules.mk b/reproduce/software/make/build-rules.mk index 66c77bc..463fbbf 100644 --- a/reproduce/software/make/build-rules.mk +++ b/reproduce/software/make/build-rules.mk @@ -3,7 +3,7 @@ # imported into 'basic.mk' and 'high-level.mk'. They should be activated # with Make's 'Call' function. # -# Copyright (C) 2018-2021 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2018-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> # # This Makefile is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -29,8 +29,13 @@ # its checksum and if it is correct, remove the extra suffix. # # Arguments: -# 1: The optional URL to use for this tarball. -# 2: The expeced checksum of the tarball. +# 1: The optional base URL (directory) to use for this tarball. +# 2: The expected checksum of the tarball. +# 3: The upstream name of the tarball file, if not automatically derived +# from the version number. +# 4: [Optional]: Alternative upstream base URL (directory) for the +# tarball, to be used in preference to user or Maneage backup +# servers. # # Necessary shell variables # 'tarball': This is the name of the actual tarball file without a @@ -56,7 +61,14 @@ import-source = final=$(tdir)/$$tarball; \ tarballurl=$(topbackupserver)/$$tarball; \ else \ bservers="$(backupservers_all)"; \ - tarballurl=$$url/$$tarball; \ + if [ "x$(strip $(3))" = "x" ]; then \ + tarballurl=$$url/$$tarball; \ + else \ + tarballurl=$$url/$(strip $(3)); \ + fi; \ + fi; \ + if [ x"$(4)" != x ]; then \ + bservers="$(strip $(4)) $$bservers"; \ fi; \ if [ -f $(ibdir)/wget ]; then \ downloader="wget --no-use-server-timestamps -O"; \ @@ -89,6 +101,48 @@ import-source = final=$(tdir)/$$tarball; \ +# Double-check an already downloaded R source +# ------------------------------------------- +# +# It is probably too late to protect the system if you have already +# installed an insecure or wrong R package. However, it's still useful +# to check that the source package is the one that you think it is. +# +# Calculate the checksum and exit with a non-zero error code if +# there's a mismatch, after informing the user. +# +# Arguments: +# 1: The expected checksum of the tarball. +# +# Necessary shell variables +# 'tarball': This is the name of the actual tarball file without a +# directory. +double-check-R-source = final=$(tdir)/R-project/$$tarball; \ + exp_checksum="$(strip $(1))"; \ + if [ x"$$exp_checksum" = x"NO-CHECK-SUM" ]; then \ + result=0; \ + else \ + if type sha512sum > /dev/null 2>/dev/null; then \ + checksum=$$(sha512sum "$$final" | awk '{print $$1}'); \ + if [ x"$$checksum" = x"$$exp_checksum" ]; then \ + result=0; \ + else \ + echo "ERROR: Non-matching checksum: $$final"; \ + echo "Checksum should be: $$exp_checksum"; \ + echo "Checksum is: $$checksum"; \ + result=1; \ + exit 1; \ + fi; \ + else \ + echo "ERROR: sha512sum is unavailable."; \ + exit 1; \ + fi; \ + fi + + + + + # Unpack a tarball # ---------------- # @@ -106,7 +160,7 @@ uncompress = csuffix=$$(echo $$utarball \ intarrm=0; \ intar=$$utarball; \ fi; \ - if tar xf $$intar; then \ + if tar -xf $$intar --no-same-owner --no-same-permissions; then \ if [ x$$intarrm = x1 ]; then rm $$intar; fi; \ else \ echo; echo "Tar error"; exit 1; \ @@ -153,23 +207,19 @@ gbuild = if [ x$(static_build) = xyes ] && [ "x$(2)" = xstatic ]; then \ else confscript="$(strip $(6))"; \ fi; \ \ - if [ -f $(ibdir)/bash ]; then \ - if [ -f "$$confscript" ]; then \ - sed -e's|\#\! /bin/sh|\#\! $(ibdir)/bash|' \ - -e's|\#\!/bin/sh|\#\! $(ibdir)/bash|' \ - $$confscript > $$confscript-tmp; \ - mv $$confscript-tmp $$confscript; \ - chmod +x $$confscript; \ - fi; \ + $(shsrcdir)/prep-source.sh $(ibdir); \ + if [ -f $(ibdir)/bash ]; then \ shellop="SHELL=$(ibdir)/bash"; \ - elif [ -f /bin/bash ]; then shellop="SHELL=/bin/bash"; \ - else shellop="SHELL=/bin/sh"; \ + else shellop="SHELL=$(ibdir)/dash"; \ fi; \ \ + if [ x$$gbuild_prefix = x ]; then prefixdir="$(idir)"; \ + else prefixdir="$$gbuild_prefix"; fi; \ + \ if [ -f "$$confscript" ]; then \ if [ x"$(strip $(1))" = x"zlib-$(zlib-version)" ]; then \ - configop="--prefix=$(idir)"; \ - else configop="$$shellop --prefix=$(idir)"; \ + configop="--prefix=$$prefixdir"; \ + else configop="$$shellop --prefix=$$prefixdir"; \ fi; \ fi; \ \ @@ -190,7 +240,7 @@ gbuild = if [ x$(static_build) = xyes ] && [ "x$(2)" = xstatic ]; then \ make "$$shellop" install $(7); \ cd ..; \ fi; \ - rm -rf $(1) + rm -rf $(1); @@ -198,10 +248,7 @@ gbuild = if [ x$(static_build) = xyes ] && [ "x$(2)" = xstatic ]; then \ # CMake # ----- # -# According to the link below, in CMake '/bin/sh' is hardcoded, so there is -# no way to change it unfortunately! -# -# https://stackoverflow.com/questions/21167014/how-to-set-shell-variable-in-makefiles-generated-by-cmake +# Used by packages that are built with CMake. cbuild = if [ x$(static_build) = xyes ] && [ $(2)x = staticx ]; then \ export LDFLAGS="$$LDFLAGS -static"; \ opts="-DBUILD_SHARED_LIBS=OFF"; \ @@ -211,13 +258,18 @@ cbuild = if [ x$(static_build) = xyes ] && [ $(2)x = staticx ]; then \ utarball=$(tdir)/$$tarball; \ $(call uncompress); \ cd $(1); \ - rm -rf project-build; \ - mkdir project-build; \ - cd project-build; \ + $(shsrcdir)/prep-source.sh $(ibdir); \ + if [ -f $(ibdir)/bash ]; then \ + shellop="SHELL=$(ibdir)/bash"; \ + else shellop="SHELL=$(ibdir)/dash"; \ + fi; \ + rm -rf maneage-build; \ + mkdir maneage-build; \ + cd maneage-build; \ cmake .. -DCMAKE_LIBRARY_PATH=$(ildir) \ -DCMAKE_INSTALL_PREFIX=$(idir) \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON $$opts $(3); \ - make; \ - make install; \ + make $$shellop; \ + make $$shellop install; \ cd ../..; \ rm -rf $(1) diff --git a/reproduce/software/make/high-level.mk b/reproduce/software/make/high-level.mk index 6ea782c..67ca8b6 100644 --- a/reproduce/software/make/high-level.mk +++ b/reproduce/software/make/high-level.mk @@ -3,7 +3,7 @@ # ------------------------------------------------------------------------ # !!!!! IMPORTANT NOTES !!!!! # -# This Makefile will be run by the initial `./project configure' script. It +# This Makefile will be run by the initial './project configure' script. It # is not included into the project afterwards. # # This Makefile builds the high-level (optional) software in Maneage that @@ -12,8 +12,8 @@ # # ------------------------------------------------------------------------ # -# Copyright (C) 2018-2021 Mohammad Akhlaghi <mohammad@akhlaghi.org> -# Copyright (C) 2019-2021 Raul Infante-Sainz <infantesainz@gmail.com> +# Copyright (C) 2018-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2019-2025 Raul Infante-Sainz <infantesainz@gmail.com> # # This Makefile is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ # along with this Makefile. If not, see <http://www.gnu.org/licenses/>. # Top level environment (same as 'basic.mk') -include reproduce/software/config/LOCAL.conf +include .build/software/config/LOCAL.conf include reproduce/software/make/build-rules.mk include reproduce/software/config/versions.conf include reproduce/software/config/checksums.conf @@ -49,6 +49,7 @@ ddir = $(BDIR)/software/build-tmp idir = $(BDIR)/software/installed ibdir = $(BDIR)/software/installed/bin ildir = $(BDIR)/software/installed/lib +iidir = $(BDIR)/software/installed/include ibidir = $(BDIR)/software/installed/version-info/proglib # Basic directories (specific to this Makefile). @@ -60,6 +61,15 @@ patchdir = "$(shell pwd)"/reproduce/software/patches itidir = $(BDIR)/software/installed/version-info/tex ictdir = $(BDIR)/software/installed/version-info/cite ipydir = $(BDIR)/software/installed/version-info/python +ircrandir = $(BDIR)/software/installed/version-info/r-cran +ilibrcrandir = $(BDIR)/software/installed/lib/R/library + +# Special files. +makewshell = $(ibdir)/make-with-shell + + + + # Targets to build. ifeq ($(strip $(all_highlevel)),1) @@ -75,7 +85,7 @@ ifeq ($(strip $(all_highlevel)),1) # included here because there is no explicit target for them: they will # be built as part of the other package. targets-proglib := $(filter-out minizip-% lapack-% ghostscript-fonts-%, \ - $(shell awk '/^# CLASS:PYTHON/{good=0} \ + $(shell awk '/^# CLASS:(PYTHON|R-CRAN)/{good=0} \ good==1 && !/^#/ && $$1 ~ /-version$$/ { \ printf("%s %s ", $$1, $$3)} \ /^# CLASS:HIGHLEVEL/{good=1}' \ @@ -85,22 +95,40 @@ ifeq ($(strip $(all_highlevel)),1) # List all existing Python packages. targets-python := $(shell \ - awk '/^# CLASS:PYTHON/{good=1} \ - good==1 && !/^#/ && $$1 ~ /-version$$/ {printf("%s %s ",$$1,$$3)}' \ - reproduce/software/config/versions.conf | sed 's/version //g') + awk '/^# CLASS:PYTHON-START/{good=1} good; \ + /^# CLASS:PYTHON-END/{good=0}' \ + reproduce/software/config/versions.conf \ + | awk '!/^#/' \ + | sed 's/-version = /-/g') + + # List all existing R-CRAN packages. + targets-r-cran := $(shell \ + awk '/^# CLASS:R-CRAN-START/{good=1} good; \ + /^# CLASS:R-CRAN-END/{good=0}' \ + reproduce/software/config/versions.conf \ + | awk '!/^#/' \ + | sed 's/-version = /-/g') else - # Append the version of each software to its name. We are using a Make + # Append the version of each software package to its name. We are using a Make # feature where a variable name is defined with another variable. targets-python := $(foreach p,$(top-level-python),$(p)-$($(p)-version)) + targets-r-cran := $(foreach p,$(top-level-r-cran),$(p)-$($(p)-version)) targets-proglib := $(foreach p,$(top-level-programs),$(p)-$($(p)-version)) endif -# Ultimate Makefile target. +# Disable the TeXLive target if `--offline` +ifneq ($(strip $(offline)),1) + target-texlive := $(itidir)/texlive +endif + +# Ultimate Makefile target. The recipe is '@echo > /dev/null' so Make does +# not print "make: Nothing to be done for 'all'." all: $(foreach p, $(targets-proglib), $(ibidir)/$(p)) \ $(foreach p, $(targets-python), $(ipydir)/$(p)) \ - $(itidir)/texlive + $(foreach p, $(targets-r-cran), $(ircrandir)/$(p)) \ + $(target-texlive); @echo > /dev/null # Define the shell environment # ---------------------------- @@ -112,14 +140,18 @@ all: $(foreach p, $(targets-proglib), $(ibidir)/$(p)) \ # # To investigate: # -# 1) Set SHELL to `$(ibdir)/env - NAME=VALUE $(ibdir)/bash' and set all -# the parameters defined bellow as `NAME=VALUE' statements before +# 1) Set SHELL to '$(ibdir)/env - NAME=VALUE $(ibdir)/bash' and set all +# the parameters defined bellow as 'NAME=VALUE' statements before # calling Bash. This will enable us to completely ignore the user's # native environment. # -# 2) Add `--noprofile --norc' to `.SHELLFLAGS' so doesn't load the +# 2) Add '--noprofile --norc' to '.SHELLFLAGS' so doesn't load the # user's environment. # +# 3) Add the '-u' flag so that an error occurs if an environment +# variable is empty; this reduces the chance of catastrophic +# file removal with 'rm -fr ../../$${FORGOT_TO_DEFINE_THIS}'. +# # Shell settings similar to 'basic.mk': .ONESHELL: export PATH := $(ibdir) @@ -128,9 +160,11 @@ export SHELL := $(ibdir)/bash .SHELLFLAGS := --noprofile --norc -ec export LDFLAGS := $(rpath_command) -L$(ildir) export PKG_CONFIG_LIBDIR := $(ildir)/pkgconfig -export CPPFLAGS := -I$(idir)/include -Wno-nullability-completeness export PKG_CONFIG_PATH := $(ildir)/pkgconfig:$(idir)/share/pkgconfig +# Disable built-in rules (which are not needed here!) +.SUFFIXES: + # Settings specific to this Makefile. export CC := $(ibdir)/gcc export CXX := $(ibdir)/g++ @@ -138,6 +172,13 @@ export F77 := $(ibdir)/gfortran export LD_RUN_PATH := $(ildir):$(il64dir) export LD_LIBRARY_PATH := $(ildir):$(il64dir) +# See description of '-Wno-nullability-completeness' in +# 'reproduce/software/shell/configure.sh'. +ifeq ($(on_mac_os),yes) + noccwarnings=-Wno-nullability-completeness +endif +export CPPFLAGS := -I$(idir)/include $(noccwarnings) + # In macOS, if a directory exists in both 'C_INCLUDE_PATH' and 'CPPFLAGS' # it will be ignored in 'CPPFLAGS' (which has higher precedence). So, we # should not define 'C_INCLUDE_PATH' on macOS. This happened with clang @@ -147,16 +188,16 @@ export C_INCLUDE_PATH := $(iidir) export CPLUS_INCLUDE_PATH := $(iidir) endif -# Recipe startup script, see `reproduce/software/shell/bashrc.sh'. +# Recipe startup script, see 'reproduce/software/shell/bashrc.sh'. export PROJECT_STATUS := configure_highlevel export BASH_ENV := $(shell pwd)/reproduce/software/shell/bashrc.sh # Until we build our own C library, without this, our GCC won't be able to # compile anything! Note that on most systems (in particular -# non-Debian-based), `sys_cpath' will be empty. +# non-Debian-based), 'sys_cpath' will be empty. export CPATH := $(sys_cpath) -# RPATH is automatically written in macOS, so `DYLD_LIBRARY_PATH' is +# RPATH is automatically written in macOS, so 'DYLD_LIBRARY_PATH' is # ultimately redundant. But on some systems, even having a single value # causes crashs (see bug #56682). So we'll just give it no value at all. export DYLD_LIBRARY_PATH := @@ -164,8 +205,8 @@ export DYLD_LIBRARY_PATH := # On Debian-based OSs, the basic C libraries are in a target-specific # location, not in standard places. Until we merge the building of the C # library, it is thus necessary to include this location here. On systems -# that don't need it, `sys_library_path' is just empty. This is necessary -# for `ld'. +# that don't need it, 'sys_library_path' is just empty. This is necessary +# for 'ld'. # # If this variable is not defined, it will be interpretted as the current # directory. In this case, when the program source has a 'specs' directory, @@ -179,12 +220,18 @@ endif # Building flags: # # C++ flags: when we build GCC, the C++ standard library needs to link with -# libiconv. So it is necessary to generically include `-liconv' for all C++ +# libiconv. So it is necessary to generically include '-liconv' for all C++ # builds. ifeq ($(host_cc),0) export CXXFLAGS := -liconv endif +# Custom installation prefix for software that can cause conflicts with +# others, to avoid crowding the to Maneage installed software directory, +# we'll put them all in a 'custom' directory. +idircustom = $(idir)/custom +$(idircustom):; mkdir $@ + # Servers to use as backup. Maneage already has some fixed servers that can # be used to download software tarballs. They are in a configuation # file. But we give precedence to the "user" backup servers. @@ -197,7 +244,7 @@ endif # Afer putting everything together, we use the first server as the # reference for all software if their '-url' variable isn't defined (in # 'reproduce/software/config/urls.conf'). -downloadwrapper = ./reproduce/analysis/bash/download-multi-try +downloadwrapper = ./reproduce/analysis/bash/download-multi-try.sh maneage_backup_urls := $(shell awk '!/^#/{printf "%s ", $$1}' \ reproduce/software/config/servers-backup.conf) backupservers_all = $(user_backup_urls) $(maneage_backup_urls) @@ -211,6 +258,8 @@ backupservers = $(filter-out $(topbackupserver),$(backupservers_all)) # Import rules to build specialized software include reproduce/software/make/xorg.mk include reproduce/software/make/python.mk +include reproduce/software/make/r-cran.mk + @@ -226,61 +275,27 @@ include reproduce/software/make/python.mk # # We would prefer to build static libraries, but some compilers like LLVM # don't have static capabilities, so they'll only build dynamic/shared -# libraries. Therefore, we can't use the easy `.a' suffix for static +# libraries. Therefore, we can't use the easy '.a' suffix for static # libraries as targets and there are different conventions for shared # library names. - -# Until version 0.11.0 is released, we are using the version corresponding -# to commit 014954db (603 commits after version 0.10.0, most recent when -# first importing log4cxx into this project). -# -# Note that after cloning the project, the following changes are necessary -# in `configure.ac'. -# - Update the final name of the tarball and its version (from `git -# - describe') by modifying the `AC_INIT' line: -# AC_INIT([apachelog4cxx], [0.10.0-603-014954db]) -# - Because of the long file names in the project, some files will not be -# packaged by default, so pass the `tar-ustar' option to Automake (the -# `AM_INIT_AUTOMAKE' line of `configure.ac': -# AM_INIT_AUTOMAKE([foreign subdir-objects -Wall tar-ustar]) -# -# You can then simply bootstrap the project and make the distribution -# tarball like this: -# ./autogen.sh && ./configure && make -j8 && make dist-lzip -# -# Unfortunately we have to re-run the `autogen.sh' script on the tarball to -# build it because it will complain about the version of libtool, so until -# the version 0.11.0 of log4cxx, we'll have to run `autogen.sh' on the -# unpacked source also. $(ibidir)/apachelog4cxx-$(apachelog4cxx-version): \ + $(ibidir)/cmake-$(cmake-version) \ $(ibidir)/expat-$(expat-version) \ $(ibidir)/apr-util-$(apr-util-version) \ $(ibidir)/automake-$(automake-version) - tarball=apachelog4cxx-$(apachelog4cxx-version).tar.lz + tarball=apache-log4cxx-$(apachelog4cxx-version).tar.lz $(call import-source, $(apachelog4cxx-url), $(apachelog4cxx-checksum)) - pdir=apachelog4cxx-$(apachelog4cxx-version) - rm -rf $(ddir)/$$pdir - topdir=$(pwd) - cd $(ddir) - tar xf $(tdir)/$$tarball - cd $$pdir - ./autogen.sh - ./configure SHELL=$(ibdir)/bash --prefix=$(idir) - make -j$(numthreads) SHELL=$(ibdir)/bash - make install - cd .. - rm -rf $$pdir - cd $$topdir + $(call cbuild, apache-log4cxx-$(apachelog4cxx-version), static) echo "Apache log4cxx $(apachelog4cxx-version)" > $@ $(ibidir)/apr-$(apr-version): - tarball=apr-$(apr-version).tar.gz + tarball=apr-$(apr-version).tar.lz $(call import-source, $(apr-url), $(apr-checksum)) $(call gbuild, apr-$(apr-version), ,--disable-static) echo "Apache Portable Runtime $(apr-version)" > $@ $(ibidir)/apr-util-$(apr-util-version): $(ibidir)/apr-$(apr-version) - tarball=apr-util-$(apr-util-version).tar.gz + tarball=apr-util-$(apr-util-version).tar.lz $(call import-source, $(apr-util-url), $(apr-util-checksum)) $(call gbuild, apr-util-$(apr-util-version), , \ --disable-static \ @@ -291,20 +306,19 @@ $(ibidir)/apr-util-$(apr-util-version): $(ibidir)/apr-$(apr-version) $(ibidir)/atlas-$(atlas-version): - tarball=lapack-$(lapack-version).tar.gz + tarball=lapack-$(lapack-version).tar.lz $(call import-source, $(lapack-url), $(lapack-checksum)) - tarball=atlas-$(atlas-version).tar.bz2 + tarball=atlas-$(atlas-version).tar.lz $(call import-source, $(atlas-url), $(atlas-checksum)) - # Get the operating system specific features (how to get - # CPU frequency and the library suffixes). To make the steps - # more readable, the different library version suffixes are - # named with a single character: `s' for no version in the - # name, `m' for the major version suffix, and `f' for the - # full version suffix. - # GCC in Mac OS doesn't work. To work around this issue, on Mac - # systems we force ATLAS to use `clang' instead of `gcc'. +# Get the operating system specific features (how to get CPU +# frequency and the library suffixes). To make the steps more +# readable, the different library version suffixes are named with a +# single character: 's' for no version in the name, 'm' for the major +# version suffix, and 'f' for the full version suffix. GCC in Mac OS +# doesn't work. To work around this issue, on Mac systems we force +# ATLAS to use 'clang' instead of 'gcc'. if [ x$(on_mac_os) = xyes ]; then s=dylib m=3.dylib @@ -321,8 +335,8 @@ $(ibidir)/atlas-$(atlas-version): | sed "s/.*: \([0-9.]*\).*/\1/") fi - # See if the shared libraries should be build for a single CPU - # thread or multiple threads. +# See if the shared libraries should be build for a single CPU thread +# or multiple threads. N=$$(nproc) srcdir=$$(pwd)/reproduce/software/make if [ $$N = 1 ]; then @@ -331,25 +345,27 @@ $(ibidir)/atlas-$(atlas-version): sharedmk=$$srcdir/atlas-multiple.mk fi - # The linking step here doesn't recognize the `-Wl' in the - # `rpath_command'. +# The linking step here doesn't recognize the '-Wl' in the +# 'rpath_command'. export LDFLAGS=-L$(ildir) cd $(ddir) - tar xf $(tdir)/atlas-$(atlas-version).tar.bz2 + tar -xf $(tdir)/atlas-$(atlas-version).tar.lz \ + --no-same-owner --no-same-permissions cd ATLAS + $(shsrcdir)/prep-source.sh $(ibdir) rm -rf build mkdir build cd build ../configure -b 64 -D c -DPentiumCPS=$$core \ - --with-netlib-lapack-tarfile=$(tdir)/lapack-$(lapack-version).tar.gz \ + --with-netlib-lapack-tarfile=$(tdir)/lapack-$(lapack-version).tar.lz \ --cripple-atlas-performance \ -Fa alg -fPIC --shared $$clangflag \ --prefix=$(idir) - # Static build. +# Static build. make - # Currently the shared libraries have problems on macOS. +# Currently the shared libraries have problems on macOS. if [ "x$(on_mac_os)" != xyes ]; then cd lib make -f $$sharedmk @@ -362,21 +378,21 @@ $(ibidir)/atlas-$(atlas-version): ln -fs $(ildir)/liblapack.$$f $(ildir)/liblapack.$$m fi - # Install the libraries. +# Install the libraries. make install - # We need to check the existance of `libptlapack.a', but we can't - # do this in the `&&' steps above (it will conflict). So we'll do - # the check after seeing if `libtatlas.so' is installed, then we'll - # finalize the build (delete the untarred directory). +# We need to check the existance of 'libptlapack.a', but we can't do +# this in the '&&' steps above (it will conflict). So we'll do the +# check after seeing if 'libtatlas.so' is installed, then we'll +# finalize the build (delete the untarred directory). if [ "x$(on_mac_os)" != xyes ]; then \ [ -e lib/libptlapack.a ] && cp lib/libptlapack.a $(ildir); \ cd $(ddir); \ rm -rf ATLAS; \ fi - # We'll check the full installation with the static library (not - # currently building shared library on Mac. +# We'll check the full installation with the static library (not +# currently building shared library on Mac. if [ -f $(ildir)/libatlas.a ]; then \ echo "ATLAS $(atlas-version)" > $@; \ fi @@ -391,8 +407,9 @@ $(ibidir)/boost-$(boost-version): \ rm -rf $(ddir)/$$unpackdir topdir=$(pwd) cd $(ddir) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) ./bootstrap.sh --prefix=$(idir) --with-libraries=all \ --with-python=python3 echo "using mpi ;" > project-config.jam @@ -404,57 +421,63 @@ $(ibidir)/boost-$(boost-version): \ $(ibidir)/cfitsio-$(cfitsio-version): - # Download the tarball - tarball=cfitsio-$(cfitsio-version).tar.gz +# Download the tarball + tarball=cfitsio-$(cfitsio-version).tar.lz $(call import-source, $(cfitsio-url), $(cfitsio-checksum)) - # CFITSIO hard-codes '@rpath' inside the shared library on - # Mac systems. So we need to change it to our library - # installation path. It doesn't affect GNU/Linux, so we'll - # just do it in any case to keep things clean. - topdir=$(pwd); cd $(ddir); tar xf $(tdir)/$$tarball +# CFITSIO hard-codes '@rpath' inside the shared library on Mac +# systems. So we need to change it to our library installation +# path. It doesn't affect GNU/Linux, so we'll just do it in any case +# to keep things clean. + topdir=$(pwd); cd $(ddir) + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions customtar=cfitsio-$(cfitsio-version)-custom.tar.gz cd cfitsio-$(cfitsio-version) - sed configure -e's|@rpath|$(ildir)|g' > configure_tmp - mv configure_tmp configure - chmod +x configure + sed -i -e's|@rpath|$(ildir)|g' configure cd .. tar cf $$customtar cfitsio-$(cfitsio-version) cd $$topdir - # Continue the standard build on the customized tarball. Note that - # with the installation of CFITSIO, `fpack' and `funpack' are not - # installed by default. Because of that, they are added explicity. +# Continue the standard build on the customized tarball. Note that +# with the installation of CFITSIO, 'fpack' and 'funpack' are not +# installed by default. Because of that, they are added explicity. +# +# Note that older versions of CFITSIO (before 4.4.0) require a +# specific 'shared' target for the building of the shared libraries. export gbuild_tar=$(ddir)/$$customtar $(call gbuild, cfitsio-$(cfitsio-version), , \ --enable-sse2 --enable-reentrant \ --with-bzip2=$(idir), , \ - make shared fpack funpack) + make fpack funpack) rm $$customtar echo "CFITSIO $(cfitsio-version)" > $@ $(ibidir)/cairo-$(cairo-version): \ + $(ibidir)/libxt-$(libxt-version) \ $(ibidir)/pixman-$(pixman-version) \ $(ibidir)/libpng-$(libpng-version) \ $(ibidir)/freetype-$(freetype-version) - tarball=cairo-$(cairo-version).tar.xz + tarball=cairo-$(cairo-version).tar.lz $(call import-source, $(cairo-url), $(cairo-checksum)) $(call gbuild, cairo-$(cairo-version), static, \ --with-x=yes, -j$(numthreads) V=1) echo "Cairo $(cairo-version)" > $@ # Eigen is just headers! So it doesn't need to be compiled. Once unpacked -# it has a checksum after `eigen-eigen', so we'll just use a `*' to choose +# it has a checksum after 'eigen-eigen', so we'll just use a '*' to choose # the unpacked directory. $(ibidir)/eigen-$(eigen-version): - tarball=eigen-$(eigen-version).tar.gz + tarball=eigen-$(eigen-version).tar.lz $(call import-source, $(eigen-url), $(eigen-checksum)) rm -rf $(ddir)/eigen-eigen-* - topdir=$(pwd); cd $(ddir); tar xf $(tdir)/$$tarball - cd eigen-eigen-* - cp -r Eigen $(iidir)/eigen3 + topdir=$(pwd); cd $(ddir) + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd eigen-$(eigen-version) + if ! [ -d $(iidir)/eigen3 ]; then mkdir $(iidir)/eigen3; fi + cp -r Eigen/* $(iidir)/eigen3/ # Some expect 'eigen3'. + ln -s $(iidir)/eigen3 $(iidir)/Eigen # Others expect 'Eigen'. cd $$topdir - rm -rf $(ddir)/eigen-eigen-* + rm -rf $(ddir)/eigen-$(eigen-version) echo "Eigen $(eigen-version)" > $@ # GNU Emacs is an advanced text editor (among many other things!), so it @@ -468,7 +491,7 @@ $(ibidir)/eigen-$(eigen-version): # except the core Emacs functionality (using '--without-all') and we are # also disabling all graphic user interface features (using '--without-x'). $(ibidir)/emacs-$(emacs-version): - tarball=emacs-$(emacs-version).tar.xz + tarball=emacs-$(emacs-version).tar.lz $(call import-source, $(emacs-url), $(emacs-checksum)) $(call gbuild, emacs-$(emacs-version), static, \ --without-all --without-x \ @@ -483,15 +506,28 @@ $(ibidir)/expat-$(expat-version): echo "Expat $(expat-version)" > $@ $(ibidir)/fftw-$(fftw-version): - # Prepare the source tarball. - tarball=fftw-$(fftw-version).tar.gz + +# Prepare the source tarball. + tarball=fftw-$(fftw-version).tar.lz $(call import-source, $(fftw-url), $(fftw-checksum)) - # FFTW's single and double precission libraries must be built - # independently: for the the single-precision library, we need to - # add the `--enable-float' option. We will build this first, then - # the default double-precision library. - confop="--enable-shared --enable-threads --enable-avx --enable-sse2" +# FFTW's single and double precision libraries must be built +# independently: for the the single-precision library, we need to add +# the '--enable-float' option. We will build this first, then the +# default double-precision library. +# +# There are Intel-specific optimizations that can be enabled by +# adding the following two options to 'confop' +# +# --enable-avx --enable-sse2 +# +# However, they cause crashs on non-Intel processors (has been +# confirmed in ARM's aarch64). So in the generic scenario they are +# removed. Checking how these optimizations affect the numeric +# accuracy of the result (and thus optionally adding them for +# Intel-based processors) should be studied before they are +# optionally added for Intel-based CPUs (and ignored for others). + confop="--enable-shared --enable-threads" $(call gbuild, fftw-$(fftw-version), static, \ $$confop --enable-float) $(call gbuild, fftw-$(fftw-version), static, \ @@ -500,19 +536,25 @@ $(ibidir)/fftw-$(fftw-version): echo "FFTW $(fftw-version) \citep{fftw}" > $@ $(ibidir)/freetype-$(freetype-version): $(ibidir)/libpng-$(libpng-version) - tarball=freetype-$(freetype-version).tar.gz +# As of version 2.13.2, FreeType doesn't account for the 'SHELL' +# environment variable. The issue has been reported to the +# developers. But until future versions, the work-around was +# discoverd to be setting the 'GNUMAKE' environment variable so it +# includes 'SHELL'. + export GNUMAKE="$(makewshell)" + tarball=freetype-$(freetype-version).tar.lz $(call import-source, $(freetype-url), $(freetype-checksum)) $(call gbuild, freetype-$(freetype-version), static) echo "FreeType $(freetype-version)" > $@ $(ibidir)/gperf-$(gperf-version): - tarball=gperf-$(gperf-version).tar.gz + tarball=gperf-$(gperf-version).tar.lz $(call import-source, $(gperf-url), $(gperf-checksum)) $(call gbuild, gperf-$(gperf-version), static) echo "GNU gperf $(gperf-version)" > $@ $(ibidir)/gsl-$(gsl-version): - tarball=gsl-$(gsl-version).tar.gz + tarball=gsl-$(gsl-version).tar.lz $(call import-source, $(gsl-url), $(gsl-checksum)) $(call gbuild, gsl-$(gsl-version), static) echo "GNU Scientific Library $(gsl-version)" > $@ @@ -520,7 +562,7 @@ $(ibidir)/gsl-$(gsl-version): $(ibidir)/hdf5-$(hdf5-version): $(ibidir)/openmpi-$(openmpi-version) export CC=mpicc export FC=mpif90 - tarball=hdf5-$(hdf5-version).tar.gz + tarball=hdf5-$(hdf5-version).tar.lz $(call import-source, $(hdf5-url), $(hdf5-checksum)) $(call gbuild, hdf5-$(hdf5-version), static, \ --enable-parallel \ @@ -531,14 +573,14 @@ $(ibidir)/hdf5-$(hdf5-version): $(ibidir)/openmpi-$(openmpi-version) # HEALPix includes the source of its C, C++, Python (and several other # languages) libraries within one tarball. We will include the Python # installation only when any other Python module is requested (in -# `TARGETS.conf'). +# 'TARGETS.conf'). # -# Note that the default `./configure' script is an interactive script which -# is hard to automate. So we need to go into the `autotools' directory of -# the `C' and `cxx' directories and configure the GNU Build System (with -# `autoreconf', which uses `autoconf' and `automake') to easily build the +# Note that the default './configure' script is an interactive script which +# is hard to automate. So we need to go into the 'autotools' directory of +# the 'C' and 'cxx' directories and configure the GNU Build System (with +# 'autoreconf', which uses 'autoconf' and 'automake') to easily build the # HEALPix C/C++ libraries in batch mode. -ifeq ($(strip $(top-level-python)),) +ifeq ($(strip $(targets-python)),) healpix-python-dep = else healpix-python-dep = $(ipydir)/matplotlib-$(matplotlib-version) \ @@ -548,7 +590,7 @@ $(ibidir)/healpix-$(healpix-version): $(healpix-python-dep) \ $(ibidir)/cfitsio-$(cfitsio-version) \ $(ibidir)/autoconf-$(autoconf-version) \ $(ibidir)/automake-$(automake-version) - tarball=healpix-$(healpix-version).tar.gz + tarball=healpix-$(healpix-version).tar.lz $(call import-source, $(healpix-url), $(healpix-checksum)) if [ x"$(healpix-python-dep)" = x ]; then pycommand1="echo no-healpy-because-no-other-python" @@ -559,8 +601,10 @@ $(ibidir)/healpix-$(healpix-version): $(healpix-python-dep) \ fi rm -rf $(ddir)/Healpix_$(healpix-version) topdir=$(pwd); cd $(ddir); - tar xf $(tdir)/$$tarball - cd Healpix_$(healpix-version)/src/C/autotools/ + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd Healpix_$(healpix-version) + $(shsrcdir)/prep-source.sh $(ibdir) + cd src/C/autotools autoreconf --install ./configure --prefix=$(idir) make V=1 -j$(numthreads) SHELL=$(ibdir)/bash @@ -568,6 +612,13 @@ $(ibidir)/healpix-$(healpix-version): $(healpix-python-dep) \ cd ../../cxx/autotools/ autoreconf --install ./configure --prefix=$(idir) + +# With CFITSIO 4.0, the 'CFITSIO_VERSION' macro has three +# components. But this version of Healpix doesn't yet account for +# this. + sed -i -e's/CFITSIO_VERSION/fitsversion/' cxxsupport/fitshandle.cc + +# Continue with the building. make V=1 -j$(numthreads) SHELL=$(ibdir)/bash make install cd ../../healpy @@ -578,19 +629,52 @@ $(ibidir)/healpix-$(healpix-version): $(healpix-python-dep) \ cp $(dtexdir)/healpix.tex $(ictdir)/ echo "HEALPix $(healpix-version) \citep{healpix}" > $@ +$(ibidir)/libbsd-$(libbsd-version): $(ibidir)/libmd-$(libmd-version) + tarball=libbsd-$(libbsd-version).tar.lz + $(call import-source, $(libbsd-url), $(libbsd-checksum)) + if [ x$(on_mac_os) = xyes ]; then + echo "" > $@ + else + export LDFLAGS="-L$(idirlibmd)/lib $$LDFLAGS" + export CPPFLAGS="-I$(idirlibmd)/include $$CPPFLAGS" + $(call gbuild, libbsd-$(libbsd-version), static,,V=1) + echo "Libbsd $(libbsd-version)" > $@ + fi + $(ibidir)/libidn-$(libidn-version): - tarball=libidn-$(libidn-version).tar.gz + tarball=libidn-$(libidn-version).tar.lz $(call import-source, $(libidn-url), $(libidn-checksum)) $(call gbuild, libidn-$(libidn-version), static, \ --disable-doc, -j$(numthreads) V=1) echo "Libidn $(libidn-version)" > $@ $(ibidir)/libjpeg-$(libjpeg-version): - tarball=jpegsrc.$(libjpeg-version).tar.gz + tarball=libjpeg-$(libjpeg-version).tar.lz $(call import-source, $(libjpeg-url), $(libjpeg-checksum)) - $(call gbuild, jpeg-9b, static,,V=1) + $(call gbuild, libjpeg-$(libjpeg-version), static,,V=1) echo "Libjpeg $(libjpeg-version)" > $@ +# libmd is a set of "message digest" functions that are available in in the +# C library of BSD-based systems, but not others (like GNU-based +# systems). It includes hash functions like MD5 and SHAs. +# +# Libmd is being installed in a non-standard location because its headers +# (like 'md5.h') will conflict with similarly named headers by the system +# during the building of Binutils later! So any program that needs libmd's +# headers or libraries (like 'libbsd'), should add this special location to +# its CPPFLAGS and LDFLAGS. +idirlibmd=$(idircustom)/libmd +$(ibidir)/libmd-$(libmd-version): | $(idircustom) + tarball=libmd-$(libmd-version).tar.lz + $(call import-source, $(libmd-url), $(libmd-checksum)) + if [ x$(on_mac_os) = xyes ]; then + echo "" > $@ + else + export gbuild_prefix=$(idirlibmd) + $(call gbuild, libmd-$(libmd-version), static,,V=1) + echo "Libmd $(libmd-version)" > $@ + fi + $(ibidir)/libnsl-$(libnsl-version): \ $(ibidir)/libtirpc-$(libtirpc-version) \ $(ibidir)/rpcsvc-proto-$(rpcsvc-proto-version) @@ -603,15 +687,16 @@ $(ibidir)/libnsl-$(libnsl-version): \ $(ibidir)/libpaper-$(libpaper-version): \ $(ibidir)/automake-$(automake-version) - # Download the tarball. - tarball=libpaper-$(libpaper-version).tar.gz +# Download the tarball. + tarball=libpaper-$(libpaper-version).tar.lz $(call import-source, $(libpaper-url), $(libpaper-checksum)) - # Unpack, build the configure system, build and install. +# Unpack, build the configure system, build and install. cd $(ddir) - tar -xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions unpackdir=libpaper-$(libpaper-version) cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) autoreconf -fi ./configure --prefix=$(idir) --sysconfdir=$(idir)/etc \ --disable-static @@ -620,10 +705,10 @@ $(ibidir)/libpaper-$(libpaper-version): \ cd .. rm -rf $$unpackdir - # Post-processing: according to Linux From Scratch, libpaper - # expects that packages will install files into this directory and - # 'paperconfig' is a script which will invoke 'run-parts' if - # '/etc/libpaper.d' exists +# Post-processing: according to Linux From Scratch, libpaper expects +# that packages will install files into this directory and +# 'paperconfig' is a script which will invoke 'run-parts' if +# '/etc/libpaper.d' exists mkdir -vp $(idir)/etc/libpaper.d sed -e's|MANEAGESHELL|$(SHELL)|' $(shsrcdir)/run-parts.in \ > $(ibdir)/run-parts @@ -631,15 +716,19 @@ $(ibidir)/libpaper-$(libpaper-version): \ echo "Libpaper $(libpaper-version)" > $@ $(ibidir)/libpng-$(libpng-version): - tarball=libpng-$(libpng-version).tar.xz + +# The option '-DPNG_ARM_NEON_OPT=0' prevents an arm64 'neon' library +# from being required at compile time. + tarball=libpng-$(libpng-version).tar.lz $(call import-source, $(libpng-url), $(libpng-checksum)) - $(call gbuild, libpng-$(libpng-version), static) + $(call gbuild, libpng-$(libpng-version), static, \ + CFLAGS="-DPNG_ARM_NEON_OPT=0") echo "Libpng $(libpng-version)" > $@ $(ibidir)/libtiff-$(libtiff-version): $(ibidir)/libjpeg-$(libjpeg-version) - tarball=tiff-$(libtiff-version).tar.gz + tarball=libtiff-$(libtiff-version).tar.lz $(call import-source, $(libtiff-url), $(libtiff-checksum)) - $(call gbuild, tiff-$(libtiff-version), static, \ + $(call gbuild, libtiff-$(libtiff-version), static, \ --disable-jbig \ --disable-webp \ --disable-zstd) @@ -652,21 +741,119 @@ $(ibidir)/libtirpc-$(libtirpc-version): --disable-gssapi, V=1) echo "libtirpc $(libtirpc-version)" > $@ +# Metastore is used (through a Git hook) to restore the source modification +# dates of files after a Git checkout. Another Git hook saves all file +# metadata just before a commit (to allow restoration after a +# checkout). Since this project is managed in Makefiles, file modification +# dates are critical to not having to redo the whole analysis after +# checking out between branches. +# +# Note that we aren't using the standard version of Metastore, but a fork +# of it that is maintained in this repository: +# https://gitlab.com/makhlaghi/metastore-fork +# +# Libbsd is not necessary on macOS systems, because macOS is already a +# BSD-based distribution. But on GNU/Linux systems, it is necessary. +$(ibidir)/metastore-$(metastore-version): \ + $(ibidir)/libbsd-$(libbsd-version) + +# Download the tarball. + tarball=metastore-$(metastore-version).tar.lz + $(call import-source, $(metastore-url), $(metastore-checksum)) + +# Metastore doesn't have any './configure' script. So we'll just call +# 'pwd' as a place-holder for the './configure' command. +# +# File attributes are also not available on some systems, since the +# main purpose here is modification dates (and not attributes), we'll +# also set the 'NO_XATTR' flag. +# +# After installing Metastore, write the relevant hooks into this +# system's Git hooks, while setting the system-specific +# directories/files. +# +# Note that the metastore -O and -G options used in this template are +# currently only available in a fork of 'metastore' hosted at: +# https://github.com/mohammad-akhlaghi/metastore +# +# Checking for presence of '.git'. When the project source is +# downloaded from a non-Git source (for example from arXiv), there is +# no '.git' directory to work with. So until we find a better +# solution, avoid the step to to add the Git hooks. + current_dir=$$(pwd); \ + $(call gbuild, metastore-$(metastore-version), static,, \ + NO_XATTR=1 V=1,,pwd,PREFIX=$(idir)) + +# Correct RPATH when necessary. + if [ -f $(ibdir)/patchelf ]; then + $(ibdir)/patchelf --set-rpath $(ildir) $(ibdir)/metastore + fi + +# If this project is being built in a directory version controlled +# by Git, copy the hooks into the Git configuation. + if [ -f $(ibdir)/metastore ]; then + if [ -d .git ]; then + user=$$(whoami) + group=$$(groups | awk '{print $$1}') + cd $$current_dir + for f in pre-commit post-checkout; do + sed -e's|@USER[@]|'$$user'|g' \ + -e's|@GROUP[@]|'$$group'|g' \ + -e's|@BINDIR[@]|$(ibdir)|g' \ + -e's|@TOP_PROJECT_DIR[@]|'$$current_dir'|g' \ + reproduce/software/shell/git-$$f > .git/hooks/$$f + chmod +x .git/hooks/$$f + done + fi + echo "Metastore (forked) $(metastore-version)" > $@ + else + echo; echo; echo + echo "*****************" + echo "metastore couldn't be installed!" + echo + echo "Its used for preserving timestamps on Git commits." + echo "Its useful for development, not simple running of " + echo "the project. So we won't stop the configuration " + echo "because it wasn't built." + echo "*****************" + echo "" > $@ + fi + +# The Ninja build system (https://ninja-build.org) is also known as simply +# "Ninja". But other package managers (for example Debian) use +# "ninja-build" (the old "ninja" name has become obsolete there). Also, +# their own URL is called "ninja-build". So we use the same convention in +# Maneage. +$(ibidir)/ninjabuild-$(ninjabuild-version): $(ibidir)/cmake-$(cmake-version) + tarball=ninjabuild-$(ninjabuild-version).tar.lz + $(call import-source, $(ninjabuild-url), $(ninjabuild-checksum)) + cd $(ddir) + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd ninjabuild-$(ninjabuild-version) + cmake -Bbuild-cmake + cmake --build build-cmake -j$(numthreads) + ./build-cmake/ninja_test + cp -pv build-cmake/ninja $(ibdir)/ + cd .. + rm -rf ninjabuild-$(ninjabuild-version) + echo "Ninja build system $(ninjabuild-version)" > $@ + $(ibidir)/openblas-$(openblas-version): - tarball=OpenBLAS-$(openblas-version).tar.gz + tarball=openblas-$(openblas-version).tar.lz $(call import-source, $(openblas-url), $(openblas-checksum)) if [ x$(on_mac_os) = xyes ]; then export CC=clang; fi cd $(ddir) - tar xf $(tdir)/$$tarball - cd OpenBLAS-$(openblas-version) + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd openblas-$(openblas-version) + $(shsrcdir)/prep-source.sh $(ibdir) make -j$(numthreads) make PREFIX=$(idir) install cd .. - rm -rf OpenBLAS-$(openblas-version) + rm -rf openblas-$(openblas-version) echo "OpenBLAS $(openblas-version)" > $@ $(ibidir)/openmpi-$(openmpi-version): - tarball=openmpi-$(openmpi-version).tar.gz + tarball=openmpi-$(openmpi-version).tar.lz $(call import-source, $(openmpi-url), $(openmpi-checksum)) $(call gbuild, openmpi-$(openmpi-version), static, \ --with-pmix=internal \ @@ -692,22 +879,22 @@ $(ibidir)/openssh-$(openssh-version): echo "OpenSSH $(openssh-version)" > $@ $(ibidir)/pixman-$(pixman-version): - tarball=pixman-$(pixman-version).tar.gz + tarball=pixman-$(pixman-version).tar.lz $(call import-source, $(pixman-url), $(pixman-checksum)) $(call gbuild, pixman-$(pixman-version), static, , \ -j$(numthreads) V=1) echo "Pixman $(pixman-version)" > $@ $(ibidir)/rpcsvc-proto-$(rpcsvc-proto-version): - # 'libintl' is installed as part of GNU Gettext in - # 'basic.mk'. rpcsvc-proto needs to link with it on macOS. +# 'libintl' is installed as part of GNU Gettext in +# 'basic.mk'. rpcsvc-proto needs to link with it on macOS. if [ x$(on_mac_os) = xyes ]; then export CC=clang export CXX=clang++ export LDFLAGS="-lintl $$LDFLAGS" fi - # Download the tarball and build rpcsvc-proto. +# Download the tarball and build rpcsvc-proto. tarball=rpcsvc-proto-$(rpcsvc-proto-version).tar.xz $(call import-source, $(rpcsvc-proto-url), $(rpcsvc-proto-checksum)) $(call gbuild, rpcsvc-proto-$(rpcsvc-proto-version), static) @@ -721,35 +908,10 @@ $(ibidir)/tides-$(tides-version): cp $(dtexdir)/tides.tex $(ictdir)/ echo "TIDES $(tides-version) \citep{tides}" > $@ -$(ibidir)/valgrind-$(valgrind-version): \ - $(ibidir)/patch-$(patch-version) \ - $(ibidir)/autoconf-$(autoconf-version) \ - $(ibidir)/automake-$(automake-version) - # Import the tarball - tarball=valgrind-$(valgrind-version).tar.bz2 +$(ibidir)/valgrind-$(valgrind-version): + tarball=valgrind-$(valgrind-version).tar.lz $(call import-source, $(valgrind-url), $(valgrind-checksum)) - - # For valgrind-3.15.0, see - # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=946329 for a - # report on an MPI-related compile bug and the two patches - # below. These two patches and `automake` should allow valgrind to - # compile with gcc-9.2.0. - cd $(ddir) - tar -xf $(tdir)/$$tarball - valgrinddir=valgrind-$(valgrind-version) - cd $${valgrinddir} - printf "valgrindir=$${valgrinddir} ; pwd = %s .\n" $$($(ibdir)/pwd) - if [ "x$(valgrind-version)" = "x3.15.0" ]; then - patch --verbose -p1 < $(patchdir)/valgrind-3.15.0-mpi-fix1.patch - patch --verbose -p1 < $(patchdir)/valgrind-3.15.0-mpi-fix2.patch - fi - autoreconf - ./configure --prefix=$(idir) - make -j$(numthreads) - if ! make check -j$(numthreads); then - echo; echo "Valgrind's 'make check' failed!"; echo - fi - make install + $(call gbuild, valgrind-$(valgrind-version), static) echo "Valgrind $(valgrind-version)" > $@ $(ibidir)/yaml-$(yaml-version): @@ -773,47 +935,55 @@ $(ibidir)/yaml-$(yaml-version): # manually. # # For example, Libgit2 page recommends doing a static build, especially for -# Mac systems (with `-DBUILD_SHARED_LIBS=OFF'): "It’s highly recommended +# Mac systems (with '-DBUILD_SHARED_LIBS=OFF'): "It’s highly recommended # that you build libgit2 as a static library for Xcode projects. This # simplifies distribution significantly, as the resolution of dynamic # libraries at runtime can be extremely problematic.". This is a major # problem we have been having so far with Mac systems: # https://libgit2.org/docs/guides/build-and-link -# On macOS system, `libgit2' complains about not finding `_iconv*' -# functions! But apparently `libgit2' has its own implementation of libiconv +# On macOS system, 'libgit2' complains about not finding '_iconv*' +# functions! But apparently 'libgit2' has its own implementation of libiconv # that it uses if it can't find libiconv on macOS. So, to fix this problem -# it is necessary to use the option `-DUSE_ICONV=OFF` in the configure step. +# it is necessary to use the option '-DUSE_ICONV=OFF' in the configure step. $(ibidir)/libgit2-$(libgit2-version): $(ibidir)/cmake-$(cmake-version) - tarball=libgit2-$(libgit2-version).tar.gz + tarball=libgit2-$(libgit2-version).tar.lz $(call import-source, $(libgit2-url), $(libgit2-checksum)) $(call cbuild, libgit2-$(libgit2-version), static, \ -DUSE_SSH=OFF -DBUILD_CLAR=OFF \ -DTHREADSAFE=ON -DUSE_ICONV=OFF ) if [ x$(on_mac_os) = xyes ]; then - install_name_tool -id $(ildir)/libgit2.1.0.dylib \ - $(ildir)/libgit2.1.0.dylib + install_name_tool -id $(ildir)/libgit2.1.9.dylib \ + $(ildir)/libgit2.1.9.dylib fi echo "Libgit2 $(libgit2-version)" > $@ $(ibidir)/wcslib-$(wcslib-version): $(ibidir)/cfitsio-$(cfitsio-version) - # Import the tarball. - tarball=wcslib-$(wcslib-version).tar.bz2 - $(call import-source, $(wcslib-url), $(wcslib-checksum)) - # If Fortran isn't present, don't build WCSLIB with it. - if type gfortran &> /dev/null; then fortranopt=""; - else fortranopt="--disable-fortran" - fi +# Import the tarball. + tarball=wcslib-$(wcslib-version).tar.lz + $(call import-source, $(wcslib-url), $(wcslib-checksum)) - # Build WCSLIB. +# Build WCSLIB while disabling some features: +# - Fortran is disabled because as of May 2023, on macOS systems +# where we do not install GCC (and thus a standard 'gfortran'), the +# LLVM Fortran compiler is not complete and will cause a crash. If +# you use the Fortran features of WCSLIB, feel free to remove +# '--disable-fortran', but be careful with portability on other +# systems. Hopefully some time in the future, GCC will also be +# install-able on macOS within Maneage or LLVM's 'gfortran' will +# also be complete and will not cause a crash. +# - PGPLOT is disabled because it has many manual steps in its +# installation. Therefore, we currently do not build PGPlots in +# Maneage. Once (if) it is added, we can remove '--without-pgplot'. $(call gbuild, wcslib-$(wcslib-version), , \ LIBS="-pthread -lcurl -lm" \ + --without-pgplot \ + --disable-fortran \ --with-cfitsiolib=$(ildir) \ - --with-cfitsioinc=$(idir)/include \ - --without-pgplot $$fortranopt) + --with-cfitsioinc=$(idir)/include) if [ x$(on_mac_os) = xyes ]; then - install_name_tool -id $(ildir)/libwcs.7.3.dylib \ - $(ildir)/libwcs.7.3.dylib + install_name_tool -id $(ildir)/libwcs.$(wcslib-version).dylib \ + $(ildir)/libwcs.$(wcslib-version).dylib fi echo "WCSLIB $(wcslib-version)" > $@ @@ -831,30 +1001,60 @@ $(ibidir)/wcslib-$(wcslib-version): $(ibidir)/cfitsio-$(cfitsio-version) # # Astrometry-net contains a lot of programs. We need to specify the # installation directory and the Python executable (by default it will look -# for /usr/bin/python) +# for /usr/bin/python). +# +# An optional dependency is 'netpbm' but it has many dependencies and a +# crazy build system. So, it is not in the default preprequisites. If you +# need it you can add it as a prerequisite and pray that it will work. +# +# A consequence of not having 'netpbm' is that for obtaining the +# astrometric solution of one image using 'solve-field', it is necessary to +# build a catalog of sources with image coordinates and flux (x,y,flux) in +# advance. The catalog has to be sorted by flux. Finally, when invoking +# 'solve-field', the width and heigh of the original image have to be +# provided. +# +# More explicitly, raw basic steps using Gnuastro: +# +# - Obtain a catalog with image coordinates and flux (x,y,brightness): +# $ astnoisechisel img.fits -o det.fits +# $ astsegment det.fits -o seg.fits +# $ astmkcatalog seg.fits --clumpscat --x --y --brightness -o cat-raw.fits +# +# - Sort by flux: +# $ asttable cat-raw.fits --hdu 2 --sort brightness --descending \ +# --output cat.fits +# +# - Get the x-size and y-size from the header: +# $ xsize=$(astfits img.fits --keyvalue NAXIS1 --quiet) +# $ ysize=$(astfits img.fits --keyvalue NAXIS2 --quiet) +# +# - Run 'solve-field' to obtain the astrometric solution: +# $ solve-field cat.fits --width $xsize --height $ysize [--other-parameters] $(ibidir)/astrometrynet-$(astrometrynet-version): \ $(ibidir)/gsl-$(gsl-version) \ $(ibidir)/swig-$(swig-version) \ $(ipydir)/numpy-$(numpy-version) \ $(ibidir)/cairo-$(cairo-version) \ $(ibidir)/libpng-$(libpng-version) \ - $(ibidir)/netpbm-$(netpbm-version) \ $(ibidir)/wcslib-$(wcslib-version) \ + $(ipydir)/astropy-$(astropy-version) \ $(ibidir)/cfitsio-$(cfitsio-version) \ $(ibidir)/libjpeg-$(libjpeg-version) - # Import the tarball - tarball=astrometry.net-$(astrometrynet-version).tar.gz +# Import the tarball + tarball=astrometry.net-$(astrometrynet-version).tar.lz $(call import-source, $(astrometrynet-url), $(astrometrynet-checksum)) - # We are modifying the Makefile in two steps because on Mac OS - # system we do not have `/proc/cpuinfo' nor `free'. Since this is - # only for the `report.txt', this changes do not causes problems in - # running `astrometrynet' +# We are modifying the Makefile in two steps because on Mac OS system +# we do not have '/proc/cpuinfo' nor 'free'. Since this is only for +# the 'report.txt', this changes do not causes problems in running +# 'astrometrynet' cd $(ddir) rm -rf astrometry.net-$(astrometrynet-version) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd astrometry.net-$(astrometrynet-version) + $(shsrcdir)/prep-source.sh $(ibdir) sed -e 's|cat /proc/cpuinfo|echo "Ignoring CPU info"|' \ -e 's|-free|echo "Ignoring RAM info"|' Makefile > Makefile.tmp mv Makefile.tmp Makefile @@ -874,30 +1074,26 @@ $(ibidir)/autoconf-$(autoconf-version): echo "GNU Autoconf $(autoconf-version)" > $@ $(ibidir)/automake-$(automake-version): $(ibidir)/autoconf-$(autoconf-version) - tarball=automake-$(automake-version).tar.gz + tarball=automake-$(automake-version).tar.lz $(call import-source, $(automake-url), $(automake-checksum)) $(call gbuild, automake-$(automake-version), static, ,V=1) echo "GNU Automake $(automake-version)" > $@ -$(ibidir)/bison-$(bison-version): $(ibidir)/help2man-$(help2man-version) - tarball=bison-$(bison-version).tar.lz - $(call import-source, $(bison-url), $(bison-checksum)) - $(call gbuild, bison-$(bison-version), static, ,V=1 -j$(numthreads)) - echo "GNU Bison $(bison-version)" > $@ - # cdsclient is a set of software written in c to interact with astronomical -# database servers. It is a dependency of `scamp' to be able to download +# database servers. It is a dependency of 'scamp' to be able to download # reference catalogues. -# NOTE: we do not use a convencional `gbuild' installation because the +# +# NOTE: we do not use a convencional 'gbuild' installation because the # programs are scripts and we need to touch them before installing. # Otherwise this software will be re-built each time the configure step is # invoked. $(ibidir)/cdsclient-$(cdsclient-version): - tarball=cdsclient-$(cdsclient-version).tar.gz + tarball=cdsclient-$(cdsclient-version).tar.lz $(call import-source, $(cdsclient-url), $(cdsclient-checksum)) cd $(ddir) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd cdsclient-$(cdsclient-version) + $(shsrcdir)/prep-source.sh $(ibdir) touch * ./configure --prefix=$(idir) make @@ -906,31 +1102,47 @@ $(ibidir)/cdsclient-$(cdsclient-version): rm -rf cdsclient-$(cdsclient-version) echo "cdsclient $(cdsclient-version)" > $@ -# CMake can be built with its custom `./bootstrap' script. -$(ibidir)/cmake-$(cmake-version): $(ibidir)/curl-$(curl-version) - # Import the tarball - tarball=cmake-$(cmake-version).tar.gz +# CMake can be built with its custom './bootstrap' script and has no +# dependencies beyond the basic Maneage software. +$(ibidir)/cmake-$(cmake-version): + +# Import the tarball + tarball=cmake-$(cmake-version).tar.lz $(call import-source, $(cmake-url), $(cmake-checksum)) - # After searching in `bootstrap', I couldn't find `LIBS', only - # `LDFLAGS'. So the extra libraries are being added to `LDFLAGS', - # not `LIBS'. - # - # On Mac systems, the build complains about `clang' specific - # features, so we can't use our own GCC build here. +# On Mac systems, the build complains about 'clang' specific +# features, so we can't use our own GCC build here. if [ x$(on_mac_os) = xyes ]; then export CC=clang export CXX=clang++ fi + +# CMake wants a single executable for 'MAKE', so we can't use 'make +# SHELL=$(SHELL) and we have defined this script. + export MAKE="$(makewshell)" + +# Go into the unpacked directory and prepare CMake. cd $(ddir) rm -rf cmake-$(cmake-version) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd cmake-$(cmake-version) - ./bootstrap --prefix=$(idir) --system-curl --system-zlib \ - --system-bzip2 --system-liblzma --no-qt-gui \ + $(shsrcdir)/prep-source.sh $(ibdir) + +# Bootstrap, build and install CMake: +# - With the '--no-system-libs' option, CMake builds and statically +# links all the libraries it needs. Even though some of those (like +# liblzma, libcurl, zlib or bzip2) are within Maneage, we +# discovered that CMake can get confused and use out-of-Maneage +# libraries (https://savannah.nongnu.org/bugs/?63043). + ./bootstrap --no-qt-gui \ + --prefix=$(idir) \ + --no-system-libs \ --parallel=$(numthreads) - make -j$(numthreads) LIBS="$$LIBS -lssl -lcrypto -lz" VERBOSE=1 - make install + $(makewshell) VERBOSE=1 LIBS="$$LIBS -lssl -lcrypto -lz" \ + -j$(numthreads) + $(makewshell) install + +# Clean up. cd .. rm -rf cmake-$(cmake-version) echo "CMake $(cmake-version)" > $@ @@ -938,11 +1150,15 @@ $(ibidir)/cmake-$(cmake-version): $(ibidir)/curl-$(curl-version) $(ibidir)/flex-$(flex-version): $(ibidir)/bison-$(bison-version) tarball=flex-$(flex-version).tar.lz $(call import-source, $(flex-url), $(flex-checksum)) - $(call gbuild, flex-$(flex-version), static, ,V=1 -j$(numthreads)) + $(call gbuild, flex-$(flex-version), static, \ + --with-libiconv-prefix=$(idir) \ + --with-libintl-prefix=$(idir) \ + --disable-dependency-tracking, \ + V=1 -j$(numthreads)) echo "Flex $(flex-version)" > $@ $(ibidir)/gdb-$(gdb-version): $(ibidir)/python-$(python-version) - tarball=gdb-$(gdb-version).tar.gz + tarball=gdb-$(gdb-version).tar.lz export configure_in_different_directory=1; $(call import-source, $(gdb-url), $(gdb-checksum)) $(call gbuild, gdb-$(gdb-version),,,V=1 -j$(numthreads)) @@ -956,49 +1172,54 @@ $(ibidir)/ghostscript-$(ghostscript-version): \ $(ibidir)/libtiff-$(libtiff-version) \ $(ibidir)/libpaper-$(libpaper-version) - # Download the standard collection of Ghostscript fonts. - tarball=ghostscript-fonts-std-$(ghostscript-fonts-std-version).tar.gz +# Download the standard collection of Ghostscript fonts. + tarball=ghostscript-fonts-std-$(ghostscript-fonts-std-version).tar.lz $(call import-source, $(ghostscript-fonts-std-url), \ $(ghostscript-fonts-std-checksum)) - # Download the extra GNU fonts for Ghostscript. - tarball=ghostscript-fonts-gnu-$(ghostscript-fonts-gnu-version).tar.gz +# Download the extra GNU fonts for Ghostscript. + tarball=ghostscript-fonts-gnu-$(ghostscript-fonts-gnu-version).tar.lz $(call import-source, $(ghostscript-fonts-gnu-url), \ $(ghostscript-fonts-gnu-checksum)) - # Download the tarball - tarball=ghostscript-$(ghostscript-version).tar.gz +# Download the tarball + tarball=ghostscript-$(ghostscript-version).tar.lz $(call import-source, $(ghostscript-url), $(ghostscript-checksum)) - # Unpack it and configure Ghostscript. +# Unpack it and configure Ghostscript. The option +# '-DPNG_ARM_NEON_OPT=0' prevents an arm64 'neon' library from being +# required at compile time. cd $(ddir) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd ghostscript-$(ghostscript-version) + $(shsrcdir)/prep-source.sh $(ibdir) ./configure --prefix=$(idir) \ --disable-cups \ --enable-dynamic \ - --with-system-libtiff \ - --disable-compile-inits + --disable-compile-inits \ + --disable-hidden-visibility \ + CFLAGS="-DPNG_ARM_NEON_OPT=0" \ + LDFLAGS=-Wl,--copy-dt-needed-entries - # Build and install the program and the shared libraries. +# Build and install the program and the shared libraries. make V=1 -j$(numthreads) make so V=1 -j$(numthreads) make install make soinstall - # Install headers and set PostScript (PS) headers to point there. +# Install headers and set PostScript (PS) headers to point there. install -v -m644 base/*.h $(iidir)/ghostscript ln -sfvn $(iidir)/ghostscript $(iidir)/ps - # Install the fonts. - tar -xvf $(tdir)/ghostscript-fonts-std-$(ghostscript-fonts-std-version).tar.gz \ - -C $(idir)/share/ghostscript - tar -xvf $(tdir)/ghostscript-fonts-gnu-$(ghostscript-fonts-gnu-version).tar.gz \ - -C $(idir)/share/ghostscript +# Install the fonts. + tar -xvf $(tdir)/ghostscript-fonts-std-$(ghostscript-fonts-std-version).tar.lz \ + -C $(idir)/share/ghostscript --no-same-owner --no-same-permissions + tar -xvf $(tdir)/ghostscript-fonts-gnu-$(ghostscript-fonts-gnu-version).tar.lz \ + -C $(idir)/share/ghostscript --no-same-owner --no-same-permissions fc-cache -v $(idir)/share/ghostscript/fonts/ echo; echo "Ghostscript fonts added to Fontconfig."; echo; - # Clean up and write the output target. +# Clean up and write the output target. cd .. rm -rf ghostscript-$(ghostscript-version) echo "GPL Ghostscript $(ghostscript-version)" > $@ @@ -1017,64 +1238,106 @@ $(ibidir)/gnuastro-$(gnuastro-version): \ cp $(dtexdir)/gnuastro.tex $(ictdir)/ echo "GNU Astronomy Utilities $(gnuastro-version) \citep{gnuastro}" > $@ -$(ibidir)/help2man-$(help2man-version): - tarball=help2man-$(help2man-version).tar.xz - $(call import-source, $(help2man-url), $(help2man-checksum)) - $(call gbuild, help2man-$(help2man-version), static, ,V=1) - echo "Help2man $(Help2man-version)" > $@ +$(ibidir)/icu-$(icu-version): $(ibidir)/python-$(python-version) + +# First, we need to remove any possibly existing ICU installation +# because it can cause conflicts during a new configuration +# (especially if a new version is to replace the old one). + for i in data i18n io test tu uc; do + rm -fv $(ildir)/libicu$$i.*; + done + +# Prepare the tarball, unpack, build and install ICU (some +# customizations are necessary, so we're not using 'gbuild'). + tarball=icu-$(icu-version).tar.lz + $(call import-source, $(icu-url), $(icu-checksum)) + cd $(ddir) + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + unpackdir=icu-$(icu-version) + cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) + cd icu4c/source + ./configure --enable-static --prefix=$(idir) + make -j$(numthreads) V=1 + make install + cd $(ddir) + rm -rf $$unpackdir + echo "ICU $(icu-version)" > $@ $(ibidir)/imagemagick-$(imagemagick-version): \ $(ibidir)/zlib-$(zlib-version) \ $(ibidir)/libjpeg-$(libjpeg-version) \ - $(ibidir)/libtiff-$(libtiff-version) - tarball=imagemagick-$(imagemagick-version).tar.xz + $(ibidir)/libtiff-$(libtiff-version) \ + $(ibidir)/ghostscript-$(ghostscript-version) + tarball=ImageMagick-$(imagemagick-version).tar.lz $(call import-source, $(imagemagick-url), $(imagemagick-checksum)) $(call gbuild, ImageMagick-$(imagemagick-version), static, \ - --without-x --disable-openmp, V=1 -j$(numthreads)) + --without-x \ + --with-gslib \ + --disable-openmp \ + --with-libstdc=$(ildir), \ + V=1 -j$(numthreads)) + +# On macOS, an executable and several libraries are not properly +# linked with the Ghostscript library (libgs), so we need to fix it +# manually. + if [ x$(on_mac_os) = xyes ]; then + gsversion=$$(echo $(ghostscript-version) \ + | awk -F'.' '{print $$1"."$$2}') + libMagicks=$$(ls -l $(ildir)/libMagick*.dylib \ + | awk '/^-/{print $$NF}') + libMagicks_all="$(ibdir)/magick $$libMagicks" + for f in $$libMagicks_all; do \ + install_name_tool -change libgs.dylib.$$gsversion \ + $(ildir)/libgs.dylib.$$gsversion $$f; done + fi echo "ImageMagick $(imagemagick-version)" > $@ -# `imfit' doesn't use the traditional `configure' and `make' to install -# itself. Instead of that, it uses `scons'. As a consequence, the +# 'imfit' doesn't use the traditional 'configure' and 'make' to install +# itself. Instead of that, it uses 'scons'. As a consequence, the # installation is manually done by decompressing the tarball, and running -# `scons' with the necessary flags. Despite of that, it is necessary to +# 'scons' with the necessary flags. Despite of that, it is necessary to # replace the default searching paths in this script by our installation -# paths. This is done with `sed', replacing each ocurrence of `/usr/local' -# by `$(idir)'. After that, each compiled program (`imfit', `imfit-mcmc' -# and `makeimage') is copied into the installation directory and an `rpath' +# paths. This is done with 'sed', replacing each ocurrence of '/usr/local' +# by '$(idir)'. After that, each compiled program ('imfit', 'imfit-mcmc' +# and 'makeimage') is copied into the installation directory and an 'rpath' # is added. $(ibidir)/imfit-$(imfit-version): \ $(ibidir)/gsl-$(gsl-version) \ $(ibidir)/fftw-$(fftw-version) \ $(ibidir)/scons-$(scons-version) \ $(ibidir)/cfitsio-$(cfitsio-version) + +# Prepare the source. tarball=imfit-$(imfit-version).tar.gz $(call import-source, $(imfit-url), $(imfit-checksum)) - # If the C library is in a non-standard location. +# If the C library is in a non-standard location. if ! [ x$(SYS_CPATH) = x ]; then headerpath="--header-path=$(SYS_CPATH)" fi - # Unpack and build imfit and its accompanying programs. +# Unpack and build imfit and its accompanying programs. cd $(ddir) unpackdir=imfit-$(imfit-version) rm -rf $$unpackdir - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) sed -i 's|/usr/local|$(idir)|g' SConstruct sed -i 's|/usr/include|$(idir)/include|g' SConstruct sed -i 's|.append(|.insert(0,|g' SConstruct - scons --no-openmp --no-nlopt \ + scons --no-openmp --no-nlopt \ --cc=$(ibdir)/gcc --cpp=$(ibdir)/g++ \ --header-path=$(idir)/include $$headerpath \ --lib-path=$(idir)/lib imfit cp imfit $(ibdir) - scons --no-openmp --no-nlopt \ + scons --no-openmp --no-nlopt \ --cc=$(ibdir)/gcc --cpp=$(ibdir)/g++ \ --header-path=$(idir)/include $$headerpath \ --lib-path=$(idir)/lib imfit-mcmc cp imfit-mcmc $(ibdir) - scons --no-openmp --no-nlopt \ + scons --no-openmp --no-nlopt \ --cc=$(ibdir)/gcc --cpp=$(ibdir)/g++ \ --header-path=$(idir)/include $$headerpath \ --lib-path=$(idir)/lib makeimage @@ -1086,6 +1349,8 @@ $(ibidir)/imfit-$(imfit-version): \ done fi cp $(dtexdir)/imfit.tex $(ictdir)/ + cd .. + rm -rf $$unpackdir echo "Imfit $(imfit-version) \citep{imfit2015}" > $@ # Minizip 1.x is actually distributed within zlib. It doesn't have its own @@ -1098,14 +1363,16 @@ $(ibidir)/imfit-$(imfit-version): \ # About deleting the final crypt.h file after installation, see # https://bugzilla.redhat.com/show_bug.cgi?id=1424609 $(ibidir)/minizip-$(minizip-version): $(ibidir)/automake-$(automake-version) - tarball=zlib-$(zlib-version).tar.gz - $(call import-source, $(minizip-url), $(minizip-checksum)) + tarball=zlib-$(zlib-version).tar.lz + $(call import-source, $(zlib-url), $(zlib-checksum)) cd $(ddir) unpackdir=minizip-$(minizip-version) rm -rf $$unpackdir mkdir $$unpackdir - tar xf $(tdir)/$$tarball -C$$unpackdir --strip-components=1 + tar -xf $(tdir)/$$tarball -C$$unpackdir --strip-components=1 \ + --no-same-owner --no-same-permissions cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) ./configure --prefix=$(idir) make cd contrib/minizip @@ -1138,29 +1405,50 @@ $(ibidir)/missfits-$(missfits-version): cp $(dtexdir)/missfits.tex $(ictdir)/ echo "MissFITS $(missfits-version) \citep{missfits}" > $@ -# Netpbm is a prerequisite of Astrometry-net, it contains a lot of programs. -# This program has a crazy dialogue installation which is override using the -# printf statment. Each `\n' is a new question that the installation process -# ask to the user. We give all answers with a pipe to the scripts (configure -# and install). The questions are different depending on the system (tested -# on GNU/Linux and Mac OS). +# Netpbm is an optional prerequisite of Astrometry-net, it contains a lot +# of programs. This program has a crazy dialogue installation which is +# override using the printf statment. Each '\n' is a new question that the +# installation process ask to the user. We give all answers with a pipe to +# the scripts (configure and install). The questions are different +# depending on the system (tested on GNU/Linux and Mac OS). $(ibidir)/netpbm-$(netpbm-version): \ + $(ibidir)/flex-$(flex-version) \ $(ibidir)/libpng-$(libpng-version) \ + $(ibidir)/libx11-$(libx11-version) \ $(ibidir)/libjpeg-$(libjpeg-version) \ $(ibidir)/libtiff-$(libtiff-version) \ $(ibidir)/libxml2-$(libxml2-version) - tarball=netpbm-$(netpbm-version).tar.gz + tarball=netpbm-$(netpbm-version).tar.lz $(call import-source, $(netpbm-url), $(netpbm-checksum)) + +# Answers to the configuration questions. if [ x$(on_mac_os) = xyes ]; then answers='\n\n$(ildir)\n\n\n\n\n\n$(ildir)/include\n\n$(ildir)/include\n\n$(ildir)/include\nnone\n\n' else answers='\n\n\n\n\n\n\n\n\n\n\n\n\nnone\n\n\n' fi + +# Go into the temporary directory and unpack the tarball. cd $(ddir) unpackdir=netpbm-$(netpbm-version) rm -rf $$unpackdir - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) + +# As of NetPBM 10.73.39 and Flex 2.6.4-410-74a89fd (commit 74a89fd in +# Flex's Git that is 410 commits after version 2.6.4), there is the +# following line: 'if (0) yyunput(0, NULL);'. It will cause a crash +# and is just to avoid compiler warnings! So we are setting the +# 'yyunput(0, NULL);' to the redundant 'yyunput(0, NULL);' to let the +# compilation finish! + awk '$$1=="if" && $$2=="(0)"{inif=1} \ + {if(inif==1 && $$1=="yyunput(0,") \ + print "{int a=1;}"; else print $$0}' \ + converter/pbm/thinkjettopbm.l > thinkjettopbm.tmp + mv thinkjettopbm.tmp converter/pbm/thinkjettopbm.l + +# Pass the answers to the configure script then build and install it. printf "$$answers" | ./configure make rm -rf $(ddir)/$$unpackdir/install @@ -1189,60 +1477,43 @@ $(ibidir)/pcre-$(pcre-version): , V=1 -j$(numthreads)) echo "Perl Compatible Regular Expressions $(pcre-version)" > $@ -# Comment on building R without GUI support ('--without-tcltlk') +# On macOS 12.3 Monterey with AppleClang 13.1.6.13160021, Plplot 5.15.0 +# needs the 'finite' function of 'math.h' which has been deprecated in +# macOS. By manually adding "#define finite isfinite" in 'math.h' like +# below, we fixed this problem but still it can't find 'exit' during the +# configuration phase so we stopped trying to port it to macOS. It means +# that on macOS Plplot is not available. For other OSs it should be fine. +# On macOS, the file 'tmath.h' can be found with 'xcrun --show-sdk-path'. # -# Tcl/Tk are a set of tools to provide Graphic User Interface (GUI) support -# in some software. But they are not yet natively built within Maneage, -# primarily because we have higher-priority work right now (if anyone is -# interested, they can ofcourse contribute!). GUI tools in general aren't -# high on our priority list right now because they are generally good for -# human interaction (which is contrary to the reproducible philosophy: -# there will always be human-error and frustration, for example in GUI -# tools the best level of reproducibility is statements like this: "move -# your mouse to button XXX, then click on menu YYY and etc"). A robust -# reproducible solution must be done automatically. -# -# If someone wants to use R's GUI functionalities while investigating for -# their analysis, they can do the GUI part on their host OS -# implementation. Later, they can bring the finalized source into Maneage -# to be automatically run in Maneage. This will also be the recommended way -# to deal with GUI tools later when we do install them within Maneage. -$(ibidir)/R-$(R-version): \ - $(ibidir)/pcre-$(pcre-version) \ - $(ibidir)/cairo-$(cairo-version) \ - $(ibidir)/libpng-$(libpng-version) \ - $(ibidir)/libjpeg-$(libjpeg-version) \ - $(ibidir)/libtiff-$(libtiff-version) \ - $(ibidir)/libpaper-$(libpaper-version) - tarball=R-$(R-version).tar.gz - $(call import-source, $(R-url), $(R-checksum)) - cd $(ddir) - tar xf $(tdir)/$$tarball - cd R-$(R-version) - - # We need to manually remove the lines with '~autodetect~', they - # cause the configure script to crash in version 4.0.2. They are - # used in relation to Java, and we don't use Java anyway. - sed -i -e '/\~autodetect\~/ s/^/#/g' configure - export R_SHELL=$(SHELL) - ./configure --prefix=$(idir) \ - --without-x \ - --with-pcre1 \ - --disable-java \ - --with-readline \ - --without-tcltk \ - --disable-openmp - make -j$(numthreads) - make install - cd .. - rm -rf R-$(R-version) - echo "R $(R-version)" > $@ +# cp /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/math.h \ +# $(iidir)/math.h +# awk '{if($$0 ~ /#define isinf\(x\)/) {print "#define finite isfinite"; print $$0} else print $$0 }' \ +# $(iidir)/math.h > $(iidir)/math-tmp.h +# mv $(iidir)/math-tmp.h $(iidir)/math.h +$(ibidir)/plplot-$(plplot-version): \ + $(ibidir)/cairo-$(cairo-version) \ + $(ibidir)/freetype-$(freetype-version) + tarball=plplot-$(plplot-version).tar.lz + $(call import-source, $(plplot-url), $(plplot-checksum)) + $(call cbuild, plplot-$(plplot-version), static, \ + -DDEFAULT_NO_BINDINGS:BOOL=ON \ + -DENABLE_cxx:BOOL=ON \ + -DENABLE_fortran:BOOL=ON \ + -DDEFAULT_NO_QT_DEVICES:BOOL=ON) + echo "PLplot $(pcre-version)" > $@ # SCAMP documentation says ATLAS is a mandatory prerequisite for using # SCAMP. We have ATLAS into the project but there are some problems with the # libraries that are not yet solved. However, we tried to install it with # the option --enable-openblas and it worked (same issue happened with -# `sextractor'. +# 'sextractor'. +# +# Plplot in SCAMP cannot be built for macOS. See comments on top of Plplot. +# But if you are not using macOS and want to enable plots, follow the +# steps below: +# +# 1. Add '$(ibidir)/plplot-$(plplot-version)' to the prerequisites +# 2. Remove the option '--enable-plplot=no' from the call of 'gbuild' $(ibidir)/scamp-$(scamp-version): \ $(ibidir)/fftw-$(fftw-version) \ $(ibidir)/openblas-$(openblas-version) \ @@ -1250,7 +1521,7 @@ $(ibidir)/scamp-$(scamp-version): \ tarball=scamp-$(scamp-version).tar.lz $(call import-source, $(scamp-url), $(scamp-checksum)) - # See comment above 'missfits' for '-fcommon'. +# See comment above 'missfits' for '-fcommon'. $(call gbuild, scamp-$(scamp-version), static, \ CFLAGS="-fcommon" \ --enable-threads \ @@ -1263,48 +1534,109 @@ $(ibidir)/scamp-$(scamp-version): \ cp $(dtexdir)/scamp.tex $(ictdir)/ echo "SCAMP $(scamp-version) \citep{scamp}" > $@ -# Since `scons' doesn't use the traditional GNU installation with -# `configure' and `make' it is installed manually using `python'. +# Since 'scons' doesn't use the traditional GNU installation with 'configure' +# and 'make' it is installed manually using 'python'. After 'scons' is +# installed, there is a file, '$(ildir)/scons/SCons/Platform/posix.py', that +# contains several hard coded paths like '/usr/local'. This is bad because it +# causes later problems in the installation of other programs (e.g., 'imfit'). +# As a consequence, at the end of the installation we replace the +# '/usr/local' by the one Maneage uses: '$(idir)'. Only one of these paths +# is replaced, the first one: '/usr/local'. $(ibidir)/scons-$(scons-version): $(ibidir)/python-$(python-version) + +# Prepare the tarball tarball=scons-$(scons-version).tar.gz $(call import-source, $(scons-url), $(scons-checksum)) + +# Unpack and enter the source directory cd $(ddir) unpackdir=scons-$(scons-version) rm -rf $$unpackdir - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) + +# Unfortuantely SCons hard-codes its search PATH in its source (to +# use POSIX operating system defaults)! So the only way to modify it +# is to edit the source manually! Instead of using SED to replace a +# fixed string, we are using AWK to replace the value. This is done +# because in future versions, they may suddenly change the order, and +# the fixed string won't match with SED. But with AWK, we can be +# fully ignorant to their default value, and just change the value of +# the known variable. Some technical notes: +# - In the shell, the single quote is used to separate AWK's +# environment from the shell, we are using '\47' instead of the +# single quote. +# - In Python (the source we are editing) indentation is +# meaningful, but SPACE is a delimiter in AWK and AWK will +# remove leading/trailing SPACE from its values. So we'll +# manually inseart the necessary number of spaces before the +# modified line. + awk '{ if($$1=="env[\47ENV\47][\47PATH\47]") \ + {$$3="\47'$(ibdir)'\47"; print " "$$0} \ + else print}' engine/SCons/Platform/posix.py > posix-edited.py + mv posix-edited.py engine/SCons/Platform/posix.py + +# Install SCons python setup.py install + cd .. + rm -rf $$unpackdir echo "SCons $(scons-version)" > $@ # Sextractor crashes complaining about not linking with some ATLAS -# libraries. But we can override this issue since we have Openblas +# libraries. But we can override this issue since we have OpenBLAS # installed, it is just necessary to explicity tell sextractor to use it in # the configuration step. -# -# The '-fcommon' is a necessary C compilation flag for GCC 10 and above. It -# is necessary for astromatic libraries, otherwise their build will crash. $(ibidir)/sextractor-$(sextractor-version): \ $(ibidir)/fftw-$(fftw-version) \ $(ibidir)/openblas-$(openblas-version) +# Import the source. tarball=sextractor-$(sextractor-version).tar.lz $(call import-source, $(sextractor-url), $(sextractor-checksum)) - # See comment above 'missfits' for '-fcommon'. - $(call gbuild, sextractor-$(sextractor-version), static, \ - CFLAGS="-fcommon" \ - --enable-threads \ - --enable-openblas \ - --with-openblas-libdir=$(ildir) \ - --with-openblas-incdir=$(idir)/include) +# Unpack the tarball and enter the directory. + unpackdir=sextractor-$(sextractor-version) + cd $(ddir) + rm -rf $$unpackdir + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd $$unpackdir + +# See comment above 'missfits' for '-fcommon'. + ./configure --prefix="$(idir)" \ + CFLAGS="-fcommon" \ + --enable-threads \ + --enable-openblas \ + --libdir=$(ildir) \ + --includedir=$(iidir) \ + --with-openblas-libdir=$(ildir) \ + --with-openblas-incdir=$(iidir) + +# On macOS we need to manually change 'finite' to 'isfinite' in the +# header file 'src/levmar/compiler.h'. Until this problem is +# hopefully fixed in next releases, we are doing it manually using +# 'sed'. Consequently we are not installing it using 'gbuild'. Once +# this is fixed upstream, we can use the standard 'gbuild'. + sed -i -e's|define LM_FINITE finite |define LM_FINITE isfinite |' \ + src/levmar/compiler.h + +# Build, install and delete the temporary files. + make V=1 + make install + cd .. + rm -rf $$unpackdir + +# Make links for other possibly used names, copy citation and build +# the final target. ln -fs $(ibdir)/sex $(ibdir)/sextractor + ln -fs $(ibdir)/sex $(ibdir)/source-extractor cp $(dtexdir)/sextractor.tex $(ictdir)/ echo "SExtractor $(sextractor-version) \citep{sextractor}" > $@ $(ibidir)/swarp-$(swarp-version): $(ibidir)/fftw-$(fftw-version) - tarball=swarp-$(swarp-version).tar.gz + tarball=swarp-$(swarp-version).tar.lz $(call import-source, $(swarp-url), $(swarp-checksum)) - # See comment above 'missfits' for '-fcommon'. +# See comment above 'missfits' for '-fcommon'. $(call gbuild, swarp-$(swarp-version), static, \ CFLAGS="-fcommon" \ --enable-threads) @@ -1312,10 +1644,11 @@ $(ibidir)/swarp-$(swarp-version): $(ibidir)/fftw-$(fftw-version) echo "SWarp $(swarp-version) \citep{swarp}" > $@ $(ibidir)/swig-$(swig-version): - # Option --without-pcre was a suggestion once the configure step - # was tried and it failed. It was not recommended but it works! - # pcr is a dependency of swig - tarball=swig-$(swig-version).tar.gz + +# Option --without-pcre was a suggestion once the configure step was +# tried and it failed. It was not recommended but it works! pcr is a +# dependency of swig + tarball=swig-$(swig-version).tar.lz $(call import-source, $(swig-url), $(swig-checksum)) $(call gbuild, swig-$(swig-version), static, \ --without-pcre --without-tcl) @@ -1331,6 +1664,14 @@ $(ibidir)/swig-$(swig-version): # --disable-mount # --disable-wall # --disable-su +# Because they fail on older kernels (tested on Linux 2.6.32) +# and they need root (to actually use; so are not relevant to +# Maneage): +# --disable-swapon +# --disable-unshare +# --disable-libmount +# --disable-mountpoint +# --enable-libmount-support-mtab # # NOTE ON INSTALLATION DIRECTORY: Util-linux libraries are relatively # low-level and may cause conflicts with system libraries (especilly when @@ -1345,44 +1686,79 @@ $(ibidir)/swig-$(swig-version): # '$(ibdir)'. If any program does need 'util-linux' libraries, they can # simply add the proper directories to the environment variables, see # 'fontconfig' for example. -$(ibidir)/util-linux-$(util-linux-version): +$(ibidir)/util-linux-$(util-linux-version): \ + $(ibidir)/autoconf-$(autoconf-version) \ + $(ibidir)/automake-$(automake-version) \ + | $(idircustom) - # Import the source. - tarball=util-linux-$(util-linux-version).tar.xz +# Import the source. + tarball=util-linux-$(util-linux-version).tar.lz $(call import-source, $(util-linux-url), $(util-linux-checksum)) - # Unpack the source and set it to install in a special directory - # (as explained above). As shown below, later, we'll put a symbolic - # link of all the necessary binaries in the main '$(idir)/bin'. +# Unpack the source and set it to install in a special directory (as +# explained above). As shown below, later, we'll put a symbolic link +# of all the necessary binaries in the main '$(idir)/bin'. cd $(ddir) - tar xf $(tdir)/$$tarball + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions cd util-linux-$(util-linux-version) - ./configure --prefix=$(idir)/util-linux \ + $(shsrcdir)/prep-source.sh $(ibdir) + +# If a patch is necessary, apply it. + if [ -f $(patchdir)/util-linux-$(util-linux-version)-macos.patch ]; then + cp $(patchdir)/util-linux-$(util-linux-version)-macos.patch \ + util-linux-$(util-linux-version)-macos.patch + git apply util-linux-$(util-linux-version)-macos.patch + fi + +# The 'mkswap' feature needs low-level file system and kernel headers +# that are not always available (in particular on older Linux +# kernels). Also, creating SWAP space will need root permissions, so +# its not something a Maneager may need! Unfortunately there is no +# configuration option to disable this so we'll have to disable it +# manually by commenting the relevant files in the +# 'configure.ac'. + sed -e's|UL_BUILD_INIT(\[mkswap\], \[yes\])|UL_BUILD_INIT(\[mkswap\], \[no\])|' \ + -i configure.ac + +# Having updated 'configure.ac', we need to re-generate the +# './configure' script with 'autoreconf' (which is part of Autoconf +# and needs Automake; hence why they are dependencies. + autoreconf -f + +# Configure Util-linux + export CONFIG_SHELL=$(ibdir)/bash + ./configure --prefix=$(idircustom)/util-linux \ --disable-dependency-tracking \ + --enable-libmount-support-mtab \ --disable-silent-rules \ + --disable-liblastlog2 \ + --disable-mountpoint \ + --disable-libmount \ + --disable-unshare \ --without-systemd \ --enable-libuuid \ + --disable-swapon \ --disable-mount \ --disable-ipcrm \ --disable-ipcs \ --disable-wall \ --disable-su - # Build and install it. +# Build and install it. make V=1 -j$(numthreads) make install - # Put a symbolic link to installed programs in main installation - # directory. If 'sbin' exists in the main installation directory, - # put util-linux's 'sbin/' directory there too. - ln -sf $(idir)/util-linux/bin/* $(ibdir)/ +# Put a symbolic link to installed programs in main installation +# directory. If 'sbin' exists in the main installation directory, put +# util-linux's 'sbin/' directory there too. + ln -sf $(idircustom)/util-linux/bin/* $(ibdir)/ if [ -d $(idir)/sbin ]; then - ln -sf $(idir)/util-linux/sbin/* $(idir)/sbin + ln -sf $(idircustom)/util-linux/sbin/* $(idir)/sbin else - ln -sf $(idir)/util-linux/sbin/* $(idir)/bin + ln -sf $(idircustom)/util-linux/sbin/* $(idir)/bin fi - # Clean up and write the main target. +# Clean up and write the main target. cd ../ rm -rf util-linux-$(util-linux-version) echo "util-Linux $(util-linux-version)" > $@ @@ -1425,12 +1801,13 @@ $(ibidir)/xlsxio-$(xlsxio-version): \ # useful in projects during its development, for more see the comment above # GNU Emacs. $(ibidir)/vim-$(vim-version): - tarball=vim-$(vim-version).tar.bz2 + tarball=vim-$(vim-version).tar.lz $(call import-source, $(vim-url), $(vim-checksum)) cd $(ddir) - tar xf $(tdir)/$$tarball - n=$$(echo $(vim-version) | sed -e's|\.||') - cd $(ddir)/vim$$n + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + unpackdir=vim-$(vim-version) + cd $(ddir)/$$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) ./configure --prefix=$(idir) \ --disable-canberra \ --enable-multibyte \ @@ -1443,9 +1820,29 @@ $(ibidir)/vim-$(vim-version): make -j$(numthreads) make install cd .. - rm -rf vim$$n + rm -rf $$unpackdir echo "VIM $(vim-version)" > $@ +$(ibidir)/unzip-$(unzip-version): $(ibidir)/gzip-$(gzip-version) + tarball=unzip-$(unzip-version).tar.lz + $(call import-source, $(unzip-url), $(unzip-checksum)) + $(call gbuild, unzip-$(unzip-version), static,, \ + -f unix/Makefile generic \ + CFLAGS="-DBIG_MEM -DMMAP",,pwd, \ + -f unix/Makefile generic \ + BINDIR=$(ibdir) MANDIR=$(idir)/man/man1 ) + echo "Unzip $(unzip-version)" > $@ + +$(ibidir)/zip-$(zip-version): $(ibidir)/gzip-$(gzip-version) + tarball=zip-$(zip-version).tar.lz + $(call import-source, $(zip-url), $(zip-checksum)) + $(call gbuild, zip-$(zip-version), static,, \ + -f unix/Makefile generic \ + CFLAGS="-DBIG_MEM -DMMAP",,pwd, \ + -f unix/Makefile generic \ + BINDIR=$(ibdir) MANDIR=$(idir)/man/man1 ) + echo "Zip $(zip-version)" > $@ + @@ -1455,7 +1852,7 @@ $(ibidir)/vim-$(vim-version): # hard to track for Make (as a target). Also, TeX in general is optional # for the project (the processing is the main target, not the generation of # the final PDF). So we'll make a simple ASCII file called -# `texlive-ready-tlmgr' and use its contents to mark if we can use it or +# 'texlive-ready-tlmgr' and use its contents to mark if we can use it or # not. # # TeX Live mirror @@ -1463,8 +1860,8 @@ $(ibidir)/vim-$(vim-version): # # The automatic mirror finding fails sometimes. So we'll manually set it to # use a fixed mirror. I first tried the LaTeX root webpage -# (`ftp.dante.de'), however, it is far too slow (when I tested it). The -# `rit.edu' server seems to be a good alternative (given the importance of +# ('ftp.dante.de'), however, it is far too slow (when I tested it). The +# 'rit.edu' server seems to be a good alternative (given the importance of # NY on the internet infrastructure). texlive-url=http://mirrors.rit.edu/CTAN/systems/texlive/tlnet $(itidir)/texlive-ready-tlmgr: reproduce/software/config/texlive.conf @@ -1472,92 +1869,103 @@ $(itidir)/texlive-ready-tlmgr: reproduce/software/config/texlive.conf tarball=install-tl-unx.tar.gz $(call import-source, $(texlive-url), NO-CHECK-SUM) - # Unpack, enter the directory, and install based on the given - # configuration (prerequisite of this rule). +# Unpack, enter the directory, and install based on the given +# configuration (prerequisite of this rule). @topdir=$$(pwd) cd $(ddir) rm -rf install-tl-* - tar xf $(tdir)/install-tl-unx.tar.gz + tar -xf $(tdir)/install-tl-unx.tar.gz \ + --no-same-owner --no-same-permissions cd install-tl-* + $(shsrcdir)/prep-source.sh $(ibdir) sed -e's|@installdir[@]|$(idir)|g' \ "$$topdir"/reproduce/software/config/texlive.conf \ > texlive.conf - # TeX Live's installation may fail due to any reason. But TeX Live - # is optional (only necessary for building the final PDF). So we - # don't want the configure script to fail if it can't run. - # Possible error messages will be saved into `log.txt' and if it - # fails, 'log.txt' will be checked to see if the error is due to - # the different version of the current tarball and the TeXLive - # server or something else. - # - # The problem with versions is this: each installer tarball (that - # is downloaded and a user may backup) is for a specific version of - # TeXLive (specified by year, usually around April). So if a user - # has an old tarball, but the CTAN server has been updated, the - # script will fail with a message like this: - # - # ============================================================= - # ./install-tl: The TeX Live versions of the local installation - # and the repository being accessed are not compatible: - # local: 2019 - # repository: 2020 - # Perhaps you need to use a different CTAN mirror? - # (For more, see the output of install-tl --help, especially the - # -repository option. Online via https://tug.org/texlive/doc.) - # ============================================================= - # - # To address this problem, when this happens, we simply download a - # the most recent tarball, and if it succeeds, we will build - # TeXLive using that. The old tarball will be preserved, but will - # have an '-OLD' suffix after it. +# We do not build TeXLive from source and for its installation it +# downloads components from the web internally; and those components +# can use '/bin/sh' (which will need '$(sys_library_sh_path)'). + export LD_LIBRARY_PATH="$(sys_library_sh_path):$$LD_LIBRARY_PATH" + +# TeX Live's installation may fail due to any reason. But TeX Live is +# optional (only necessary for building the final PDF). So we don't +# want the configure script to fail if it can't run. Possible error +# messages will be saved into 'log.txt' and if it fails, 'log.txt' +# will be checked to see if the error is due to the different version +# of the current tarball and the TeXLive server or something else. +# +# The problem with versions is this: each installer tarball (that is +# downloaded and a user may backup) is for a specific version of +# TeXLive (specified by year, usually around April). So if a user has +# an old tarball, but the CTAN server has been updated, the script +# will fail with a message like this: +# +# ============================================================= +# ./install-tl: The TeX Live versions of the local installation +# and the repository being accessed are not compatible: +# local: 2019 +# repository: 2020 +# Perhaps you need to use a different CTAN mirror? +# (For more, see the output of install-tl --help, especially the +# -repository option. Online via https://tug.org/texlive/doc.) +# ============================================================= +# +# To address this problem, when this happens, we simply download a +# the most recent tarball, and if it succeeds, we will build TeXLive +# using that. The old tarball will be preserved, but will have an +# '-OLD' suffix after it. if ./install-tl --profile=texlive.conf -repository \ $(texlive-url) 2> log.txt; then - # Put a symbolic link of the TeX Live executables in `ibdir' to - # avoid all the complexities of its sub-directories and additions - # to PATH. +# Put a symbolic link of the TeX Live executables in 'ibdir' to +# avoid all the complexities of its sub-directories and additions +# to PATH. ln -fs $(idir)/texlive/maneage/bin/*/* $(ibdir)/ - # Register that the build was successful. +# Register that the build was successful. echo "TeX Live is ready." > $@ - # The build failed! +# The build failed! else - # Print on the command line the error messages during the - # installation. +# Print on the command line the error messages during the +# installation. cat log.txt - # Look for words `repository:' and `local:' in `log.txt' and make - # sure that two lines are returned. Note that we need to check - # for two lines because one of them may exist, but another may - # not (in this case, its not a version conflict scenario). +# Look for words 'repository:' and 'local:' in 'log.txt' and make +# sure that two lines are returned. Note that we need to check for +# two lines because one of them may exist, but another may not (in +# this case, its not a version conflict scenario). version_check=$$(grep -w 'repository:\|local:' log.txt | wc -l) - # If these words exists and two lines are found, there is a - # conflict with the main TeXLive version in the tarball and on - # the server. So it is necessary to move the old tarball and - # download the new one to install it. +# If these words exists and two lines are found, there is a +# conflict with the main TeXLive version in the tarball and on the +# server. So it is necessary to move the old tarball and download +# the new one to install it. if [ x"$$version_check" = x2 ]; then - # Go back to the top project directory, don't remove the - # tarball, just rename it. + +# Go back to the top project directory, don't remove the tarball, +# just rename it. cd $$topdir mv $(tdir)/install-tl-unx.tar.gz $(tdir)/install-tl-unx-OLD.tar.gz - # Download using the script specially defined for this job. If - # the download of new tarball success, install it (same lines - # than above). If not, record the fail into the target. +# Download using the script specially defined for this job. If +# the download of new tarball success, install it (same lines +# than above). If not, record the fail into the target. url=http://mirror.ctan.org/systems/texlive/tlnet tarballurl=$$url/install-tl-unx.tar.gz touch $(lockdir)/download downloader="wget --no-use-server-timestamps -O" - if $(downloadwrapper) "$$downloader" $(lockdir)/download \ - $$tarballurl "$(tdir)/install-tl-unx.tar.gz" \ - "$(backupservers)"; then + if $(downloadwrapper) "$$downloader" \ + $(lockdir)/download \ + $$tarballurl \ + "$(tdir)/install-tl-unx.tar.gz" \ + "$(backupservers)"; then cd $(ddir) rm -rf install-tl-* - tar xf $(tdir)/install-tl-unx.tar.gz + tar -xf $(tdir)/install-tl-unx.tar.gz \ + --no-same-owner --no-same-permissions cd install-tl-* + $(shsrcdir)/prep-source.sh $(ibdir) sed -e's|@installdir[@]|$(idir)|g' \ $$topdir/reproduce/software/config/texlive.conf \ > texlive.conf @@ -1576,7 +1984,7 @@ $(itidir)/texlive-ready-tlmgr: reproduce/software/config/texlive.conf fi fi - # Clean up +# Clean up cd .. rm -rf install-tl-* @@ -1588,51 +1996,72 @@ $(itidir)/texlive-ready-tlmgr: reproduce/software/config/texlive.conf # Live itself (only very basic TeX and LaTeX) and the installation of its # necessary packages into two packages. # -# Note that Biber needs to link with libraries like libnsl. However, we -# don't currently build biber from source. So we can't choose the library -# version. But we have the source and build instructions for the `nsl' -# library. When we later build biber from source, we can easily use them. +# Note that we do not build the TeXLive executables (like Biber) from +# source. So in case they need special libraries, we can't choose the +# library version here (for example see [1] and [2]). In such cases there +# is no solution but to manually add the location necessary library to +# LD_LIBRARY_PATH when calling the respective LaTeX command in +# 'reproduce/analysis/make/paper.mk'. Fortunately as of Biber 2.20, it does +# not depend on anything except the C library (all dependencies are now +# statically linked), so problems [1] and [2] will not happen. But this can +# generally happen for any other tool/OS, so it is important to build +# TeXLive from source as soon as possible [3]. +# [1] https://github.com/plk/biber/issues/445 +# [2] https://savannah.nongnu.org/bugs/index.php?63175 +# [3] https://savannah.nongnu.org/task/?15267 $(itidir)/texlive: reproduce/software/config/texlive-packages.conf \ $(itidir)/texlive-ready-tlmgr - # To work with TeX live installation, we'll need the internet. +# To work with TeX live installation, we'll need the internet. @res=$$(cat $(itidir)/texlive-ready-tlmgr) if [ x"$$res" = x"NOT!" ]; then echo "" > $@ else - # To update itself, tlmgr needs a backup directory. + +# We do not build TeXLive from source and for its installation it +# downloads components from the web internally; and those +# components can use '/bin/sh' (which needs 'sys_library_sh_path'). + export LD_LIBRARY_PATH="$(sys_library_sh_path)" + +# To update itself, tlmgr needs a backup directory. backupdir=$(idir)/texlive/backups mkdir -p $$backupdir - # Before checking LaTeX packages, update tlmgr itself. +# Before checking LaTeX packages, update tlmgr itself. tlmgr option backupdir $$backupdir tlmgr -repository $(texlive-url) update --self - # Install all the extra necessary packages. If LaTeX complains - # about not finding a command/file/what-ever/XXXXXX, simply run - # the following command to find which package its in, then add it - # to the `texlive-packages' variable of the first prerequisite. - # - # ./.local/bin/tlmgr info XXXXXX - # - # We are putting a notice, because if there is no internet, - # `tlmgr' just hangs waiting. +# Install all the extra necessary packages. If LaTeX complains +# about not finding a command/file/what-ever/XXXXXX, simply run the +# following command to find which package its in, then add it to +# the 'texlive-packages' variable of the first prerequisite. +# +# ./.local/bin/tlmgr info XXXXXX +# +# We are putting a notice, because if there is no internet, 'tlmgr' +# just hangs waiting. tlmgr install $(texlive-packages) - # Make a symbolic link of all the TeX Live executables in the bin - # directory so we don't have to modify `PATH'. +# Make a symbolic link of all the TeX Live executables in the bin +# directory so we don't have to modify 'PATH'. ln -fs $(idir)/texlive/maneage/bin/*/* $(ibdir)/ - # Get all the necessary versions. +# Correct any reference to '/bin/sh' within the installed LaTeX +# files (this is because we do no yet install LaTeX from source): + cdir=$$(pwd) + cd $(idir)/texlive + cd $$cdir + +# Get all the necessary versions. texlive=$$(pdflatex --version \ | awk 'NR==1' \ | sed 's/.*(\(.*\))/\1/' \ | awk '{print $$NF}'); - # Package names and versions. Note that all TeXLive packages - # don't have a version unfortunately! So we need to also read the - # `revision' and `cat-date' elements and print them incase - # version isn't available. +# Package names and versions. Note that all TeXLive packages +# don't have a version unfortunately! So we need to also read the +# 'revision' and 'cat-date' elements and print them incase +# version isn't available. tlmgr info $(texlive-packages) --only-installed | awk \ '$$1=="package:" { \ if(name!=0) \ diff --git a/reproduce/software/make/python.mk b/reproduce/software/make/python.mk index 18c68de..c994e3f 100644 --- a/reproduce/software/make/python.mk +++ b/reproduce/software/make/python.mk @@ -4,7 +4,7 @@ # !!!!! IMPORTANT NOTES !!!!! # # This Makefile will be loaded into 'high-level.mk', which is called by the -# `./project configure' script. It is not included into the project +# './project configure' script. It is not included into the project # afterwards. # # This Makefile contains instructions to build all the Python-related @@ -12,8 +12,8 @@ # # ------------------------------------------------------------------------ # -# Copyright (C) 2019-2021 Raul Infante-Sainz <infantesainz@gmail.com> -# Copyright (C) 2019-2021 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2019-2025 Raul Infante-Sainz <infantesainz@gmail.com> +# Copyright (C) 2019-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> # # This Makefile is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -35,7 +35,7 @@ # Python enviroment # ----------------- # -# The main Python environment variable is `PYTHONPATH'. However, so far we +# The main Python environment variable is 'PYTHONPATH'. However, so far we # have found several other Python-related environment variables on some # systems which might interfere. To be safe, we are removing all their # values. @@ -51,6 +51,8 @@ export MPI_PYTHON3_SITEARCH := # Python-specific installation directories. python-major-version = $(shell echo $(python-version) | awk 'BEGIN{FS="."} \ {printf "%d.%d\n", $$1, $$2}') +# This is for 'installer' (the python installer) itself: +ilibpymajorversion = $(idir)/lib/python$(python-major-version) @@ -62,19 +64,20 @@ python-major-version = $(shell echo $(python-version) | awk 'BEGIN{FS="."} \ # While this Makefile is for Python programs, in some cases, we need # certain programs (like Python itself), or libraries for the modules. $(ibidir)/libffi-$(libffi-version): - # Prepare the source. - tarball=libffi-$(libffi-version).tar.gz + +# Prepare the source. + tarball=libffi-$(libffi-version).tar.lz $(call import-source, $(libffi-url), $(libffi-checksum)) - # Build libffi. +# Build libffi. $(call gbuild, libffi-$(libffi-version), , \ CFLAGS="-DNO_JAVA_RAW_API=1") - # On some Fedora systems, libffi installs in `lib64', not - # `lib'. This will cause problems when building setuptools - # later. To fix this problem, we'll first check if this has indeed - # happened (it exists under `lib64', but not under `lib'). If so, - # we'll put a copy of the installed libffi libraries in `lib'. +# On some Fedora systems, libffi installs in 'lib64', not 'lib'. This +# will cause problems when building setuptools later. To fix this +# problem, we'll first check if this has indeed happened (it exists +# under 'lib64', but not under 'lib'). If so, we'll put a copy of the +# installed libffi libraries in 'lib'. if [ -f $(idir)/lib64/libffi.a ] && ! [ -f $(idir)/lib/libffi.a ]; then cp $(idir)/lib64/libffi* $(ildir)/ fi @@ -82,23 +85,58 @@ $(ibidir)/libffi-$(libffi-version): $(ibidir)/python-$(python-version): $(ibidir)/libffi-$(libffi-version) - # Download the source. - tarball=python-$(python-version).tar.gz +# Download the source. + tarball=python-$(python-version).tar.lz $(call import-source, $(python-url), $(python-checksum)) - # On Mac systems, the build complains about `clang' specific - # features, so we can't use our own GCC build here. +# On Mac systems, the build complains about 'clang' specific +# features, so we can't use our own GCC build here. if [ x$(on_mac_os) = xyes ]; then export CC=clang export CXX=clang++ fi - $(call gbuild, Python-$(python-version),, \ - --without-ensurepip \ - --with-system-ffi \ - --enable-shared, -j$(numthreads)) + +# Unpack the tarball (see below for the necessary modification). + cd $(ddir) + unpackdir=python-$(python-version) + tar -xf $(tdir)/$$tarball --no-same-owner --no-same-permissions + cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) + +# Python's 'setup.py' uses 'os.system' to run shell scripts. On the +# other hand 'os.system' only runs '/bin/sh' (which has its own +# libraries to link to and those are blocked at this level). So we +# need to add an extra line on top of the 'os.system' funciton and +# put '/usr/lib' in 'LD_LIBRARY_PATH' within Python's environment for +# system calls (with 'os.putenv'). As of Python 3.13.2 the tarball no +# longer has an 'setup.py'. But when it did, the change below was +# necessary. + if [ -f setup.py ]; then + awk '{if(/os.system\(/) \ + { print " os.putenv(\"LD_LIBRARY_PATH\", \"$$LD_LIBRARY_PATH:$(sys_library_sh_path)\");"; \ + print $$0;} \ + else print $$0}' \ + setup.py > setup-tmp.py + mv setup-tmp.py setup.py + fi + +# Do the basic installation and delete the temporary directory. + ./configure SHELL=$(ibdir)/bash \ + --enable-optimizations \ + --without-ensurepip \ + --prefix="$(idir)" \ + --with-system-ffi \ + --enable-shared + $(makewshell) -j$(numthreads) + $(makewshell) install -j$(numthreads) + cd .. + rm -rf $$unpackdir + +# Set the necessary environment variables and finish the build. ln -sf $(ildir)/python$(python-major-version) $(ildir)/python ln -sf $(ibdir)/python$(python-major-version) $(ibdir)/python - ln -sf $(iidir)/python$(python-major-version)m $(iidir)/python$(python-major-version) + ln -sf $(iidir)/python$(python-major-version)m \ + $(iidir)/python$(python-major-version) rm -rf $(ipydir) mkdir $(ipydir) echo "Python $(python-version)" > $@ @@ -107,39 +145,138 @@ $(ibidir)/python-$(python-version): $(ibidir)/libffi-$(libffi-version) -# Non-PiP Python module installation +# Non-pip Python module installation # ---------------------------------- # -# To build Python packages with direct access to a `setup.py' (if no direct -# access to `setup.py' is needed, pip can be used). Note that the -# software's packaged source code is the first prerequisite that is in the -# `tdir' directory. +# Build strategy for python modules as of February 2025, for python 3.13.2. + +# This strategy is mostly based on recommendations by E Schwartz +# (ztrawhcse) on #python (Libera Chat), in October 2022 and February +# 2025. Some discussions are on documented in Savannah tasks [1][2]. The +# build strategy for 'python-installer' is inspired by the gentoo script +# 'python_domodule' [3]. + +# Bootstrap-step: 'gpep517' [4], motivated by PEP 517 [5], together with +# 'python-installer' (module called 'installer') are built without +# dependences on other python packages apart from python itself. The build +# rules for these two packages do python byte compilation and copy the .py +# and .pyc files into the python install directory. These two packages are +# considered to be 'frontends'. + +# Once these two frontends are available, other packages that do building +# tasks, including both backends and alternative frontends or a mix of +# these (in particular: setuptools, meson [6]/ninja-build [7] , flit-core, +# and meson-python), can be built with the 'python-installer' and +# 'gpep517'. The aims of the various build tools are diverse, include +# ecosystem resilience, reproducibility, build speed and convenience in +# building bigger packages such as numpy, scipy and astropy. + +# The python.mk script now includes only three methods: the boot +# build methods of 'python-installer' and 'gpep517'; and the gpep517 +# frontend. No method is provided for using 'python-installer' directly; +# it is invoked indirectly by source files of many packages, which +# also give metadata describing information for build methods. + +# Why not pip? We do not build any python packages with 'pip' because we +# want to have a fully documented pipeline of (i) the original upstream +# locations of tarballs, (ii) the tarballs' checksums, and (iii) the exact +# sequence of build commands. + +# For an alternative viewpoint on a python build strategy, see [8]. + +# Prerequisite for the pybuild script here: the package's source code +# (tarball) must already be located in the directory 'tdir'. # -# Arguments of this function are the numbers +# Arguments: # 1) Unpack command # 2) Unpacked directory name after unpacking the tarball # 3) site.cfg file (optional). -# 4) Official software name (for paper). +# 4) Official software name (for paper.tex). +# 5) Obligatory parameter: build method (see below): +# BOOT_INSTALLER - only for 'python-installer' +# BOOT_GPEP517 - only for 'gpep517' +# GPEP517 - for any other python package # # Hooks: -# pyhook_before: optional steps before running `python setup.py build' -# pyhook_after: optional steps after running `python setup.py install' -pybuild = cd $(ddir); rm -rf $(2); \ - if ! $(1) $(tdir)/$$tarball; then \ +# pyhook_before: optional steps before running 'python setup.py build' +# pyhook_after: optional steps after running 'python setup.py install' + +# [1] https://savannah.nongnu.org/task/?16268 +# [2] https://savannah.nongnu.org/task/?16625 +# [3] https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/python-utils-r1.eclass#n646 +# [4] https://pypi.org/project/gpep517 +# [5] https://peps.python.org/pep-0517 +# [6] https://mesonbuild.com +# [7] https://ninja-build.org +# [8] https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html + + +pybuild = cd $(ddir); \ + packagedir=$(strip $(2)); \ + if (printf "$$packagedir" | grep "[a-z][a-z]"); then rm -rf $$packagedir; fi; \ + printf "\nStarting to install python package with maneage pybuild rule: $(4)\n ..."; \ + if ! $(1) $(tdir)/$$tarball --no-same-owner --no-same-permissions; then \ echo; echo "Tar error"; exit 1; \ fi; \ - cd $(2); \ + cd $$packagedir; \ if [ "x$(strip $(3))" != x ]; then \ sed -e 's|@LIBDIR[@]|'"$(ildir)"'|' \ -e 's|@INCDIR[@]|'"$(idir)/include"'|' \ $(3) > site.cfg; \ fi; \ if type pyhook_before &>/dev/null; then pyhook_before; fi; \ - python setup.py build; \ - python setup.py install; \ + printf "pybuild option5 = __ %s __\n" "$(strip $(5))"; \ + if [ "x$(strip $(5))" = xBOOT_INSTALLER ]; then \ + chmod 0644 src/installer/*.py; \ + mkdir -p $(ilibpymajorversion)/installer; \ + mkdir -p $(ilibpymajorversion)/installer/__pycache__ ; \ + mkdir -p $(ilibpymajorversion)/installer/_scripts; \ + mkdir -p $(ilibpymajorversion)/installer/_scripts/__pycache__ ; \ + cp -pv src/installer/*.py $(ilibpymajorversion)/installer/; \ + cp -pv src/installer/_scripts/__init__.py $(ilibpymajorversion)/installer/_scripts/; \ + cd src/installer/; \ + python -m compileall -o 1 -o 2 -l -f \ + -d $(ilibpymajorversion)/installer/ .; \ + chmod 0644 __pycache__/*.pyc; \ + cp -pv __pycache__/*.pyc \ + $(ilibpymajorversion)/installer/__pycache__; \ + cd -; \ + cd src/installer/_scripts/; \ + python -m compileall -o 1 -o 2 -l -f \ + -d $(ilibpymajorversion)/installer/_scripts/ __init__.py; \ + chmod 0644 __pycache__/*.pyc; \ + cp -pv __pycache__/*.pyc \ + $(ilibpymajorversion)/installer/_scripts/__pycache__; \ + cd -; \ + elif [ "x$(strip $(5))" = xBOOT_GPEP517 ]; then \ + chmod 0644 gpep517/*.py; \ + mkdir -p $(ilibpymajorversion)/gpep517; \ + mkdir -p $(ilibpymajorversion)/gpep517/__pycache__ ; \ + cp -pv gpep517/*.py $(ilibpymajorversion)/gpep517/; \ + cd gpep517/; \ + python -m compileall -o 1 -o 2 -l -f \ + -d $(ilibpymajorversion)/gpep517/ .; \ + chmod 0644 __pycache__/*.pyc; \ + cp -pv __pycache__/*.pyc \ + $(ilibpymajorversion)/gpep517/__pycache__; \ + cd -; \ + elif [ "x$(strip $(5))" = xGPEP517 ]; then \ + printf "\n\n\n=== python build method: gpep517 ====== "; pwd; \ + printf "...............\n\n\n"; \ + python -m gpep517 install-from-source \ + --prefix "" \ + --destdir $(idir) \ + --optimize all; \ + else \ + printf "Error: Unknown pybuild method for $$packagedir: __ $(strip $(5)) __\n"; \ + printf "The pybuild 5th parameter should very likely be set "; \ + printf "to GPEP517 after checking the build rule and "; \ + printf "upgrading if needed.\n"; \ + exit 1; \ + fi; \ if type pyhook_after &>/dev/null; then pyhook_after; fi; \ cd ..; \ - rm -rf $(2); \ + if (printf "$$packagedir" | grep "[a-z][a-z]"); then rm -fr $$packagedir; fi; \ echo "$(4)" > $@ @@ -148,18 +285,20 @@ pybuild = cd $(ddir); rm -rf $(2); \ # Python modules # --------------- -# + + # All the necessary Python modules go here. -$(ipydir)/asn1crypto-$(asn1crypto-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/asn1crypto-$(asn1crypto-version): \ + $(ipydir)/setuptools-$(setuptools-version) tarball=asn1crypto-$(asn1crypto-version).tar.gz $(call import-source, $(asn1crypto-url), $(asn1crypto-checksum)) - $(call pybuild, tar xf, asn1crypto-$(asn1crypto-version), , \ + $(call pybuild, tar -xf, asn1crypto-$(asn1crypto-version), , \ Asn1crypto $(asn1crypto-version)) $(ipydir)/asteval-$(asteval-version): $(ipydir)/numpy-$(numpy-version) tarball=asteval-$(asteval-version).tar.gz $(call import-source, $(asteval-url), $(asteval-checksum)) - $(call pybuild, tar xf, asteval-$(asteval-version), , \ + $(call pybuild, tar -xf, asteval-$(asteval-version), , \ ASTEVAL $(asteval-version)) $(ipydir)/astroquery-$(astroquery-version): \ @@ -168,96 +307,154 @@ $(ipydir)/astroquery-$(astroquery-version): \ $(ipydir)/requests-$(requests-version) tarball=astroquery-$(astroquery-version).tar.gz $(call import-source, $(astroquery-url), $(astroquery-checksum)) - $(call pybuild, tar xf, astroquery-$(astroquery-version), , \ + $(call pybuild, tar -xf, astroquery-$(astroquery-version), , \ Astroquery $(astroquery-version)) +# Astropy: points to consider about dependencies: +# +# The optional dependency 'h5py' that is necessary for writting tables in +# HDF5 format has been removed from Astropy because on macOS it cannot be +# installed. +# +# 2022-or-older dependencies: +# $(ibidir)/expat-$(expat-version) \ +# $(ipydir)/jinja2-$(jinja2-version) \ +# $(ipydir)/html5lib-$(html5lib-version) \ +# $(ipydir)/beautifulsoup4-$(beautifulsoup4-version) \ +# +# While the astropy pyproject.toml file says that the astropy build depends +# on numpy, not scipy, and does not depend on matplotlib; the +# runtime is recommended to depend on both scipy and matplotlib. +# In practice, users of astropy will generally expect scipy and matplotlib +# to be available at runtime, so we set these as prerequisites. $(ipydir)/astropy-$(astropy-version): \ - $(ipydir)/h5py-$(h5py-version) \ - $(ibidir)/expat-$(expat-version) \ $(ipydir)/scipy-$(scipy-version) \ - $(ipydir)/numpy-$(numpy-version) \ + $(ipydir)/pyerfa-$(pyerfa-version) \ $(ipydir)/pyyaml-$(pyyaml-version) \ - $(ipydir)/html5lib-$(html5lib-version) \ - $(ipydir)/beautifulsoup4-$(beautifulsoup4-version) + $(ipydir)/matplotlib-$(matplotlib-version) \ + $(ipydir)/astropy-iers-data-$(astropy-iers-data-version) \ + $(ipydir)/extension-helpers-$(extension-helpers-version) - # Download the source. - tarball=astropy-$(astropy-version).tar.gz +# Tarball and its preparation. + tarball=astropy-$(astropy-version).tar.lz $(call import-source, $(astropy-url), $(astropy-checksum)) - # Currently, when the Expat library is already built in a project - # (for example as a dependency of another program), Astropy's - # internal building of Expat will conflict with the project's. So - # we have added Expat as a dependency of Astropy (so it is always - # built before it, and we tell Astropy to use the project's - # libexpat. - pyhook_before () { - echo "" >> setup.cfg - echo "[build]" >> setup.cfg - echo "use_system_expat=1" >> setup.cfg - } - $(call pybuild, tar xf, astropy-$(astropy-version)) - cp $(dtexdir)/astropy.tex $(ictdir)/ +# Conservatively purge old version (but not astropy_iers, +# astropy-iers): + rm -fvr $(idir)/lib/python*/site-packages/astropy/ + rm -fvr $(idir)/lib/python*/site-packages/astropy-[0-9]*-info/ + rm -fv $(idir)/bin/fits{diff,check,header,info,2bitmap} + rm -fv $(idir)/bin/{samp_hub,showtable,volint,wcslint} + +# Do the basic build. + $(call pybuild, tar -xf, astropy-$(astropy-version),,, \ + GPEP517) + cp -pv $(dtexdir)/astropy.tex $(ictdir)/ echo "Astropy $(astropy-version) \citep{astropy2013,astropy2018}" > $@ +$(ipydir)/astropy-iers-data-$(astropy-iers-data-version): \ + $(ipydir)/setuptools-$(setuptools-version) + tarball=astropy-iers-data-$(astropy-iers-data-version).tar.lz + $(call import-source, $(astropy-iers-data-url), \ + $(astropy-iers-data-checksum)) + $(call pybuild, tar -xf, \ + astropy-iers-data-$(astropy-iers-data-version),,, \ + GPEP517) + echo "Astropy-Iers-Data $(astropy-iers-data-version)" > $@ + $(ipydir)/beautifulsoup4-$(beautifulsoup4-version): \ $(ipydir)/soupsieve-$(soupsieve-version) - tarball=beautifulsoup4-$(beautifulsoup4-version).tar.gz + tarball=beautifulsoup4-$(beautifulsoup4-version).tar.lz $(call import-source, $(beautifulsoup4-url), $(beautifulsoup4-checksum)) - $(call pybuild, tar xf, beautifulsoup4-$(beautifulsoup4-version), , \ + $(call pybuild, tar -xf, beautifulsoup4-$(beautifulsoup4-version), , \ BeautifulSoup $(beautifulsoup4-version)) -$(ipydir)/certifi-$(certifi-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/beniget-$(beniget-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=beniget-$(beniget-version).tar.lz + $(call import-source, $(beniget-url), $(beniget-checksum)) + $(call pybuild, tar -xf, beniget-$(beniget-version), , \ + Beniget $(beniget-version)) + +$(ipydir)/certifi-$(certifi-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=certifi-$(certifi-version).tar.gz $(call import-source, $(certifi-url), $(certifi-checksum)) - $(call pybuild, tar xf, certifi-$(certifi-version), , \ + $(call pybuild, tar -xf, certifi-$(certifi-version), , \ Certifi $(certifi-version)) $(ipydir)/cffi-$(cffi-version): \ $(ibidir)/libffi-$(libffi-version) \ $(ipydir)/pycparser-$(pycparser-version) - tarball=cffi-$(cffi-version).tar.gz + tarball=cffi-$(cffi-version).tar.lz $(call import-source, $(cffi-url), $(cffi-checksum)) - $(call pybuild, tar xf, cffi-$(cffi-version), ,cffi $(cffi-version)) + $(call pybuild, tar -xf, cffi-$(cffi-version), ,cffi $(cffi-version)) -$(ipydir)/chardet-$(chardet-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/chardet-$(chardet-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=chardet-$(chardet-version).tar.gz $(call import-source, $(chardet-url), $(chardet-checksum)) - $(call pybuild, tar xf, chardet-$(chardet-version), , \ + $(call pybuild, tar -xf, chardet-$(chardet-version), , \ Chardet $(chardet-version)) +$(ipydir)/contourpy-$(contourpy-version): \ + $(ipydir)/pybind11-$(pybind11-version) \ + $(ipydir)/meson-python-$(meson-python-version) + tarball=contourpy-$(contourpy-version).tar.lz + $(call import-source, $(contourpy-url), $(contourpy-checksum)) + $(call pybuild, tar -xf, contourpy-$(contourpy-version), , \ + Contourpy $(contourpy-version), GPEP517) + echo "Contourpy $(contourpy-version)" > $@ + $(ipydir)/corner-$(corner-version): $(ipydir)/matplotlib-$(matplotlib-version) tarball=corner-$(corner-version).tar.gz $(call import-source, $(corner-url), $(corner-checksum)) - $(call pybuild, tar xf, corner-$(corner-version), , \ + $(call pybuild, tar -xf, corner-$(corner-version), , \ Corner $(corner-version)) cp $(dtexdir)/corner.tex $(ictdir)/ echo "Corner $(corner-version) \citep{corner}" > $@ +$(ipydir)/cppy-$(cppy-version): \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) + tarball=cppy-$(cppy-version).tar.lz + $(call import-source, $(cppy-url), $(cppy-checksum)) + $(call pybuild, tar -xf, cppy-$(cppy-version), , \ + Cppy $(cppy-version), GPEP517) + $(ipydir)/cryptography-$(cryptography-version): \ $(ipydir)/cffi-$(cffi-version) \ - $(ipydir)/asn1crypto-$(asn1crypto-version) - tarball=cryptography-$(cryptography-version).tar.gz + $(ipydir)/asn1crypto-$(asn1crypto-version) \ + $(ipydir)/setuptools-rust-$(setuptools-rust-version) + tarball=cryptography-$(cryptography-version).tar.lz $(call import-source, $(cryptography-url), $(cryptography-checksum)) - $(call pybuild, tar xf, cryptography-$(cryptography-version), , \ + $(call pybuild, tar -xf, cryptography-$(cryptography-version), , \ Cryptography $(cryptography-version)) $(ipydir)/cycler-$(cycler-version): $(ipydir)/six-$(six-version) - tarball=cycler-$(cycler-version).tar.gz + tarball=cycler-$(cycler-version).tar.lz $(call import-source, $(cycler-url), $(cycler-checksum)) - $(call pybuild, tar xf, cycler-$(cycler-version), , \ - Cycler $(cycler-version)) + $(call pybuild, tar -xf, cycler-$(cycler-version), , \ + Cycler $(cycler-version), GPEP517) + echo "Cycler $(cycler-version)" > $@ -$(ipydir)/cython-$(cython-version): $(ipydir)/setuptools-$(setuptools-version) - tarball=cython-$(cython-version).tar.gz +$(ipydir)/cython-$(cython-version): \ + $(ipydir)/python-installer-$(python-installer-version) \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/setuptools-$(setuptools-version) + tarball=cython-$(cython-version).tar.lz $(call import-source, $(cython-url), $(cython-checksum)) - $(call pybuild, tar xf, Cython-$(cython-version)) - cp $(dtexdir)/cython.tex $(ictdir)/ + $(call pybuild, tar -xf, cython-$(cython-version),,, GPEP517) + cp -pv $(dtexdir)/cython.tex $(ictdir)/ echo "Cython $(cython-version) \citep{cython2011}" > $@ $(ipydir)/esutil-$(esutil-version): $(ipydir)/numpy-$(numpy-version) - tarball=esutil-$(esutil-version).tar.gz + export CFLAGS="-std=c++14 $$CFLAGS" + tarball=esutil-$(esutil-version).tar.lz $(call import-source, $(esutil-url), $(esutil-checksum)) - $(call pybuild, tar xf, esutil-$(esutil-version), , \ + $(call pybuild, tar -xf, esutil-$(esutil-version), , \ esutil $(esutil-version)) $(ipydir)/eigency-$(eigency-version): \ @@ -266,36 +463,68 @@ $(ipydir)/eigency-$(eigency-version): \ $(ipydir)/cython-$(cython-version) tarball=eigency-$(eigency-version).tar.gz $(call import-source, $(eigency-url), $(eigency-checksum)) - $(call pybuild, tar xf, eigency-$(eigency-version), , \ + $(call pybuild, tar -xf, eigency-$(eigency-version), , \ eigency $(eigency-version)) $(ipydir)/emcee-$(emcee-version): \ $(ipydir)/numpy-$(numpy-version) \ - $(ipydir)/setuptools_scm-$(setuptools_scm-version) + $(ipydir)/setuptools-scm-$(setuptools-scm-version) tarball=emcee-$(emcee-version).tar.gz $(call import-source, $(emcee-url), $(emcee-checksum)) - $(call pybuild, tar xf, emcee-$(emcee-version), , \ + $(call pybuild, tar -xf, emcee-$(emcee-version), , \ emcee $(emcee-version)) $(ipydir)/entrypoints-$(entrypoints-version): \ - $(ipydir)/setuptools-$(setuptools-version) + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=entrypoints-$(entrypoints-version).tar.gz $(call import-source, $(entrypoints-url), $(entrypoints-checksum)) - $(call pybuild, tar xf, entrypoints-$(entrypoints-version), , \ + $(call pybuild, tar -xf, entrypoints-$(entrypoints-version), , \ EntryPoints $(entrypoints-version)) +$(ipydir)/extension-helpers-$(extension-helpers-version): \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) + tarball=extension-helpers-$(extension-helpers-version).tar.lz + $(call import-source, $(extension-helpers-url), \ + $(extension-helpers-checksum)) + $(call pybuild, tar -xf, \ + extension-helpers-$(extension-helpers-version),, \ + Extension-Helpers $(extension-helpers-version), GPEP517) + $(ipydir)/flake8-$(flake8-version): \ $(ipydir)/pyflakes-$(pyflakes-version) \ $(ipydir)/pycodestyle-$(pycodestyle-version) tarball=flake8-$(flake8-version).tar.gz $(call import-source, $(flake8-url), $(flake8-checksum)) - $(call pybuild, tar xf, flake8-$(flake8-version), , \ + $(call pybuild, tar -xf, flake8-$(flake8-version), , \ Flake8 $(flake8-version)) -$(ipydir)/future-$(future-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/flit-core-$(flit-core-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=flit-core-$(flit-core-version).tar.lz + $(call import-source, $(flit-core-url), $(flit-core-checksum)) + $(call pybuild, tar -xf, flit-core-$(flit-core-version), , \ + Flit-core $(flit-core-version), GPEP517) + +# Although cython is not an obligatory prerequisite of fonttools, we force +# it as a prerequisite for reproducibility; otherwise build parallelism may +# lead to some builds with and some builds without cython, depending on how +# many cpus the host machine has. +$(ipydir)/fonttools-$(fonttools-version): \ + $(ipydir)/cython-$(cython-version) \ + $(ipydir)/setuptools-$(setuptools-version) + tarball=fonttools-$(fonttools-version).tar.lz + $(call import-source, $(fonttools-url), $(fonttools-checksum)) + $(call pybuild, tar -xf, fonttools-$(fonttools-version), , \ + fonttools $(fonttools-version), GPEP517) + +$(ipydir)/future-$(future-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=future-$(future-version).tar.gz $(call import-source, $(future-url), $(future-checksum)) - $(call pybuild, tar xf, future-$(future-version), , \ + $(call pybuild, tar -xf, future-$(future-version), , \ Future $(future-version)) $(ipydir)/galsim-$(galsim-version): \ @@ -304,12 +533,31 @@ $(ipydir)/galsim-$(galsim-version): \ $(ipydir)/eigency-$(eigency-version) \ $(ipydir)/pybind11-$(pybind11-version) \ $(ipydir)/lsstdesccoord-$(lsstdesccoord-version) - tarball=galsim-$(galsim-version).tar.gz + tarball=galsim-$(galsim-version).tar.lz $(call import-source, $(galsim-url), $(galsim-checksum)) - $(call pybuild, tar xf, GalSim-$(galsim-version)) + $(call pybuild, tar -xf, galsim-$(galsim-version)) cp $(dtexdir)/galsim.tex $(ictdir)/ echo "Galsim $(galsim-version) \citep{galsim}" > $@ +$(ipydir)/gast-$(gast-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=gast-$(gast-version).tar.lz + $(call import-source, $(gast-url), $(gast-checksum)) + $(call pybuild, tar -xf, gast-$(gast-version), , \ + Gast $(gast-version)) + +$(ipydir)/gpep517-$(gpep517-version): \ + $(ibidir)/python-$(python-version) + tarball=gpep517-$(gpep517-version).tar.lz + $(call import-source, $(gpep517-url), $(gpep517-checksum)) + $(call pybuild, tar -xf, \ + gpep517-$(gpep517-version), \ + , \ + gpep517 $(gpep517-version), \ + BOOT_GPEP517) + echo "gpep517 $(gpep517-version)" > $@ + $(ipydir)/h5py-$(h5py-version): \ $(ipydir)/six-$(six-version) \ $(ibidir)/hdf5-$(hdf5-version) \ @@ -321,15 +569,15 @@ $(ipydir)/h5py-$(h5py-version): \ export HDF5_DIR=$(ildir) tarball=h5py-$(h5py-version).tar.gz $(call import-source, $(h5py-url), $(h5py-checksum)) - $(call pybuild, tar xf, h5py-$(h5py-version), , \ + $(call pybuild, tar -xf, h5py-$(h5py-version), , \ h5py $(h5py-version)) -# `healpy' is actually installed as part of the HEALPix package. It will be +# 'healpy' is actually installed as part of the HEALPix package. It will be # installed with its C/C++ libraries if any other Python library is -# requested with HEALPix. So actually calling for `healpix' (when `healpix' +# requested with HEALPix. So actually calling for 'healpix' (when 'healpix' # is requested) is not necessary. But some users might not know about this -# and just ask for `healpy'. To avoid confusion in such cases, we'll just -# set `healpy' to be dependent on `healpix' and not download any tarball +# and just ask for 'healpy'. To avoid confusion in such cases, we'll just +# set 'healpy' to be dependent on 'healpix' and not download any tarball # for it, or write anything in the final target. $(ipydir)/healpy-$(healpy-version): $(ibidir)/healpix-$(healpix-version) touch $@ @@ -339,35 +587,49 @@ $(ipydir)/html5lib-$(html5lib-version): \ $(ipydir)/webencodings-$(webencodings-version) tarball=html5lib-$(html5lib-version).tar.gz $(call import-source, $(html5lib-url), $(html5lib-checksum)) - $(call pybuild, tar xf, html5lib-$(html5lib-version), , \ + $(call pybuild, tar -xf, html5lib-$(html5lib-version), , \ HTML5lib $(html5lib-version)) -$(ipydir)/idna-$(idna-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/idna-$(idna-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=idna-$(idna-version).tar.gz $(call import-source, $(idna-url), $(idna-checksum)) - $(call pybuild, tar xf, idna-$(idna-version), , \ + $(call pybuild, tar -xf, idna-$(idna-version), , \ idna $(idna-version)) -$(ipydir)/jeepney-$(jeepney-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/jeepney-$(jeepney-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=jeepney-$(jeepney-version).tar.gz $(call import-source, $(jeepney-url), $(jeepney-checksum)) - $(call pybuild, tar xf, jeepney-$(jeepney-version), , \ + $(call pybuild, tar -xf, jeepney-$(jeepney-version), , \ Jeepney $(jeepney-version)) +$(ipydir)/jinja2-$(jinja2-version): $(ipydir)/markupsafe-$(markupsafe-version) + tarball=jinja2-$(jinja2-version).tar.lz + $(call import-source, $(jinja2-url), $(jinja2-checksum)) + $(call pybuild, tar -xf, jinja2-$(jinja2-version), , \ + Jinja2 $(jinja2-version)) + $(ipydir)/keyring-$(keyring-version): \ $(ipydir)/entrypoints-$(entrypoints-version) \ $(ipydir)/secretstorage-$(secretstorage-version) \ - $(ipydir)/setuptools_scm-$(setuptools_scm-version) + $(ipydir)/setuptools-scm-$(setuptools-scm-version) tarball=keyring-$(keyring-version).tar.gz $(call import-source, $(keyring-url), $(keyring-checksum)) - $(call pybuild, tar xf, keyring-$(keyring-version), , \ + $(call pybuild, tar -xf, keyring-$(keyring-version), , \ Keyring $(keyring-version)) -$(ipydir)/kiwisolver-$(kiwisolver-version): $(ipydir)/setuptools-$(setuptools-version) - tarball=kiwisolver-$(kiwisolver-version).tar.gz +$(ipydir)/kiwisolver-$(kiwisolver-version): \ + $(ipydir)/cppy-$(cppy-version) \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) + tarball=kiwisolver-$(kiwisolver-version).tar.lz $(call import-source, $(kiwisolver-url), $(kiwisolver-checksum)) - $(call pybuild, tar xf, kiwisolver-$(kiwisolver-version), , \ - Kiwisolver $(kiwisolver-version)) + $(call pybuild, tar -xf, kiwisolver-$(kiwisolver-version), , \ + Kiwisolver $(kiwisolver-version), GPEP517) + cp -pv $(dtexdir)/kiwisolver.tex $(ictdir)/ + echo "Kiwisolver $(kiwisolver-version) \citep{cassowary2001}" > $@ $(ipydir)/lmfit-$(lmfit-version): \ $(ipydir)/six-$(six-version) \ @@ -379,238 +641,421 @@ $(ipydir)/lmfit-$(lmfit-version): \ $(ipydir)/uncertainties-$(uncertainties-version) tarball=lmfit-$(lmfit-version).tar.gz $(call import-source, $(lmfit-url), $(lmfit-checksum)) - $(call pybuild, tar xf, lmfit-$(lmfit-version), , \ + $(call pybuild, tar -xf, lmfit-$(lmfit-version), , \ LMFIT $(lmfit-version)) $(ipydir)/lsstdesccoord-$(lsstdesccoord-version): \ - $(ipydir)/setuptools-$(setuptools-version) + $(ipydir)/cffi-$(cffi-version) \ + $(ipydir)/numpy-$(numpy-version) \ + $(ipydir)/future-$(future-version) tarball=lsstdesccoord-$(lsstdesccoord-version).tar.gz $(call import-source, $(lsstdesccoord-url), $(lsstdesccoord-checksum)) - $(call pybuild, tar xf, LSSTDESC.Coord-$(lsstdesccoord-version), , \ + $(call pybuild, tar -xf, LSSTDESC.Coord-$(lsstdesccoord-version), , \ LSSTDESC.Coord $(lsstdesccoord-version)) +$(ipydir)/markupsafe-$(markupsafe-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=markupsafe-$(markupsafe-version).tar.lz + $(call import-source, $(markupsafe-url), $(markupsafe-checksum)) + $(call pybuild, tar -xf, markupsafe-$(markupsafe-version), , \ + MarkupSafe $(markupsafe-version)) + $(ipydir)/matplotlib-$(matplotlib-version): \ $(itidir)/texlive \ $(ipydir)/numpy-$(numpy-version) \ $(ipydir)/cycler-$(cycler-version) \ - $(ibidir)/freetype-$(freetype-version) \ - $(ipydir)/pyparsing-$(pyparsing-version) \ + $(ipydir)/pillow-$(pillow-version) \ + $(ipydir)/fonttools-$(fonttools-version) \ + $(ipydir)/contourpy-$(contourpy-version) \ $(ipydir)/kiwisolver-$(kiwisolver-version) \ - $(ibidir)/ghostscript-$(ghostscript-version) \ - $(ibidir)/imagemagick-$(imagemagick-version) \ $(ipydir)/python-dateutil-$(python-dateutil-version) - # Download the source. - tarball=matplotlib-$(matplotlib-version).tar.gz +# Prepare the source. + tarball=matplotlib-$(matplotlib-version).tar.lz $(call import-source, $(matplotlib-url), $(matplotlib-checksum)) - # On Mac systems, the build complains about `clang' specific - # features, so we can't use our own GCC build here. +# On Mac systems, the build complains about 'clang' specific +# features, so we can't use our own GCC build here. if [ x$(on_mac_os) = xyes ]; then export CC=clang export CXX=clang++ fi - $(call pybuild, tar xf, matplotlib-$(matplotlib-version)) + $(call pybuild, tar -xf, matplotlib-$(matplotlib-version),,, GPEP517) cp $(dtexdir)/matplotlib.tex $(ictdir)/ echo "Matplotlib $(matplotlib-version) \citep{matplotlib2007}" > $@ +$(ipydir)/meson-$(meson-version): \ + $(ibidir)/ninjabuild-$(ninjabuild-version) \ + $(ipydir)/setuptools-$(setuptools-version) + tarball=meson-$(meson-version).tar.lz + $(call import-source, $(meson-url), $(meson-checksum)) + $(call pybuild, tar -xf, meson-$(meson-version), , \ + Meson $(meson-version), GPEP517) + echo "Meson $(meson-version)" > $@ + +# The 'meson-python' package may be helpful or requred for some packages. +$(ipydir)/meson-python-$(meson-python-version): \ + $(ipydir)/meson-$(meson-version) \ + $(ipydir)/packaging-$(packaging-version) \ + $(ipydir)/pyproject-metadata-$(pyproject-metadata-version) + tarball=meson-python-$(meson-python-version).tar.lz + $(call import-source, $(meson-python-url), $(meson-python-checksum)) + $(call pybuild, tar -xf, meson-python-$(meson-python-version), , \ + Meson-python $(meson-python-version), GPEP517) + echo "Meson-Python $(meson-python-version)" > $@ + $(ipydir)/mpi4py-$(mpi4py-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ $(ibidir)/openmpi-$(openmpi-version) \ - $(ipydir)/setuptools-$(setuptools-version) - tarball=mpi4py-$(mpi4py-version).tar.gz + $(ipydir)/python-installer-$(python-installer-version) + tarball=mpi4py-$(mpi4py-version).tar.lz $(call import-source, $(mpi4py-url), $(mpi4py-checksum)) - $(call pybuild, tar xf, mpi4py-$(mpi4py-version)) + $(call pybuild, tar -xf, mpi4py-$(mpi4py-version)) cp $(dtexdir)/mpi4py.tex $(ictdir)/ echo "mpi4py $(mpi4py-version) \citep{mpi4py2011}" > $@ -$(ipydir)/mpmath-$(mpmath-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/mpmath-$(mpmath-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=mpmath-$(mpmath-version).tar.gz $(call import-source, $(mpmath-url), $(mpmath-checksum)) - $(call pybuild, tar xf, mpmath-$(mpmath-version), , \ + $(call pybuild, tar -xf, mpmath-$(mpmath-version), , \ mpmath $(mpmath-version)) +# Until 2025-02-22: we had 'export CFLAGS="--std=c99 $$CFLAGS"' before +# calling pybuild; but that doesn't seem to be necessary. $(ipydir)/numpy-$(numpy-version): \ - $(ibidir)/unzip-$(unzip-version) \ $(ipydir)/cython-$(cython-version) \ $(ibidir)/openblas-$(openblas-version) \ - $(ipydir)/setuptools-$(setuptools-version) - tarball=numpy-$(numpy-version).zip + $(ipydir)/pybind11-$(pybind11-version) \ + $(ipydir)/meson-python-$(meson-python-version) + tarball=numpy-$(numpy-version).tar.lz $(call import-source, $(numpy-url), $(numpy-checksum)) if [ x$(on_mac_os) = xyes ]; then export LDFLAGS="$(LDFLAGS) -undefined dynamic_lookup -bundle" - else - export LDFLAGS="$(LDFLAGS) -shared" fi - export CFLAGS="--std=c99 $$CFLAGS" conf="$$(pwd)/reproduce/software/config/numpy-scipy.cfg" - $(call pybuild, unzip, numpy-$(numpy-version),$$conf, \ - Numpy $(numpy-version)) + $(call pybuild, tar -xf, numpy-$(numpy-version),$$conf, \ + Numpy $(numpy-version), GPEP517) cp $(dtexdir)/numpy.tex $(ictdir)/ - echo "Numpy $(numpy-version) \citep{numpy2011}" > $@ - -$(ipydir)/pexpect-$(pexpect-version): $(ipydir)/setuptools-$(setuptools-version) + echo "Numpy $(numpy-version) \citep{numpy2020}" > $@ + +$(ipydir)/packaging-$(packaging-version): \ + $(ipydir)/pyparsing-$(pyparsing-version) + tarball=packaging-$(packaging-version).tar.lz + $(call import-source, $(packaging-url), $(packaging-checksum)) + $(call pybuild, tar -xf, packaging-$(packaging-version), , \ + Packaging $(packaging-version), GPEP517) + +$(ipydir)/pexpect-$(pexpect-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=pexpect-$(pexpect-version).tar.gz $(call import-source, $(pexpect-url), $(pexpect-checksum)) - $(call pybuild, tar xf, pexpect-$(pexpect-version), , \ + $(call pybuild, tar -xf, pexpect-$(pexpect-version), , \ Pexpect $(pexpect-version)) -$(ipydir)/pip-$(pip-version): $(ipydir)/setuptools-$(setuptools-version) - tarball=pip-$(pip-version).tar.gz - $(call import-source, $(pip-url), $(pip-checksum)) - $(call pybuild, tar xf, pip-$(pip-version), , \ - PiP $(pip-version)) +$(ipydir)/pillow-$(pillow-version): $(ibidir)/libjpeg-$(libjpeg-version) \ + $(ipydir)/setuptools-$(setuptools-version) + tarball=pillow-$(pillow-version).tar.lz + $(call import-source, $(pillow-url), $(pillow-checksum)) + $(call pybuild, tar -xf, pillow-$(pillow-version), , \ + Pillow $(pillow-version), GPEP517) + +# This should normally not be used, because it's a front-end that obstructs +# reproducibility - source URL; checksum of the tarball; build rule. +# $(ipydir)/pip-$(pip-version): \ +# $(ipydir)/python-installer-$(python-installer-version) \ +# $(ipydir)/wheel-$(wheel-version) +# tarball=pip-$(pip-version).tar.gz +# $(call import-source, $(pip-url), $(pip-checksum)) +# $(call pybuild, tar -xf, pip-$(pip-version), , \ +# PiP $(pip-version)) + +$(ipydir)/ply-$(ply-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=ply-$(ply-version).tar.lz + $(call import-source, $(ply-url), $(ply-checksum)) + $(call pybuild, tar -xf, ply-$(ply-version), , \ + ply $(ply-version)) $(ipydir)/pycodestyle-$(pycodestyle-version): \ - $(ipydir)/setuptools-$(setuptools-version) + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=pycodestyle-$(pycodestyle-version).tar.gz $(call import-source, $(pycodestyle-url), $(pycodestyle-checksum)) - $(call pybuild, tar xf, pycodestyle-$(pycodestyle-version), , \ + $(call pybuild, tar -xf, pycodestyle-$(pycodestyle-version), , \ pycodestyle $(pycodestyle-version)) $(ipydir)/pybind11-$(pybind11-version): \ $(ibidir)/eigen-$(eigen-version) \ $(ibidir)/boost-$(boost-version) \ - $(ipydir)/setuptools-$(setuptools-version) - tarball=pybind11-$(pybind11-version).tar.gz + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=pybind11-$(pybind11-version).tar.lz $(call import-source, $(pybind11-url), $(pybind11-checksum)) pyhook_after() { - cp -r include/pybind11 $(iidir)/python$(python-major-version)m/ + cp -pvr pybind11/include/pybind11 \ + $(iidir)/python$(python-major-version)m/ } - $(call pybuild, tar xf, pybind11-$(pybind11-version), , \ - pybind11 $(pybind11-version)) + $(call pybuild, tar -xf, pybind11-$(pybind11-version), , \ + pybind11 $(pybind11-version), GPEP517) + echo "Pybind11 $(pybind11-version)" > $@ -$(ipydir)/pycparser-$(pycparser-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/pycparser-$(pycparser-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=pycparser-$(pycparser-version).tar.gz $(call import-source, $(pycparser-url), $(pycparser-checksum)) - $(call pybuild, tar xf, pycparser-$(pycparser-version), , \ + $(call pybuild, tar -xf, pycparser-$(pycparser-version), , \ pycparser $(pycparser-version)) -$(ipydir)/pyflakes-$(pyflakes-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/pyerfa-$(pyerfa-version): \ + $(ipydir)/numpy-$(numpy-version) \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) + tarball=pyerfa-$(pyerfa-version).tar.lz + $(call import-source, $(pyerfa-url), $(pyerfa-checksum)) + $(call pybuild, tar -xf, pyerfa-$(pyerfa-version), , \ + PyERFA $(pyerfa-version), GPEP517) + +$(ipydir)/pyflakes-$(pyflakes-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=pyflakes-$(pyflakes-version).tar.gz $(call import-source, $(pyflakes-url), $(pyflakes-checksum)) - $(call pybuild, tar xf, pyflakes-$(pyflakes-version), , \ + $(call pybuild, tar -xf, pyflakes-$(pyflakes-version), , \ pyflakes $(pyflakes-version)) -$(ipydir)/pyparsing-$(pyparsing-version): $(ipydir)/setuptools-$(setuptools-version) - tarball=pyparsing-$(pyparsing-version).tar.gz +$(ipydir)/pyparsing-$(pyparsing-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/flit-core-$(flit-core-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=pyparsing-$(pyparsing-version).tar.lz $(call import-source, $(pyparsing-url), $(pyparsing-checksum)) - $(call pybuild, tar xf, pyparsing-$(pyparsing-version), , \ - PyParsing $(pyparsing-version)) + $(call pybuild, tar -xf, pyparsing-$(pyparsing-version), , \ + PyParsing $(pyparsing-version), GPEP517) -$(ipydir)/pypkgconfig-$(pypkgconfig-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/pypkgconfig-$(pypkgconfig-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=pkgconfig-$(pypkgconfig-version).tar.gz $(call import-source, $(pypkgconfig-url), $(pypkgconfig-checksum)) - $(call pybuild, tar xf, pkgconfig-$(pypkgconfig-version), , + $(call pybuild, tar -xf, pkgconfig-$(pypkgconfig-version), , pkgconfig $(pypkgconfig-version)) +$(ipydir)/pyproject-metadata-$(pyproject-metadata-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/flit-core-$(flit-core-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=pyproject-metadata-$(pyproject-metadata-version).tar.lz + $(call import-source, $(pyproject-metadata-url), $(pyproject-metadata-checksum)) + $(call pybuild, tar -xf, \ + pyproject-metadata-$(pyproject-metadata-version),,, GPEP517) + $(ipydir)/python-dateutil-$(python-dateutil-version): \ - $(ipydir)/six-$(six-version) \ - $(ipydir)/setuptools_scm-$(setuptools_scm-version) - tarball=python-dateutil-$(python-dateutil-version).tar.gz + $(ipydir)/setuptools-scm-$(setuptools-scm-version) + tarball=python-dateutil-$(python-dateutil-version).tar.lz $(call import-source, $(python-dateutil-url), $(python-dateutil-checksum)) - $(call pybuild, tar xf, python-dateutil-$(python-dateutil-version), , \ - python-dateutil $(python-dateutil-version)) + $(call pybuild, tar -xf, python-dateutil-$(python-dateutil-version), , \ + python-dateutil $(python-dateutil-version), GPEP517) + +$(ipydir)/python-installer-$(python-installer-version): \ + $(ibidir)/python-$(python-version) + +# Prepare the tarball. + tarball=python-installer-$(python-installer-version).tar.lz + $(call import-source, $(python-installer-url), $(python-installer-checksum)) + +# Modify the line in the source that will cause a crash when a +# to-be-installed file already exists in the installation path. This +# is very important for Python packages in Maneage (when a dependency +# is updated, the package needs to be re-built, but that would cause +# due to this line). + pyhook_before(){ + mv -v src/installer/destinations.py src/installer/destinations.py.orig; \ + sed -e 's/\(raise FileExistsError.message.\)/## \1/' \ + src/installer/destinations.py.orig > src/installer/destinations.py + } + +# Build the Python installer. + $(call pybuild, tar -xf, \ + python-installer-$(python-installer-version),,, \ + BOOT_INSTALLER) + echo "Python-installer $(python-installer-version)" > $@ + +$(ipydir)/pythran-$(pythran-version): \ + $(ipydir)/ply-$(ply-version) \ + $(ipydir)/gast-$(gast-version) \ + $(ibidir)/boost-$(boost-version) \ + $(ipydir)/beniget-$(beniget-version) \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) + tarball=pythran-$(pythran-version).tar.lz + $(call import-source, $(pythran-url), $(pythran-checksum)) + $(call pybuild, tar -xf, pythran-$(pythran-version), , \ + pythran $(pythran-version)) $(ipydir)/pyyaml-$(pyyaml-version): \ $(ibidir)/yaml-$(yaml-version) \ $(ipydir)/cython-$(cython-version) - tarball=pyyaml-$(pyyaml-version).tar.gz + tarball=pyyaml-$(pyyaml-version).tar.lz $(call import-source, $(pyyaml-url), $(pyyaml-checksum)) - $(call pybuild, tar xf, PyYAML-$(pyyaml-version), , \ - PyYAML $(pyyaml-version)) + $(call pybuild, tar -xf, pyyaml-$(pyyaml-version), , \ + PyYAML $(pyyaml-version), GPEP517) $(ipydir)/requests-$(requests-version): $(ipydir)/idna-$(idna-version) \ - $(ipydir)/numpy-$(numpy-version) \ - $(ipydir)/certifi-$(certifi-version) \ - $(ipydir)/chardet-$(chardet-version) \ - $(ipydir)/urllib3-$(urllib3-version) + $(ipydir)/numpy-$(numpy-version) \ + $(ipydir)/certifi-$(certifi-version) \ + $(ipydir)/chardet-$(chardet-version) \ + $(ipydir)/urllib3-$(urllib3-version) tarball=requests-$(requests-version).tar.gz $(call import-source, $(requests-url), $(requests-checksum)) - $(call pybuild, tar xf, requests-$(requests-version), , \ + $(call pybuild, tar -xf, requests-$(requests-version), , \ Requests $(requests-version)) +# 'pythran' is disabled in the build of Scipy because of complications it +# caused on some systems. We explicitly disable it using a preprocessor +# directive. 'Pythran' can in principle speed up compilation of scientific +# software [1][2]. +# [1] https://pythran.readthedocs.io/en/latest +# [2] https://docs.scipy.org/doc/scipy-1.15.2/dev/roadmap-detailed.html $(ipydir)/scipy-$(scipy-version): \ $(ipydir)/numpy-$(numpy-version) \ $(ipydir)/pybind11-$(pybind11-version) - tarball=scipy-$(scipy-version).tar.gz + tarball=scipy-$(scipy-version).tar.lz $(call import-source, $(scipy-url), $(scipy-checksum)) if [ x$(on_mac_os) = xyes ]; then export LDFLAGS="$(LDFLAGS) -undefined dynamic_lookup -bundle" else - export LDFLAGS="$(LDFLAGS) -shared" +# Same question as for 'numpy': why '-shared'? This obstructs +# the meson build. +# export LDFLAGS="$(LDFLAGS) -shared" + : fi conf="$$(pwd)/reproduce/software/config/numpy-scipy.cfg" - $(call pybuild, tar xf, scipy-$(scipy-version),$$conf) + +# Disable pythran: see +# https://docs.scipy.org/doc/scipy-1.15.2/dev/roadmap-detailed.html#use-of-pythran +# export SCIPY_USE_PYTHRAN=0 # deprecated(?) +# Option 1: Hack the source: + pyhook_before() { + mv -iv meson.options meson.options.orig; \ + sed -e 's/\(use-pythran.*value: *\)true/\1false/' \ + meson.options.orig > meson.options + } + +# Option 2: pass the string +# --config-json='{"setup-args": "-Duse-pythran=false"}' +# to gpep517 with correct escaping of single and double quotes. +# Not tried as of 2025-02-25. + $(call pybuild, tar -xf, scipy-$(scipy-version),$$conf,, GPEP517) cp $(dtexdir)/scipy.tex $(ictdir)/ - echo "Scipy $(scipy-version) \citep{scipy2007,scipy2011}" > $@ + echo "Scipy $(scipy-version) \citep{scipy2020}" > $@ $(ipydir)/secretstorage-$(secretstorage-version): \ $(ipydir)/jeepney-$(jeepney-version) \ $(ipydir)/cryptography-$(cryptography-version) tarball=secretstorage-$(secretstorage-version).tar.gz $(call import-source, $(secretstorage-url), $(secretstorage-checksum)) - $(call pybuild, tar xf, SecretStorage-$(secretstorage-version), , \ + $(call pybuild, tar -xf, SecretStorage-$(secretstorage-version), , \ SecretStorage $(secretstorage-version)) +$(ipydir)/semantic-version-$(semantic-version-version): \ + $(ipydir)/setuptools-$(setuptools-version) + tarball=semantic-version-$(semantic-version-version).tar.lz + $(call import-source, $(semantic-version-url), \ + $(semantic-version-checksum)) + $(call pybuild, tar -xf, \ + semantic-version-$(semantic-version-version), , \ + Semantic-version $(semantic-version-version), GPEP517) + $(ipydir)/setuptools-$(setuptools-version): \ - $(ibidir)/unzip-$(unzip-version) \ - $(ibidir)/python-$(python-version) - tarball=setuptools-$(setuptools-version).zip + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) + tarball=setuptools-$(setuptools-version).tar.lz $(call import-source, $(setuptools-url), $(setuptools-checksum)) - $(call pybuild, unzip, setuptools-$(setuptools-version), , \ - Setuptools $(setuptools-version)) + $(call pybuild, tar -xf, setuptools-$(setuptools-version), , \ + Setuptools $(setuptools-version), GPEP517) -$(ipydir)/setuptools_scm-$(setuptools_scm-version): \ +$(ipydir)/setuptools-scm-$(setuptools-scm-version): \ $(ipydir)/setuptools-$(setuptools-version) - tarball=setuptools_scm-$(setuptools_scm-version).tar.gz - $(call import-source, $(setuptools_scm-url), $(setuptools_scm-checksum)) - $(call pybuild, tar xf, setuptools_scm-$(setuptools_scm-version), , \ - Setuptools-scm $(setuptools_scm-version)) + tarball=setuptools-scm-$(setuptools-scm-version).tar.lz + $(call import-source, $(setuptools-scm-url), $(setuptools-scm-checksum)) + $(call pybuild, tar -xf, setuptools-scm-$(setuptools-scm-version), , \ + Setuptools-scm $(setuptools-scm-version), GPEP517) + +$(ipydir)/setuptools-rust-$(setuptools-rust-version): \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) \ + $(ipydir)/semantic-version-$(semantic-version-version) + tarball=setuptools-rust-$(setuptools-rust-version).tar.lz + $(call import-source, $(setuptools-rust-url), \ + $(setuptools-rust-checksum)) + $(call pybuild, tar -xf, setuptools-rust-$(setuptools-rust-version), , \ + Setuptools-rust $(setuptools-rust-version), GPEP517) $(ipydir)/sip_tpv-$(sip_tpv-version): \ $(ipydir)/sympy-$(sympy-version) \ $(ipydir)/astropy-$(astropy-version) tarball=sip_tpv-$(sip_tpv-version).tar.gz $(call import-source, $(sip_tpv-url), $(sip_tpv-checksum)) - $(call pybuild, tar xf, sip_tpv-$(sip_tpv-version), ,) + $(call pybuild, tar -xf, sip_tpv-$(sip_tpv-version), ,) cp $(dtexdir)/sip_tpv.tex $(ictdir)/ echo "sip_tpv $(sip_tpv-version) \citep{sip-tpv}" > $@ - -$(ipydir)/six-$(six-version): $(ipydir)/setuptools-$(setuptools-version) - tarball=six-$(six-version).tar.gz +$(ipydir)/six-$(six-version): \ + $(ipydir)/setuptools-$(setuptools-version) + tarball=six-$(six-version).tar.lz $(call import-source, $(six-url), $(six-checksum)) - $(call pybuild, tar xf, six-$(six-version), , \ - Six $(six-version)) + $(call pybuild, tar -xf, six-$(six-version), , \ + Six $(six-version), GPEP517) + echo "Six $(six-version)" > $@ -$(ipydir)/soupsieve-$(soupsieve-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/soupsieve-$(soupsieve-version): \ + $(ipydir)/setuptools-$(setuptools-version) \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) tarball=soupsieve-$(soupsieve-version).tar.gz $(call import-source, $(soupsieve-url), $(soupsieve-checksum)) - $(call pybuild, tar xf, soupsieve-$(soupsieve-version), , \ + $(call pybuild, tar -xf, soupsieve-$(soupsieve-version), , \ SoupSieve $(soupsieve-version)) $(ipydir)/sympy-$(sympy-version): $(ipydir)/mpmath-$(mpmath-version) tarball=sympy-$(sympy-version).tar.gz $(call import-source, $(sympy-url), $(sympy-checksum)) - $(call pybuild, tar xf, sympy-$(sympy-version), ,) + $(call pybuild, tar -xf, sympy-$(sympy-version), ,) cp $(dtexdir)/sympy.tex $(ictdir)/ echo "SymPy $(sympy-version) \citep{sympy}" > $@ $(ipydir)/uncertainties-$(uncertainties-version): $(ipydir)/numpy-$(numpy-version) - tarball=uncertainties-$(uncertainties-version).tar.gz + tarball=uncertainties-$(uncertainties-version).tar.lz $(call import-source, $(uncertainties-url), $(uncertainties-checksum)) - $(call pybuild, tar xf, uncertainties-$(uncertainties-version), , \ + $(call pybuild, tar -xf, uncertainties-$(uncertainties-version), , \ uncertainties $(uncertainties-version)) -$(ipydir)/urllib3-$(urllib3-version): $(ipydir)/setuptools-$(setuptools-version) +$(ipydir)/urllib3-$(urllib3-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/python-installer-$(python-installer-version) tarball=urllib3-$(urllib3-version).tar.gz $(call import-source, $(urllib3-url), $(urllib3-checksum)) - $(call pybuild, tar xf, urllib3-$(urllib3-version), , \ + $(call pybuild, tar -xf, urllib3-$(urllib3-version), , \ Urllib3 $(urllib3-version)) $(ipydir)/webencodings-$(webencodings-version): \ - $(ipydir)/setuptools-$(setuptools-version) + $(ipydir)/setuptools-$(setuptools-version) \ + $(ipydir)/setuptools-scm-$(setuptools-scm-version) tarball=webencodings-$(webencodings-version).tar.gz $(call import-source, $(webencodings-url), $(webencodings-checksum)) - $(call pybuild, tar xf, webencodings-$(webencodings-version), , \ + $(call pybuild, tar -xf, webencodings-$(webencodings-version), , \ Webencodings $(webencodings-version)) + +# As of 2025-02, this is only needed if you want 'wheel' on the command +# line; 'setuptools' provides its own version of wheels. +$(ipydir)/wheel-$(wheel-version): \ + $(ipydir)/gpep517-$(gpep517-version) \ + $(ipydir)/flit-core-$(flit-core-version) \ + $(ipydir)/python-installer-$(python-installer-version) +# tarball=wheel-$(wheel-version).tar.lz + tarball=wheel-$(wheel-version).tar.gz + $(call import-source, $(wheel-url), $(wheel-checksum)) + $(call pybuild, tar -xf, wheel-$(wheel-version), , \ + Wheel $(wheel-version), GPEP517) diff --git a/reproduce/software/make/r-cran.mk b/reproduce/software/make/r-cran.mk new file mode 100644 index 0000000..7c86c23 --- /dev/null +++ b/reproduce/software/make/r-cran.mk @@ -0,0 +1,488 @@ +# Build the project's R (here called R-CRAN) dependencies. +# +# ------------------------------------------------------------------------ +# !!!!! IMPORTANT NOTES !!!!! +# +# This Makefile will be loaded into 'high-level.mk', which is called by the +# './project configure' script. It is not included into the project +# afterwards. +# +# This Makefile contains instructions to build all the R-CRAN-related +# software within the project. +# +# ------------------------------------------------------------------------ +# +# Copyright (C) 2022-2025 Boud Roukema <boud@cosmo.torun.pl> +# Copyright (C) 2022-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# +# This Makefile is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This Makefile is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this Makefile. If not, see <http://www.gnu.org/licenses/>. + + + + + +# BUGS/IMPROVEMENTS +# ----------------- +# +# As of 2021-06-20, the R system is still very new and has not yet +# been tested on non-Debian-derived systems. Please provide bug +# reports ( https://savannah.nongnu.org/task/?15772 ) or propose fixes +# as git pull requests on a public git server (e.g. on a fork of +# https://codeberg.org/boud/maneage_dev ). + + + + + +# R-CRAN enviroment +# ----------------- +# +# It may be necessary to override host-level R-related environment +# variables that interfere with the Maneage-installed R system. +# systems which might interfere. + +# Ideas for which environment variables might create problems +# and might need to be set to be empty here: +# +# https://stat.ethz.ch/R-manual/R-devel/library/base/html/EnvVar.html + +# These first variables should be set automatically when R starts: +#export R_HOME := $(idir)/lib/R +#export R_INCLUDE_DIR := $(idir)/lib/R/include + + + + + +# R-CRAN-specific installation directories. +r-cran-major-version = $(shell echo $(r-cran-version) \ + | awk 'BEGIN{FS="."} \ + {printf "%d.%d\n", $$1, $$2}') + + + + + +# R-CRAN-specific build rules for 'make' +# ====================================== + +# Double-check an already downloaded R source +# ------------------------------------------- +# +# Check that the tarball with the version in +# 'reproduce/software/conf/versions.conf' has the sha512sum (checksum) +# stated 'reproduce/software/conf/checksums.conf'. This does not do any +# security checks; it only checks that the source file package is the one +# that is expected the last time that someone updated these two files for +# the R package of interest. +# +# Calculate the checksum and exit with a non-zero error code if there's a +# mismatch, after informing the user. +# +# Arguments: +# 1: The expected checksum of the tarball. +# +# Necessary shell variables +# 'tarball': This is the name of the actual tarball file without a +# directory. +double-check-R-source = final=$(tdir)/$$tarball; \ + exp_checksum="$(strip $(1))"; \ + if [ x"$$exp_checksum" = x"NO-CHECK-SUM" ]; then \ + result=0; \ + else \ + if type sha512sum > /dev/null 2>/dev/null; then \ + checksum=$$(sha512sum "$$final" | awk '{print $$1}'); \ + if [ x"$$checksum" = x"$$exp_checksum" ]; then \ + result=0; \ + else \ + echo "ERROR: Non-matching checksum: $$final"; \ + echo "Checksum should be: $$exp_checksum"; \ + echo "Checksum is: $$checksum"; \ + result=1; \ + exit 1; \ + fi; \ + else \ + echo "ERROR: sha512sum is unavailable."; \ + exit 1; \ + fi; \ + fi + +# Default 'make' build rules for an CRAN package +# ----------------------------------------------- +# +# The default 'install.packages' function of R only recognizes 'tar.gz' +# tarballs. But Maneage uses '.tar.lz' format for its archival. So to be +# agnostic to the compression algorithm, we will be using 'tar' externally +# (before entering R), then give the un-compressed directory to +# 'install.packages'. +# +# Parameters: +# 1. package name (without 'r-cran', without the version string) +# 2. version string +# 3. checksum of the package +r_cran_build = \ + pkg=$(strip $(1)); \ + version=$(strip $(2)); \ + checksum=$(strip $(3)); \ + $(call import-source, \ + https://cran.r-project.org/src/contrib, \ + $$checksum, \ + $$tarball, \ + https://cran.r-project.org/src/contrib/00Archive/$$pkg); \ + cd "$(ddir)"; \ + tar -xf $(tdir)/$$tarball; \ + unpackdir=$$pkg-$$version; \ + (printf "install.packages(c(\"$(ddir)/$$unpackdir\"),"; \ + printf 'lib="$(ilibrcrandir)",'; \ + printf 'repos=NULL,'; \ + printf 'type="source")\n'; \ + printf 'quit()\n'; \ + printf 'n\n') | R --no-save; \ + rm -rf $$unpackdir; \ + if [ $$pkg = r-pkgconfig ]; then iname=pkgconfig; \ + else iname=$$pkg; fi; \ + if [ -e "$(ilibrcrandir)"/$$iname/Meta/nsInfo.rds ]; then \ + $(call double-check-R-source, $$checksum) \ + && echo "$$pkg $$version" > $@; \ + else \ + printf "r-cran-$$pkg failed: Meta/nsInfo.rds missing.\n"; \ + exit 1; \ + fi + + + + + +# Necessary programs and libraries +# -------------------------------- +# +# While this Makefile is for R programs, in some cases, we need certain +# programs (like R itself), or libraries for the modules. Comment on +# building R without GUI support ('--without-tcltlk') +# +# Tcl/Tk are a set of tools to provide Graphic User Interface (GUI) support +# in some software. But they are not yet natively built within Maneage, +# primarily because we have higher-priority work right now (if anyone is +# interested, they can ofcourse contribute!). GUI tools in general aren't +# high on our priority list right now because they are generally good for +# human interaction (which is contrary to the reproducible philosophy: +# there will always be human-error and frustration, for example in GUI +# tools the best level of reproducibility is statements like this: "move +# your mouse to button XXX, then click on menu YYY and etc"). A robust +# reproducible solution must be done automatically. +# +# If someone wants to use R's GUI functionalities while investigating for +# their analysis, they can do the GUI part on their host OS +# implementation. Later, they can bring the finalized source into Maneage +# to be automatically run in Maneage. This will also be the recommended way +# to deal with GUI tools later when we do install them within Maneage. +$(ibidir)/r-cran-$(r-cran-version): \ + $(itidir)/texlive \ + $(ibidir)/icu-$(icu-version) \ + $(ibidir)/pcre-$(pcre-version) \ + $(ibidir)/cairo-$(cairo-version) \ + $(ibidir)/libpng-$(libpng-version) \ + $(ibidir)/libjpeg-$(libjpeg-version) \ + $(ibidir)/libtiff-$(libtiff-version) \ + $(ibidir)/libpaper-$(libpaper-version) + +# Prepare the tarball, unpack it and enter the directory. + tarball=R-$(r-cran-version).tar.lz + $(call import-source, $(r-cran-url), $(r-cran-checksum)) + cd $(ddir) + tar -xf $(tdir)/$$tarball + unpackdir=R-$(r-cran-version) + cd $$unpackdir + $(shsrcdir)/prep-source.sh $(ibdir) + +# We need to manually remove the lines with '~autodetect~', they +# cause the configure script to crash in version 4.0.2. They are used +# in relation to Java, and we don't use Java anyway. + sed -i -e '/\~autodetect\~/ s/^/#/g' configure + export R_SHELL=$(SHELL) + ./configure --prefix=$(idir) \ + --without-x \ + --with-pcre1 \ + --disable-java \ + --with-readline \ + --without-tcltk \ + --disable-openmp + make -j$(numthreads) + make install + cd .. + rm -rf R-$(r-cran-version) + cp -p $(dtexdir)/r-cran.tex $(ictdir)/ + echo "R $(r-cran-version) \citep{RIhakaGentleman1996}" > $@ + + + + + +# Non-Maneage'd tarballs +# ---------------------- +# +# CRAN tarballs differ in two aspects from Maneage'd tarballs: +# - CRAN uses '.tar.gz', while Maneage uses 'tar.lz'. +# - CRAN uses 'name_version', while Maneage uses 'name-version'. +# +# So if you add a new R package, or update the version of an existing one +# (that is not yet in Maneage's archive), you need to use the CRAN naming +# format for the 'tarball' variable. + + + + + +# R-CRAN modules +# --------------- +# +# The rules for downloading, compiling and installing any R-CRAN modules +# that are needed should be provided here. Each target (before the colon) +# is first shown with its dependence on prerequisites (which are listed +# after the colon. The default macro 'r_cran_build' will install the +# package without checking on dependencies. + +$(ircrandir)/r-cran-cli-$(r-cran-cli-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-glue-$(r-cran-glue-version) + tarball=cli-$(r-cran-cli-version).tar.lz + $(call r_cran_build, cli, $(r-cran-cli-version), \ + $(r-cran-cli-checksum)) + +$(ircrandir)/r-cran-colorspace-$(r-cran-colorspace-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=colorspace-$(r-cran-colorspace-version).tar.lz + $(call r_cran_build, colorspace, $(r-cran-colorspace-version), \ + $(r-cran-colorspace-checksum)) + +$(ircrandir)/r-cran-cowplot-$(r-cran-cowplot-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-rlang-$(r-cran-rlang-version) \ + $(ircrandir)/r-cran-gtable-$(r-cran-gtable-version) \ + $(ircrandir)/r-cran-scales-$(r-cran-scales-version) \ + $(ircrandir)/r-cran-ggplot2-$(r-cran-ggplot2-version) + tarball=cowplot-$(r-cran-cowplot-version).tar.lz + $(call r_cran_build, cowplot, $(r-cran-cowplot-version), \ + $(r-cran-cowplot-checksum)) + +$(ircrandir)/r-cran-crayon-$(r-cran-crayon-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=crayon-$(r-cran-crayon-version).tar.lz + $(call r_cran_build, crayon, $(r-cran-crayon-version), \ + $(r-cran-crayon-checksum)) + +$(ircrandir)/r-cran-digest-$(r-cran-digest-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=digest-$(r-cran-digest-version).tar.lz + $(call r_cran_build, digest, $(r-cran-digest-version), \ + $(r-cran-digest-checksum)) + +$(ircrandir)/r-cran-farver-$(r-cran-farver-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=farver-$(r-cran-farver-version).tar.lz + $(call r_cran_build, farver, $(r-cran-farver-version), \ + $(r-cran-farver-checksum)) + +$(ircrandir)/r-cran-ellipsis-$(r-cran-ellipsis-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-rlang-$(r-cran-rlang-version) + tarball=ellipsis-$(r-cran-ellipsis-version).tar.lz + $(call r_cran_build, ellipsis, $(r-cran-ellipsis-version), \ + $(r-cran-ellipsis-checksum)) + +$(ircrandir)/r-cran-fansi-$(r-cran-fansi-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=fansi-$(r-cran-fansi-version).tar.lz + $(call r_cran_build, fansi, $(r-cran-fansi-version), \ + $(r-cran-fansi-checksum)) + +$(ircrandir)/r-cran-ggplot2-$(r-cran-ggplot2-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-glue-$(r-cran-glue-version) \ + $(ircrandir)/r-cran-mgcv-$(r-cran-mgcv-version) \ + $(ircrandir)/r-cran-MASS-$(r-cran-MASS-version) \ + $(ircrandir)/r-cran-rlang-$(r-cran-rlang-version) \ + $(ircrandir)/r-cran-withr-$(r-cran-withr-version) \ + $(ircrandir)/r-cran-digest-$(r-cran-digest-version) \ + $(ircrandir)/r-cran-gtable-$(r-cran-gtable-version) \ + $(ircrandir)/r-cran-scales-$(r-cran-scales-version) \ + $(ircrandir)/r-cran-tibble-$(r-cran-tibble-version) \ + $(ircrandir)/r-cran-isoband-$(r-cran-isoband-version) + tarball=ggplot2-$(r-cran-ggplot2-version).tar.lz + $(call r_cran_build, ggplot2, $(r-cran-ggplot2-version), \ + $(r-cran-ggplot2-checksum)) + +$(ircrandir)/r-cran-glue-$(r-cran-glue-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=glue-$(r-cran-glue-version).tar.lz + $(call r_cran_build, glue, $(r-cran-glue-version), \ + $(r-cran-glue-checksum)) + +$(ircrandir)/r-cran-gridExtra-$(r-cran-gridExtra-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-gtable-$(r-cran-gtable-version) + tarball=gridExtra-$(r-cran-gridExtra-version).tar.lz + $(call r_cran_build, gridExtra, $(r-cran-gridExtra-version), \ + $(r-cran-gridExtra-checksum)) + +$(ircrandir)/r-cran-gtable-$(r-cran-gtable-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=gtable-$(r-cran-gtable-version).tar.lz + $(call r_cran_build, gtable, $(r-cran-gtable-version), \ + $(r-cran-gtable-checksum)) + +$(ircrandir)/r-cran-isoband-$(r-cran-isoband-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=isoband-$(r-cran-isoband-version).tar.lz + $(call r_cran_build, isoband, $(r-cran-isoband-version), \ + $(r-cran-isoband-checksum)) + +$(ircrandir)/r-cran-labeling-$(r-cran-labeling-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=labeling-$(r-cran-labeling-version).tar.lz + $(call r_cran_build, labeling, $(r-cran-labeling-version), \ + $(r-cran-labeling-checksum)) + +$(ircrandir)/r-cran-lifecycle-$(r-cran-lifecycle-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-glue-$(r-cran-glue-version) \ + $(ircrandir)/r-cran-rlang-$(r-cran-rlang-version) + tarball=lifecycle-$(r-cran-lifecycle-version).tar.lz + $(call r_cran_build, lifecycle, $(r-cran-lifecycle-version), \ + $(r-cran-lifecycle-checksum)) + +$(ircrandir)/r-cran-magrittr-$(r-cran-magrittr-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=magrittr-$(r-cran-magrittr-version).tar.lz + $(call r_cran_build, magrittr, $(r-cran-magrittr-version), \ + $(r-cran-magrittr-checksum)) + +$(ircrandir)/r-cran-MASS-$(r-cran-MASS-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=MASS-$(r-cran-MASS-version).tar.lz + $(call r_cran_build, MASS, $(r-cran-MASS-version), \ + $(r-cran-MASS-checksum)) + +# The base R-2.0.4 install includes nlme and Matrix. +# https://cran.r-project.org/web/packages/mgcv/index.html +$(ircrandir)/r-cran-mgcv-$(r-cran-mgcv-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=mgcv-$(r-cran-mgcv-version).tar.lz + $(call r_cran_build, mgcv, $(r-cran-mgcv-version), \ + $(r-cran-mgcv-checksum)) + +$(ircrandir)/r-cran-munsell-$(r-cran-munsell-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-colorspace-$(r-cran-colorspace-version) + tarball=munsell-$(r-cran-munsell-version).tar.lz + $(call r_cran_build, munsell, $(r-cran-munsell-version), \ + $(r-cran-munsell-checksum)) + +#TODO: https://cran.r-project.org/web/packages/pillar/index.html +$(ircrandir)/r-cran-pillar-$(r-cran-pillar-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-cli-$(r-cran-cli-version) \ + $(ircrandir)/r-cran-utf8-$(r-cran-utf8-version) \ + $(ircrandir)/r-cran-fansi-$(r-cran-fansi-version) \ + $(ircrandir)/r-cran-rlang-$(r-cran-rlang-version) \ + $(ircrandir)/r-cran-vctrs-$(r-cran-vctrs-version) \ + $(ircrandir)/r-cran-crayon-$(r-cran-crayon-version) \ + $(ircrandir)/r-cran-ellipsis-$(r-cran-ellipsis-version) \ + $(ircrandir)/r-cran-lifecycle-$(r-cran-lifecycle-version) + tarball=pillar-$(r-cran-pillar-version).tar.lz + $(call r_cran_build, pillar, $(r-cran-pillar-version), \ + $(r-cran-pillar-checksum)) + +# Since we have other software packages with the name 'pkgconfig', to avoid +# confusion with those tarballs, we have put a 'r-' prefix in the tarball +# name. If you want to use the CRAN tarball, please correct the name +# accordingly (as described in the comment above this group of rules). +$(ircrandir)/r-cran-pkgconfig-$(r-cran-pkgconfig-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=r-pkgconfig-$(r-cran-pkgconfig-version).tar.lz + $(call r_cran_build, r-pkgconfig, $(r-cran-pkgconfig-version), \ + $(r-cran-pkgconfig-checksum)) + +$(ircrandir)/r-cran-RColorBrewer-$(r-cran-RColorBrewer-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=RColorBrewer-$(r-cran-RColorBrewer-version).tar.lz + $(call r_cran_build, RColorBrewer, $(r-cran-RColorBrewer-version), \ + $(r-cran-RColorBrewer-checksum)) + +$(ircrandir)/r-cran-R6-$(r-cran-R6-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=R6-$(r-cran-R6-version).tar.lz + $(call r_cran_build, R6, $(r-cran-R6-version), $(r-cran-R6-checksum)) + +$(ircrandir)/r-cran-rlang-$(r-cran-rlang-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=rlang-$(r-cran-rlang-version).tar.lz + $(call r_cran_build, rlang, $(r-cran-rlang-version), \ + $(r-cran-rlang-checksum)) + +# https://cran.r-project.org/web/packages/scales/index.html +$(ircrandir)/r-cran-scales-$(r-cran-scales-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-R6-$(r-cran-R6-version) \ + $(ircrandir)/r-cran-farver-$(r-cran-farver-version) \ + $(ircrandir)/r-cran-munsell-$(r-cran-munsell-version) \ + $(ircrandir)/r-cran-labeling-$(r-cran-labeling-version) \ + $(ircrandir)/r-cran-lifecycle-$(r-cran-lifecycle-version) \ + $(ircrandir)/r-cran-viridisLite-$(r-cran-viridisLite-version) \ + $(ircrandir)/r-cran-RColorBrewer-$(r-cran-RColorBrewer-version) + tarball=scales-$(r-cran-scales-version).tar.lz + $(call r_cran_build, scales, $(r-cran-scales-version), \ + $(r-cran-scales-checksum)) + +#https://cran.r-project.org/web/packages/tibble/index.html +$(ircrandir)/r-cran-tibble-$(r-cran-tibble-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-fansi-$(r-cran-fansi-version) \ + $(ircrandir)/r-cran-rlang-$(r-cran-rlang-version) \ + $(ircrandir)/r-cran-vctrs-$(r-cran-vctrs-version) \ + $(ircrandir)/r-cran-pillar-$(r-cran-pillar-version) \ + $(ircrandir)/r-cran-ellipsis-$(r-cran-ellipsis-version) \ + $(ircrandir)/r-cran-magrittr-$(r-cran-magrittr-version) \ + $(ircrandir)/r-cran-lifecycle-$(r-cran-lifecycle-version) \ + $(ircrandir)/r-cran-pkgconfig-$(r-cran-pkgconfig-version) + tarball=tibble-$(r-cran-tibble-version).tar.lz + $(call r_cran_build, tibble, $(r-cran-tibble-version), \ + $(r-cran-tibble-checksum)) + +$(ircrandir)/r-cran-utf8-$(r-cran-utf8-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=utf8-$(r-cran-utf8-version).tar.lz + $(call r_cran_build, utf8, $(r-cran-utf8-version), \ + $(r-cran-utf8-checksum)) + +$(ircrandir)/r-cran-vctrs-$(r-cran-vctrs-version): \ + $(ibidir)/r-cran-$(r-cran-version) \ + $(ircrandir)/r-cran-glue-$(r-cran-glue-version) \ + $(ircrandir)/r-cran-rlang-$(r-cran-rlang-version) \ + $(ircrandir)/r-cran-ellipsis-$(r-cran-ellipsis-version) + tarball=vctrs-$(r-cran-vctrs-version).tar.lz + $(call r_cran_build, vctrs, $(r-cran-vctrs-version), \ + $(r-cran-vctrs-checksum)) + +$(ircrandir)/r-cran-viridisLite-$(r-cran-viridisLite-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=viridisLite-$(r-cran-viridisLite-version).tar.lz + $(call r_cran_build, viridisLite, $(r-cran-viridisLite-version), \ + $(r-cran-viridisLite-checksum)) + +$(ircrandir)/r-cran-withr-$(r-cran-withr-version): \ + $(ibidir)/r-cran-$(r-cran-version) + tarball=withr-$(r-cran-withr-version).tar.lz + $(call r_cran_build, withr, $(r-cran-withr-version), \ + $(r-cran-withr-checksum)) diff --git a/reproduce/software/make/xorg.mk b/reproduce/software/make/xorg.mk index 3178cb4..864c32a 100644 --- a/reproduce/software/make/xorg.mk +++ b/reproduce/software/make/xorg.mk @@ -4,7 +4,7 @@ # !!!!! IMPORTANT NOTES !!!!! # # This Makefile will be loaded into 'high-level.mk', which is called by the -# `./project configure' script. It is not included into the project +# './project configure' script. It is not included into the project # afterwards. # # This Makefile contains instructions to build all the Xorg-related @@ -14,8 +14,8 @@ # # ------------------------------------------------------------------------ # -# Copyright (C) 2021 Mohammad Akhlaghi <mohammad@akhlaghi.org> -# Copyright (C) 2021 Raul Infante-Sainz <infantesainz@gmail.com> +# Copyright (C) 2021-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2021-2025 Raul Infante-Sainz <infantesainz@gmail.com> # # This Makefile is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -57,7 +57,7 @@ $(idir)/etc/profile.d/xorg.sh: | $(idir)/etc/profile.d $(ibidir)/util-macros-$(util-macros-version): \ $(idir)/etc/profile.d/xorg.sh \ $(ibidir)/automake-$(automake-version) - tarball=util-macros-$(util-macros-version).tar.bz2 + tarball=util-macros-$(util-macros-version).tar.lz $(call import-source, $(util-macros-url), $(util-macros-checksum)) $(call gbuild, util-macros-$(util-macros-version),,$(XORG_CONFIG),V=1) echo "util-macros (Xorg) $(util-macros-version)" > $@ @@ -65,21 +65,21 @@ $(ibidir)/util-macros-$(util-macros-version): \ # Necessaary headers to define the Xorg protocols. $(ibidir)/xorgproto-$(xorgproto-version): \ $(ibidir)/util-macros-$(util-macros-version) - tarball=xorgproto-$(xorgproto-version).tar.bz2 + tarball=xorgproto-$(xorgproto-version).tar.lz $(call import-source, $(xorg-proto-url), $(xorgproto-checksum)) $(call gbuild, xorgproto-$(xorgproto-version),,$(XORG_CONFIG),V=1) echo "xorgproto $(xorgproto-version)" > $@ # Necessaary headers to define the Xorg protocols. $(ibidir)/libxau-$(libxau-version): $(ibidir)/xorgproto-$(xorgproto-version) - tarball=libXau-$(libxau-version).tar.bz2 + tarball=libXau-$(libxau-version).tar.lz $(call import-source, $(libaxu-url), $(libxau-checksum)) $(call gbuild, libXau-$(libxau-version),,$(XORG_CONFIG), V=1) echo "libXau (Xorg) $(libxau-version)" > $@ # Library implementing the X Display Manager Control Protocol. $(ibidir)/libxdmcp-$(libxdmcp-version): $(ibidir)/libxau-$(libxau-version) - tarball=libXdmcp-$(libxdmcp-version).tar.bz2 + tarball=libXdmcp-$(libxdmcp-version).tar.lz $(call import-source, $(libxdmcp-url), $(libxdmcp-checksum)) $(call gbuild, libXdmcp-$(libxdmcp-version),,$(XORG_CONFIG), V=1) echo "libXdmcp (Xorg) $(libxdmcp-version)" > $@ @@ -88,7 +88,7 @@ $(ibidir)/libxdmcp-$(libxdmcp-version): $(ibidir)/libxau-$(libxau-version) $(ibidir)/xcb-proto-$(xcb-proto-version): \ $(ibidir)/python-$(python-version) \ $(ibidir)/libxml2-$(libxml2-version) - tarball=xcb-proto-$(xcb-proto-version).tar.xz + tarball=xcb-proto-$(xcb-proto-version).tar.lz $(call import-source, $(xcb-proto-url), $(xcb-proto-checksum)) $(call gbuild, xcb-proto-$(xcb-proto-version),,$(XORG_CONFIG), V=1) echo "XCB-proto (Xorg) $(xcb-proto-version)" > $@ @@ -98,7 +98,7 @@ $(ibidir)/libxcb-$(libxcb-version): \ $(ibidir)/libxdmcp-$(libxdmcp-version) \ $(ibidir)/xcb-proto-$(xcb-proto-version) \ $(ibidir)/libpthread-stubs-$(libpthread-stubs-version) - tarball=libxcb-$(libxcb-version).tar.xz + tarball=libxcb-$(libxcb-version).tar.lz $(call import-source, $(libxcb-url), $(libxcb-checksum)) $(call gbuild, libxcb-$(libxcb-version),, \ $(XORG_CONFIG) --without-doxygen, \ @@ -107,7 +107,7 @@ $(ibidir)/libxcb-$(libxcb-version): \ $(ibidir)/libpthread-stubs-$(libpthread-stubs-version): \ $(ibidir)/automake-$(automake-version) - tarball=libpthread-stubs-$(libpthread-stubs-version).tar.gz + tarball=libpthread-stubs-$(libpthread-stubs-version).tar.lz $(call import-source, $(libpthread-stubs-url), $(libpthread-stubs-checksum)) $(call gbuild, libpthread-stubs-$(libpthread-stubs-version),, V=1) echo "libpthread-stubs (Xorg) $(libpthread-stubs-version)" > $@ @@ -116,21 +116,22 @@ $(ibidir)/libpthread-stubs-$(libpthread-stubs-version): \ $(ibidir)/fontconfig-$(fontconfig-version): \ $(ibidir)/gperf-$(gperf-version) \ $(ibidir)/expat-$(expat-version) \ + $(ibidir)/python-$(python-version) \ $(ibidir)/libxml2-$(libxml2-version) \ $(ibidir)/freetype-$(freetype-version) \ $(ibidir)/util-linux-$(util-linux-version) - # Import the source. - tarball=fontconfig-$(fontconfig-version).tar.bz2 +# Import the source. + tarball=fontconfig-$(fontconfig-version).tar.lz $(call import-source, $(fontconfig-url), $(fontconfig-checksum)) - # Add the extra environment variables for using 'libuuid' of - # 'util-linux'. +# Add the extra environment variables for using 'libuuid' of +# 'util-linux'. ulidir=$(idir)/util-linux export LDFLAGS="-L$$ulidir/lib $(LDFLAGS)" export CPPFLAGS="-I$$ulidir/include $(CPPFLAGS)" export PKG_CONFIG_PATH=$(PKG_CONFIG_PATH):$$ulidir/lib/pkgconfig - # Build it. +# Build it. $(call gbuild, fontconfig-$(fontconfig-version),, \ $(XORG_CONFIG) --sysconfdir=$(idir)/etc \ --disable-docs, V=1 -j$(numthreads)) @@ -139,27 +140,27 @@ $(ibidir)/fontconfig-$(fontconfig-version): \ $(ibidir)/xtrans-$(xtrans-version): \ $(ibidir)/libxcb-$(libxcb-version) \ $(ibidir)/fontconfig-$(fontconfig-version) - tarball=xtrans-$(xtrans-version).tar.bz2 + tarball=xtrans-$(xtrans-version).tar.lz $(call import-source, $(xtrans-url), $(xtrans-checksum)) $(call gbuild, xtrans-$(xtrans-version),,$(XORG_CONFIG), V=1) echo "xtrans (Xorg) $(xtrans-version)" > $@ $(ibidir)/libx11-$(libx11-version): $(ibidir)/xtrans-$(xtrans-version) - tarball=libX11-$(libx11-version).tar.bz2 + tarball=libX11-$(libx11-version).tar.lz $(call import-source, $(libx11-url), $(libx11-checksum)) $(call gbuild, libX11-$(libx11-version),,$(XORG_CONFIG), \ -j$(numthreads) V=1) echo "X11 library $(libx11-version)" > $@ $(ibidir)/libxext-$(libxext-version): $(ibidir)/libx11-$(libx11-version) - tarball=libXext-$(libxext-version).tar.bz2 + tarball=libXext-$(libxext-version).tar.lz $(call import-source, $(libxext-url), $(libxext-checksum)) $(call gbuild, libXext-$(libxext-version),,$(XORG_CONFIG), \ -j$(numthreads) V=1) echo "libXext $(libxext-version)" > $@ $(ibidir)/libice-$(libice-version): $(ibidir)/libxext-$(libxext-version) - tarball=libICE-$(libice-version).tar.bz2 + tarball=libICE-$(libice-version).tar.lz $(call import-source, $(libice-url), $(libice-checksum)) $(call gbuild, libICE-$(libice-version),, \ $(XORG_CONFIG) ICE_LIBS=-lpthread, \ @@ -167,14 +168,14 @@ $(ibidir)/libice-$(libice-version): $(ibidir)/libxext-$(libxext-version) echo "libICE $(libice-version)" > $@ $(ibidir)/libsm-$(libsm-version): $(ibidir)/libice-$(libice-version) - tarball=libSM-$(libsm-version).tar.bz2 + tarball=libSM-$(libsm-version).tar.lz $(call import-source, $(libsm-url), $(libsm-checksum)) $(call gbuild, libSM-$(libsm-version),, \ $(XORG_CONFIG), -j$(numthreads) V=1) echo "libSM $(libsm-version)" > $@ $(ibidir)/libxt-$(libxt-version): $(ibidir)/libsm-$(libsm-version) - tarball=libXt-$(libxt-version).tar.bz2 + tarball=libXt-$(libxt-version).tar.lz $(call import-source, $(libxt-url), $(libxt-checksum)) $(call gbuild, libXt-$(libxt-version),, \ $(XORG_CONFIG), -j$(numthreads) V=1) |