<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jun 19, 2024, 7:28 AM Larry McVoy <<a href="mailto:lm@mcvoy.com">lm@mcvoy.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tue, Jun 18, 2024 at 07:46:15PM -0500, Nevin Liber wrote:<br>
> But I'll bite.  There was the claim by Larry McVoy that "Writing Makefiles<br>
> isn't that hard".<br>
> <br>
> Please show these beautiful makefiles for a non-toy non-trivial product<br>
<br>
Works on *BSD, MacOS, Windows, Linux on a bunch of different architectures,<br>
Solaris, HPUX, AIX, IRIX, Tru64, etc.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">The posted Makefile is no a strictly conforming POSIX Makefile, but uses gmake extensions extensively... And eyes of the beholder may vary...</div><div dir="auto"><br></div><div dir="auto">Warner</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
# Copyright 1999-2016 BitMover, Inc<br>
<br>
# Licensed under the Apache License, Version 2.0 (the "License");<br>
# you may not use this file except in compliance with the License.<br>
# You may obtain a copy of the License at<br>
<br>
#     <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
<br>
# Unless required by applicable law or agreed to in writing, software<br>
# distributed under the License is distributed on an "AS IS" BASIS,<br>
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br>
# See the License for the specific language governing permissions and<br>
# limitations under the License.<br>
<br>
# Makefile for BitKeeper.<br>
<br>
# Bitmover makefiles try to provide the following targets:<br>
#<br>
# all           build everything under the current directory<br>
#<br>
# clean         remove all objects and programs<br>
#<br>
# clobber       run clean plus 'bk -r. clean'<br>
#<br>
# srcs          bk get all sources in current directory<br>
#<br>
# tags          build ctags for all srcs (only needed in this (top) makefile)<br>
#<br>
# tags.local    build ctags for srcs under current directory relative to top<br>
#<br>
#---<br>
# Special make variables commonly used this makefile:<br>
#   $@  target<br>
#   $^  all sources<br>
#   $<  first source<br>
<br>
INSTALLED_BK    ?= $(shell bash -c "cd / && command -v bk")<br>
INREPO  ?= $(shell bash -c "test -d ../.bk && echo true || echo false")<br>
HERE    := $(shell pwd)<br>
ROOT    := $(shell dirname $(HERE))<br>
REPO    := $(notdir $(ROOT))<br>
URL     := $(shell echo bk://work/$(ROOT) | sed s,/home/bk/,,)<br>
LOG     = $(shell echo LOG-`bk getuser`)<br>
OSTYPE  := $(shell bash -c 'echo $$OSTYPE')<br>
<br>
include <a href="http://conf.mk" rel="noreferrer noreferrer" target="_blank">conf.mk</a><br>
<br>
## Which hosts are used for producing nightly builds<br>
NIGHTLY_HOSTS   := macos106 win7-vm debian40 debian40-64<br>
<br>
ifeq "$(OSTYPE)" "msys"<br>
        SYS=win32<br>
        EXE=.exe<br>
        XTRA=win32<br>
        ifeq (,$(INSTALLED_BK))<br>
                # BINDIR should really be :C:/Program Files/BitKeeper<br>
                # The shell can not handle space in pathname, so<br>
                # we use the short name here<br>
                BINDIR := "C:/PROGRA~1/BITKEE~1"<br>
        else<br>
                BINDIR := $(shell bk pwd -s "`bk _registry get 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion' ProgramFilesDir`/BitKeeper")<br>
        endif<br>
        INSTALL=installdir<br>
        RESOURCE=bkres.o<br>
        UWT_C=$(patsubst %,win32/uwtlib/%.c, wapi_intf wcrt_intf)<br>
        BKGUI=bkg$(EXE)<br>
        BKG_O=bkg.o<br>
else<br>
        SYS=unix<br>
        EXE=<br>
        # You can set this to anywhere you like and do a <br>
        # build production" and you'll have an installed BitKeeper.<br>
        ifeq (,$(INSTALLED_BK))<br>
                BINDIR := /usr/local/bitkeeper<br>
        else<br>
                BINDIR := $(shell "$(INSTALLED_BK)" bin)<br>
        endif<br>
        INSTALL=install<br>
        RESOURCE=<br>
endif<br>
<br>
# By default, we don't print verbose output. If you want to see<br>
# the full compiler command line, use 'make V=1'<br>
# The trick is to do "$(Q)$(CC)" instead of just "$(CC)" so that if<br>
# Q is not set, it's just "$(CC)" and if Q is set to @ it becomes<br>
# a quiet "@$(CC)".<br>
# For the verbose messages, gmake provides<br>
# $(if $(Q),<then>,<else>)<br>
# so we just conditionalize on Q. Empty is false.<br>
ifndef V<br>
        Q=@<br>
        export Q<br>
endif<br>
<br>
BK=./bk$(EXE)<br>
G       =-g<br>
TRIAL   =0<br>
IMGDIR  =$(HERE)/tmp/bitkeeper<br>
<br>
# Handle warning arguments in GCC<br>
#<br>
# -Wall enables a bunch of warnings by default<br>
# -Wno-parentheses shuts up "suggest parentheses around assignment ...".<br>
#  Unfortunately it also turns off dangling else warnings.<br>
# -Wno-char-subscripts shuts up "subscript has type char", which comes<br>
#  up all the time with broken <ctype.h> implementations.  <br>
#  (renabled in GCC3 since it supresses warnings in system files by default)<br>
# -Wno-format-y2k supresses complains about '%y' in strftime formats<br>
# -Wstrict-prototypes    Don't allow non-ansi function declarations<br>
WARNINGS=-Wall -Wno-parentheses -Wno-char-subscripts -Wno-format-y2k \<br>
        -Wstrict-prototypes<br>
<br>
# Warnings enabled with GCC newer than 3.0<br>
#<br>
# -Wredundant-decls       Declaring same function twice<br>
# -Wmissing-declarations  Functions without a prototype<br>
WARNINGS_GCC3=-Wchar-subscripts -Wredundant-decls -Wmissing-declarations<br>
<br>
# Warnings enabled with GCC newer than 4.0<br>
#<br>
# -Wextra  enable a bunch of random things (called -Wextra in newer gccs)<br>
# -Wno-pointer-sign  Suppress warnings about changing the signs of pointers<br>
# -Wno-sign-compare  Suppress warnings about comparing signed and unsigned vars<br>
# -Wno-unsed-parameter Support warnings about function parameters that are <br>
#  no used<br>
# -Wno-missing-field-initializers<br>
# -Wdeclaration-after-statement Warn if someone does a C++ thing of declaring<br>
#  a variable in the middle of a block<br>
WARNINGS_GCC4=-Wextra -Wno-pointer-sign -Wno-sign-compare \<br>
        -Wno-unused-parameter -Wno-missing-field-initializers \<br>
        -Wdeclaration-after-statement -Wpointer-arith<br>
<br>
# Warnings enabled with GCC newer than 5.0<br>
#<br>
# -Wno-unusedr-esult Do not warn if a caller ignores return value<br>
WARNINGS_GCC5=-Wno-unused-result<br>
<br>
WARNINGS_GCC6= -Wno-misleading-indentation<br>
<br>
# XXX could not get -Wimplicit-fallthrough=3 to work<br>
WARNINGS_GCC7= -Wno-implicit-fallthrough<br>
<br>
# Other options to consider enabling in the future:<br>
#<br>
# -Wnested-externs Prototypes declared in a function<br>
# -Wwrite-string warn in string constant is passed to a char *<br>
# -Wmissing-prototypes<br>
# -Wunused-parameter<br>
# -Wold-style-definition Would be nice, but zlib falls all over here<br>
<br>
GCC_MAJOR_REV=$(shell $(CC) -dumpversion | sed 's/\..*//')<br>
GCC_MINOR_REV=$(shell $(CC) -dumpversion | sed 's/.*\.//')<br>
ifeq ($(GCC_MAJOR_REV),3)<br>
        WARNINGS += $(WARNINGS_GCC3)<br>
endif<br>
ifeq ($(GCC_MAJOR_REV),4)<br>
        WARNINGS += $(WARNINGS_GCC3) $(WARNINGS_GCC4)<br>
        ifeq ($(shell expr $(GCC_MINOR_REV) \> 5), 1)<br>
                WARNINGS += -Wno-unused-result<br>
        endif<br>
endif<br>
ifeq ($(GCC_MAJOR_REV),5)<br>
        WARNINGS += $(WARNINGS_GCC3) $(WARNINGS_GCC4) $(WARNINGS_GCC5)<br>
endif<br>
ifeq ($(GCC_MAJOR_REV),6)<br>
        WARNINGS += $(WARNINGS_GCC3) $(WARNINGS_GCC4) $(WARNINGS_GCC5) \<br>
                    $(WARNINGS_GCC6)<br>
endif<br>
ifeq ($(GCC_MAJOR_REV),7)<br>
        WARNINGS += $(WARNINGS_GCC3) $(WARNINGS_GCC4) $(WARNINGS_GCC5) \<br>
                    $(WARNINGS_GCC6) $(WARNINGS_GCC7)<br>
endif<br>
ifeq ($(GCC_MAJOR_REV),8)<br>
        WARNINGS += $(WARNINGS_GCC3) $(WARNINGS_GCC4) $(WARNINGS_GCC5) \<br>
                    $(WARNINGS_GCC6) $(WARNINGS_GCC7) $(WARNINGS_GCC8)<br>
endif<br>
<br>
TRACE = -DUSE_TRACE<br>
<br>
ifeq ($(shell uname -s), Darwin)<br>
        XLIBS += -lresolv<br>
        G       += -DNOPROC<br>
endif<br>
<br>
ifeq (clang, $(findstring clang, $(shell $(CC) --version)))<br>
        WARNINGS += -Wno-unused-value -Wno-empty-body -Wno-self-assign<br>
endif<br>
<br>
GCCOPTS=<br>
CC_DEBUG=$(GCCOPTS) $G $(WARNINGS) $(TRACE)<br>
CC_FAST_DEBUG=$(GCCOPTS) $G -O2 $(WARNINGS) $(TRACE)<br>
CC_FAST =$(CC_FAST_DEBUG)<br>
CC_WALL=$(GCCOPTS) $G -DLINT $(WARNINGS) $(TRACE)<br>
BINS    = $(BK) $(BKGUI)<br>
<br>
# List of all objects in bk other than bk.o. Keep it sorted.<br>
# But put bkver.o/cmd.o first, they generate headers.<br>
OBJ =   bkver.o cmd.o \<br>
        abort.o adler32.o alias.o admin.o annotate.o attributes.o \<br>
        bam.o bisect.o bkd.o bkd_bam.o bkd_cd.o \<br>
        bkd_changes.o bkd_client.o bkd_clone.o bkd_cmdtab.o \<br>
        bkd_findkey.o bkd_http.o \<br>
        bkd_id.o bkd_kill.o bkd_level.o bkd_misc.o bkd_nested.o \<br>
        bkd_partition.o bkd_pull.o bkd_push.o bkd_pwd.o \<br>
        bkd_r2c.o \<br>
        bkd_rclone.o bkd_rootkey.o bkd_status.o bkd_synckeys.o bkd_version.o \<br>
        bkverinfo.o \<br>
        cat.o cfile.o changes.o config.o \<br>
        check.o checksum.o clean.o cleanpath.o clone.o \<br>
        cmdlog.o \<br>
        collapse.o comment.o comments.o commit.o comps.o compress.o \<br>
        contrib/cat.o \<br>
        contrib/test.o \<br>
        converge.o \<br>
        cp.o \<br>
        crypto.o \<br>
        cset.o cset_inex.o csetprune.o csets.o cweave.o \<br>
        dataheap.o dbfile.o delta.o diff.o dspec.o \<br>
        export.o \<br>
        fast-import.o fast-export.o features.o findmerge.o \<br>
        find.o findcset.o fixtool.o fsl.o fslayer.o \<br>
        g2bk.o gca.o get.o gethelp.o \<br>
        gethost.o gettemp.o getuser.o gfiles.o glob.o \<br>
        gnupatch.o graft.o grep.o \<br>
        hash_nokey.o \<br>
        heapdump.o help.o here.o here_check.o hostme.o http.o \<br>
        idcache.o isascii.o info.o \<br>
        key2rev.o key2path.o kill.o kv.o \<br>
        libcommit.o libdiff.o libgraph.o librange.o \<br>
        libsfiles.o lines.o \<br>
        localtm.o lock.o locking.o \<br>
        mail.o merge.o mklock.o \<br>
        mailslot.o \<br>
        mtime.o mv.o names.o ndiff.o nested.o newroot.o \<br>
        opark.o \<br>
        parent.o park.o partition.o \<br>
        patch.o \<br>
        pending.o preference.o proj.o \<br>
        poly.o \<br>
        populate.o \<br>
        port/bkd_server.o \<br>
        port/check_rsh.o \<br>
        port/gethomedir.o \<br>
        port/gethost.o port/getinput.o \<br>
        port/getrealname.o port/getrusage.o port/globalroot.o port/gui.o \<br>
        port/hostColonPath.o port/http_proxy.o \<br>
        port/mail.o port/mnext.o port/networkfs.o \<br>
        port/notifier.o port/ns_sock_host2ip.o port/platforminit.o \<br>
        port/sccs_getuser.o port/sccs_lockfile.o \<br>
        port/startmenu.o \<br>
        port/svcinfo.o \<br>
        port/uninstall.o \<br>
        progress.o \<br>
        prs.o pull.o push.o pwd.o \<br>
        randombits.o randseed.o range.o rcheck.o rclone.o \<br>
        rcs2bk.o rcsparse.o \<br>
        receive.o redblack.o regex.o registry.o renumber.o \<br>
        remap.o remote.o \<br>
        repo.o repos.o repogca.o repostats.o repotype.o \<br>
        resolve.o resolve_binaries.o resolve_contents.o \<br>
        resolve_create.o resolve_filetypes.o \<br>
        resolve_flags.o resolve_generic.o resolve_modes.o \<br>
        resolve_renames.o resolve_tags.o restore.o review.o \<br>
        rm.o rmdel.o rmgone.o \<br>
        root.o rset.o sane.o scat.o sccs.o sccs2bk.o \<br>
        sccslog.o sccs_mv.o search.o sec2hms.o send.o sendbug.o \<br>
        set.o setup.o sfio.o shrink.o sinfo.o \<br>
        slib.o smerge.o sort.o startmenu.o \<br>
        stat.o stattest.o status.o stripdel.o synckeys.o \<br>
        tagmerge.o testcode.o tclsh.o takepatch.o \<br>
        testdates.o time.o timestamp.o touch.o trigger.o \<br>
        unbk.o undo.o undos.o unedit.o \<br>
        unique.o uninstall.o unlink.o unlock.o unpull.o unrm.o unwrap.o upgrade.o \<br>
        urlinfo.o \<br>
        utils.o uu.o what.o which.o \<br>
        xfile.o xflags.o \<br>
        zone.o<br>
SCRIPTS = bk.script import \<br>
        uuwrap unuuwrap gzip_uuwrap ungzip_uuwrap \<br>
        b64wrap unb64wrap gzip_b64wrap ungzip_b64wrap<br>
PSCR    = t/doit t/guitest<br>
PROGS   = libc/mtst$(EXE)<br>
LIBS    = libc/libc.a<br>
DATA    = bkmsg.txt bkhelp.txt version \<br>
        ../doc/<a href="http://bk_refcard.ps" rel="noreferrer noreferrer" target="_blank">bk_refcard.ps</a> ../doc/bk_refcard.pdf ../RELEASE-NOTES.md \<br>
        dspec-changes dspec-changes-3.2 dspec-changes-4.0 dspec-changes-h \<br>
        dspec-changes-hv dspec-changes-json dspec-changes-json-v \<br>
        dspec-changes-vv dspec-log dspec-prs<br>
<br>
CONTRIB = gui/ide/emacs/vc-bk.el contrib/git2bk.l<br>
ALL     = PCRE $(LIBS) $(BINS) $(SCRIPTS) $(PSCR) $(XTRA) \<br>
        $(PROGS) L-clean GUI L-doc $(DATA)<br>
<br>
CFLAGS  = $(CC_DEBUG)<br>
export CFLAGS<br>
CPPFLAGS= -Ilibc $(TOMCRYPT_CPPFLAGS) $(TOMMATH_CPPFLAGS) \<br>
        $(PCRE_CPPFLAGS) $(LZ4_CPPFLAGS) $(ZLIB_CPPFLAGS)<br>
# Override this if you don't have it.<br>
RANLIB  = ranlib<br>
<br>
# list of C sources in bk<br>
SRCS    = bk.c $(OBJ:.o=.c)<br>
# list of headers in bk<br>
HDRS    = bam.h bkd.h bk-features.h config.h configvars.def diff.h fsfuncs.h \<br>
          graph.h nested.h \<br>
          progress.h range.h rcs.h resolve.h sccs.h \<br>
          cmd.h poly.h proj.h redblack.h libc/system.h xfile.h<br>
<br>
# list of non-C sources in bk<br>
SCRSRCS = bk.sh import.sh <a href="http://kwextract.pl" rel="noreferrer noreferrer" target="_blank">kwextract.pl</a> uuwrap.sh unuuwrap.sh \<br>
          port/unix_platform.sh port/win32_platform.sh \<br>
          gzip_uuwrap.sh ungzip_uuwrap.sh \<br>
          substvars.sh b64wrap.sh gzip_b64wrap.sh \<br>
          unb64wrap.sh ungzip_b64wrap.sh <br>
MISC    = bkmsg.doc t/doit.sh<br>
<br>
default:<br>
        $(MAKE) p<br>
<br>
SUBDIRS = libc $(shell ls -d tomcrypt tommath 2>/dev/null)<br>
<br>
all: $(ALL)<br>
<br>
prof:<br>
        $(MAKE) CFLAGS="$G -pg -O2" LDFLAGS=-pg all<br>
gprof:<br>
        $(MAKE) CFLAGS="$G -DPROFILE -pg -O2" LDFLAGS=-pg all<br>
ggprof:<br>
        $(MAKE) CFLAGS="$G -DPROFILE -pg" LDFLAGS=-pg all<br>
# Debugging...<br>
d:<br>
        $(MAKE) CFLAGS="$G -DDEBUG" all<br>
debug:<br>
        $(MAKE) CFLAGS="$G -DDEBUG" all<br>
debug2:<br>
        $(MAKE) CFLAGS="$G -DDEBUG2" all<br>
<br>
gWall Wall:<br>
        $(MAKE) CFLAGS="$(CC_WALL)" all<br>
<br>
# production builds<br>
p:  ## Build a production version of BitKeeper (no -g)<br>
        $(MAKE) CFLAGS="$(CC_FAST) $(CF)" all<br>
<br>
trial:<br>
        $(MAKE) TRIAL="3*WEEK" CFLAGS="$(CC_FAST) $(CF)" all<br>
<br>
trial3M:<br>
        $(MAKE) TRIAL="3*MONTH" CFLAGS="$(CC_FAST) $(CF)" all<br>
<br>
g:  ## Build a debug version of BitKeeper (-g)<br>
        $(MAKE) CFLAGS="$(CC_DEBUG)" all<br>
gO:<br>
        $(MAKE) CFLAGS="$(CC_FAST_DEBUG)" all<br>
gcov:<br>
        $(MAKE) CFLAGS="$(CC_DEBUG) -fprofile-arcs -ftest-coverage" all<br>
<br>
clean: L-clean FORCE  ## Remove object files and executables<br>
        $(if $(Q),@echo Cleaning up,)<br>
        $(Q)for sub in $(SUBDIRS) ../doc ../man gui utils win32 t t/win32; \<br>
        do      $(MAKE) -C$$sub "CFLAGS=$(CFLAGS)" $@; \<br>
        done<br>
        $(Q)$(RM) $(OBJ) bk.o $(BKG_O) $(BINS) $(SCRIPTS) \<br>
            $(PSRC) $(PROGS)<br>
        $(Q)$(RM) tags TAGS tags.local cscope.out substvars a.out cmd.c cmd.h \<br>
                core *.bb *.bbg *.da *.gcov \<br>
                bk.ico \<br>
                bkmsg.txt bkhelp.txt bkver.c version \<br>
                t/doit t/guitest kw2val_lookup.c bkres.o svcmgr.exe \<br>
                <a href="http://conf.mk" rel="noreferrer noreferrer" target="_blank">conf.mk</a><br>
        $(Q)$(RM) -r tmp<br>
ifeq "$(OSTYPE)" "msys"<br>
        $(Q)$(RM) -rf gnu/bin gnu/doc gnu/etc gnu/share<br>
        $(Q)$(RM) -f gnu/m.ico gnu/msys.bat gnu/msys.ico<br>
        $(Q)-rmdir gnu/tmp<br>
        $(Q)-rmdir gnu<br>
endif<br>
ifeq (true,$(INREPO))<br>
ifneq (,$(INSTALLED_BK))<br>
        $(Q)EXTRALIST=`"$(INSTALLED_BK)" -Aax | \<br>
                grep -v '~$$\|conf-.*\.mk$$'` ; \<br>
        if [ "$$EXTRALIST" ]; then \<br>
                echo "Clean left behind the following files:" ; \<br>
                for file in $$EXTRALIST; do \<br>
                        echo "  $$file" ; \<br>
                done ; \<br>
        else \<br>
                echo Clean complete ; \<br>
        fi<br>
endif<br>
endif<br>
<br>
clobber: clean FORCE ## Same as 'clean' but also bk clean files<br>
        -@$(BK) -A clean<br>
<br>
# XXX subdirs? (see tags)<br>
wc: $(HDRS) $(SRCS) $(SCRSRCS) $(MISC)<br>
        wc -l $(SRCS) $(HDRS) $(SCRSRCS) $(MISC)<br>
<br>
get-e: FORCE<br>
        -@$(BK) edit -qT `echo $(HDRS) $(SRCS) $(SCRSRCS) $(MISC) | fmt -1|sort -u`<br>
        $(Q)$(MAKE) tags<br>
<br>
srcs: $(SRCS) $(HDRS) FORCE<br>
        $(Q)for sub in $(SUBDIRS); do $(BK) -r$$sub co -q; done<br>
<br>
tags: $(patsubst %,%/tags.local, $(SUBDIRS)) tags.local<br>
        @if [ -x $(BK) ]; \<br>
        then    $(BK) get -Sq tags.skippats; \<br>
                $(BK) _sort -u $^ | grep -v -ftags.skippats > $@; \<br>
        else \<br>
                bk get -Sq tags.skippats; \<br>
                bk _sort -u $^ | grep -v -ftags.skippats > $@; \<br>
        fi<br>
        @echo ctags completed<br>
<br>
tags.local: $(SRCS) $(HDRS)<br>
        @ctags -f $@ --file-tags=yes --c-types=d+f+s+t $^<br>
<br>
%/tags.local: FORCE<br>
        $(Q)$(MAKE) -C $(dir $@) tags.local<br>
<br>
ssh sshtest:<br>
        $(MAKE) realtest<br>
<br>
rsh rshtest:<br>
        PREFER_RSH=YES $(MAKE) realtest<br>
<br>
test tests:<br>
        DO_REMOTE=NO $(MAKE) -C t<br>
<br>
nonet nonet_test localtest:<br>
        BK_NONET=YES PREFER_RSH=YES $(MAKE) realtest<br>
<br>
realtest: $(ALL) t/doit<br>
        -cd gui/tcltk && $(MAKE) clobber<br>
        -$(BK) get -qS t/setup t/win32/win32_common<br>
        $(BK) -rt get -qTS 't.*'<br>
        cd t && ./doit -f 5<br>
<br>
guitest: $(ALL) t/doit<br>
        -$(BK) get -qS t/SCCS/s.g.* t/setup t/win32/win32_common t/guitest.tcl<br>
        cd t && ./doit -g -i<br>
<br>
t/doit: t/doit.sh substvars<br>
        ./substvars t/doit.sh > t/doit<br>
        chmod +x t/doit<br>
<br>
t/guitest: t/guitest.tcl<br>
        cat < t/guitest.tcl > t/guitest<br>
<br>
.PHONY: FORCE<br>
FORCE:<br>
<br>
win32: FORCE<br>
        cd win32 && $(MAKE) BINDIR=$(BINDIR)<br>
        cd t/win32 && $(MAKE)<br>
<br>
# build libraries in sub directories<br>
%.a: FORCE<br>
        $(Q)$(MAKE) -C $(dir $@) $(notdir $@)<br>
<br>
libc/mtst$(EXE): libc/libc.a FORCE<br>
        $(Q)$(MAKE) -C libc mtst$(EXE)<br>
<br>
bkres.o: win32/data/bk.rc bk.ico<br>
        windres -i win32/data/bk.rc -o bkres.o<br>
<br>
bk.ico: win32/data/bk.ico<br>
        @cp -f win32/data/bk.ico .<br>
<br>
ifneq ($(TOMCRYPT_SYSTEM),1)<br>
# add dependency on building libraries first<br>
$(BK): $(TOMCRYPT_LDFLAGS)<br>
endif<br>
ifneq ($(TOMMATH_SYSTEM),1)<br>
# add dependency on building libraries first<br>
$(BK): $(TOMMATH_LDFLAGS)<br>
endif<br>
<br>
$(BK): $(LIBS) bk.o $(RESOURCE) $(OBJ)<br>
        $(if $(Q),@echo LINKING $(BK),)<br>
        $(Q)$(LD) $(LDFLAGS) -o $@ bk.o $(OBJ) $(RESOURCE) $(LIBS) \<br>
                $(TOMCRYPT_LDFLAGS) $(TOMMATH_LDFLAGS) \<br>
                $(PCRE_LDFLAGS) $(LZ4_LDFLAGS) $(ZLIB_LDFLAGS) $(XLIBS)<br>
<br>
# Windows only rule, BKGUI should be blank on other platforms<br>
$(BKGUI): bkg.o $(RESOURCE)<br>
        $(if $(Q),@echo LINKING $(BKGUI),)<br>
        $(Q)$(LD) $(LDFLAGS) -o $@ bkg.o $(RESOURCE) -Llibc -lc -mwindows $(XLIBS)<br>
<br>
bk.script: bk.sh port/$(SYS)_platform.sh<br>
        cat port/$(SYS)_platform.sh bk.sh > bk.script<br>
        chmod +x bk.script <br>
<br>
bkmsg.txt: bkmsg.doc<br>
        cp -f $< $@<br>
<br>
L-clean: FORCE<br>
        @rm -f gui/share/doc/L/little.man ../man/man1/bk-little.1<br>
        @rm -f ../man/man2help/bk-little-1.fmt<br>
<br>
# has to run before bkhelp.txt but after GUI<br>
L-doc L-docs: GUI FORCE<br>
        @test -f gui/share/doc/L/little.man || { \<br>
                echo Failed to build gui/share/doc/L/little.man; \<br>
                exit 1; \<br>
        }<br>
        @if [ -s gui/share/doc/L/little.man ]; \<br>
        then    cp gui/share/doc/L/little.man ../man/man1/bk-little.1; \<br>
        else    cp ../man/man1/bk-little.1.pfmt ../man/man1/bk-little.1; \<br>
        fi; \<br>
        chmod +w ../man/man1/bk-little.1<br>
<br>
bkhelp.txt: $(BK) version L-docs FORCE<br>
        @rm -f ../man/man2help/bk-little.fmt<br>
        @cd ../man/man2help && $(MAKE) BK=$(HERE)/bk$(EXE) helptxt<br>
        @cp ../man/man2help/helptxt bkhelp.txt<br>
        @rm -f ../man/man1/bk-little.1<br>
<br>
html-docs: bkhelp.txt<br>
        @cd ../man/man2html && $(MAKE)<br>
<br>
../doc/<a href="http://bk_refcard.ps" rel="noreferrer noreferrer" target="_blank">bk_refcard.ps</a>: $(BK) FORCE<br>
        $(Q)echo building $@<br>
        $(Q)-$(BK) -r../doc co -qS<br>
        $(Q)$(MAKE) -C ../doc BK=$(HERE)/bk$(EXE) all<br>
<br>
../doc/bk_refcard.pdf: ../doc/<a href="http://bk_refcard.ps" rel="noreferrer noreferrer" target="_blank">bk_refcard.ps</a><br>
<br>
# This must be rebuilt every time because it includes the build time<br>
bkver.c: utils/bk_version FORCE<br>
        $(if $(Q),@echo Building $@,)<br>
        $(Q)echo "#include \"sccs.h\"" > bk.v<br>
        $(Q)echo "char *bk_platform = \""`./utils/bk_version`"\";" >> bk.v<br>
        $(Q)echo "int test_release = "$(TRIAL)";" >> bk.v<br>
        $(Q)echo "time_t bk_build_timet = "`perl -e "print time"`";" >> bk.v<br>
        $(Q)echo "char *bk_build_dir = \""`pwd`"\";" >> bk.v<br>
        $(Q)mv -f bk.v bkver.c<br>
<br>
version: version.sh $(BK) utils/bk_version GUI FORCE<br>
        bash version.sh > $@<br>
<br>
%: %.sh<br>
        $(if $(Q),@echo Building $@,)<br>
        $(Q)$(RM) $@<br>
        $(Q)cp $< $@<br>
        $(Q)chmod +x $@<br>
<br>
%: %.l<br>
        $(if $(Q),@echo Not lexing $@,)<br>
<br>
import: import.sh port/$(SYS)_platform.sh<br>
        cat port/$(SYS)_platform.sh import.sh > import.T<br>
        chmod +x import.T<br>
        mv -f import.T import<br>
<br>
# Quick and dirty target so we can make all the gui tools without the rest<br>
.PHONY: GUI<br>
GUI: PCRE $(BK)<br>
        @$(MAKE) -Cgui BK=$(HERE)/bk$(EXE) gui<br>
<br>
install: installdir<br>
        tmp/bitkeeper/bk _install -d -f $(DESTDIR)$(BINDIR)<br>
        @echo BitKeeper is installed in $(BINDIR)<br>
        @echo We suggest you run:<br>
        @echo<br>
        @echo sudo $(BINDIR)/bk links /usr/local/bin<br>
        @echo<br>
        @echo to create the bk symlink.<br>
<br>
installdir: utils/registry.tcl<br>
        rm -rf $(IMGDIR) || exit 1<br>
        mkdir -p $(IMGDIR)/contrib<br>
        mkdir -p $(IMGDIR)/lscripts<br>
        -$(BK) -rwww get -S<br>
        -cp -f -r www $(IMGDIR)<br>
        -$(BK) get -S $(CONTRIB)<br>
        tar cf - $(BINS) $(SCRIPTS) lscripts gui/bin gui/lib gui/images \<br>
                | (cd $(IMGDIR) && tar xf -)<br>
        cp -f $(DATA) $(IMGDIR)<br>
        cp -f $(CONTRIB) $(IMGDIR)/contrib<br>
        (cd ../doc/nested && $(MAKE) install HTML=$(IMGDIR)/html)<br>
        if [ $(SYS) = unix ]; \<br>
        then    $(BK) get -S ../man/Makefile; \<br>
                cd ../man && $(MAKE) install BINDIR=$(IMGDIR) ;\<br>
        else \<br>
                (cd win32 && $(MAKE) BINDIR=$(IMGDIR) install); \<br>
                cp utils/registry.tcl $(IMGDIR)/gui/lib; \<br>
        fi<br>
        cd $(IMGDIR); \<br>
            find . -type l | \<br>
                perl -ne 'chomp; $$a = readlink; print "$$a|$$_\n";'>symlinks; \<br>
            test -s symlinks || rm -f symlinks<br>
        @true<br>
<br>
image:  ## Build the installer (left in src/utils/bk-*)<br>
        $(MAKE) p<br>
        $(MAKE) _image<br>
<br>
_image:<br>
        $(MAKE) installdir<br>
        ${MAKE} -Cutils BINDIR=$(IMGDIR) "CC=$(CC)" "BK=$(HERE)/bk$(EXE)" "CFLAGS=$(CFLAGS)" image<br>
<br>
crankturn: crank.sh remote.sh  ## Run a clean-build + regressions in cluster<br>
        REPO=$(REPO) URL=$(URL) REMOTE=remote.sh LOG=$(LOG) bash crank.sh<br>
<br>
cranksave: crank.sh remote.sh  ## Run a crankturn but save the built images<br>
        REPO=$(REPO) URL=$(URL) REMOTE=remote.sh LOG=$(LOG) bash crank.sh save<br>
<br>
crankstatus: crank.sh remote.sh  ## See how the crank is going<br>
        REPO=$(REPO) URL=$(URL) REMOTE=remote.sh LOG=$(LOG) bash crank.sh status<br>
<br>
crankrelease nightly: $(BK) crank.sh remote.sh  ## Do a BitKeeper release (or nightly build)<br>
        @(TAG=$(shell $(BK) changes -r+ -d:TAG:) ; \<br>
        test x$$TAG = x && { \<br>
                echo Cannot crankrelease with a non-tagged tip ; \<br>
                exit 1 ; \<br>
        } ; \<br>
        case $@ in \<br>
        crankrelease ) \<br>
                TYPE=release; DIR=/home/bk/images/$$TAG; \<br>
                ;; \<br>
        nightly ) \<br>
                TYPE=nightly; DIR=/home/bk/images/nightly; \<br>
                HOSTS="$(NIGHTLY_HOSTS)" ; \<br>
                ;; \<br>
        esac ; \<br>
        test -d $$DIR || mkdir -p $$DIR ; \<br>
        REPO=$(REPO) URL=$(URL) HOSTS=$$HOSTS REMOTE=remote.sh \<br>
            LOG=$(LOG) bash crank.sh $$TYPE ; \<br>
        $(BK) -R get -qS ../RELEASE-NOTES.md ; \<br>
        cp ../RELEASE-NOTES.md $$DIR ; \<br>
        SAVED_WD=$(shell pwd) ; \<br>
        cd $$DIR && chmod +rx bk-* >/dev/null 2>&1 ; \<br>
        rm -f MD5SUMS ; \<br>
        md5sum bk-* >> MD5SUMS ; \<br>
        echo "Your images are in $$DIR" ; \<br>
        case $@  in  \<br>
        crankrelease ) \<br>
                echo "Run './mkrelease $$TAG' to release this version of bk."; \<br>
                ;; \<br>
        nightly ) \<br>
