X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Makefile;h=f40e3ee5c47be7d1508fa583fca1bc1f35f20b5b;hb=34cc75e1a62638f2833815746ebce0a9114dc26b;hp=9b02279eefb00835eb2928a9a3a65e594f42e6a5;hpb=bc4924fc7c5e76694e450f190e92bb22ce6aa4c5;p=ghc-hetmet.git diff --git a/Makefile b/Makefile index 9b02279..726801d 100644 --- a/Makefile +++ b/Makefile @@ -1,208 +1,143 @@ -############################################################################ -# -# fptools/Makefile -# -# This is the main Makefile for fptools. -# -############################################################################ -TOP=. -include $(TOP)/mk/boilerplate.mk -SRC_DIST_DIR=$(shell pwd)/$(SRC_DIST_NAME) +ifeq "$(wildcard distrib/)" "" -# -# Totally evil hack to make the setting of SUBDIRS be dependent -# on whether we do `make install' or not. Having a $(ifeq ... ) would -# be preferable.. -CURRENT_TARGET = $(MAKECMDGOALS) -SUBDIRS = $(shell if (test x$(CURRENT_TARGET) = xinstall) ; then echo $(ProjectsToInstall); else echo $(ProjectsToBuild); fi) - -ifneq "$(Project)" "" - include $(shell echo $(Project) | tr A-Z a-z)/mk/config.mk -endif +# We're in a bindist -# -# Files to include in fptools source distribution -# -SRC_DIST_DIRS += mk docs distrib $(ProjectsToBuild) -SRC_DIST_FILES += configure.in config.guess config.sub configure aclocal.m4 acconfig.h README INSTALL Makefile install-sh +.PHONY: default +default: + @echo 'Run "make install" to install' + @false -# ----------------------------------------------------------------------------- -# Make sure configure is up-to-date +.PHONY: install +install: + $(MAKE) -r --no-print-directory -f ghc.mk install BINDIST=YES NO_INCLUDE_DEPS=YES -all boot :: configure -configure :: configure.in - @echo "WARNING: configure needs to be regenerated. Type" - @echo " make -f Makefile.config ./configure" - @echo "and rerun make." - @exit 16 - -# ----------------------------------------------------------------------------- -# Making a binary distribution -# -# To make a particular binary distribution: -# set $(Project) to the name of the project (currently Ghc or Happy). +.PHONY: show +show: + $(MAKE) -r --no-print-directory -f ghc.mk $@ -BIN_DIST_TMPDIR=$(FPTOOLS_TOP_ABS) -BIN_DIST_NAME=$(ProjectNameShort)-$(ProjectVersion) +else +# The problem we need to solve is as follows. # -# list of toplevel directories to include in binary distrib. +# GNU make supports included Makefiles, and it is clever enough to try +# to update those Makefiles when they are out-of-date or missing. It +# first reads all the Makefiles, and then tries to build each one if +# it is out-of-date, using the rules in the Makefiles themselves. +# When it has brought all the Makefiles up-to-date, it restarts itself +# to read the newly-generated Makefiles. # -BIN_DIST_MAIN_DIR=$($(Project)MainDir) -BIN_DIST_DIRS=$($(Project)BinDistDirs) - -binary-dist:: binary-dist-pre - -BIN_DIST_TOP= distrib/Makefile-bin.in \ - distrib/configure-bin.in \ - README \ - distrib/INSTALL \ - $(BIN_DIST_MAIN_DIR)/ANNOUNCE \ - $(BIN_DIST_MAIN_DIR)/VERSION \ - $(BIN_DIST_MAIN_DIR)/RELEASE \ - $(BIN_DIST_MAIN_DIR)/LICENSE \ - glafp-utils/mkdirhier/mkdirhier \ - install-sh \ - config.guess \ - config.sub \ - aclocal.m4 - -# -# binary-dist creates a binary bundle, set BIN_DIST_NAME -# to package name and do `make binary-dist Project=' -# (normally this just a thing you would do from the toplevel of fptools) +# This works fine, unless there are dependencies *between* the +# Makefiles. For example in the GHC build, for each package we have a +# package-data.mk file which is generated by the ghc-cabal program, +# and we have a .depend file. The .depend file cannot be generated +# until package-data.mk has been generated and make has been restarted +# to read in its contents, because it is the package-data.mk file that +# tells us which modules are in the package. But make always makes +# all the Makefiles before restarting - it doesn't take into account a +# dependency between Makefiles and restart itself earlier. + +# Consider the following makefile: + +# -------------------- +# all : # -.PHONY: binary-dist-pre binary-dist binary-pack - -BIN_DIST_NAME=$(ProjectNameShort)-$(ProjectVersion) -BIN_DIST_TMPDIR=$(FPTOOLS_TOP_ABS) - -binary-dist-pre:: - -rm -rf $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) - -rm -f $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME).tar.gz - @for i in $(BIN_DIST_DIRS); do \ - if test -d "$$i"; then \ - echo $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM); \ - $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM); \ - echo $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM); \ - $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM); \ - echo $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share; \ - $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share; \ - echo $(MAKE) -C $$i $(MFLAGS) install \ - prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \ - exec_prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \ - bindir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM) \ - libdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM) \ - libexecdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM) \ - datadir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share; \ - $(MAKE) -C $$i $(MFLAGS) install \ - prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \ - exec_prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \ - bindir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM) \ - libdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM) \ - libexecdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM) \ - datadir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share; \ - fi; \ - done - -binary-dist:: - @for i in $(BIN_DIST_TOP); do \ - if test -f "$$i"; then \ - echo cp $$i $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME); \ - cp $$i $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME); \ - fi; \ - done; - @echo "Configuring the Makefile for this project..." - touch $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - echo "package = $(ProjectNameShort)" >> $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - echo "version = $(ProjectVersion)" >> $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - echo "PACKAGE_SH_SCRIPTS = $($(Project)BinDistShScripts)" >> $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - echo "PACKAGE_PRL_SCRIPTS = $($(Project)BinDistPrlScripts)" >> $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - echo "PACKAGE_LIB_PRL_SCRIPTS = $($(Project)BinDistLibPrlScripts)" >> $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - echo "PACKAGE_BINS = $($(Project)BinDistBins)" >> $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - cat $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile-bin.in >> $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/Makefile.in - @echo "Generating a shippable configure script.." - $(MV) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/configure-bin.in $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/configure.in - ( cd $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME); autoconf ) +# include inc1.mk +# +# inc1.mk : Makefile +# echo "X = C" >$@ +# +# include inc2.mk +# +# inc2.mk : inc1.mk +# echo "Y = $(X)" >$@ +# -------------------- +# Now try it: +# +# $ make -f fail.mk +# fail.mk:3: inc1.mk: No such file or directory +# fail.mk:8: inc2.mk: No such file or directory +# echo "X = C" >inc1.mk +# echo "Y = " >inc2.mk +# make: Nothing to be done for `all'. + +# make built both inc1.mk and inc2.mk without restarting itself +# between the two (even though we added a dependency on inc1.mk from +# inc2.mk). # -# binary dist'ing the documentation. -# Which documentation to build/install is hardcoded below. -# +# The solution we adopt in the GHC build system is essentially this: -BINDIST_DOCS = $($(Project)BinDistDocs) -BINDIST_DOCS_WAYS = html ps - -binary-dist :: - @for way in $(BINDIST_DOCS_WAYS); do \ - $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/$$way; \ - for dir in $(BINDIST_DOCS); do \ - echo Making $$way documentation in $$dir && \ - $(MAKE) -C $$dir --no-print-directory $(MFLAGS) $$way >.doclog 2>&1 && \ - if [ "$$way" = "html" ]; then \ - for subdir in `perl -n -e '/output will be in ([_\-A-Za-z0-9]*)/ && do { print $$1; };' <.doclog`; do \ - echo Copying HTML docs from $$subdir...; \ - cp -Rf $$dir/$$subdir $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/$$way; \ - done \ - else \ - cp -f $$dir/*.$$way $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/$$way; \ - fi && \ - echo "Done."; \ - done; \ - done - @rm -f .doclog - -# Rename scripts to $i.prl and $i.sh where necessary. -# ToDo: do this in a cleaner way... - -ifneq "$($(Project)BinDistPrlScripts)" "" -binary-dist:: - @for i in $($(Project)BinDistPrlScripts); do \ - echo "Renaming $$i to $$i.prl"; \ - $(MV) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$$i $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$$i.prl; \ - done -endif - -ifneq "$($(Project)BinDistLibPrlScripts)" "" -binary-dist:: - @for i in $($(Project)BinDistLibPrlScripts); do \ - echo "Renaming $$i to $$i.prl"; \ - $(MV) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$$i $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$$i.prl; \ - done -endif - -ifneq "$($(Project)BinDistShScripts)" "" -binary-dist:: - @for i in $($(Project)BinDistShScripts); do \ - echo "Renaming $$i to $$i.sh"; \ - $(MV) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$$i $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$$i.sh; \ - done -endif - -# -# Do this separately for now +# -------------------- +# PHASE = 0 # -binary-pack:: - ( cd $(BIN_DIST_TMPDIR); $(TAR) chzf $(BIN_DIST_NAME).tar.gz $(BIN_DIST_NAME) ) - -ifneq "$(way)" "" -package-way-dist:: - ( cd $(BIN_DIST_TMPDIR); find $(BIN_DIST_NAME)/ \( -name "*$(_way).a" -o -name "*.$(way_)hi" \) -print | xargs tar cvf $(BIN_DIST_TMPDIR)/ghc-$(ProjectVersion)-$(way)-$(TARGETPLATFORM).tar ) - gzip $(BIN_DIST_TMPDIR)/ghc-$(ProjectVersion)-$(way)-$(TARGETPLATFORM).tar -endif +# ifeq "$(PHASE)" "0" +# all : +# $(MAKE) PHASE=1 +# else +# all : +# endif +# +# -include inc1.mk +# +# inc1.mk : Makefile +# echo "X = C" >$@ +# +# ifneq "$(PHASE)" "0" +# include inc2.mk +# +# inc2.mk : inc1.mk +# echo "Y = $(X)" >$@ +# endif +# +# clean : +# rm -f inc1.mk inc2.mk +# -------------------- + +# That is, every time make is invoked, we force it to update inc1.mk +# and then restart. In the GHC build system we need to divide the +# build into 4 phases in fact, with a restart between each phase. See +# ghc.mk for the details on what happens in each phase and why. + +default : all + @: + +# No need to update makefiles for these targets: +REALGOALS=$(filter-out clean clean_% distclean maintainer-clean show,$(MAKECMDGOALS)) + +# NB. not the same as saying '%: ...', which doesn't do the right thing: +# it does nothing if we specify a target that already exists. +.PHONY: $(REALGOALS) +$(REALGOALS) all: + @echo "===--- updating makefiles phase 0" + $(MAKE) -r --no-print-directory -f ghc.mk phase=0 just-makefiles + @echo "===--- updating makefiles phase 1" + $(MAKE) -r --no-print-directory -f ghc.mk phase=1 just-makefiles + @echo "===--- updating makefiles phase 2" + $(MAKE) -r --no-print-directory -f ghc.mk phase=2 just-makefiles + @echo "===--- updating makefiles phase 3" + $(MAKE) -r --no-print-directory -f ghc.mk phase=3 just-makefiles + @echo "===--- finished updating makefiles" + $(MAKE) -r --no-print-directory -f ghc.mk $@ + +binary-dist: + rm -f bindist-list + $(MAKE) -r --no-print-directory -f ghc.mk bindist BINDIST=YES + $(MAKE) -r --no-print-directory -f ghc.mk binary-dist + +clean distclean maintainer-clean: + $(MAKE) -r --no-print-directory -f ghc.mk $@ + test ! -d testsuite || $(MAKE) -C testsuite $@ + +$(filter clean_%, $(MAKECMDGOALS)) : clean_% : + $(MAKE) -r --no-print-directory -f ghc.mk $@ + +show: + $(MAKE) -r --no-print-directory -f ghc.mk $@ + +# If the user says 'make A B', then we don't want to invoke two +# instances of the rule above in parallel: +.NOTPARALLEL: -ifneq "$(way)" "" -remove-way-dist:: - ( cd $(BIN_DIST_TMPDIR); find $(BIN_DIST_NAME)/ \( -name "*$(_way).a" -o -name "*.$(way_)hi" \) -print -exec rm -f {} \; ) endif -binary-dist:: - @echo "Mechanical and super-natty! Inspect the result and *if* happy; freeze, sell and get some sleep!" - -# ----------------------------------------------------------------------------- - -dist :: dist-pre -include $(TOP)/mk/target.mk -dist :: dist-post -