The gorilla example,
Building Starkits and Starpacks using a Makefile, was great, but it rebuilds the whole shebang every time. I was looking for a Makefile that would let me make local changes, rebuild, and test before checking the source back in.
I removed the dependency on the local Tcl installation from my earlier version, because that became impossible to maintain. All the required files now get checked out to a well-known tree rooted at SUPPORT.
Much simplified from earlier version. This will build on Linux and Windows platforms (tested on Redhat and Suse and XP.) For example, you can cross-compile a Linux binary on XP using:
$make ARCH=LINUX
See also
cross-building a starkit, for a cross-build that starts with a starkit and builds for several platforms.
LV 2009-11-18 So on Windows, what files are needed to support this Makefile process?
dcd 2009-12-10 You need, obviously, a tclkitsh built for Windows and gnu make, cp, rm and mkdir; preferably a recent version of make. I use a cygwin environment, but you could just grab unix-utils and stay with your dos shell; untested, but I'm pretty sure you could make that work and avoid the overhead of a full cygwin install.
# Support for Linux and Windows XP platforms
# This builds from the app.tcl source, not a kit
#
# SUPPORT is the base for the runtimes and tcl libraries
SUPPORT := ../support/tcl
WINRT := $(SUPPORT)/win/bin/tclkitsh-win32.upx.exe
LINRT := $(SUPPORT)/unix/bin/tclkitsh-linux
TCLLIB := $(SUPPORT)/lib
SDXKIT := $(SUPPORT)/sdx.kit
# OS is defined on Windows, not on Linux
ifndef OS
OS := LINUX
else
OS := WIN
endif
# pick the correct tclkit to run sdx.kit
ifeq ($(OS),WIN)
SDX = $(WINRT) $(SDXKIT)
else
SDX = $(LINRT) $(SDXKIT)
endif
# if not defined
# set the target architecture to the build machine
ifndef ARCH
ARCH = $(OS)
endif
# point to the correct runtime
# and to the location of the platform specific binaries
# and get the application extension set
ifeq ($(ARCH),WIN)
LIBTCL := $(SUPPORT)/win/lib
RUNTIME = $(WINRT)
APPEXT = .exe
else
ifeq ($(ARCH),LINUX)
LIBTCL := $(SUPPORT)/unix/lib
RUNTIME = $(LINRT)
APPEXT =
endif
endif
# TCLLIBS, here, means pure tcl packages, not just from Tcllib
# each lib here should be in its own directory in $(SUPPORT)/lib
TCLLIBS := uri
# each package in BINLIBS s.b. in its own platform specific library
BINLIBS := tnc tdom0.8.2 Tcldom2.6 Tclxml2.6
APP := myapp
EXE := $(patsubst %,%$(APPEXT),$(APP))
VFS = $(APP).vfs
VFSLIB = $(VFS)/lib
# a list of files you want copied into the application
PACKAGES = $(TCLLIBS) $(BINLIBS) dtd.xml
all: $(EXE)
# it appears that windows or sdx doesn't like copying the runtime
# if it is the same runtime that is executing sdx.kit
# so the copy / remove dance is necessary
%$(APPEXT) : %.vfs $(PACKAGES)
cp $(RUNTIME) ./runtime
$(SDX) wrap $@ -runtime runtime
rm runtime
chmod +x $@
# this prevents make from trying, and failing, to delete
# the vfs directory, which is not a regular file
.SECONDARY : $(patsubst %,%.vfs,$(APP))
# make 3.81 doesn't require this workaround
export PACKAGES
%.vfs : %.tcl
if [ ! -d $@ ]; \
then $(SDX) qwrap $<; $(SDX) unwrap $*.kit; fi; \
cp $< $@/lib/app-$*/
# put packages here, they may each have different idiosyncracies
.PHONY : $(PACKAGES)
$(PACKAGES) : $(VFS)
$(TCLLIBS): $(APP).vfs
if [ ! -d $(VFSLIB)/$@ ] ; then \
mkdir $(VFSLIB)/$@ ; fi
cp $(TCLLIB)/$(@)/*.tcl $(VFSLIB)/$@
dtd.xml: $(APP).vfs
cp $(APP)/$@ $<
$(BINLIBS): $(APP).vfs
if [ ! -d $(VFSLIB)/$@ ] ; then \
mkdir $(VFSLIB)/$@ ; fi
cp $(LIBTCL)/$(@)/* $(VFSLIB)/$@
clean:
rm -f $(APP) $(patsubst %,%.kit,$(APP)) $(patsubst %,%.exe,$(APP)); \
rm -rf $(patsubst %,%.vfs,$(APP))