#               cd $$SAVED_WD ; \<br>
#               ./mkupgrades --nightly $$TAG ; \<br>
                ;; \<br>
        esac)<br>
<br>
crankclean: crank.sh remote.sh<br>
        REPO=$(REPO) URL=$(URL) REMOTE=remote.sh LOG=$(LOG) bash crank.sh clean<br>
<br>
# This target assumes a bk repository<br>
.PHONY: src-tar<br>
src-tar: $(BK) version ## build tar.gz image for the current tree<br>
ifeq (false,$(INREPO))<br>
        $(error This target only works in a BK source repository)<br>
else<br>
        ./bk here add default TCLTK<br>
        $(Q)-mkdir -p tmp/src<br>
        $(Q)(DIR=bk-$(shell $(BK) version -s) ; \<br>
             TAR="$$DIR".tar.gz ; \<br>
             echo "Creating $$TAR in tmp/src..." ; \<br>
             cd tmp/src ; \<br>
             rm -rf "$$DIR" ; \<br>
             ../../bk export -tplain -kwr+ -sdefault -sTCLTK "$$DIR" ; \<br>
             cat ../../version > "$$DIR/src/bkvers.txt" ; \<br>
             tar -czf "$$TAR" "$$DIR" ; \<br>
             rm -rf "$$DIR" ; \<br>
             echo Done ; \<br>
        )<br>
