I've written a scons
build chain form a little C project, but I'm afraid users won't like to be told "You should install SCons first. Besides, it's really cool!" (expecially my professor, as he's kind of from the old guard).
Is there a way I can set up a Makefile that will wrap scons, not requiring it to be installed on the target system?
After looking for such a solution some time ago, I ended up writing a Makefile for this purpose.
Because SCons also comes as a drop-in userspace package scons-local
(see the download page), one can fetch in and run it. Here is a dissectioned and commented version of my Makefile, which I also uploaded as a gist.
all: get_scons
@$(SCONS_EXE)
↑ The default action depends on scons
being available, and simply runs the scons command (set later in the script) (the @
symbol prevents make from printing the command)
SCONS_VERSION=2.3.4
scons-local-%.tar.gz:
curl -L http://sourceforge.net/projects/scons/files/scons-local/$(SCONS_VERSION)/scons-local-$(SCONS_VERSION).tar.gz > scons-local-$(SCONS_VERSION).tar.gz
touch scons-local-$(SCONS_VERSION).tar.gz
scons-local: scons-local-$(SCONS_VERSION).tar.gz
mkdir -p scons-local
tar xzf scons-local-$(SCONS_VERSION).tar.gz --directory scons-local
touch scons-local
↑ Set up the rules for fetching the tarball and unpack it into the scons-local
directory
NATIVE_SCONS=$(strip $(shell which scons 2>/dev/null))
ifeq ($(NATIVE_SCONS),)
SCONS_EXE=python2 ./scons-local/scons.py
get_scons: scons-local
@echo "Couldn't find an installation of SCons, using a local copy"
else
SCONS_EXE=$(NATIVE_SCONS)
get_scons:
@echo "Found SCons installation at $(SCONS_EXE)"
endif
↑ Look for the scons
executable in the search path (using the which
command): if it is available, set up the get-scons
target to simply print it is available. If, instead, it is not available, create the get-scons
target instructing it to depend on the scons-local
target defined earlier.
clean:
$(SCONS_EXE) -c
rm -rf scons-local
rm -f scons-local-*.tar.gz
.PHONY: all clean get_scons
↑ Finally, set-up the clean
target that delegates to scons and deletes the local installation afterwards. The .PHONY
rule tells make
that the following rules do not correspond to files being created.
At this point, one could add more proxy rules of the kind:
mytarget: get_scons
@$(SCONS_EXE) mytarget
Which will invoke scons with the corresponding target.
Hope this is useful, feel free to correct me in case there's something wrong (I'm actually not a Makefile expert, and I'm trying not to become one by using SCons instead :P )