#
# rcsid $Header: /usr/cvsroot/magic-8.0/Makefile,v 1.1.1.1 2008/02/03 20:43:49 tim Exp $
#
MAGICDIR = .
# Absolute path to the source tree (config.status substitutes @abs_top_srcdir@).
# For an in-tree build this is the same directory as the build top. Recursion
# into subdirectories goes through $(submake) (defined below).
MAGICSRC = @abs_top_srcdir@
PROGRAMS = magic
TECHS = scmos
LIBRARIES = database utils extflat
MODULES = bplane cmwind commands database dbwind debug drc extflat \
extract graphics netmenu plow resis select sim textio tiles \
utils windows wiring
# This was `cat VERSION`
VERSION := $(shell cat ${MAGICSRC}/VERSION)
MAKEFLAGS =
INSTALL_CAD_DIRS = windows doc ${TECHS}
-include defs.mak
# "docs" when configure found latex+dvips (regenerate PostScript from .tex into
# the build tree), empty otherwise (the pre-built PostScript is installed as-is).
DOCS_TARGET = @DOCS_TARGET@
# $(call submake,
,) -- recurse into a build subdirectory.
# Every module is a configure-generated Makefile, so config.status
# already created the build subdir with its Makefile: recurse natively. The one
# exception is readline/, which is intentionally never converted; it has no
# generated Makefile, so it takes the -f path against the source Makefile (and its
# build subdir is created on demand).
define submake
if test "x$(1)" = xreadline; then mkdir -p $(1) && $(MAKE) -C $(1) -f $(MAGICSRC)/$(1)/Makefile $(2); else $(MAKE) -C $(1) $(2); fi
endef
all: $(ALL_TARGET) techs $(DOCS_TARGET)
standard: mains
tcl: tcllibrary
force:
@${MAKE} clean
@${MAKE} all
defs.mak:
@echo No \"defs.mak\" file found. Run "configure" to make one.
@exit 1
config:
${MAGICSRC}/configure
# ---------------------------------------------------------------------------
# Declarative subdir recursion.
#
# Each (phase, dir) pair is a PHONY target "@" whose recipe recurses
# into with that phase's goal via $(submake) (so readline/ still takes the
# -f path). A phase aggregate (depend, modules, libs, ...) is then just a list
# of its per-dir targets as prerequisites -- no shell `for` loops, no FORCE
# pattern-rule hack. Ordering between phases is expressed as prerequisites on the
# per-dir targets (e.g. every module@ waits for `depend`), so the graph is correct
# under `make -jN`, not just left-to-right in a serial build. '@' never appears
# in a real target name, so it is a safe namespace separator.
# ---------------------------------------------------------------------------
# main@ / tcl-main@: link the final program(s) (PROGRAMS is "magic").
MAIN_TARGETS := $(addprefix main@,${PROGRAMS})
TCLMAIN_TARGETS := $(addprefix tcl-main@,${PROGRAMS})
.PHONY: $(MAIN_TARGETS) $(TCLMAIN_TARGETS)
$(MAIN_TARGETS): main@%: ${DATABASE_H} modules libs
@$(call submake,$*,main)
$(TCLMAIN_TARGETS): tcl-main@%: ${DATABASE_H} modules
@$(call submake,$*,tcl-main)
.PHONY: tcllibrary mains
tcllibrary: $(TCLMAIN_TARGETS)
mains: $(MAIN_TARGETS)
# makedbh is the one generated helper script; it lives in the *build* tree.
# ${DATABASE_H} is $(builddir)/database/database.h in-tree, or
# $(builddir)/include/database/database.h when relocated (see defs.mak GENINC).
${DATABASE_H}: ${MAGICSRC}/database/database.h.in
@echo --- making header file ${DATABASE_H}
@mkdir -p $(dir ${DATABASE_H})
${MAGICDIR}/scripts/makedbh ${MAGICSRC}/database/database.h.in ${DATABASE_H}
# "prepare" is the stable, path-independent way to (re)generate the build-time
# headers (currently database.h) before compiling -- use it instead of naming
# the header directly (its path depends on in-tree vs relocated; see GENINC).
# It is .PHONY so the name is always valid, but its prerequisite ${DATABASE_H}
# is a real file target, so the header is regenerated only when out of date.
.PHONY: prepare
prepare: ${DATABASE_H}
# module@ builds /lib.o; lib@ builds /lib.a.
# Every module@/lib@ waits for the whole `depend` phase first (it used to be a
# prereq of the `modules`/`libs` aggregates; moving it onto each per-dir target
# keeps depend before compilation even under -j).
MODULE_TARGETS := $(addprefix module@,${MODULES})
LIB_TARGETS := $(addprefix lib@,${MODULES})
.PHONY: $(MODULE_TARGETS) $(LIB_TARGETS)
$(MODULE_TARGETS): module@%: depend
@$(call submake,$*,module)
$(LIB_TARGETS): lib@%: depend
@$(call submake,$*,lib)
# Cross-module archive edge (-j correctness): libdatabase.a physically archives
# tiles/libtiles.o and utils/libutils.o (database/Makefile.in: LIB_OBJS += ...),
# so lib@database must not run until those module objects exist. A serial build
# got this from prerequisite order; under -j it needs the explicit edge. No other
# default-built module archives another module's objects.
lib@database: module@tiles module@utils
.PHONY: modules
modules: $(MODULE_TARGETS)
.PHONY: libs
libs: $(LIB_TARGETS)
#
# extcheck - utility tool
# net2ir - utility tool
# oa - disabled (needs 'clean' target renaming)
SUBDIRS = bplane cmwind commands database dbwind debug drc extflat extract graphics \
magic netmenu plow resis select sim textio tiles utils windows wiring
BUNDLED_MODULES = readline lisp
# Unique list of all subdir that might have Depend file, we have to deduplicate otherwise
# MAKE will warning loudly. This list is somewhat empty when defs.mak does not exist
SUBDIRS_FILTERED := $(shell echo ${MODULES} ${PROGRAMS} ${SUBDIRS} | tr ' ' '\n' | sort | uniq)
SUBDIRS_DEPEND = $(addsuffix /Depend, ${SUBDIRS_FILTERED})
${SUBDIRS_DEPEND}: ${DATABASE_H}
@echo --- making dependencies
@$(call submake,$(patsubst %/,%,$(dir $@)),depend)
.PHONY: depend
depend: defs.mak ${SUBDIRS_DEPEND}
# tech@: build a technology dir (goal "all").
TECH_TARGETS := $(addprefix tech@,${TECHS})
.PHONY: $(TECH_TARGETS)
$(TECH_TARGETS): tech@%: depend
@$(call submake,$*,all)
.PHONY: techs
techs: $(TECH_TARGETS)
# Regenerate the PostScript documentation from its .tex sources (only reached
# from "all" when configure found latex+dvips; see DOCS_TARGET). Force -j1: the
# latexfiles rules share per-run aux files (.aux/.log) in one directory and are
# not parallel-safe, so under a parallel top-level build they would race and drop
# documents. Doc regeneration is best-effort anyway (pre-built PostScript is the
# install fallback), so serializing it costs nothing and keeps -j deterministic.
.PHONY: docs
docs:
@echo --- making documentation
@${MAKE} -j1 -k -C doc/latexfiles all || \
echo "--- WARNING: some documents did not regenerate; the pre-built PostScript will be used for those at 'make install'"
install: $(INSTALL_TARGET)
install-magic:
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR}
@echo --- installing runtime files to $(DESTDIR)${INSTALL_LIBDIR}
@${MAKE} install-real
# install@: install one subdir's artifacts (CAD dirs, then the programs).
INSTALL_TARGETS := $(addprefix install@,${INSTALL_CAD_DIRS} ${PROGRAMS})
.PHONY: $(INSTALL_TARGETS)
$(INSTALL_TARGETS): install@%: install-dirs
@$(call submake,$*,install)
install-real: $(INSTALL_TARGETS)
install-tcl-dirs:
${SCRIPTS}/mkdirs $(DESTDIR)${INSTALL_BINDIR} \
$(DESTDIR)${INSTALL_MANDIR} $(DESTDIR)${INSTALL_SYSDIR} \
$(DESTDIR)${INSTALL_TCLDIR} $(DESTDIR)${INSTALL_TCLDIR}/bitmaps
install-dirs:
${SCRIPTS}/mkdirs $(DESTDIR)${INSTALL_BINDIR} \
$(DESTDIR)${INSTALL_MANDIR} $(DESTDIR)${INSTALL_SYSDIR} \
$(DESTDIR)${INSTALL_SCMDIR}
install-tcl:
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR}
@echo --- installing runtime files to $(DESTDIR)${INSTALL_LIBDIR}
@${MAKE} install-tcl-real
# install-tcl@: install one subdir's Tcl-flavoured artifacts.
INSTALLTCL_TARGETS := $(addprefix install-tcl@,${INSTALL_CAD_DIRS} ${PROGRAMS})
.PHONY: $(INSTALLTCL_TARGETS)
$(INSTALLTCL_TARGETS): install-tcl@%: install-tcl-dirs
@$(call submake,$*,install-tcl)
install-tcl-real: $(INSTALLTCL_TARGETS)
# clean@: clean one subdir if it exists. Must not create dirs (skip absent
# ones) and must not fail the build (|| true). readline/ uses the -f path
# (mirrors $(submake); it is the one unconverted module).
CLEAN_TARGETS := $(addprefix clean@,$(sort ${SUBDIRS_FILTERED} ${TECHS} ${BUNDLED_MODULES}))
.PHONY: $(CLEAN_TARGETS)
$(CLEAN_TARGETS): clean@%:
@test -d $* || exit 0; \
if test "x$*" = xreadline; then ${MAKE} -C $* -f ${MAGICSRC}/$*/Makefile clean; \
else ${MAKE} -C $* clean; fi || true
.PHONY: clean
clean: $(CLEAN_TARGETS)
${RM} *.tmp */*.tmp *.sav */*.sav *.log TAGS tags
distclean:
touch defs.mak
@${MAKE} clean
# rules.mak is no longer copied into the build top (subdir Makefiles include
# ${MAGICSRC}/rules.mak straight from the source tree), so there is nothing to
# remove for it here; defs.mak is the only generated make fragment.
${RM} defs.mak old.defs.mak
${RM} scripts/makedbh scripts/default.conf
${RM} config.log config.status
${RM} ${DATABASE_H}
${RM} scripts/magic.spec magic-${VERSION} magic-${VERSION}.tgz
${RM} *.log
dist:
${RM} scripts/magic.spec magic-${VERSION} magic-${VERSION}.tgz
${SED} -e /@VERSION@/s%@VERSION@%${VERSION}% \
${MAGICSRC}/scripts/magic.spec.in > scripts/magic.spec
${LN} -nsf . magic-${VERSION}
tar zchvf magic-${VERSION}.tgz --exclude CVS \
--exclude magic-${VERSION}/magic-${VERSION} \
--exclude magic-${VERSION}/magic-${VERSION}.tgz \
magic-${VERSION}
clean-mains:
${RM} $(foreach p,${PROGRAMS},$p/$p)
tags:
${RM} tags
cd ${MAGICSRC} && find . ${MODULES} ${PROGRAMS} -name "*.[ch]" -maxdepth 1 | xargs ctags -o $(CURDIR)/tags
TAGS:
${RM} TAGS
cd ${MAGICSRC} && find . ${MODULES} ${PROGRAMS} -name "*.[ch]" -maxdepth 1 | xargs etags -o $(CURDIR)/TAGS
setup-git:
git config --local include.path ../.gitconfig
git stash save
${RM} .git/index
git checkout HEAD -- "$$(git rev-parse --show-toplevel)"
git stash pop