endif<br>
<br>
# only depend on conf.mk.local if it exists<br>
<a href="http://conf.mk" rel="noreferrer noreferrer" target="_blank">conf.mk</a>: mkconf.sh $(wildcard conf.mk.local)<br>
        sh mkconf.sh > $@ || { $(RM) $@; false; }<br>
<br>
%.o: %.c<br>
        $(if $(Q),@echo CC $<,)<br>
        $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@<br>
<br>
port/startmenu.o: port/startmenu.c $(HDRS)<br>
        $(if $(Q),@echo CC $<,)<br>
        $(Q)$(CC) $(CFLAGS) -fno-strict-aliasing $(CPPFLAGS) -c $< -o $@<br>
<br>
depend: $(SRCS)<br>
        $(CC) -MM -MG -D_DEPEND $(SRCS) > depends<br>
<br>
# for system.h we need to actually run libc's makefile because it includes<br>
# calculated header files<br>
libc/system.h: FORCE<br>
        $(MAKE) -C libc system.h<br>
<br>
libc/libc.a: libc/system.h<br>
<br>
sccs.h: PCRE<br>
.PHONY: PCRE<br>
PCRE:<br>
ifneq ($(PCRE_SYSTEM),1)<br>
        $(MAKE) -Cgui/tcltk pcre<br>
