diff options
Diffstat (limited to 'reproduce/analysis/make/initialize.mk')
-rw-r--r-- | reproduce/analysis/make/initialize.mk | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/reproduce/analysis/make/initialize.mk b/reproduce/analysis/make/initialize.mk new file mode 100644 index 0000000..a034494 --- /dev/null +++ b/reproduce/analysis/make/initialize.mk @@ -0,0 +1,339 @@ +# Project initialization. +# +# 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/>. + + + + + +# High-level directory definitions +# -------------------------------- +# +# Basic directories that are used throughout the project. +# +# Locks are used to make sure that an operation is done in series not in +# parallel (even if Make is run in parallel with the `-j' option). The most +# common case is downloads which are better done in series and not in +# parallel. Also, some programs may not be thread-safe, therefore it will +# be necessary to put a lock on them. This project uses the `flock' program +# to achieve this. +texdir = $(BDIR)/tex +lockdir = $(BDIR)/locks +indir = $(BDIR)/inputs +mtexdir = $(texdir)/macros +bashdir = reproduce/analysis/bash +pconfdir = reproduce/analysis/config +installdir = $(BDIR)/software/installed +# --------- Delete for no Gnuastro --------- +gconfdir = reproduce/software/config/gnuastro +# ------------------------------------------ + + + + + +# TeX build directory +# ------------------ +# +# In scenarios where multiple users are working on the project +# simultaneously, they can't all build the final paper together, there will +# be conflicts! It is possible to manage the working on the analysis, so no +# conflict is caused in that phase, but it would be very slow to only let +# one of the project members to build the paper at every instance +# (independent parts of the paper can be added to it independently). To fix +# this problem, when we are in a group setting, we'll use the user's ID to +# create a separate LaTeX build directory for each user. +# +# The same logic applies to the final paper PDF: each user will create a +# separte final PDF (for example `paper-user1.pdf' and `paper-user2.pdf') +# and no `paper.pdf' will be built. This isn't a problem because +# `initialize.tex' is a .PHONY prerequisite, so the rule to build the final +# paper is always executed (even if it is present and nothing has +# changed). So in terms of over-all efficiency and processing steps, this +# doesn't change anything. +ifeq (x$(GROUP-NAME),x) +texbdir = $(texdir)/build +final-paper = paper.pdf +else +user = $(shell whoami) +texbdir = $(texdir)/build-$(user) +final-paper = paper-$(user).pdf +endif +tikzdir = $(texbdir)/tikz + + + + + +# Original system environment +# --------------------------- +# +# Before defining the local sub-environment here, we'll need to save the +# system's environment for some scenarios (for example after `clean'ing the +# built programs). +sys-path := $(PATH) +sys-rm := $(shell which rm) +curdir := $(shell echo $$(pwd)) + + + + + +# High level environment +# ---------------------- +# +# We want the full recipe to be executed in one call to the shell. Also we +# want Make to run the specific version of Bash that we have installed +# during `./configure' time. +# +# Regarding the directories, this project builds its major dependencies +# itself and doesn't use the local system's default tools. With these +# environment variables, we are setting it to prefer the software we have +# build here. +.ONESHELL: +.SHELLFLAGS = -ec +export CCACHE_DISABLE := 1 +export PATH := $(installdir)/bin +export LD_LIBRARY_PATH := $(installdir)/lib +export LDFLAGS := -L$(installdir)/lib +export SHELL := $(installdir)/bin/bash +export CPPFLAGS := -I$(installdir)/include + + + + + +# Python enviroment +# ----------------- +# +# 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. +export PYTHONPATH := $(installdir)/lib/python/site-packages +export PYTHONPATH3 := $(PYTHONPATH) +export _LMFILES_ := +export PYTHONPATH2 := +export LOADEDMODULES := +export MPI_PYTHON_SITEARCH := +export MPI_PYTHON2_SITEARCH := +export MPI_PYTHON3_SITEARCH := + + + + + +# High-level level directories +# ---------------------------- +# +# These are just the top-level directories for all the separate steps. The +# directories (or possible sub-directories) for individual steps will be +# defined and added within their own Makefiles. +# +# The `.SUFFIXES' rule with no prerequisite is defined to eliminate all the +# default implicit rules. The default implicit rules are to do with +# programming (for example converting `.c' files to `.o' files). The +# problem they cause is when you want to debug the make command with `-d' +# option: they add too many extra checks that make it hard to find what you +# are looking for in the outputs. +.SUFFIXES: +$(lockdir): | $(BDIR); mkdir $@ +$(texbdir): | $(texdir); mkdir $@ +$(tikzdir): | $(texbdir); mkdir $@ && ln -fs $@ tex/tikz + + + + + +# High-level Makefile management +# ------------------------------ +# +# About `.PHONY': these are targets that must be built even if a file with +# their name exists. +# +# Only `$(mtexdir)/initialize.tex' corresponds to a file. This is because +# we want to ensure that the file is always built in every run: it contains +# the project version which may change between two separate runs, even when +# no file actually differs. +packagebasename := $(shell echo paper-$$(git describe --dirty --always)) +packagecontents = $(texdir)/$(packagebasename) +.PHONY: all clean dist dist-zip distclean clean-mmap $(packagecontents) \ + $(mtexdir)/initialize.tex + +# --------- Delete for no Gnuastro --------- +clean-mmap:; rm -f reproduce/config/gnuastro/mmap* +# ------------------------------------------ + +clean: clean-mmap + # Delete the top-level PDF file. + rm -f *.pdf + + # Delete all the built outputs except the dependency + # programs. We'll use Bash's extended options builtin (`shopt') to + # enable "extended glob" (for listing of files). It allows extended + # features like ignoring the listing of a file with `!()' that we + # are using afterwards. + shopt -s extglob + rm -rf $(BDIR)/!(dependencies) + +distclean: clean + # We'll be deleting the built environent programs and just need the + # `rm' program. So for this recipe, we'll use the host system's + # `rm', not our own. + $(sys-rm) -rf $(BDIR) reproduce/build + $(sys-rm) -f Makefile .gnuastro .local + $(sys-rm) -f $(pconfdir)/LOCAL.mk $(gconfdir)/gnuastro-local.conf + + + + + +# Packaging rules +# --------------- +# +# With the rules in this section, you can package the project in a state +# that is ready for building the final PDF with LaTeX. This is useful for +# collaborators who only want to contribute to the text of your project, +# without having to worry about the technicalities of the analysis. +$(packagecontents): | $(texdir) + + # Set up the output directory, delete it if it exists and remake it + # to fill with new contents. + dir=$(texdir)/$(packagebasename) + rm -rf $$dir + mkdir $$dir + + # Build a small Makefile to help in automatizing the paper building + # (including the bibliography). + m=$$dir/Makefile + echo "paper.pdf: paper.tex paper.bbl" > $$m + printf "\tpdflatex -shell-escape -halt-on-error paper\n" >> $$m + echo "paper.bbl: tex/src/references.tex" >> $$m + printf "\tpdflatex -shell-escape -halt-on-error paper\n" >> $$m + printf "\tbiber paper\n" >> $$m + echo ".PHONY: clean" >> $$m + echo "clean:" >> $$m + printf "\trm -f *.aux *.auxlock *.bbl *.bcf\n" >> $$m + printf "\trm -f *.blg *.log *.out *.run.xml\n" >> $$m + + # Copy the top-level contents into it. + cp configure COPYING for-group README.md README-hacking.md $$dir/ + + # Build the top-level directories. + mkdir $$dir/reproduce $$dir/tex $$dir/tex/tikz $$dir/tex/build + + # Copy all the necessary `reproduce' and `tex' contents. + shopt -s extglob + cp -r tex/src $$dir/tex/src + cp tex/tikz/*.pdf $$dir/tex/tikz + cp -r reproduce/ $$dir/reproduce + cp -r tex/build/!($(packagebasename)) $$dir/tex/build + + # Clean up un-necessary/local files: 1) the $(texdir)/build* + # directories (when building in a group structure, there will be + # `build-user1', `build-user2' and etc), are just temporary LaTeX + # build files and don't have any relevant/hand-written files in + # them. 2) The `LOCAL.mk' and `gnuastro-local.conf' files just have + # this machine's local settings and are irrelevant for anyone else. + rm -rf $$dir/tex/build/build* + rm $$dir/reproduce/software/config/installation/LOCAL.mk + rm $$dir/reproduce/software/config/gnuastro/gnuastro-local.conf + + # PROJECT SPECIFIC: under this comment, copy any other file for + # packaging, or remove any of the copied files above to suite your + # project. + + # Since the packaging is mainly intended for high-level building of + # the PDF with LaTeX, we'll comment the `makepdf' LaTeX macro in + # the paper. + sed -e's|\\newcommand{\\makepdf}{}|%\\newcommand{\\makepdf}{}|' \ + paper.tex > $$dir/paper.tex + + # Just in case the package users want to rebuild some of the + # figures (manually un-comments the `makepdf' command we commented + # above), correct the TikZ external directory, so the figures can + # be rebuilt. + pgfsettings="$$dir/tex/src/preamble-pgfplots.tex" + sed -e's|{tikz/}|{tex/tikz/}|' $$pgfsettings > $$pgfsettings.new + mv $$pgfsettings.new $$pgfsettings + + # Clean temporary (currently those ending in `~') files. + cd $(texdir) + find $(packagebasename) -name \*~ -delete + +# Package into `.tar.gz'. +dist: $(packagecontents) + curdir=$$(pwd) + cd $(texdir) + tar -cf $(packagebasename).tar $(packagebasename) + gzip -f --best $(packagebasename).tar + cd $$curdir + mv $(texdir)/$(packagebasename).tar.gz ./ + +# Package into `.zip'. +dist-zip: $(packagecontents) + curdir=$$(pwd) + cd $(texdir) + zip -q -r $(packagebasename).zip $(packagebasename) + cd $$curdir + mv $(texdir)/$(packagebasename).zip ./ + + + + + +# Check the version of programs which write their version +# ------------------------------------------------------- +pvcheck = prog="$(strip $(1))"; \ + ver="$(strip $(2))"; \ + name="$(strip $(3))"; \ + macro="$(strip $(4))"; \ + verop="$(strip $(5))"; \ + if [ "x$$verop" = x ]; then V="--version"; else V=$$verop; fi; \ + v=$$($$prog $$V | awk '/'$$ver'/{print "y"; exit 0}'); \ + if [ x$$v != xy ]; then \ + echo; echo "PROJECT ERROR: Not running $$name $$ver"; echo; \ + exit 1; \ + fi; \ + echo "\newcommand{\\$$macro}{$$ver}" >> $@ + +lvcheck = idir=$(BDIR)/dependencies/installed/include; \ + f="$$idir/$(strip $(1))"; \ + ver="$(strip $(2))"; \ + name="$(strip $(3))"; \ + macro="$(strip $(4))"; \ + v=$$(awk '/^\#/&&/define/&&/'$$ver'/{print "y";exit 0}' $$f); \ + if [ x$$v != xy ]; then \ + echo; echo "PROJECT ERROR: Not linking with $$name $$ver"; \ + echo; exit 1; \ + fi; \ + echo "\newcommand{\\$$macro}{$$ver}" >> $@ + + + + +# Project initialization results +# ------------------------------ +# +# This file will store some basic info about the project that is necessary +# for the final PDF. Since these are not version controlled, it must be +# calculated everytime the project is run. So even though this file +# actually exists, it is also aded as a `.PHONY' target above. +$(mtexdir)/initialize.tex: | $(mtexdir) + + # Version of the project. + @v=$$(git describe --dirty --always); + echo "\newcommand{\projectversion}{$$v}" > $@ |