# # 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) .PHONY: modules modules: $(MODULE_TARGETS) .PHONY: libs # libdatabase.a needs the tiles/utils module objects first. Listing them before # $(LIB_TARGETS) orders a serial build correctly; the explicit per-target -j edge # is added in a later commit. libs: module@tiles module@utils $(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). .PHONY: docs docs: @echo --- making documentation @${MAKE} -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