endif<br>
<br>
$(OBJ) bk.o: $(HDRS)<br>
<br>
cmd.c cmd.h: <a href="http://cmd.pl" rel="noreferrer noreferrer" target="_blank">cmd.pl</a> bk.sh $(filter bkd_%,$(SRCS))<br>
        $(if $(Q),@echo Building $@,)<br>
        $(Q)perl <a href="http://cmd.pl" rel="noreferrer noreferrer" target="_blank">cmd.pl</a> || (rm -f cmd.c cmd.h; exit 1)<br>
<br>
# This parses slib.c and extracts the meta-data keywords expanded<br>
# by kw2val() and passes them to gperf to generate hash lookup code.<br>
slib.o: kw2val_lookup.c<br>
kw2val_lookup.c: slib.c <a href="http://kw2val.pl" rel="noreferrer noreferrer" target="_blank">kw2val.pl</a><br>
        $(if $(Q),@echo Building $@,)<br>
        $(Q)perl <a href="http://kw2val.pl" rel="noreferrer noreferrer" target="_blank">kw2val.pl</a> slib.c || (rm -f kw2val_lookup.c; exit 1)<br>
<br>
check-syntax:<br>
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -S ${CHK_SOURCES} -o /dev/null<br>
<br>
# print a make variable  'make print-REPO'<br>
#   <a href="http://www.cmcrossroads.com/article/printing-value-makefile-variable" rel="noreferrer noreferrer" target="_blank">http://www.cmcrossroads.com/article/printing-value-makefile-variable</a><br>
print-%:<br>
        @echo $* = \"$($*)\"<br>
<br>
.PHONY: help<br>
<br>
help:<br>
        @grep -E -h '^[-a-zA-Z_\ ]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'<br>
        @echo Suggested: make -j12 image<br>
<br>
</blockquote></div></div></div>