diff options
Diffstat (limited to 'reproduce/software/make/high-level.mk')
-rw-r--r-- | reproduce/software/make/high-level.mk | 720 |
1 files changed, 720 insertions, 0 deletions
diff --git a/reproduce/software/make/high-level.mk b/reproduce/software/make/high-level.mk new file mode 100644 index 0000000..f7b1f4f --- /dev/null +++ b/reproduce/software/make/high-level.mk @@ -0,0 +1,720 @@ +# Build the project's dependencies (programs and libraries). +# +# ------------------------------------------------------------------------ +# !!!!! IMPORTANT NOTES !!!!! +# +# This Makefile will be run by the initial `./configure' script. It is not +# included into the reproduction pipe after that. +# +# ------------------------------------------------------------------------ +# +# Copyright (C) 2018-2019 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. +# +# A copy of the GNU General Public License is available at +# <http://www.gnu.org/licenses/>. + + + +# Top level environment +include reproduce/software/make/build-rules.mk +include reproduce/software/config/installation/LOCAL.mk +include reproduce/software/config/installation/texlive.mk +include reproduce/software/config/installation/versions.mk + +lockdir = $(BDIR)/locks +tdir = $(BDIR)/software/tarballs +ddir = $(BDIR)/software/build-tmp +idir = $(BDIR)/software/installed +ibdir = $(BDIR)/software/installed/bin +ildir = $(BDIR)/software/installed/lib +dtexdir = $(shell pwd)/reproduce/software/bibtex +ibidir = $(BDIR)/software/installed/version-info/bin +ilidir = $(BDIR)/software/installed/version-info/lib +itidir = $(BDIR)/software/installed/version-info/tex +ictdir = $(BDIR)/software/installed/version-info/cite +ipydir = $(BDIR)/software/installed/version-info/python + +# Define the top-level programs to build (installed in `.local/bin'). +# +# About ATLAS: currently the template does not depend on ATLAS but many +# high level software depend on it. The current rule for ATLAS is tested +# successfully on Mac (only static) and GNU/Linux (shared and static). But, +# since it takes a few hours to build, it is not currently a target. +top-level-libraries = # atlas +top-level-python = astroquery matplotlib +top-level-programs = gnuastro metastore +all: $(foreach p, $(top-level-libraries), $(ilidir)/$(p)) \ + $(foreach p, $(top-level-programs), $(ibidir)/$(p)) \ + $(foreach p, $(top-level-python), $(ipydir)/$(p)) \ + $(itidir)/texlive + +# Other basic environment settings: We are only including the host +# operating system's PATH environment variable (after our own!) for the +# compiler and linker. For the library binaries and headers, we are only +# using our internally built libraries. +# +# To investigate: +# +# 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 +# user's environment. +.ONESHELL: +.SHELLFLAGS := --noprofile --norc -ec +export CCACHE_DISABLE := 1 +export PATH := $(ibdir) +export SHELL := $(ibdir)/bash +export CPPFLAGS := -I$(idir)/include +export PKG_CONFIG_PATH := $(ildir)/pkgconfig +export PKG_CONFIG_LIBDIR := $(ildir)/pkgconfig +export LD_RUN_PATH := $(ildir):$(il64dir) +export LD_LIBRARY_PATH := $(ildir):$(il64dir) +export LDFLAGS := $(rpath_command) -L$(ildir) + + +# We want the download to happen on a single thread. So we need to define a +# lock, and call a special script we have written for this job. These are +# placed here because we want them both in the `high-level.mk' and +# `python.mk'. +$(lockdir): | $(BDIR); mkdir $@ +downloader="wget --no-use-server-timestamps -O"; +downloadwrapper = ./reproduce/analysis/bash/download-multi-try + + + + + +# Python packages +include reproduce/software/make/python.mk + + + + + +# Tarballs +# -------- +# +# All the necessary tarballs are defined and prepared with this rule. +# +# Note that we want the tarballs to follow the convention of NAME-VERSION +# before the `tar.XX' prefix. For those programs that don't follow this +# convention, but include the name/version in their tarball names with +# another format, we'll do the modification before the download so the +# downloaded file has our desired format. +tarballs = $(foreach t, cfitsio-$(cfitsio-version).tar.gz \ + atlas-$(atlas-version).tar.bz2 \ + cmake-$(cmake-version).tar.gz \ + curl-$(curl-version).tar.gz \ + freetype-$(freetype-version).tar.gz \ + fftw-$(fftw-version).tar.gz \ + ghostscript-$(ghostscript-version).tar.gz \ + git-$(git-version).tar.xz \ + gnuastro-$(gnuastro-version).tar.lz \ + gsl-$(gsl-version).tar.gz \ + hdf5-$(hdf5-version).tar.gz \ + install-tl-unx.tar.gz \ + jpegsrc.$(libjpeg-version).tar.gz \ + lapack-$(lapack-version).tar.gz \ + libbsd-$(libbsd-version).tar.xz \ + libpng-$(libpng-version).tar.xz \ + libgit2-$(libgit2-version).tar.gz \ + metastore-$(metastore-version).tar.gz \ + openmpi-$(openmpi-version).tar.gz \ + openblas-$(openblas-version).tar.gz \ + tiff-$(libtiff-version).tar.gz \ + wcslib-$(wcslib-version).tar.bz2 \ + , $(tdir)/$(t) ) +$(tarballs): $(tdir)/%: | $(lockdir) + if [ -f $(DEPENDENCIES-DIR)/$* ]; then + cp $(DEPENDENCIES-DIR)/$* $@ + else + # Remove all numbers, `-' and `.' from the tarball name so we can + # search more easily only with the program name. + n=$$(echo $* | sed -e's/[0-9\-]/ /g' -e's/\./ /g' \ + | awk '{print $$1}' ) + + # Set the top download link of the requested tarball. + mergenames=1 + if [ $$n = cfitsio ]; then + mergenames=0 + v=$$(echo $(cfitsio-version) | sed -e's/\.//' \ + | awk '{l=length($$1); \ + printf (l==4 ? "%d\n" \ + : (l==3 ? "%d0\n" \ + : (l==2 ? "%d00\n" \ + : "%d000\n") ), $$1)}') + w=https://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio$$v.tar.gz + elif [ $$n = atlas ]; then + mergenames=0 + w=https://sourceforge.net/projects/math-atlas/files/Stable/$(atlas-version)/atlas$(atlas-version).tar.bz2/download + elif [ $$n = cmake ]; then + mergenames=0 + majv=$$(echo $(cmake-version) \ + | sed -e's/\./ /' \ + | awk '{printf("%d.%d", $$1, $$2)}') + w=https://cmake.org/files/v$$majv/cmake-$(cmake-version).tar.gz + elif [ $$n = curl ]; then w=https://curl.haxx.se/download + elif [ $$n = fftw ]; then w=ftp://ftp.fftw.org/pub/fftw + elif [ $$n = freetype ]; then w=https://download.savannah.gnu.org/releases/freetype + elif [ $$n = hdf ]; then + mergenames=0 + majorver=$$(echo $(hdf5-version) | sed -e 's/\./ /g' | awk '{printf("%d.%d", $$1, $$2)}') + w=https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-$$majorver/hdf5-$(hdf5-version)/src/$* + elif [ $$n = ghostscript ]; then w=https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926 + elif [ $$n = git ]; then w=http://mirrors.edge.kernel.org/pub/software/scm/git + elif [ $$n = gnuastro ]; then w=http://ftp.gnu.org/gnu/gnuastro + elif [ $$n = gsl ]; then w=http://ftp.gnu.org/gnu/gsl + elif [ $$n = install ]; then w=http://mirror.ctan.org/systems/texlive/tlnet + elif [ $$n = jpegsrc ]; then w=http://ijg.org/files + elif [ $$n = lapack ]; then w=http://www.netlib.org/lapack + elif [ $$n = libbsd ]; then w=http://libbsd.freedesktop.org/releases + elif [ $$n = libpng ]; then w=https://download.sourceforge.net/libpng + elif [ $$n = libgit ]; then + mergenames=0 + w=https://github.com/libgit2/libgit2/archive/v$(libgit2-version).tar.gz + elif [ $$n = metastore ]; then w=http://akhlaghi.org/src + elif [ $$n = openblas ]; then + mergenames=0 + w=https://github.com/xianyi/OpenBLAS/archive/v$(openblas-version).tar.gz + elif [ $$n = openmpi ]; then + mergenames=0 + majorver=$$(echo $(openmpi-version) | sed -e 's/\./ /g' | awk '{printf("%d.%d", $$1, $$2)}') + w=https://download.open-mpi.org/release/open-mpi/v$$majorver/$* + elif [ $$n = tiff ]; then w=https://download.osgeo.org/libtiff + elif [ $$n = wcslib ]; then w=ftp://ftp.atnf.csiro.au/pub/software/wcslib + else + echo; echo; echo; + echo "'$$n' not recognized as a dependency name to download." + echo; echo; echo; + exit 1 + fi + + # Download the requested tarball. Note that some packages may not + # follow our naming convention (where the package name is merged + # with its version number). In such cases, `w' will be the full + # address, not just the top directory address. But since we are + # storing all the tarballs in one directory, we want it to have + # the same naming convention, so we'll download it to a temporary + # name, then rename that. + if [ $$mergenames = 1 ]; then tarballurl=$$w/"$*" + else tarballurl=$$w + fi + + # Download using the script specially defined for this job. + touch $(lockdir)/download + downloader="wget --no-use-server-timestamps -O" + $(downloadwrapper) "$$downloader" $(lockdir)/download \ + $$tarballurl $@ + fi + + + + + +# Libraries +# --------- +# +# 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 as targets and there are different conventions for shared +# library names. +# +# For the actual build, the same compiler that built the library will build +# the programs, so exact knowledge of the suffix is ultimately irrelevant +# for us here. So, we'll make an `$(ildir)/built' directory and make a +# simple plain text file in it with the basic library name (an no prefix) +# and create/write into it when the library is successfully built. +$(ilidir)/cfitsio: $(tdir)/cfitsio-$(cfitsio-version).tar.gz \ + $(ibidir)/curl + + # CFITSIO hard-codes the absolute address of cURL's `curl-config' + # program (which gives the necessary header and linking + # information) into the configure script. So we'll have to modify + # it manually before doing the standard build. + topdir=$(pwd); cd $(ddir); tar xf $< + customtar=cfitsio-$(cfitsio-version)-custom.tar.gz + sed cfitsio/configure \ + -e's|/usr/bin/curl-config|$(ibdir)/curl-config|g' \ + > cfitsio/configure_tmp + mv cfitsio/configure_tmp cfitsio/configure + chmod +x cfitsio/configure + tar cf $$customtar cfitsio + cd $$topdir + + # Continue the standard build on the customized tarball. + $(call gbuild, $$customtar, cfitsio, static, \ + --enable-sse2 --enable-reentrant) \ + && rm $$customtar \ + && echo "CFITSIO $(cfitsio-version)" > $@ + +$(ilidir)/gsl: $(tdir)/gsl-$(gsl-version).tar.gz + $(call gbuild, $<, gsl-$(gsl-version), static) \ + && echo "GNU Scientific Library $(gsl-version)" > $@ + +$(ilidir)/fftw: $(tdir)/fftw-$(fftw-version).tar.gz + $(call gbuild, $<, fftw-$(fftw-version), static, \ + --enable-shared) \ + && cp $(dtexdir)/fftw.tex $(ictdir)/ \ + && echo "FFTW $(fftw-version) \citep{fftw}" > $@ + +# Freetype is necessary to install matplotlib +$(ilidir)/freetype: $(tdir)/freetype-$(freetype-version).tar.gz \ + $(ilidir)/libpng + $(call gbuild, $<, freetype-$(freetype-version), static) \ + && echo "FreeType $(freetype-version)" > $@ + +$(ilidir)/hdf5: $(tdir)/hdf5-$(hdf5-version).tar.gz \ + $(ilidir)/openmpi + export CC=mpicc; \ + export FC=mpif90; \ + $(call gbuild, $<, hdf5-$(hdf5-version), static, \ + --enable-parallel \ + --enable-fortran, V=1) \ + && echo "HDF5 library $(hdf5-version)" > $@ + +$(ilidir)/libbsd: $(tdir)/libbsd-$(libbsd-version).tar.xz + $(call gbuild, $<, libbsd-$(libbsd-version), static,,V=1) \ + && echo "Libbsd $(libbsd-version)" > $@ + +$(ilidir)/libjpeg: $(tdir)/jpegsrc.$(libjpeg-version).tar.gz + $(call gbuild, $<, jpeg-9b, static) \ + && echo "Libjpeg $(libjpeg-version)" > $@ + +$(ilidir)/libpng: $(tdir)/libpng-$(libpng-version).tar.xz + $(call gbuild, $<, libpng-$(libpng-version), static) \ + && echo "Libpng $(libpng-version)" > $@ + +$(ilidir)/libtiff: $(tdir)/tiff-$(libtiff-version).tar.gz \ + $(ilidir)/libjpeg + $(call gbuild, $<, tiff-$(libtiff-version), static, \ + --disable-webp --disable-zstd) \ + && echo "Libtiff $(libtiff-version)" > $@ + +$(ilidir)/openmpi: $(tdir)/openmpi-$(openmpi-version).tar.gz + $(call gbuild, $<, openmpi-$(openmpi-version), static, , V=1) \ + && echo "OpenMPI $(openmpi-version)" > $@ + +$(ilidir)/atlas: $(tdir)/atlas-$(atlas-version).tar.bz2 \ + $(tdir)/lapack-$(lapack-version).tar.gz + + # 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 + f=3.6.1.dylib + core=$$(sysctl hw.cpufrequency | awk '{print $$2/1000000}') + clangflag="--force-clang=$(ibdir)/clang" + else + s=so + m=so.3 + f=so.3.6.1 + clangflag= + core=$$(cat /proc/cpuinfo | grep "cpu MHz" \ + | head -n 1 \ + | sed "s/.*: \([0-9.]*\).*/\1/") + fi + + # See if the shared libraries should be build for a single CPU + # thread or multiple threads. + N=$$(nproc) + srcdir=$$(pwd)/reproduce/src/make + if [ $$N = 1 ]; then + sharedmk=$$srcdir/dependencies-atlas-single.mk + else + sharedmk=$$srcdir/dependencies-atlas-multiple.mk + fi + + # The linking step here doesn't recognize the `-Wl' in the + # `rpath_command'. + export LDFLAGS=-L$(ildir) + cd $(ddir) \ + && tar xf $< \ + && cd ATLAS \ + && rm -rf build \ + && mkdir build \ + && cd build \ + && ../configure -b 64 -D c -DPentiumCPS=$$core \ + --with-netlib-lapack-tarfile=$(word 2, $^) \ + --cripple-atlas-performance \ + -Fa alg -fPIC --shared $$clangflag \ + --prefix=$(idir) \ + && make \ + && if [ "x$(on_mac_os)" != xyes ]; then \ + cd lib && make -f $$sharedmk && cd .. \ + && for l in lib/*.$$s*; do \ + patchelf --set-rpath $(ildir) $$l; done \ + && cp -d lib/*.$$s* $(ildir) \ + && ln -fs $(ildir)/libblas.$$s $(ildir)/libblas.$$m \ + && ln -fs $(ildir)/libf77blas.$$s $(ildir)/libf77blas.$$m \ + && ln -fs $(ildir)/liblapack.$$f $(ildir)/liblapack.$$s \ + && ln -fs $(ildir)/liblapack.$$f $(ildir)/liblapack.$$m; \ + fi \ + && 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). + 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. + if [ -f $(ildir)/libatlas.a ]; then \ + echo "ATLAS $(atlas-version)" > $@; \ + fi + +$(ilidir)/openblas: $(tdir)/openblas-$(openblas-version).tar.gz + if [ x$(on_mac_os) = xyes ]; then \ + export CC=clang; \ + fi; \ + cd $(ddir) \ + && tar xf $< \ + && cd OpenBLAS-$(openblas-version) \ + && make \ + && make PREFIX=$(idir) install \ + && cd .. \ + && rm -rf OpenBLAS-$(openblas-version) \ + && echo "OpenBLAS $(openblas-version)" > $@ + + + + +# Libraries with special attention on Mac OS +# ------------------------------------------ +# +# Libgit2 and WCSLIB don't set their installation path, or don't do it +# properly, in their finally installed shared libraries. But since we are +# linking everything (including OpenSSL and its dependencies) dynamically, +# we need to also make a shared libraries and can't use static +# libraries. So for Mac OS systems we have to correct their addresses +# manually. +# +# For example, Libgit2 page recommends doing a static build, especially for +# 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 +$(ilidir)/libgit2: $(tdir)/libgit2-$(libgit2-version).tar.gz \ + $(ibidir)/cmake \ + $(ibidir)/curl + # Build and install the library. + $(call cbuild, $<, libgit2-$(libgit2-version), static, \ + -DUSE_SSH=OFF -DBUILD_CLAR=OFF \ + -DTHREADSAFE=ON ) + + # Correct the shared library absolute address if necessary. + if [ x$(on_mac_os) = xyes ]; then + install_name_tool -id $(ildir)/libgit2.26.dylib \ + $(ildir)/libgit2.26.dylib + fi + + # Write the target file. + echo "Libgit2 $(libgit2-version)" > $@ + +$(ilidir)/wcslib: $(tdir)/wcslib-$(wcslib-version).tar.bz2 \ + $(ilidir)/cfitsio + # Build and install the library. + $(call gbuild, $<, wcslib-$(wcslib-version), , \ + LIBS="-pthread -lcurl -lm" \ + --with-cfitsiolib=$(ildir) \ + --with-cfitsioinc=$(idir)/include \ + --without-pgplot --disable-fortran) + + # Correct the shared library absolute address if necessary. + if [ x$(on_mac_os) = xyes ]; then + install_name_tool -id $(ildir)/libwcs.6.2.dylib \ + $(ildir)/libwcs.6.2.dylib; + fi + + # Write the target file. + echo "WCSLIB $(wcslib-version)" > $@ + + + + + +# Programs +# -------- +# +# CMake can be built with its custom `./bootstrap' script. +$(ibidir)/cmake: $(tdir)/cmake-$(cmake-version).tar.gz \ + $(ibidir)/curl + # 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. + if [ x$(on_mac_os) = xyes ]; then \ + export CC=clang; \ + export CXX=clang++; \ + fi; \ + cd $(ddir) \ + && rm -rf cmake-$(cmake-version) \ + && tar xf $< \ + && cd cmake-$(cmake-version) \ + && ./bootstrap --prefix=$(idir) --system-curl --system-zlib \ + --system-bzip2 --system-liblzma --no-qt-gui \ + && make LIBS="$$LIBS -lssl -lcrypto -lz" VERBOSE=1 \ + && make install \ + && cd .. \ + && rm -rf cmake-$(cmake-version) \ + && echo "CMake $(cmake-version)" > $@ + +# cURL (and its library, which is needed by several programs here) 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 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: $(tdir)/curl-$(curl-version).tar.gz + $(call gbuild, $<, curl-$(curl-version), , \ + LIBS="-pthread" \ + --with-zlib=$(ildir) \ + --with-ssl=$(idir) \ + --without-mesalink \ + --with-ca-fallback \ + --without-librtmp \ + --without-libidn2 \ + --without-wolfssl \ + --without-brotli \ + --without-gnutls \ + --without-cyassl \ + --without-libpsl \ + --without-axtls \ + --disable-ldaps \ + --disable-ldap \ + --without-nss, V=1) \ + && echo "cURL $(curl-version)" > $@ + +$(ibidir)/ghostscript: $(tdir)/ghostscript-$(ghostscript-version).tar.gz + $(call gbuild, $<, ghostscript-$(ghostscript-version)) \ + && echo "GPL Ghostscript $(ghostscript-version)" > $@ + +$(ibidir)/git: $(tdir)/git-$(git-version).tar.xz \ + $(ibidir)/curl + $(call gbuild, $<, git-$(git-version), static, \ + --without-tcltk --with-shell=$(ibdir)/bash, \ + V=1) \ + && echo "Git $(git-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. +ifeq ($(on_mac_os),yes) +needlibbsd = +else +needlibbsd = $(ilidir)/libbsd +endif +$(ibidir)/metastore: $(tdir)/metastore-$(metastore-version).tar.gz \ + $(needlibbsd) \ + $(ibidir)/git + + # The build command below will change the current directory of this + # build, so we'll fix its value here. + current_dir=$$(pwd) + + # 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. + $(call gbuild, $<, metastore-$(metastore-version), static,, \ + NO_XATTR=1 V=1,,pwd,PREFIX=$(idir)) + + # Write the relevant hooks into this system's Git hooks, so Git + # calls metastore properly on every commit and every checkout. + # + # Note that the -O and -G options used here are currently only in a + # fork of `metastore' currently hosted at: + # https://github.com/mohammad-akhlaghi/metastore + user=$$(whoami) + group=$$(groups | awk '{print $$1}') + cd $$current_dir + if [ -f $(ibdir)/metastore ]; then + 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/bash/git-$$f > .git/hooks/$$f + chmod +x .git/hooks/$$f + echo "Metastore (forked) $(metastore-version)" > $@ + done + 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 the project." + echo "So we won't stop the configuration because it wasn't built." + echo "*****************" + fi + +# The order of dependencies is based on how long they take to build (how +# large they are): Libgit2 depends on CMake which takes a VERY long time to +# build. Also, Ghostscript and GSL are relatively large packages. So when +# building in parallel, its better to have these packages start building +# early. +$(ibidir)/gnuastro: $(tdir)/gnuastro-$(gnuastro-version).tar.lz \ + $(ilidir)/gsl \ + $(ilidir)/wcslib \ + $(ilidir)/libjpeg \ + $(ilidir)/libtiff \ + $(ilidir)/libgit2 \ + $(ibidir)/ghostscript +ifeq ($(static_build),yes) + staticopts="--enable-static=yes --enable-shared=no"; +endif + $(call gbuild, $<, gnuastro-$(gnuastro-version), static, \ + $$staticopts, -j$(numthreads), \ + make check -j$(numthreads)) \ + && cp $(dtexdir)/gnuastro.tex $(ictdir)/ \ + && echo "GNU Astronomy Utilities $(gnuastro-version) \citep{gnuastro}" > $@ + + + + + + + + + + + + + + + + + + + + +# Since we want to avoid complicating the PATH, we are putting a symbolic +# link of all the TeX Live executables in $(ibdir). But symbolic links are +# 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 +# not. +$(itidir)/texlive-ready-tlmgr: $(tdir)/install-tl-unx.tar.gz \ + reproduce/software/config/installation/texlive.conf + + # 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 + cd install-tl-* + sed -e's|@installdir[@]|$(idir)|g' \ + $$topdir/reproduce/software/config/installation/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. + if ./install-tl --profile=texlive.conf; then + + # Put a symbolic link of the TeX Live executables in `ibdir'. The + # main problem is that the year and build system (for example + # `x86_64-linux') are also in the directory names, making it hard + # to be generic. We are using wildcards here, but only in this + # Makefile, not in any other. + ln -fs $(idir)/texlive/20*/bin/*/* $(ibdir)/ + + # Register that the build was successful. + echo "TeX Live is ready." > $@ + else + echo "NOT!" > $@ + fi + + # Clean up + cd .. + rm -rf install-tl-* + + + + + +# To keep things modular and simple, we'll break up the installation of TeX +# Live itself (only very basic TeX and LaTeX) and the installation of its +# necessary packages into two packages. +$(itidir)/texlive: reproduce/software/config/installation/texlive.mk \ + $(itidir)/texlive-ready-tlmgr + + # 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 + # 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'. + ln -fs $(idir)/texlive/20*/bin/*/* $(ibdir)/ + + # Get all the necessary versions. + texlive=$$(pdflatex --version | awk 'NR==1' | sed 's/.*(\(.*\))/\1/' \ + | awk '{print $$NF}'); + + # Package names and versions. + tlmgr info $(texlive-packages) --only-installed | awk \ + '$$1=="package:" {version=0; \ + if($$NF=="tex-gyre") name="texgyre"; \ + else name=$$NF} \ + $$1=="cat-version:" {version=$$NF} \ + $$1=="cat-date:" {if(version==0) version=$$2; \ + printf("%s %s\n", name, version)}' >> $@ + fi |