# Standard rules for GARStow ports. # # Copyright (C) 2001 Nick Moffitt # Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Adam Sampson # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # This is useful for $(wordlist ...) tricks. SPACE = $(subst X,,X X) # cookies go here, so we have to be able to find them for # dependency checking. VPATH += $(COOKIEDIR) # So these targets are all loaded into bbc.port.mk at the end, # and provide actions that would be written often, such as # running configure, automake, makemaker, etc. # # The do- targets depend on these, and they can be overridden by # a port maintainer, since they'e pattern-based. Thus: # # extract-foo.tar.gz: # (special stuff to unpack non-standard tarball, such as one # accidentally named .gz when it's really bzip2 or something) # # and this will override the extract-%.tar.gz rule. # convenience variable to make the cookie. DOMAKECOOKIE = mkdir -p `dirname $(COOKIEDIR)/$@` && date >> $(COOKIEDIR)/$@ MAKECOOKIE = @$(DOMAKECOOKIE) # The command to use to acquire a lock; the lock name will be appended to this. # (If you can't do locking for some reason, set this to "env dummy=".) WITH_LOCK := mkdir -p $(TEMPDIR) && $(SCRIPTSDIR)/with-lock $(TEMPDIR)/lock. # $(MOVE_CONTENTS) A B moves the contents of A into B, then removes A, doing # the right thing if A or B don't exist or are empty. MOVE_CONTENTS = move_contents() { \ set -e; \ rmdir "$$1" 2>/dev/null || true; \ if [ -d "$$1" ]; then \ echo " ==> Moving contents of $$1 to $$2"; \ mkdir -p "$$2"; \ mv $$1/* $$2; \ rmdir $$1; \ fi; \ } && move_contents #################### FETCH RULES #################### MASTER_SUBDIR ?= DISTFILE_SUBDIR ?= SIGFILE_SUBDIR ?= PATCHFILE_SUBDIR ?= MASTER_DIRS = $(addsuffix $(MASTER_SUBDIR),$(MASTER_SITES)) DISTFILE_DIRS = $(addsuffix $(DISTFILE_SUBDIR),$(DISTFILE_SITES)) SIGFILE_DIRS = $(addsuffix $(SIGFILE_SUBDIR),$(SIGFILE_SITES)) PATCHFILE_DIRS = $(addsuffix $(PATCHFILE_SUBDIR),$(PATCHFILE_SITES)) FILE_SITES = file://$(FILEDIR)/ file://$(GARCHIVEDIR)/ DISTFILE_URLS = $(foreach DIR,$(FILE_SITES) $(DISTFILE_DIRS) $(MASTER_DIRS),$(addprefix $(DIR),$(DISTFILES))) SIGFILE_URLS = $(foreach DIR,$(FILE_SITES) $(SIGFILE_DIRS) $(MASTER_DIRS),$(addprefix $(DIR),$(SIGFILES))) PATCHFILE_URLS = $(foreach DIR,$(FILE_SITES) $(PATCHFILE_DIRS) $(MASTER_DIRS),$(addprefix $(DIR),$(PATCHFILES))) # FIXME: doesn't handle colons that are actually in the URL. # Need to do some URI-encoding before we change the http:// to # http// etc. URLS = $(subst ://,//,$(DISTFILE_URLS) $(SIGFILE_URLS) $(PATCHFILE_URLS)) # Download the file if and only if it doesn't have a preexisting # checksum file. Loop through available URLs and stop when you # get one that doesn't return an error code. $(DOWNLOADDIR)/%: @if test -f $(COOKIEDIR)/checksum-$*; then : ; else \ echo " ==> Grabbing $@"; \ for i in $(filter %/$*,$(URLS)); do \ echo " ==> Trying $$i"; \ $(MAKE) -s $$i || continue; \ break; \ done; \ if test -r $@ ; then : ; else \ echo '*** GAR GAR GAR! Failed to download $@! GAR GAR GAR! ***' 1>&2; \ false; \ fi; \ fi # We specify --passive-ftp for all protocols because it's possible for # an HTTP URL to redirect to an FTP one -- download.kde.org works like # this, for instance. # We specify a custom User-Agent because some clueless host sites # block wget specifically. # We also specify --no-check-certificate since we can't check the validity. WGET_OPTS = -c --no-check-certificate --passive-ftp -U "GARstow/1.0" # download an http URL (colons omitted) http//%: @wget $(WGET_OPTS) -P $(DOWNLOADDIR) http://$* # download an https URL (colons omitted) https//%: @wget $(WGET_OPTS) -P $(DOWNLOADDIR) https://$* # download an ftp URL (colons omitted) ftp//%: @wget $(WGET_OPTS) -P $(DOWNLOADDIR) ftp://$* # link to a local copy of the file # (absolute path) file///%: @if test -f /$*; then \ ln -sf "/$*" $(DOWNLOADDIR)/$(notdir $*); \ else \ false; \ fi # link to a local copy of the file # (relative path) file//%: @if test -f $*; then \ ln -sf $(CURDIR)/$* $(DOWNLOADDIR)/$(notdir $*); \ else \ false; \ fi # Using Jeff Waugh's rsync rule. # DOES NOT PRESERVE SYMLINKS! rsync//%: @rsync -azvL --progress rsync://$* $(DOWNLOADDIR)/ # Download a directory tree as a tarball. RSYNC_OPTS ?= -az RSYNC_PATH ?= rsynctree//%: @mkdir -p $(DOWNLOADDIR)/rsync @rsync -v --progress $(RSYNC_OPTS) $(RSYNC_PATH) $(DOWNLOADDIR)/rsync @cd $(DOWNLOADDIR)/rsync && tar -czvf ../out * @mv $(DOWNLOADDIR)/out $(DOWNLOADDIR)/$* # Using Jeff Waugh's scp rule scp//%: @scp -C $* $(DOWNLOADDIR)/ # Check out source from CVS. CVS_CO_OPTS ?= -D$(GARVERSION) -P CVS_MODULE ?= $(GARNAME) cvs//%: @mkdir -p $(DOWNLOADDIR)/cvs @cd $(DOWNLOADDIR)/cvs && \ cvs -d$(CVS_ROOT) login && \ cvs -d$(CVS_ROOT) co -d $(DISTNAME) $(CVS_CO_OPTS) $(CVS_MODULE) && \ tar czvf ../$* $(DISTNAME) # Check out source from Subversion. SVN_REVISION ?= "{$(GARVERSION)}" SVN_CO_OPTS ?= -r $(SVN_REVISION) svnco//%: @mkdir -p $(DOWNLOADDIR)/svn @cd $(DOWNLOADDIR)/svn && \ svn co $(SVN_CO_OPTS) $(SVN_PATH) $(DISTNAME) && \ tar czvf ../$* $(DISTNAME) # Check out source from Darcs. DARCS_GET_OPTS ?= --partial --to-match "date $(GARVERSION)" darcs//%: @mkdir -p $(DOWNLOADDIR)/darcs @cd $(DOWNLOADDIR)/darcs && \ darcs get $(DARCS_GET_OPTS) $(DARCS_PATH) $(DISTNAME) && \ tar -czvf ../$* $(DISTNAME) # Check out source from Git. GIT_REVISION ?= `git log --until $(GARVERSION) -n 1 --format=oneline | cut -d' ' -f1` git//%: @mkdir -p $(DOWNLOADDIR)/git @cd $(DOWNLOADDIR)/git && \ git clone $(GIT_PATH) $(DISTNAME) && \ (cd $(DISTNAME) && git checkout $(GIT_REVISION)) && \ tar czvf ../$* $(DISTNAME) # Check out source from Mercurial. HG_REVISION ?= $(GARVERSION) HG_CLONE_OPTS ?= -r "$(HG_REVISION)" hg//%: @mkdir -p $(DOWNLOADDIR)/hg @cd $(DOWNLOADDIR)/hg && \ hg clone $(HG_CLONE_OPTS) $(HG_PATH) $(DISTNAME) && \ tar czvf ../$* $(DISTNAME) # Check out source from Bazaar. BZR_REVISION ?= before:date:$(GARVERSION) BZR_CHECKOUT_OPTS ?= -r "$(BZR_REVISION)" --lightweight bzr//%: @mkdir -p $(DOWNLOADDIR)/bzr @cd $(DOWNLOADDIR)/bzr && \ bzr checkout $(BZR_CHECKOUT_OPTS) $(BZR_PATH) $(DISTNAME) && \ tar czvf ../$* $(DISTNAME) #################### CHECKSUM RULES #################### # check a given file's checksum against $(CHECKSUM_FILE) and # error out if it mentions the file without an "OK". checksum-%: $(CHECKSUM_FILE) @echo " ==> Running checksum on $*" @if grep -- '$*' $(CHECKSUM_FILE); then \ if LC_ALL="C" LANG="C" md5sum -c $(CHECKSUM_FILE) 2>&1 | grep -- '$*' | grep -v ':[ ]\+OK'; then \ echo '*** GAR GAR GAR! $* failed checksum test! GAR GAR GAR! ***' 1>&2; \ false; \ else \ echo '$(CHECKSUM_FILE) is OK'; \ $(DOMAKECOOKIE); \ fi \ else \ echo '*** GAR GAR GAR! $* not in $(CHECKSUM_FILE) file! GAR GAR GAR! ***' 1>&2; \ false; \ fi # use a signature file to check the file it refers to GPG ?= gpg --no-default-keyring --keyring $(GPG_KEYRING) --trust-model always GPG_CHECK = check () { \ set -e; \ sigfile="$$1"; \ distfile="$$2"; \ if grep >/dev/null 'BEGIN PGP MESSAGE' "$$sigfile"; then \ echo " ==> Checking PGP encrypted message $$sigfile"; \ $(GPG) --decrypt "$$sigfile" | cmp - "$$distfile"; \ return 0; \ fi; \ echo " ==> Checking PGP detached signature $$sigfile"; \ if [ ! -e "$$distfile" ]; then \ if [ -e "$$distfile.gz" ]; then \ echo " ==> Uncompressing $$distfile"; \ gunzip <"$$distfile.gz" >"$$distfile"; \ elif [ -e "$$distfile.bz2" ]; then \ echo " ==> Uncompressing $$distfile"; \ bunzip2 <"$$distfile.bz2" >"$$distfile"; \ elif [ -e "$$distfile.xz" ]; then \ echo " ==> Uncompressing $$distfile"; \ xz -d <"$$distfile.xz" >"$$distfile"; \ else \ echo " ==> No signed distfile for $$distfile"; \ exit 1; \ fi; \ fi; \ $(GPG) --verify "$$sigfile" "$$distfile"; \ } && check checksig-%.sig.asc: @$(GPG_CHECK) $(DOWNLOADDIR)/$*.sig.asc $(DOWNLOADDIR)/$* $(MAKECOOKIE) checksig-%.asc.txt: @$(GPG_CHECK) $(DOWNLOADDIR)/$*.asc.txt $(DOWNLOADDIR)/$* $(MAKECOOKIE) checksig-%-asc.txt: @$(GPG_CHECK) $(DOWNLOADDIR)/$*-asc.txt $(DOWNLOADDIR)/$(subst -tar-,.tar.,$*) $(MAKECOOKIE) checksig-%.sig: @$(GPG_CHECK) $(DOWNLOADDIR)/$*.sig $(DOWNLOADDIR)/$* $(MAKECOOKIE) checksig-%.sign: @$(GPG_CHECK) $(DOWNLOADDIR)/$*.sign $(DOWNLOADDIR)/$* $(MAKECOOKIE) checksig-%.asc: @$(GPG_CHECK) $(DOWNLOADDIR)/$*.asc $(DOWNLOADDIR)/$* $(MAKECOOKIE) checksig-%.md5sum: @echo " ==> Checking MD5 checksums $*" @cd $(DOWNLOADDIR) && md5sum -c $*.md5sum $(MAKECOOKIE) checksig-%.sha1: @echo " ==> Checking SHA1 checksums $*" @cd $(DOWNLOADDIR) && sha1sum -c $*.sha1 $(MAKECOOKIE) #################### GARCHIVE RULES #################### # while we're here, let's just handle how to back up our # checksummed files garchive-%: @-test -h $(DOWNLOADDIR)/$* || cp -f $(DOWNLOADDIR)/$* $(GARCHIVEDIR)/ $(MAKECOOKIE) #################### EXTRACT RULES #################### # Enable the "regular user" behaviour for tar, so that we don't extract # archives with random users or world-writable permissions. TAR_OPTS = \ --no-same-owner \ --no-same-permissions # rule to extract files with tar xzf extract-%.tar.Z extract-%.tgz extract-%.tar.gz extract-%.taz: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @gzip -dc $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) | $(BUILD_CTX) tar xf - $(TAR_OPTS) -C $(EXTRACTDIR) $(MAKECOOKIE) # rule to extract files with tar and bzip extract-%.tar.bz extract-%.tar.bz2 extract-%.tbz: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @bzip2 -dc $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) | $(BUILD_CTX) tar xf - $(TAR_OPTS) -C $(EXTRACTDIR) $(MAKECOOKIE) # rule to extract files with tar and lzip extract-%.tar.lz: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @lzip -dc $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) | $(BUILD_CTX) tar xf - $(TAR_OPTS) -C $(EXTRACTDIR) $(MAKECOOKIE) # rule to extract files with tar and xz extract-%.tar.xz extract-%.tar.lzma: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @xz -dc $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) | $(BUILD_CTX) tar xf - $(TAR_OPTS) -C $(EXTRACTDIR) $(MAKECOOKIE) # rule to extract files with tar extract-%.tar: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @$(BUILD_CTX) tar xf $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) $(TAR_OPTS) -C $(EXTRACTDIR) $(MAKECOOKIE) # rule to extract files with cpio extract-%.cpio.gz: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @gzip -dc $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) | (cd $(EXTRACTDIR) && $(BUILD_CTX) cpio -mid $(CPIO_OPTS)) $(MAKECOOKIE) # rule to extract files with zip extract-%.zip: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @$(BUILD_CTX) unzip -o $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) -d $(EXTRACTDIR) $(MAKECOOKIE) # rule to extract RPM files with rpm2cpio and cpio extract-%.rpm: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @rpm2cpio $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) | (cd $(EXTRACTDIR) && $(BUILD_CTX) cpio -mid $(CPIO_OPTS)) $(MAKECOOKIE) # rule to extract shell archives extract-%.shar extract-%.run: @echo " ==> Extracting $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @path=`pwd`/$(patsubst extract-%,$(DOWNLOADDIR)/%,$@) && cd $(EXTRACTDIR) && chmod +x $$path && $$path $(MAKECOOKIE) # Unmatched files should just be copied. # This is a bit of a kludge -- it's to allow us to have packages that are built # from a load of downloaded files (i.e. cvsweb checkouts) and a patch. extract-%: @echo " ==> Copying $(patsubst extract-%,$(DOWNLOADDIR)/%,$@)" @$(BUILD_CTX) mkdir -p $(WORKSRC) @$(BUILD_CTX) cp $(patsubst extract-%,$(DOWNLOADDIR)/%,$@) $(WORKSRC) $(MAKECOOKIE) #################### PATCH RULES #################### PATCHOPTS ?= -p2 PATCHDIR ?= $(WORKSRC) PATCH = patch $(PATCHOPTS) -d $(PATCHDIR) # apply bzipped patches __patch_%.bz __patch_%.bz2: @echo " ==> Applying patch $(patsubst __patch_%,$(DOWNLOADDIR)/%,$@)" @bzip2 -dc $(patsubst __patch_%,$(DOWNLOADDIR)/%,$@) | $(BUILD_CTX) $(PATCH) $(MAKECOOKIE) # apply gzipped patches __patch_%.gz: @echo " ==> Applying patch $(patsubst __patch_%,$(DOWNLOADDIR)/%,$@)" @gzip -dc $(patsubst __patch_%,$(DOWNLOADDIR)/%,$@) | $(BUILD_CTX) $(PATCH) $(MAKECOOKIE) # apply normal patches __patch_%: @echo " ==> Applying patch $(patsubst __patch_%,$(DOWNLOADDIR)/%,$@)" @$(BUILD_CTX) $(PATCH) < $(patsubst __patch_%,$(DOWNLOADDIR)/%,$@) $(MAKECOOKIE) # This is used by makepatch %/gar-base.diff: @echo " ==> Creating patch $@" @EXTRACTDIR=$(SCRATCHDIR) COOKIEDIR=$(SCRATCHDIR)-$(COOKIEDIR) $(MAKE) extract @if diff -x 'config.log' -x 'config.status' -ru $(SCRATCHDIR) $(WORKDIR) | grep -v '^Only in' > $@; then :; else \ rm $@; \ fi #################### CONFIGURE RULES #################### DIRPATHS = \ --prefix=$(prefix) \ --sysconfdir=$(sysconfdir) \ --localstatedir=$(vardir) \ --sharedstatedir=$(vardir)/com CONFIGURE_ARGS ?= $(DIRPATHS) CONFIGURE_NAME ?= configure AUTORECONF_ARGS ?= -vfi # Rebuild autoconf files in a source directory. configure-%/autoreconf: @echo " ==> Running autoreconf in $*" @cd $* && $(BUILD_CTX) $(AUTORECONF_ENV) autoreconf $(AUTORECONF_ARGS) $(MAKECOOKIE) LIBTOOLIZE_ARGS ?= -vfi # Rebuild libtool files in a source directory. configure-%/libtoolize: @echo " ==> Running libtoolize in $*" @cd $* && $(BUILD_CTX) $(LIBTOOLIZE_ENV) libtoolize $(LIBTOOLIZE_ARGS) $(MAKECOOKIE) # configure a package that has an autoconf-style configure script, coping # correctly when WORKOBJ is set to something other than WORKDIR. configure-%/configure: @echo " ==> Running $(CONFIGURE_NAME) in $*" @cd $(if $(WORKOBJ_CHANGED_P),$(WORKOBJ),$*) && $(BUILD_CTX) $(CONFIGURE_ENV) $(if $(WORKOBJ_CHANGED_P),$(LEAVE_WORKOBJ)/$*,.)/$(CONFIGURE_NAME) $(CONFIGURE_ARGS) $(MAKECOOKIE) XMKMF_ARGS ?= -a # configure a package that uses imake # FIXME: untested and likely not the right way to handle the # arguments configure-%/Imakefile: @echo " ==> Running xmkmf in $*" @cd $* && $(BUILD_CTX) $(CONFIGURE_ENV) xmkmf $(XMKMF_ARGS) $(MAKECOOKIE) # CMake doesn't respect many of the standard environment variables, so we have # to tell it explicitly where to look for some things. CMAKE_CONFIGURE_ARGS ?= \ -DCMAKE_INSTALL_PREFIX=$(prefix) \ -DSYSCONFDIR=$(sysconfdir) \ -DPKG_CONFIG_EXECUTABLE=$(PKG_CONFIG) \ -DPKGCONFIG_EXECUTABLE=$(PKG_CONFIG) \ -DSDL_INCLUDE_DIR=$(prefix)/include/SDL # configure a package that uses CMake configure-%/CMakeLists.txt: @echo " ==> Running cmake in $*" @cd $(if $(WORKOBJ_CHANGED_P),$(WORKOBJ),$*) && $(BUILD_CTX) $(CONFIGURE_ENV) cmake $(if $(WORKOBJ_CHANGED_P),$(LEAVE_WORKOBJ)/$* ,)$(CMAKE_CONFIGURE_ARGS) $(MAKECOOKIE) # configure using Python distutils configure-%/setup.py: @echo " ==> Running setup.py config in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) python setup.py config $(PY_BUILD_ARGS) $(MAKECOOKIE) RUBY_DIRPATHS = --prefix=$(packageprefix) RUBY_CONFIGURE_ARGS ?= $(RUBY_DIRPATHS) # configure a Ruby extension configure-%/extconf.rb: @echo " ==> Running extconf.rb in $*" @cd $* && $(BUILD_CTX) $(CONFIGURE_ENV) ruby extconf.rb $(RUBY_CONFIGURE_ARGS) $(MAKECOOKIE) # configure the other sort of Ruby extension configure-%/setup.rb: @echo " ==> Running setup.rb config in $*" @cd $* && $(BUILD_CTX) $(CONFIGURE_ENV) ruby setup.rb config $(RUBY_CONFIGURE_ARGS) $(MAKECOOKIE) # configure a third sort of Ruby extension configure-%/install.rb: @echo " ==> Running install.rb config in $*" @cd $* && $(BUILD_CTX) $(CONFIGURE_ENV) ruby install.rb config $(RUBY_CONFIGURE_ARGS) $(MAKECOOKIE) # There is no standardisation for SCons arguments; we have to try several # possibilities. SCONS_ARGS ?= \ prefix=$(prefix) \ PREFIX=$(prefix) # configure using SCons (which is only needed by some packages...) configure-%/SConstruct: @echo " ==> Running scons configure in $*" @cd $* && $(BUILD_CTX) $(CONFIGURE_ENV) scons configure $(SCONS_DEBUG) $(SCONS_ARGS) $(MAKECOOKIE) CABAL_CONFIGURE_ARGS ?= --prefix=$(prefix) # configure using Cabal configure-%/Setup.hs: @echo " ==> Compiling Setup in $*" @cd $* && $(BUILD_CTX) ghc --make Setup -o Setup @echo " ==> Running Setup configure in $*" @cd $* && $(BUILD_CTX) $(CONFIGURE_ENV) ./Setup configure $(CABAL_CONFIGURE_ARGS) $(MAKECOOKIE) WAF_CONFIGURE_ARGS ?= \ --prefix=$(prefix) \ --$$waf_config_option=$(sysconfdir) # configure using waf # Some waf ports (ones using the autowaf module, I think) expect --configdir # instead of --sysconfdir. waf complains about options it doesn't recognise, so # we can't provide both... configure-%/waf: @echo " ==> Running waf configure in $*" @set -e; \ cd $*; \ waf_config_option=sysconfdir; \ if $(BUILD_CTX) $(CONFIGURE_ENV) ./waf --help | grep -q -- --configdir; then \ waf_config_option=configdir; \ fi; \ $(BUILD_CTX) $(CONFIGURE_ENV) ./waf configure $(WAF_CONFIGURE_ARGS) $(MAKECOOKIE) configure-%/qmake: @echo " ==> Running qmake-4 in $*" @cd $* && $(BUILD_CTX) qmake-4 $(QMAKE_CONFIGURE_ARGS) $(MAKECOOKIE) #################### BUILD RULES #################### # build from a standard gnu-style makefile's default rule. build-%/Makefile build-%/makefile build-%/GNUmakefile: @echo " ==> Running make in $*" @$(BUILD_CTX) $(BUILD_ENV) $(MAKE) -C $* $(MAKE_ARGS) $(BUILD_ARGS) $(MAKECOOKIE) build-%/Makefile-BSD: @echo " ==> Running pmake in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) pmake $(BUILD_ARGS) $(MAKECOOKIE) # build using Python distutils build-%/setup.py: @echo " ==> Running setup.py build in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) python setup.py build $(PY_BUILD_ARGS) $(MAKECOOKIE) # build using Ruby setup.rb build-%/setup.rb: @echo " ==> Running setup.rb setup in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) ruby setup.rb setup $(RUBY_BUILD_ARGS) $(MAKECOOKIE) # build using Ruby install.rb build-%/install.rb: @echo " ==> Running install.rb setup in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) ruby install.rb setup $(RUBY_BUILD_ARGS) $(MAKECOOKIE) # build using rake build-%/Rakefile: @echo " ==> Running rake in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) rake $(RAKE_ARGS) $(RAKE_BUILD_ARGS) $(MAKECOOKIE) # build using SCons (which pretends not to have a seperate configure step, # having "sticky options" instead...) build-%/SConstruct: @echo " ==> Running scons in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) scons $(SCONS_DEBUG) $(SCONS_ARGS) $(MAKECOOKIE) # build using Cabal build-%/Setup.hs: @echo " ==> Running Setup build in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) ./Setup build $(CABAL_BUILD_ARGS) $(MAKECOOKIE) # build using waf build-%/waf: @echo " ==> Running waf in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) ./waf $(WAF_BUILD_ARGS) $(MAKECOOKIE) #################### TEST RULES #################### TEST_ARGS ?= check # Test a program where "make check" (or similar) runs the test. test-%/Makefile test-%/makefile test-%/GNUmakefile: @echo " ==> Testing in $*" @$(BUILD_CTX) $(TEST_ENV) $(MAKE) -C $* $(MAKE_ARGS) $(TEST_ARGS) $(MAKECOOKIE) # Test a program using Python distutils. # Not all setup.py instances have a test command... test-%/setup.py: @set -e; cd $* && \ if $(BUILD_CTX) python setup.py --help test >/dev/null 2>&1; then \ echo " ==> Running setup.py test in $*"; \ $(BUILD_CTX) $(TEST_ENV) python setup.py test $(PY_TEST_ARGS); \ else \ echo " ==> No test support in $*"; \ fi $(MAKECOOKIE) # Test a program using Cabal. test-%/Setup.hs: @echo " ==> Running Setup test in $*" @cd $* && $(BUILD_CTX) $(TEST_ENV) ./Setup test $(CABAL_TEST_ARGS) $(MAKECOOKIE) # Test using waf test-%/waf: @set -e; cd $* && \ if $(BUILD_CTX) ./waf --help | grep -q '^ *test *:'; then \ echo " ==> Running waf check in $*"; \ $(BUILD_CTX) $(TEST_ENV) ./waf check $(WAF_TEST_ARGS); \ else \ echo " ==> No test support in $*"; \ fi $(MAKECOOKIE) #################### INSTALL RULES #################### # The format of stow package names. PACKAGENAME ?= $(GARNAME)-$(GARVERSION) # The package home directory. This'll be stowed into $(prefix). packagedir = $(packagesdir)/$(PACKAGENAME) # Directory containing GARstow files for the package. dotgardir = $(prefix)/.gar/$(GARNAME) # Directories to use during installation. packageDESTDIR = $(packagesdir)/$(PACKAGENAME)-DEST packageprefix = $(packageDESTDIR)$(prefix) packagedotgardir = $(packageDESTDIR)$(dotgardir) packagesysconfdir = $(packageDESTDIR)$(sysconfdir) packagevardir = $(packageDESTDIR)$(vardir) docsdir = $(prefix)/share/doc/$(GARNAME) examplesdir = $(prefix)/share/examples/$(GARNAME) packagedocs = $(packageDESTDIR)$(docsdir) packageexamples = $(packageDESTDIR)$(examplesdir) # Directories that should have pristine versions stored to be merged upon # installation. CREATED_MERGE_DIRS = \ sysconf $(sysconfdir) \ var $(vardir) \ boot $(bootdir) \ rootlib /lib # Directories that will be merged if created by a package, but won't be # created automatically. MERGE_DIRS = \ $(CREATED_MERGE_DIRS) \ root / prepare-install: @echo " ==> Preparing staging area" @rm -fr $(packageDESTDIR) @mkdir -p $(packageDESTDIR)$(prefix) @set -e; \ set -- $(CREATED_MERGE_DIRS); \ while [ "$$1" != "" ]; do \ src=$(packagedotgardir)/$$1; \ dest=$(packageDESTDIR)$$2; \ mkdir -p $$src `dirname $$dest`; \ rm -f $$dest; \ ln -sf $$src $$dest; \ shift; shift; \ done $(MAKECOOKIE) finish-install: @echo " ==> Moving files from staging area" @set -e; \ set -- $(CREATED_MERGE_DIRS); \ while [ "$$1" != "" ]; do \ rmdir 2>/dev/null $(packagedotgardir)/$$1 || true; \ rm $(packageDESTDIR)$$2; \ shift; shift; \ done @rm -rf $(packagedir) @mv $(packageDESTDIR)$(prefix) $(packagedir) @rm -r $(packageDESTDIR) $(MAKECOOKIE) GNU_INSTALL_ARGS = \ prefix=$(packageprefix) \ exec_prefix=$(packageprefix) \ sysconfdir=$(packagesysconfdir) \ localstatedir=$(packagevardir) \ sharedstatedir=$(packagevardir)/com INSTALL_TARGET ?= install INSTALL_ARGS ?= $(GNU_INSTALL_ARGS) # Use "make install" with prefix-changing. install-%/Makefile install-%/makefile install-%/GNUmakefile: @echo " ==> Running make $(INSTALL_TARGET) in $*" @$(INSTALL_ENV) $(MAKE) -C $* $(MAKE_ARGS) $(INSTALL_ARGS) $(INSTALL_TARGET) $(MAKECOOKIE) # Use "make install" with DESTDIR. DESTDIR_INSTALL_ARGS ?= install-%/Makefile-DESTDIR: @echo " ==> Running make $(INSTALL_TARGET) with DESTDIR in $*" @$(INSTALL_ENV) $(MAKE) -C $* $(MAKE_ARGS) $(DESTDIR_INSTALL_ARGS) $(INSTALL_TARGET) DESTDIR=$(packageDESTDIR) $(MAKECOOKIE) install-%/Makefile-BSD: @echo " ==> Running pmake $(INSTALL_TARGET) in $*" @cd $* && $(INSTALL_ENV) pmake $(INSTALL_ARGS) $(INSTALL_TARGET) $(MAKECOOKIE) # install using Python distutils # We have to create the installation directory first because otherwise # setuptools (spit) will complain. install-%/setup.py: @echo " ==> Running setup.py install in $*" @mkdir -p $(packageDESTDIR)`python -c 'from distutils.sysconfig import get_python_lib; print get_python_lib()'` @cd $* && $(INSTALL_ENV) python setup.py install --root=$(packageDESTDIR) $(PY_INSTALL_ARGS) $(MAKECOOKIE) # install using Ruby setup.rb install-%/setup.rb: @echo " ==> Running setup.rb install in $*" @cd $* && $(INSTALL_ENV) ruby setup.rb install $(RUBY_INSTALL_ARGS) $(MAKECOOKIE) # install using Ruby install.rb install-%/install.rb: @echo " ==> Running install.rb install in $*" @cd $* && $(INSTALL_ENV) ruby install.rb install $(RUBY_INSTALL_ARGS) $(MAKECOOKIE) # install using rake install-%/Rakefile: @echo " ==> Running rake install in $*" @cd $* && $(BUILD_CTX) $(BUILD_ENV) rake $(RAKE_ARGS) install $(RAKE_INSTALL_ARGS) DESTDIR=$(packageDESTDIR) $(MAKECOOKIE) SCONS_INSTALL_ARGS = \ destdir=$(packageDESTDIR) \ DESTDIR=$(packageDESTDIR) # install using SCons install-%/SConstruct: @echo " ==> Running scons in $*" @cd $* && $(INSTALL_ENV) scons install $(SCONS_ARGS) $(SCONS_INSTALL_ARGS) $(MAKECOOKIE) CABAL_INSTALL_ARGS ?= --destdir=$(packageDESTDIR) # install using Cabal install-%/Setup.hs: @echo " ==> Running Setup copy in $*" @cd $* && $(INSTALL_ENV) ./Setup copy $(CABAL_INSTALL_ARGS) @echo " ==> Generating Haskell package config in $*" @cd $* && $(INSTALL_ENV) ./Setup register --gen-pkg-config=package.conf @if [ -e $*/package.conf ]; then \ mkdir -p $(packagedotgardir)/haskell; \ install -m644 $*/package.conf $(packagedotgardir)/haskell; \ fi $(MAKECOOKIE) # install using CMake install-%/cmake_install.cmake: @echo " ==> Running cmake in $*" @cd $* && $(INSTALL_ENV) env DESTDIR=$(packageDESTDIR) cmake -P cmake_install.cmake $(MAKECOOKIE) # install using waf install-%/waf: @echo " ==> Running waf install in $*" @cd $* && $(INSTALL_ENV) env DESTDIR=$(packageDESTDIR) ./waf install $(WAF_INSTALL_ARGS) $(MAKECOOKIE) # install a hook install-hook-%: @echo " ==> Installing hook $*" @$(INSTALL_HOOKS) $(FILEDIR)/$* $(MAKECOOKIE) # install an Upstart file install-upstart-%: @echo " ==> Installing Upstart file $*" @$(INSTALL_UPSTART) $(FILEDIR)/$* $(MAKECOOKIE) ###################################### # Use a manifest file of the format: # src:dest[:mode[:owner[:group]]] # as in... # ${WORKSRC}/nwall:bin/nwall:2755:root:tty # ${WORKSRC}/src/foo:share/foo # ${WORKSRC}/yoink:etc/yoink:0600 # Okay, so for the benefit of future generations, this is how it # works: # # First of all, we have this file with colon-separated lines. # The $(shell cat foo) routine turns it into a space-separated # list of words. The foreach iterates over this list, putting a # colon-separated record in $(ZORCH) on each pass through. # # Next, we have the macro $(MANIFEST_LINE), which splits a record # into a space-separated list, and $(MANIFEST_SIZE), which # determines how many elements are in such a list. These are # purely for convenience, and could be inserted inline if need # be. MANIFEST_LINE = $(subst :, ,$(ZORCH)) MANIFEST_SIZE = $(words $(MANIFEST_LINE)) # So the install command takes a variable number of parameters, # and our records have from two to five elements. Gmake can't do # any sort of arithmetic, so we can't do any really intelligent # indexing into the list of parameters. # # Since the last three elements of the $(MANIFEST_LINE) are what # we're interested in, we make a parallel list with the parameter # switch text (note the dummy elements at the beginning): MANIFEST_FLAGS = notused notused --mode= --owner= --group= # ...and then we join a slice of it with the corresponding slice # of the $(MANIFEST_LINE), starting at 3 and going to # $(MANIFEST_SIZE). That's where all the real magic happens, # right there! # # following that, we just splat elements one and two of # $(MANIFEST_LINE) on the end, since they're the ones that are # always there. Slap a semicolon on the end, and you've got a # completed iteration through the foreach! Beaujolais! # FIXME: using -D may not be the right thing to do! install-$(MANIFEST_FILE): @echo " ==> Installing from $(MANIFEST_FILE)" @WORKSRC=$(WORKSRC) ; $(foreach ZORCH,$(shell cat $(MANIFEST_FILE)), install -Dc $(join $(wordlist 3,$(MANIFEST_SIZE),$(MANIFEST_FLAGS)),$(wordlist 3,$(MANIFEST_SIZE),$(MANIFEST_LINE))) $(word 1,$(MANIFEST_LINE)) $(packageprefix)/$(word 2,$(MANIFEST_LINE)) ;) $(MAKECOOKIE) # Standard deps install into the standard install dir. For the # BBC, we set the includedir to the build tree and the libdir to # the install tree. Most dependencies work this way. dep-$(GARDIR)/%: @if [ "$(filter $*,$(IGNORE_DEPS))" != "" ] ; then \ echo ' ==> Ignoring dependency $*' ; \ else \ echo ' ==> Building $* as a dependency' ; \ $(MAKE) -C $(GARDIR)/$* install-p > /dev/null 2>&1 || $(MAKE) -C $(GARDIR)/$* install ; \ fi ###################################### # Expand package variables wrapped with @s (e.g. @prefix@) EXPAND_VARS = sed $(foreach VAR,$(PACKAGE_VARS),-e 's,@$(VAR)@,$($(VAR)),g') ###################################### # Commands for installing different types of files INSTALL_BIN = install_bin () { mkdir -p $(packageprefix)/bin && install -m755 "$$@" $(packageprefix)/bin; } && install_bin INSTALL_SBIN = install_sbin () { mkdir -p $(packageprefix)/sbin && install -m755 "$$@" $(packageprefix)/sbin; } && install_sbin INSTALL_INCLUDE = install_include () { mkdir -p $(packageprefix)/include && install -m644 "$$@" $(packageprefix)/include; } && install_include INSTALL_LIB = install_lib () { mkdir -p $(packageprefix)/lib && install -m755 "$$@" $(packageprefix)/lib; } && install_lib INSTALL_MAN = install_man () { for x in "$$@"; do v=`echo "$$x" | sed 's/.*\.//'`; mkdir -p "$(packageprefix)/man/man$$v" && install -m644 "$$x" "$(packageprefix)/man/man$$v"; done; } && install_man INSTALL_CATMAN = install_catman () { for x in "$$@"; do v=`echo "$$x" | sed 's/.*\.//'`; mkdir -p "$(packageprefix)/man/cat$$v" && install -m644 "$$x" "$(packageprefix)/man/cat$$v"; done; } && install_catman INSTALL_INFO = install_info () { mkdir -p $(packageprefix)/info && install -m644 "$$@" $(packageprefix)/info; } && install_info INSTALL_DOCS = install_docs () { mkdir -p $(packagedocs) && cp -R "$$@" $(packagedocs); } && install_docs FONTSNAME ?= $(GARNAME) INSTALL_FONTS = install_fonts () { mkdir -p $(packageprefix)/share/fonts/$(FONTSNAME) && cp -R "$$@" $(packageprefix)/share/fonts/$(FONTSNAME); } && install_fonts INSTALL_SYSCONF = install_sysconf () { mkdir -p $(packagesysconfdir) && install -m644 "$$@" $(packagesysconfdir); } && install_sysconf INSTALL_LADSPA = install_ladspa () { mkdir -p $(packageprefix)/lib/ladspa && install -m755 "$$@" $(packageprefix)/lib/ladspa; } && install_ladspa INSTALL_THEMES = install_themes () { mkdir -p $(packageprefix)/share/themes && cp -R "$$@" $(packageprefix)/share/themes; } && install_themes INSTALL_HOOKS = install_hooks () { \ for x in "$$@"; do \ n=`basename $$x`; \ case "$$n" in \ *.*) \ d=$(packageDESTDIR)$(prefix)/.gar/gar.`echo "$$n" | sed 's,^.*\.,,'`; \ f=`echo "$$n" | sed 's,\..*$$,,'`; \ ;; \ *) \ d=$(packagedotgardir); \ f="$$n"; \ ;; \ esac; \ mkdir -p "$$d"; \ install -m755 "$$x" "$$d/$$f"; \ done \ } && install_hooks INSTALL_UPSTART = install_upstart() { \ for x in "$$@"; do \ n=`basename $$x`; \ mkdir -p $(packagesysconfdir)/init; \ $(EXPAND_VARS) $$x >$(packagesysconfdir)/init/$$n; \ chmod 644 $(packagesysconfdir)/init/$$n; \ done \ } && install_upstart SYMLINK_BIN = symlink_bin () { from="$$1"; shift; mkdir -p $(packageprefix)/bin && for x in "$$@" ; do ln -sf "$$from" "$(packageprefix)/bin/$$x" ; done } && symlink_bin SYMLINK_SBIN = symlink_sbin () { from="$$1"; shift; mkdir -p $(packageprefix)/sbin && for x in "$$@" ; do ln -sf "$$from" "$(packageprefix)/sbin/$$x" ; done } && symlink_sbin SYMLINK_LIB = symlink_lib () { from="$$1"; shift; mkdir -p $(packageprefix)/lib && for x in "$$@" ; do ln -sf "$$from" "$(packageprefix)/lib/$$x" ; done } && symlink_lib SUFFIX_PROG = suffix_prog () { \ suffix="$$1"; shift; \ for x in "$$@"; do \ case "$$x" in $$suffix*) continue ;; esac; \ n=`basename "$$x"`; \ maybe_mv () { \ if [ -f "$$1" ] ; then \ echo " ==> Renaming $$1 to $$2"; \ mv "$$1" "$$2"; \ fi \ }; \ maybe_mv "$$x" "$$x-$$suffix"; \ for s in 1 2 3 4 5 8; do \ maybe_mv "$(packageprefix)/man/man$$s/$$n.$$s" "$(packageprefix)/man/man$$s/$$n-$$suffix.$$s"; \ maybe_mv "$(packageprefix)/share/man/man$$s/$$n.$$s" "$(packageprefix)/share/man/man$$s/$$n-$$suffix.$$s"; \ done; \ for infodir in $(packageprefix)/info $(packageprefix)/share/info; do \ if [ -d $$infodir ]; then \ (cd $$infodir && for x in "$$n" "$$n"-* "$$n".info "$$n".info-*; do \ maybe_mv "$$x" `echo "$$x" | sed "s,^$$n,$$n-$$suffix,"`; \ done); \ fi; \ done; \ done \ } && suffix_prog #################### DEP-CHECK RULES #################### DEPCHECK_TARGETS = users NEED_USERS ?= NEED_GROUPS ?= depcheck-users: @set -e; for user in $(NEED_USERS) -; do \ [ "$$user" = "-" ] && continue; \ echo ' ==> Checking user' $$user 'exists'; \ python -c "import pwd; pwd.getpwnam('$$user')" 2>/dev/null; \ done @set -e; for group in $(NEED_GROUPS) -; do \ [ "$$group" = "-" ] && continue; \ echo ' ==> Checking group' $$group 'exists'; \ python -c "import grp; grp.getgrnam('$$group')" 2>/dev/null; \ done $(MAKECOOKIE) #################### SYS-INSTALL RULES #################### SYSINSTALL_TARGETS = normalise collisions packagevars install # Some files which multiple packages seem to contain. These get # removed before stowing. COLLISIONS ?= \ share/info/configure.info* \ share/info/dir \ share/info/dir.old \ share/info/standards.info* \ lib/libiberty.* \ lib/perl5/*/*/perllocal.pod \ lib/perl5/site_perl/*/*/perllocal.pod \ share/applications/mimeinfo.cache \ share/fonts/X11/*/fonts.cache* \ share/fonts/X11/*/fonts.dir \ share/fonts/X11/*/fonts.scale \ share/mime/XMLnamespaces \ share/mime/aliases \ share/mime/generic-icons \ share/mime/globs \ share/mime/globs2 \ share/mime/icons \ share/mime/magic \ share/mime/mime.cache \ share/mime/subclasses \ share/mime/treemagic \ share/mime/types # When a package is removed (or replaced with a newer version), files matching # any of these regexps in $(prefix)/lib that aren't present in the new version # are copied into compatlibs. COMPATLIBS = \ ^lib.*\.so\.[0-9]+$$ # Packages that may contain files that this package is allowed to replace. DECONFLICT = compatlibs # The architecture of the machine this package is built for. # A package can override this to "any" if it's not architecture-specific. GARARCH ?= $(shell $(SCRIPTSDIR)/garstow get-arch) # Variables that will be stored in $(dotgardir)/package_vars for use during # package installation, and used as part of the package hash. PACKAGE_VARS = \ GARNAME \ GARVERSION \ prefix \ sysconfdir \ vardir \ bootdir \ packagesdir \ packagedir \ dotgardir # Variables that will be included in PACKAGE_VARS only if the package has # changed them from the default value. OPTIONAL_PACKAGE_VARS = \ GARREVISION \ DECONFLICT \ COMPATLIBS # Additional variables to include in the package hash. PACKAGE_IDENT_VARS = \ GARARCH \ CFLAGS_OPTIMIZE \ LDFLAGS_OPTIMIZE \ IGNORE_DEPS # Files to include in the package hash, relative to the package source # directory. (We may include more files in the future.) PACKAGE_IDENT_FILES = \ Makefile sysinstall-collisions: @echo ' ==> Removing collisions' @rm -rf $(foreach FILE,$(COLLISIONS),$(packagedir)/$(FILE)) @set -e; find $(packagedir)/lib -name '*.la' | while read la; do \ so="`echo $$la | sed 's,la$$,so,'`"; \ if [ -e "$$so" ]; then \ echo " ==> Removing .la file $$la"; \ rm -f "$$la"; \ fi; \ done $(MAKECOOKIE) sysinstall-normalise: @echo ' ==> Normalising directory layout' @$(MOVE_CONTENTS) $(packagedir)/man $(packagedir)/share/man @$(MOVE_CONTENTS) $(packagedir)/info $(packagedir)/share/info @$(MOVE_CONTENTS) $(packagedir)/doc $(packagedir)/share/doc @$(MOVE_CONTENTS) $(packagedir)/games $(packagedir)/bin $(MAKECOOKIE) sysinstall-packagevars: @echo ' ==> Writing package metadata' @$(SCRIPTSDIR)/garstow write-metadata $(GARNAME) \ || $(SYSINSTALL_FAIL) $(MAKECOOKIE) SYSINSTALL_FAIL = (rm -f $(packagesdir)/$(GARNAME) $(COOKIEDIR)/sysinstall-*; false) sysinstall-install: @$(SCRIPTSDIR)/garstow install-version $(GARNAME) $(GARVERSION) \ || $(SYSINSTALL_FAIL) $(MAKECOOKIE) # Mmm, yesssss. cookies my preciousssss! Mmm, yes downloads it # is! We mustn't have nasty little gmakeses deleting our # precious cookieses now must we? .PRECIOUS: $(DOWNLOADDIR)/% $(COOKIEDIR)/% $(FILEDIR)/%