diff options
-rw-r--r-- | INSTALL | 41 | ||||
-rw-r--r-- | Makefile | 95 | ||||
-rw-r--r-- | README | 11 | ||||
-rw-r--r-- | configure | 11 | ||||
-rw-r--r-- | configure.cheese | 75 | ||||
-rw-r--r-- | data/Makefile | 15 | ||||
-rw-r--r-- | data/cheese.desktop (renamed from cheese.desktop) | 0 | ||||
-rw-r--r-- | data/cheese.glade (renamed from cheese.glade) | 0 | ||||
-rw-r--r-- | data/effects/Hulk.png (renamed from effects/Hulk.png) | bin | 75555 -> 75555 bytes | |||
-rw-r--r-- | data/effects/Makefile | 9 | ||||
-rw-r--r-- | data/effects/Mauve.png (renamed from effects/Mauve.png) | bin | 57137 -> 57137 bytes | |||
-rw-r--r-- | data/effects/NoirBlanc.png (renamed from effects/NoirBlanc.png) | bin | 34560 -> 34560 bytes | |||
-rw-r--r-- | data/effects/Saturation.png (renamed from effects/Saturation.png) | bin | 19489 -> 19489 bytes | |||
-rw-r--r-- | data/effects/dicetv.png (renamed from effects/dicetv.png) | bin | 70211 -> 70211 bytes | |||
-rw-r--r-- | data/effects/edgetv.png (renamed from effects/edgetv.png) | bin | 23551 -> 23551 bytes | |||
-rw-r--r-- | data/effects/identity.png (renamed from effects/identity.png) | bin | 67594 -> 67594 bytes | |||
-rw-r--r-- | data/effects/shagadelictv.png (renamed from effects/shagadelictv.png) | bin | 14272 -> 14272 bytes | |||
-rw-r--r-- | data/effects/vertigotv.png (renamed from effects/vertigotv.png) | bin | 79539 -> 79539 bytes | |||
-rw-r--r-- | data/effects/videoflip_h.png (renamed from effects/videoflip_h.png) | bin | 67043 -> 67043 bytes | |||
-rw-r--r-- | data/effects/videoflip_v.png (renamed from effects/videoflip_v.png) | bin | 67830 -> 67830 bytes | |||
-rw-r--r-- | data/effects/warptv.png (renamed from effects/warptv.png) | bin | 54572 -> 54572 bytes | |||
-rw-r--r-- | effects/mouse_events | bin | 20983 -> 0 bytes | |||
-rw-r--r-- | po/Makefile | 52 | ||||
-rw-r--r-- | po/cheese.pot | 53 | ||||
-rw-r--r-- | po/cs.po | 44 | ||||
-rw-r--r-- | po/de.po | 44 | ||||
-rw-r--r-- | po/es.po | 47 | ||||
-rw-r--r-- | po/gl.po | 47 | ||||
-rw-r--r-- | po/it.po | 47 | ||||
-rw-r--r-- | po/pt.po | 44 | ||||
-rw-r--r-- | src/Makefile | 47 | ||||
-rw-r--r-- | src/cairo-custom.c (renamed from cairo-custom.c) | 0 | ||||
-rw-r--r-- | src/cairo-custom.h (renamed from cairo-custom.h) | 0 | ||||
-rw-r--r-- | src/cheese.c (renamed from cheese.c) | 0 | ||||
-rw-r--r-- | src/cheese.h (renamed from cheese.h) | 3 | ||||
-rw-r--r-- | src/cheese_config.h.at | 9 | ||||
-rw-r--r-- | src/fileutil.c (renamed from fileutil.c) | 0 | ||||
-rw-r--r-- | src/fileutil.h (renamed from fileutil.h) | 0 | ||||
-rw-r--r-- | src/pipeline-photo.c (renamed from pipeline-photo.c) | 0 | ||||
-rw-r--r-- | src/pipeline-photo.h (renamed from pipeline-photo.h) | 0 | ||||
-rw-r--r-- | src/thumbnails.c (renamed from thumbnails.c) | 0 | ||||
-rw-r--r-- | src/thumbnails.h (renamed from thumbnails.h) | 0 | ||||
-rw-r--r-- | src/window.c (renamed from window.c) | 4 | ||||
-rw-r--r-- | src/window.h (renamed from window.h) | 2 | ||||
-rw-r--r-- | toc2.cheese.help | 3 | ||||
-rw-r--r-- | toc2.cheese.make.at | 0 | ||||
-rw-r--r-- | toc2/Makefile | 11 | ||||
-rw-r--r-- | toc2/bin/Makefile | 8 | ||||
-rw-r--r-- | toc2/bin/atsign_parse | 120 | ||||
-rw-r--r-- | toc2/bin/cleanup_vars | 17 | ||||
-rw-r--r-- | toc2/bin/create_makefile_stubs.sh | 261 | ||||
-rw-r--r-- | toc2/bin/create_project_skeleton.sh | 67 | ||||
-rw-r--r-- | toc2/bin/install-sh | 305 | ||||
-rw-r--r-- | toc2/bin/makedist | 102 | ||||
-rw-r--r-- | toc2/bin/mkdep-toc2.c | 533 | ||||
-rw-r--r-- | toc2/bin/removeDupeArgs | 29 | ||||
-rw-r--r-- | toc2/doc/Makefile | 4 | ||||
-rw-r--r-- | toc2/doc/naming-conventions.txt | 41 | ||||
-rw-r--r-- | toc2/doc/toc2-manual.odt | bin | 0 -> 49136 bytes | |||
-rw-r--r-- | toc2/doc/toc2.make | 149 | ||||
-rw-r--r-- | toc2/make/Makefile | 6 | ||||
-rw-r--r-- | toc2/make/c-bins.make | 60 | ||||
-rw-r--r-- | toc2/make/c-dlls.make | 100 | ||||
-rw-r--r-- | toc2/make/doxygen.make | 97 | ||||
-rw-r--r-- | toc2/make/file-filters.make | 98 | ||||
-rw-r--r-- | toc2/make/makerules.c-bins | 35 | ||||
-rw-r--r-- | toc2/make/makerules.c-dlls | 73 | ||||
-rw-r--r-- | toc2/make/makerules.file-filters | 101 | ||||
-rw-r--r-- | toc2/make/scratchpad.make | 41 | ||||
-rw-r--r-- | toc2/make/symlink-files.make | 31 | ||||
-rw-r--r-- | toc2/make/toc2-c.make | 222 | ||||
-rw-r--r-- | toc2/make/toc2-cleanup.make | 73 | ||||
-rw-r--r-- | toc2/make/toc2-dist.make | 139 | ||||
-rw-r--r-- | toc2/make/toc2-functions-core.make | 115 | ||||
-rw-r--r-- | toc2/make/toc2-install.make | 207 | ||||
-rw-r--r-- | toc2/make/toc2-subdirs.make | 61 | ||||
-rw-r--r-- | toc2/make/toc2.make.at | 149 | ||||
-rw-r--r-- | toc2/sbin/Makefile | 5 | ||||
-rw-r--r-- | toc2/sbin/configure.sample | 13 | ||||
-rw-r--r-- | toc2/sbin/toc2_core.sh | 863 | ||||
-rw-r--r-- | toc2/sbin/toconfigure | 140 | ||||
-rw-r--r-- | toc2/tests/Makefile | 8 | ||||
-rw-r--r-- | toc2/tests/PACKAGE_NAME-config.at | 86 | ||||
-rw-r--r-- | toc2/tests/PACKAGE_NAME-config.sh | 62 | ||||
-rw-r--r-- | toc2/tests/atfilter_file.sh | 11 | ||||
-rw-r--r-- | toc2/tests/awk.sh | 6 | ||||
-rw-r--r-- | toc2/tests/c/Makefile | 6 | ||||
-rw-r--r-- | toc2/tests/c/check_for_dlopen_and_friends.c | 34 | ||||
-rw-r--r-- | toc2/tests/c/check_for_ltdlopen_and_friends.c | 30 | ||||
-rw-r--r-- | toc2/tests/c/check_for_pthread.c | 14 | ||||
-rw-r--r-- | toc2/tests/cpp/Makefile | 6 | ||||
-rw-r--r-- | toc2/tests/cpp/check_setenv_in_cpp.cpp | 16 | ||||
-rw-r--r-- | toc2/tests/cpp/check_stl_newstyle.cpp | 8 | ||||
-rw-r--r-- | toc2/tests/cpp/gcc_2_95_typename_problem.cpp | 44 | ||||
-rw-r--r-- | toc2/tests/create_pkg-config_data.sh | 96 | ||||
-rw-r--r-- | toc2/tests/doxygen.sh | 37 | ||||
-rw-r--r-- | toc2/tests/find_appconfig.sh | 52 | ||||
-rw-r--r-- | toc2/tests/find_header.sh | 45 | ||||
-rw-r--r-- | toc2/tests/gcc_build_and_run.sh | 49 | ||||
-rw-r--r-- | toc2/tests/gcc_try_compile.sh | 48 | ||||
-rw-r--r-- | toc2/tests/gnu_cpp_tools.sh | 97 | ||||
-rw-r--r-- | toc2/tests/gnu_find.sh | 12 | ||||
-rw-r--r-- | toc2/tests/gnu_make.sh | 9 | ||||
-rw-r--r-- | toc2/tests/gnu_tar.sh | 32 | ||||
-rw-r--r-- | toc2/tests/libdl.sh | 28 | ||||
-rw-r--r-- | toc2/tests/libexpat.sh | 61 | ||||
-rw-r--r-- | toc2/tests/libltdl.sh | 33 | ||||
-rw-r--r-- | toc2/tests/pkg-config-exists.sh | 51 | ||||
-rw-r--r-- | toc2/tests/toc2_core_tests.sh | 72 | ||||
-rw-r--r-- | toc2/tests/toc2_make.sh | 62 | ||||
-rw-r--r-- | toc2/tests/toc2_project_makefile.sh | 25 | ||||
-rw-r--r-- | toc2/tests/toc2_running_under_cygwin.sh | 13 | ||||
-rw-r--r-- | toc2/tests/toc2_tests_help.sh | 68 | ||||
-rw-r--r-- | toc2/tests/user_is_stephan_beal.sh | 24 |
114 files changed, 5980 insertions, 244 deletions
diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..54d0ed83 --- /dev/null +++ b/INSTALL @@ -0,0 +1,41 @@ +======================================================================== +This is the INSTALL file for cheese +http://live.gnome.org/Cheese +======================================================================== + +While the core code is not platorm specific, the build tree and +configure script are *quite* GNU-specific, and REQUIRE "recent" +versions of the most common GNU tools, like sed, GNU make, GNU tar, +gzip, etc. Complete docs for the build tree can be found on the build +tool's home page: + + http://toc.sourceforge.net + +cheese uses a conventional 'configure' script, which is run like so: + + ./configure [--options] + +Run it with --help to see the complete list of options. None are +normally necessary, but setting a prefix is required if you want +to install cheese as a non-root user: + + ./configure --prefix=$HOME +(i.e., somewhere to which you have write access) + +If configure finds problems then you won't be able to build s11n +without manual intervention - feel free to contact us if you +have build problems. + +After configuring, simply: + + make + make install + +Of course the Makefile provides also the DESTDIR option, which +allows you to put the package content somewhere else: + + make DESTDIR=$HOME install + +======================================================================== +the end +======================================================================== @@ -1,65 +1,30 @@ -CC = gcc - -GTK_CFLAGS = $(shell pkg-config --cflags gtk+-2.0) -GTK_LIBS = $(shell pkg-config --libs gtk+-2.0) - -GLADE_CFLAGS = $(shell pkg-config --cflags libglade-2.0) -GLADE_LIBS = $(shell pkg-config --libs libglade-2.0) - -DBUS_CFLAGS = $(shell pkg-config dbus-1 --cflags) -DBUS_LIBS = $(shell pkg-config dbus-1 --libs) - -GSTREAMER_CFLAGS = $(shell pkg-config --cflags gstreamer-0.10 gstreamer-plugins-base-0.10) -GSTREAMER_LIBS = $(shell pkg-config --libs gstreamer-0.10 gstreamer-plugins-base-0.10) -lgstinterfaces-0.10 - -GNOME_VFS_CFLAGS = $(shell pkg-config --cflags gnome-vfs-2.0) -GNOME_VFS_LIBS = $(shell pkg-config --libs gnome-vfs-2.0) - -GDK_CFLAGS = $(shell pkg-config --cflags gdk-2.0) -GDK_LIBS = $(shell pkg-config --libs gdk-2.0) - -CFLAGS = -g -O2 -Wall -Werror $(DBUS_CFLAGS) $(GTK_CFLAGS) $(GLADE_CFLAGS) $(GSTREAMER_CFLAGS) $(GNOME_VFS_CFLAGS) $(GDK_CFLAGS) -LDFLAGS = -lpthread $(DBUS_LIBS) $(GTK_LIBS) $(GLADE_LIBS) $(GSTREAMER_LIBS) $(GNOME_VFS_LIBS) $(GDK_LIBS) - -SOURCES = cheese.c pipeline-photo.c fileutil.c thumbnails.c window.c cairo-custom.c -POFILES = po/cs.po po/de.po po/es.po po/gl.po po/it.po po/pt.po - -OBJS = $(SOURCES:%.c=%.o) -MOFILES = $(POFILES:%.po=%.mo) - -#all: cheese -all: cheese mo - -mo: $(MOFILES) - -cheese: $(OBJS) $(LIBS) - -cheese.o: cheese.c cheese.h - -#gst-pipeline.o: gst-pipeline.c gst-pipeline.h cheese.h - -fileutil.o: fileutil.c fileutil.h cheese.h - -pipeline-photo.o: pipeline-photo.c pipeline-photo.h cheese.h - -thumbnails.o: thumbnails.c thumbnails.h cheese.h - -window.o: window.c window.h cheese.h - -cairo-custom.o: cairo-custom.c cairo-custom.h cheese.h - -effects.o: effects.h - -%.mo: %.po - @echo Building $@... - @msgfmt --statistics -o $@ $< - -updatepo: - xgettext -L C -k_ -o po/cheese.pot $(SOURCES) - for po in $(POFILES); do \ - msgmerge -U $$po po/cheese.pot; \ - done - -clean: - rm -f cheese $(OBJS) $(MOFILES) - rm -f *~ po/*~ +#/usr/bin/env make -f + +package.subdirs = src po data +include toc2.make + +package.dist_files += \ + AUTHORS \ + ChangeLog \ + configure \ + configure.$(package.name) \ + COPYING \ + README \ + toc2.$(package.name).make.at \ + TODO + +ifneq (,$(filter distclean dist,$(MAKECMDGOALS))) + package.subdirs += toc2 + #subdirs: subdir-toc2 +endif + +ifneq (,$(filter install,$(MAKECMDGOALS))) + ifeq (1,$(CHEESE_MAINTAINER_MODE)) + $(error Your tree was configured for maintainer mode! Installing won\'t work) + endif +endif + +all: subdirs + +dist-postprocess: + -rm -f $(package.name)-$(package.version).tar @@ -13,17 +13,6 @@ Requirements: - cairo - a brain -Compiling: -To compile cheese, simply install all dependencies and then do a -'make'. you will end with the executable 'cheese'. Sorry for this, -but the next release will feature autotools, for sure! ;) - -Installing: - - copy cheese somewhere in your PATH (/usr/bin) - - copy cheese/cheese.desktop to /usr/share/applications - - copy cheese/cheese.glade to /usr/share/cheese - - install cheese/po/$lang.mo as /usr/share/locale/$lang/LC_MESSAGES/cheese.mo - Using: Simply launch 'cheese'. The taken photos will be stored in the folder images in your working path. e.g. if you start it from ~, diff --git a/configure b/configure new file mode 100644 index 00000000..8a1ac874 --- /dev/null +++ b/configure @@ -0,0 +1,11 @@ +#!/bin/bash +# ^^^^ toc needs a Genuine Bash, not some cheap work-alike!!! + +export PACKAGE_NAME=cheese +export PACKAGE_VERSION=0.1.2 +export TOC2_HOME=${PWD}/toc2 +export TOC2_QUIET=1 +# toconfigure will call configure.${PACKAGE_NAME}, so package-specific +# processing should be done there. +. ${TOC2_HOME}/sbin/toconfigure "$@" +# post-configure processing can be done in postconfig.${PACKAGE_NAME} diff --git a/configure.cheese b/configure.cheese new file mode 100644 index 00000000..23df57f0 --- /dev/null +++ b/configure.cheese @@ -0,0 +1,75 @@ +#!/do/not/bash +# ^^^^ tricks editors to go into shell mode + +do_check () +{ + if toc2_source_test pkg-config-exists $1 $2; then + echo -n "${TOC2_EMOTICON_OKAY} Found $1 " + test x != "x$2" && echo -n ">= $2" + echo + else + toc2_boldecho -n "${TOC2_EMOTICON_ERROR} Required package not found: $1 " + test x != "x$2" && toc2_boldecho -n ">= $2" + echo + die "Please make shure that you have installed $1 `test x != "x$2" && echo ">= $2"`" + fi +} + +die () { + toc2_die 127 " Configure failed, sorry! $1" +} + + +#====================================================================== +echo +toc2_boldecho "==== Checking for ${PACKAGE_NAME} dependencies..." + +maintainer=${maintainer-${configure_enable_maintainer_mode-0}} +if [[ x1 = x${maintainer} ]]; then + toc2_export CHEESE_DATA_DIR="${PWD}/data" + toc2_export_make CHEESE_MAINTAINER_MODE=1 + echo + toc2_boldecho "ATTENTION: MAINTAINER-MODE IS ENABLED" + toc2_boldecho "install will not work" + echo +else + toc2_export CHEESE_DATA_DIR="${prefix}/share/${PACKAGE_NAME}" + toc2_export_make CHEESE_MAINTAINER_MODE=0 +fi + +toc2_test_require gnu_cpp_tools + +if toc2_find_in_path pkg-config; then + pkgconfig=${TOC2_FIND_RESULT} +else + die "Couldn't find pkg-config" +fi +echo "${TOC2_EMOTICON_OKAY} Using pkg-config: ${pkgconfig}" + +# Check for libraries. +GTK_REQUIRED=3.10.0 +GLIB_REQUIRED=2.12.0 +LIBGLADE_REQUIRED=2.0.0 +GSTREAMER_REQUIRED=0.10.12 +GSTREAMER_REQUIRED=0.10.12 + +do_check glib-2.0 $GLIB_REQUIRED +do_check gobject-2.0 +do_check gtk+-2.0 $GTK_REQUIRED +do_check libglade-2.0 $LIBGLADE_REQUIRED +do_check gdk-2.0 +do_check dbus-1 +do_check gstreamer-0.10 $GSTREAMER_REQUIRED +do_check gstreamer-plugins-base-0.10 $GSTREAMER_REQUIRED +do_check gnome-vfs-2.0 +do_check cairo + +echo " all ok ${TOC2_EMOTICON_OKAY}" +echo + +toc2_test_require atfilter_file \ + src/cheese_config.h.at \ + src/cheese_config.h + +return 0 +# Now toc2.make will be generated by the top-level configure process. diff --git a/data/Makefile b/data/Makefile new file mode 100644 index 00000000..4180efe3 --- /dev/null +++ b/data/Makefile @@ -0,0 +1,15 @@ +#!/usr/bin/env make + +include toc2.make +GLADEFILE = cheese.glade +DESKTOPFILE = $(wildcard *.desktop) + +package.dist_files += $(GLADEFILE) $(EFFECTS) $(DESKTOPFILE) + +package.install.package_data += $(GLADEFILE) + +package.install.desktop = $(DESKTOPFILE) +$(eval $(call toc2.call.setup_install_rules,desktop, $(prefix)/share/applications,-m 0644)) + +package.subdirs := effects +all: subdirs diff --git a/cheese.desktop b/data/cheese.desktop index 88747ff3..88747ff3 100644 --- a/cheese.desktop +++ b/data/cheese.desktop diff --git a/cheese.glade b/data/cheese.glade index 3ca40322..3ca40322 100644 --- a/cheese.glade +++ b/data/cheese.glade diff --git a/effects/Hulk.png b/data/effects/Hulk.png Binary files differindex 48c75fee..48c75fee 100644 --- a/effects/Hulk.png +++ b/data/effects/Hulk.png diff --git a/data/effects/Makefile b/data/effects/Makefile new file mode 100644 index 00000000..3da96d42 --- /dev/null +++ b/data/effects/Makefile @@ -0,0 +1,9 @@ +#!/usr/bin/env make + +include toc2.make +EFFECTS = *.png + +package.dist_files += $(EFFECTS) +package.install.package_data.dest := $(prefix)/share/$(package.name)/effects +package.install.package_data += $(EFFECTS) + diff --git a/effects/Mauve.png b/data/effects/Mauve.png Binary files differindex fd40f092..fd40f092 100644 --- a/effects/Mauve.png +++ b/data/effects/Mauve.png diff --git a/effects/NoirBlanc.png b/data/effects/NoirBlanc.png Binary files differindex c828ea9e..c828ea9e 100644 --- a/effects/NoirBlanc.png +++ b/data/effects/NoirBlanc.png diff --git a/effects/Saturation.png b/data/effects/Saturation.png Binary files differindex 76c90c82..76c90c82 100644 --- a/effects/Saturation.png +++ b/data/effects/Saturation.png diff --git a/effects/dicetv.png b/data/effects/dicetv.png Binary files differindex 5d964054..5d964054 100644 --- a/effects/dicetv.png +++ b/data/effects/dicetv.png diff --git a/effects/edgetv.png b/data/effects/edgetv.png Binary files differindex 0790ec73..0790ec73 100644 --- a/effects/edgetv.png +++ b/data/effects/edgetv.png diff --git a/effects/identity.png b/data/effects/identity.png Binary files differindex 443a6ba2..443a6ba2 100644 --- a/effects/identity.png +++ b/data/effects/identity.png diff --git a/effects/shagadelictv.png b/data/effects/shagadelictv.png Binary files differindex ba3d8652..ba3d8652 100644 --- a/effects/shagadelictv.png +++ b/data/effects/shagadelictv.png diff --git a/effects/vertigotv.png b/data/effects/vertigotv.png Binary files differindex 3d4c59ad..3d4c59ad 100644 --- a/effects/vertigotv.png +++ b/data/effects/vertigotv.png diff --git a/effects/videoflip_h.png b/data/effects/videoflip_h.png Binary files differindex 72040987..72040987 100644 --- a/effects/videoflip_h.png +++ b/data/effects/videoflip_h.png diff --git a/effects/videoflip_v.png b/data/effects/videoflip_v.png Binary files differindex 28bc7007..28bc7007 100644 --- a/effects/videoflip_v.png +++ b/data/effects/videoflip_v.png diff --git a/effects/warptv.png b/data/effects/warptv.png Binary files differindex 531bc5d1..531bc5d1 100644 --- a/effects/warptv.png +++ b/data/effects/warptv.png diff --git a/effects/mouse_events b/effects/mouse_events Binary files differdeleted file mode 100644 index 1c311c37..00000000 --- a/effects/mouse_events +++ /dev/null diff --git a/po/Makefile b/po/Makefile new file mode 100644 index 00000000..499f641e --- /dev/null +++ b/po/Makefile @@ -0,0 +1,52 @@ +#!/usr/bin/env make + +include toc2.make + +# mo files should go to: +# $(prefix)/share/locale/$LANG/LC_MESSAGES/$pkgname.mo + +LANGS := cs de es gl it pt + +############################################################ +# $(eval $(call install-mo-lang,LANG)) +# $1 = lang +# +# Maintenance reminder: we cannot use toc2's default +# INSTALL function because the source file and target file +# have different names. We CAN use the toc2 UNINSTALL code +# and we do so because it can remove empty directories +# for us. +define install-mo-lang +install: install-mo-$(1) +install-mo-$(1)-dest := $(prefix)/share/locale/$(1)/LC_MESSAGES +install-mo-$(1): + @echo "Installing $(1).mo ..." + @test -d $(DESTDIR)$$(install-mo-$(1)-dest) && exit 0; mkdir -p $(DESTDIR)$$(install-mo-$(1)-dest) + @cp $(1).mo $(DESTDIR)$$(install-mo-$(1)-dest)/$(package.name).mo +uninstall: uninstall-mo-$(1) +uninstall-mo-$(1): + @$$(call toc2.call.uninstall,$(package.name).mo,$$(install-mo-$(1)-dest)) +endef + +$(foreach LANG,$(LANGS),$(eval $(call install-mo-lang,$(LANG)))) + +POFILES = $(LANGS:%=%.po) +MOFILES = $(POFILES:%.po=%.mo) + +package.dist_files += $(POFILES) +package.clean_files += $(MOFILES) + +all: mo + +mo: $(MOFILES) + +%.mo: %.po + @echo Building $@... + @msgfmt --statistics -o $@ $< + +SOURCES = $(wildcard $(toc2.top_srcdir)/src/*.c) +updatepo: + xgettext -L C -k_ -o cheese.pot $(SOURCES) + for po in $(POFILES); do \ + msgmerge -U $$po cheese.pot; \ + done diff --git a/po/cheese.pot b/po/cheese.pot index 1bea0a0f..f9c97467 100644 --- a/po/cheese.pot +++ b/po/cheese.pot @@ -1,13 +1,14 @@ -# cheese LANGUAGE translation -# Copyright (C) 2007 daniel g. siegel <dgsiegel@gmail.com> -# This file is distributed under the same license as cheese -# YEAR FIRST AUTHOR <EMAIL@ADDRESS> +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # +#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-06-24 02:23+0200\n" +"POT-Creation-Date: 2007-06-30 02:38+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -15,86 +16,86 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: pipeline-photo.c:165 window.c:140 +#: ../src/pipeline-photo.c:168 ../src/window.c:140 msgid "Effects" msgstr "" -#: pipeline-photo.c:176 +#: ../src/pipeline-photo.c:179 msgid "Back" msgstr "" -#: pipeline-photo.c:452 +#: ../src/pipeline-photo.c:455 msgid "No Effect" msgstr "" -#: pipeline-photo.c:453 +#: ../src/pipeline-photo.c:458 msgid "Mauve" msgstr "" -#: pipeline-photo.c:454 +#: ../src/pipeline-photo.c:461 msgid "Noir/Blanc" msgstr "" -#: pipeline-photo.c:455 +#: ../src/pipeline-photo.c:464 msgid "Saturation" msgstr "" -#: pipeline-photo.c:456 +#: ../src/pipeline-photo.c:467 msgid "Hulk" msgstr "" -#: pipeline-photo.c:457 +#: ../src/pipeline-photo.c:470 msgid "Vertical Flip" msgstr "" -#: pipeline-photo.c:458 +#: ../src/pipeline-photo.c:473 msgid "Horizontal Flip" msgstr "" -#: pipeline-photo.c:459 +#: ../src/pipeline-photo.c:476 msgid "Shagadelic" msgstr "" -#: pipeline-photo.c:460 +#: ../src/pipeline-photo.c:479 msgid "Vertigo" msgstr "" -#: pipeline-photo.c:461 +#: ../src/pipeline-photo.c:482 msgid "Edge" msgstr "" -#: pipeline-photo.c:462 +#: ../src/pipeline-photo.c:485 msgid "Dice" msgstr "" -#: pipeline-photo.c:463 +#: ../src/pipeline-photo.c:488 msgid "Warp" msgstr "" -#: window.c:43 +#: ../src/window.c:43 msgid "A cheesy program to take pictures from your webcam" msgstr "" -#: window.c:99 +#: ../src/window.c:99 msgid "Cheese" msgstr "" -#: window.c:111 +#: ../src/window.c:111 msgid "_File" msgstr "" -#: window.c:112 +#: ../src/window.c:112 msgid "_Help" msgstr "" -#: window.c:138 +#: ../src/window.c:138 msgid "Photo" msgstr "" -#: window.c:139 +#: ../src/window.c:139 msgid "Video" msgstr "" -#: window.c:141 +#: ../src/window.c:141 msgid "Take a photo" msgstr "" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: cheese 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-06-24 02:23+0200\n" +"POT-Creation-Date: 2007-06-30 02:38+0200\n" "PO-Revision-Date: 2007-06-25 11:00+0100\n" "Last-Translator: Vítězslav Kotrla <vitko@post.cz>\n" "Language-Team: LANGUAGE <cs@li.org>\n" @@ -15,86 +15,86 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pipeline-photo.c:165 window.c:140 +#: ../src/pipeline-photo.c:168 ../src/window.c:140 msgid "Effects" msgstr "Efekty" -#: pipeline-photo.c:176 +#: ../src/pipeline-photo.c:179 msgid "Back" msgstr "Zpět" -#: pipeline-photo.c:452 +#: ../src/pipeline-photo.c:455 msgid "No Effect" msgstr "Bez efektů" -#: pipeline-photo.c:453 +#: ../src/pipeline-photo.c:458 msgid "Mauve" msgstr "Růžová (lila)" -#: pipeline-photo.c:454 +#: ../src/pipeline-photo.c:461 msgid "Noir/Blanc" msgstr "Černá a bílá" -#: pipeline-photo.c:455 +#: ../src/pipeline-photo.c:464 msgid "Saturation" msgstr "Syté barvy" -#: pipeline-photo.c:456 +#: ../src/pipeline-photo.c:467 msgid "Hulk" msgstr "Hulk" -#: pipeline-photo.c:457 +#: ../src/pipeline-photo.c:470 msgid "Vertical Flip" msgstr "Svislé překlopení" -#: pipeline-photo.c:458 +#: ../src/pipeline-photo.c:473 msgid "Horizontal Flip" msgstr "Vodorovné překlopení" -#: pipeline-photo.c:459 +#: ../src/pipeline-photo.c:476 msgid "Shagadelic" msgstr "Shagadelic" -#: pipeline-photo.c:460 +#: ../src/pipeline-photo.c:479 msgid "Vertigo" msgstr "Vír" -#: pipeline-photo.c:461 +#: ../src/pipeline-photo.c:482 msgid "Edge" msgstr "Zvýraznění hran" -#: pipeline-photo.c:462 +#: ../src/pipeline-photo.c:485 msgid "Dice" msgstr "Kostičky" -#: pipeline-photo.c:463 +#: ../src/pipeline-photo.c:488 msgid "Warp" msgstr "Deformace" -#: window.c:43 +#: ../src/window.c:43 msgid "A cheesy program to take pictures from your webcam" msgstr "Vykutálený program pro snímání obrázků z webové kamery" -#: window.c:99 +#: ../src/window.c:99 msgid "Cheese" msgstr "Cheese" -#: window.c:111 +#: ../src/window.c:111 msgid "_File" msgstr "Soubor" -#: window.c:112 +#: ../src/window.c:112 msgid "_Help" msgstr "Nápověda" -#: window.c:138 +#: ../src/window.c:138 msgid "Photo" msgstr "Snímek" -#: window.c:139 +#: ../src/window.c:139 msgid "Video" msgstr "Video" -#: window.c:141 +#: ../src/window.c:141 msgid "Take a photo" msgstr "Vyfotit" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: cheese 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-06-24 02:23+0200\n" +"POT-Creation-Date: 2007-06-30 02:38+0200\n" "PO-Revision-Date: 2007-06-25 02:23+0200\n" "Last-Translator: daniel g. siegel <dgsiegel@gmail.com>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -15,86 +15,86 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pipeline-photo.c:165 window.c:140 +#: ../src/pipeline-photo.c:168 ../src/window.c:140 msgid "Effects" msgstr "Effekte" -#: pipeline-photo.c:176 +#: ../src/pipeline-photo.c:179 msgid "Back" msgstr "Zurück" -#: pipeline-photo.c:452 +#: ../src/pipeline-photo.c:455 msgid "No Effect" msgstr "Kein Effekt" -#: pipeline-photo.c:453 +#: ../src/pipeline-photo.c:458 msgid "Mauve" msgstr "Mauve" -#: pipeline-photo.c:454 +#: ../src/pipeline-photo.c:461 msgid "Noir/Blanc" msgstr "Schwarz/weiß" -#: pipeline-photo.c:455 +#: ../src/pipeline-photo.c:464 msgid "Saturation" msgstr "Saturation" -#: pipeline-photo.c:456 +#: ../src/pipeline-photo.c:467 msgid "Hulk" msgstr "Hulk" -#: pipeline-photo.c:457 +#: ../src/pipeline-photo.c:470 msgid "Vertical Flip" msgstr "Vertikale Drehung" -#: pipeline-photo.c:458 +#: ../src/pipeline-photo.c:473 msgid "Horizontal Flip" msgstr "Horizontale Drehung" -#: pipeline-photo.c:459 +#: ../src/pipeline-photo.c:476 msgid "Shagadelic" msgstr "Shagadelic" -#: pipeline-photo.c:460 +#: ../src/pipeline-photo.c:479 msgid "Vertigo" msgstr "Vertigo" -#: pipeline-photo.c:461 +#: ../src/pipeline-photo.c:482 msgid "Edge" msgstr "Edge" -#: pipeline-photo.c:462 +#: ../src/pipeline-photo.c:485 msgid "Dice" msgstr "Würfel" -#: pipeline-photo.c:463 +#: ../src/pipeline-photo.c:488 msgid "Warp" msgstr "Warp" -#: window.c:43 +#: ../src/window.c:43 msgid "A cheesy program to take pictures from your webcam" msgstr "Ein Programm um Bilder deiner Webcam aufzunehmen" -#: window.c:99 +#: ../src/window.c:99 msgid "Cheese" msgstr "Cheese" -#: window.c:111 +#: ../src/window.c:111 msgid "_File" msgstr "_Datei" -#: window.c:112 +#: ../src/window.c:112 msgid "_Help" msgstr "_Hilfe" -#: window.c:138 +#: ../src/window.c:138 msgid "Photo" msgstr "Foto" -#: window.c:139 +#: ../src/window.c:139 msgid "Video" msgstr "Video" -#: window.c:141 +#: ../src/window.c:141 msgid "Take a photo" msgstr "Foto aufnehmen" @@ -6,7 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: cheese 0.1.1\n" -"POT-Creation-Date: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-06-30 02:38+0200\n" "PO-Revision-Date: 2007-06-27 18:46+0100\n" "Last-Translator: Ricardo González Castro <rick@jinlabs.com>\n" "Language-Team: \n" @@ -14,88 +15,86 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pipeline-photo.c:165 -#: window.c:140 +#: ../src/pipeline-photo.c:168 ../src/window.c:140 msgid "Effects" msgstr "Efectos" -#: pipeline-photo.c:176 +#: ../src/pipeline-photo.c:179 msgid "Back" msgstr "Atras" -#: pipeline-photo.c:452 +#: ../src/pipeline-photo.c:455 msgid "No Effect" msgstr "Sin efectos" -#: pipeline-photo.c:453 +#: ../src/pipeline-photo.c:458 msgid "Mauve" msgstr "Malva" -#: pipeline-photo.c:454 +#: ../src/pipeline-photo.c:461 msgid "Noir/Blanc" msgstr "Blanco/Negro" -#: pipeline-photo.c:455 +#: ../src/pipeline-photo.c:464 msgid "Saturation" msgstr "Saturación" -#: pipeline-photo.c:456 +#: ../src/pipeline-photo.c:467 msgid "Hulk" msgstr "Hulk" -#: pipeline-photo.c:457 +#: ../src/pipeline-photo.c:470 msgid "Vertical Flip" msgstr "Giro vertical" -#: pipeline-photo.c:458 +#: ../src/pipeline-photo.c:473 msgid "Horizontal Flip" msgstr "Giro horizontal" -#: pipeline-photo.c:459 +#: ../src/pipeline-photo.c:476 msgid "Shagadelic" msgstr "Psicodélico" -#: pipeline-photo.c:460 +#: ../src/pipeline-photo.c:479 msgid "Vertigo" msgstr "Vértigo" -#: pipeline-photo.c:461 +#: ../src/pipeline-photo.c:482 msgid "Edge" msgstr "Contornos" -#: pipeline-photo.c:462 +#: ../src/pipeline-photo.c:485 msgid "Dice" msgstr "Pedazos" -#: pipeline-photo.c:463 +#: ../src/pipeline-photo.c:488 msgid "Warp" msgstr "Distorsión" -#: window.c:43 +#: ../src/window.c:43 msgid "A cheesy program to take pictures from your webcam" msgstr "Un programa para sacar fotografías con tu cámara web" -#: window.c:99 +#: ../src/window.c:99 msgid "Cheese" msgstr "Cheese" -#: window.c:111 +#: ../src/window.c:111 msgid "_File" msgstr "_Archivo" -#: window.c:112 +#: ../src/window.c:112 msgid "_Help" msgstr "Ayuda" -#: window.c:138 +#: ../src/window.c:138 msgid "Photo" msgstr "Fotografía" -#: window.c:139 +#: ../src/window.c:139 msgid "Video" msgstr "Video" -#: window.c:141 +#: ../src/window.c:141 msgid "Take a photo" msgstr "Sacar una fotografía" - @@ -6,7 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: cheese 0.1.1\n" -"POT-Creation-Date: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-06-30 02:38+0200\n" "PO-Revision-Date: 2007-06-27 18:46+0100\n" "Last-Translator: Ricardo González Castro <rick@jinlabs.com>\n" "Language-Team: \n" @@ -14,88 +15,86 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pipeline-photo.c:165 -#: window.c:140 +#: ../src/pipeline-photo.c:168 ../src/window.c:140 msgid "Effects" msgstr "Efectos" -#: pipeline-photo.c:176 +#: ../src/pipeline-photo.c:179 msgid "Back" msgstr "Atras" -#: pipeline-photo.c:452 +#: ../src/pipeline-photo.c:455 msgid "No Effect" msgstr "Sen efectos" -#: pipeline-photo.c:453 +#: ../src/pipeline-photo.c:458 msgid "Mauve" msgstr "Malva" -#: pipeline-photo.c:454 +#: ../src/pipeline-photo.c:461 msgid "Noir/Blanc" msgstr "Branco/Negro" -#: pipeline-photo.c:455 +#: ../src/pipeline-photo.c:464 msgid "Saturation" msgstr "Saturación" -#: pipeline-photo.c:456 +#: ../src/pipeline-photo.c:467 msgid "Hulk" msgstr "Hulk" -#: pipeline-photo.c:457 +#: ../src/pipeline-photo.c:470 msgid "Vertical Flip" msgstr "Xiro vertical" -#: pipeline-photo.c:458 +#: ../src/pipeline-photo.c:473 msgid "Horizontal Flip" msgstr "Xiro horizontal" -#: pipeline-photo.c:459 +#: ../src/pipeline-photo.c:476 msgid "Shagadelic" msgstr "Psicodélico" -#: pipeline-photo.c:460 +#: ../src/pipeline-photo.c:479 msgid "Vertigo" msgstr "Vértigo" -#: pipeline-photo.c:461 +#: ../src/pipeline-photo.c:482 msgid "Edge" msgstr "Contornos" -#: pipeline-photo.c:462 +#: ../src/pipeline-photo.c:485 msgid "Dice" msgstr "Anacos" -#: pipeline-photo.c:463 +#: ../src/pipeline-photo.c:488 msgid "Warp" msgstr "Distorsión" -#: window.c:43 +#: ../src/window.c:43 msgid "A cheesy program to take pictures from your webcam" msgstr "Un programa para sacar fotografías coa tua cámara web" -#: window.c:99 +#: ../src/window.c:99 msgid "Cheese" msgstr "Cheese" -#: window.c:111 +#: ../src/window.c:111 msgid "_File" msgstr "_Arquivo" -#: window.c:112 +#: ../src/window.c:112 msgid "_Help" msgstr "Axuda" -#: window.c:138 +#: ../src/window.c:138 msgid "Photo" msgstr "Fotografía" -#: window.c:139 +#: ../src/window.c:139 msgid "Video" msgstr "Video" -#: window.c:141 +#: ../src/window.c:141 msgid "Take a photo" msgstr "Sacar unha fotografía" - @@ -6,7 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: cheese 0.1.1\n" -"POT-Creation-Date: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-06-30 02:38+0200\n" "PO-Revision-Date: 2007-06-28 00:04+0100\n" "Last-Translator: Alessandro Falappa <alessandro@falappa.net>\n" "Language-Team: \n" @@ -14,88 +15,86 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pipeline-photo.c:165 -#: window.c:140 +#: ../src/pipeline-photo.c:168 ../src/window.c:140 msgid "Effects" msgstr "Effetti" -#: pipeline-photo.c:176 +#: ../src/pipeline-photo.c:179 msgid "Back" msgstr "Indietro" -#: pipeline-photo.c:452 +#: ../src/pipeline-photo.c:455 msgid "No Effect" msgstr "Nessun effetto" -#: pipeline-photo.c:453 +#: ../src/pipeline-photo.c:458 msgid "Mauve" msgstr "Viola" -#: pipeline-photo.c:454 +#: ../src/pipeline-photo.c:461 msgid "Noir/Blanc" msgstr "Bianco e nero" -#: pipeline-photo.c:455 +#: ../src/pipeline-photo.c:464 msgid "Saturation" msgstr "Saturazione" -#: pipeline-photo.c:456 +#: ../src/pipeline-photo.c:467 msgid "Hulk" msgstr "Hulk" -#: pipeline-photo.c:457 +#: ../src/pipeline-photo.c:470 msgid "Vertical Flip" msgstr "Riflesso verticale" -#: pipeline-photo.c:458 +#: ../src/pipeline-photo.c:473 msgid "Horizontal Flip" msgstr "Riflesso orizzontale" -#: pipeline-photo.c:459 +#: ../src/pipeline-photo.c:476 msgid "Shagadelic" msgstr "Psichedelico" -#: pipeline-photo.c:460 +#: ../src/pipeline-photo.c:479 msgid "Vertigo" msgstr "Vertigo" -#: pipeline-photo.c:461 +#: ../src/pipeline-photo.c:482 msgid "Edge" msgstr "Bordi" -#: pipeline-photo.c:462 +#: ../src/pipeline-photo.c:485 msgid "Dice" msgstr "A quadratini" -#: pipeline-photo.c:463 +#: ../src/pipeline-photo.c:488 msgid "Warp" msgstr "Distorsione" -#: window.c:43 +#: ../src/window.c:43 msgid "A cheesy program to take pictures from your webcam" msgstr "Un programma sfizioso per scattare fotografie con la propria webcam" -#: window.c:99 +#: ../src/window.c:99 msgid "Cheese" msgstr "Cheese" -#: window.c:111 +#: ../src/window.c:111 msgid "_File" msgstr "_File" -#: window.c:112 +#: ../src/window.c:112 msgid "_Help" msgstr "_Aiuto" -#: window.c:138 +#: ../src/window.c:138 msgid "Photo" msgstr "Foto" -#: window.c:139 +#: ../src/window.c:139 msgid "Video" msgstr "Video" -#: window.c:141 +#: ../src/window.c:141 msgid "Take a photo" msgstr "Scatta foto" - @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: cheese 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-06-24 02:23+0200\n" +"POT-Creation-Date: 2007-06-30 02:38+0200\n" "PO-Revision-Date: 2007-06-25 12:30+WEST\n" "Last-Translator: Miguel Rosa <miguelpires@gmail.com>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -15,86 +15,86 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pipeline-photo.c:165 window.c:140 +#: ../src/pipeline-photo.c:168 ../src/window.c:140 msgid "Effects" msgstr "Efeitos" -#: pipeline-photo.c:176 +#: ../src/pipeline-photo.c:179 msgid "Back" msgstr "Retroceder" -#: pipeline-photo.c:452 +#: ../src/pipeline-photo.c:455 msgid "No Effect" msgstr "Sem efeitos" -#: pipeline-photo.c:453 +#: ../src/pipeline-photo.c:458 msgid "Mauve" msgstr "Lilás" -#: pipeline-photo.c:454 +#: ../src/pipeline-photo.c:461 msgid "Noir/Blanc" msgstr "Negro/Branco" -#: pipeline-photo.c:455 +#: ../src/pipeline-photo.c:464 msgid "Saturation" msgstr "Saturação" -#: pipeline-photo.c:456 +#: ../src/pipeline-photo.c:467 msgid "Hulk" msgstr "Hulk" -#: pipeline-photo.c:457 +#: ../src/pipeline-photo.c:470 msgid "Vertical Flip" msgstr "Inversão vertical" -#: pipeline-photo.c:458 +#: ../src/pipeline-photo.c:473 msgid "Horizontal Flip" msgstr "Inversão horizontal" -#: pipeline-photo.c:459 +#: ../src/pipeline-photo.c:476 msgid "Shagadelic" msgstr "Psicadélico" -#: pipeline-photo.c:460 +#: ../src/pipeline-photo.c:479 msgid "Vertigo" msgstr "Vertigo" -#: pipeline-photo.c:461 +#: ../src/pipeline-photo.c:482 msgid "Edge" msgstr "Contornos" -#: pipeline-photo.c:462 +#: ../src/pipeline-photo.c:485 msgid "Dice" msgstr "Pedaços" -#: pipeline-photo.c:463 +#: ../src/pipeline-photo.c:488 msgid "Warp" msgstr "Distorção" -#: window.c:43 +#: ../src/window.c:43 msgid "A cheesy program to take pictures from your webcam" msgstr "Uma aplicação para tirar fotografias da sua webcam" -#: window.c:99 +#: ../src/window.c:99 msgid "Cheese" msgstr "Cheese" -#: window.c:111 +#: ../src/window.c:111 msgid "_File" msgstr "_Ficheiro" -#: window.c:112 +#: ../src/window.c:112 msgid "_Help" msgstr "Ajuda" -#: window.c:138 +#: ../src/window.c:138 msgid "Photo" msgstr "Foto" -#: window.c:139 +#: ../src/window.c:139 msgid "Video" msgstr "Vídeo" -#: window.c:141 +#: ../src/window.c:141 msgid "Take a photo" msgstr "Tirar uma foto" diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 00000000..d06b8acb --- /dev/null +++ b/src/Makefile @@ -0,0 +1,47 @@ +#!/usr/bin/env make + +include toc2.make +include $(toc2.dirs.makefiles)/toc2-c.make + +SOURCES := cheese.c pipeline-photo.c fileutil.c thumbnails.c window.c cairo-custom.c + +print-var-%: + @echo $*=$($*) + echo value $*=$(value $*) + +GTK_CFLAGS := $(GTK_2_0_CFLAGS) +GTK_LIBS := $(GTK_2_0_LIBS) + +GLADE_CFLAGS := $(LIBGLADE_2_0_CFLAGS) +GLADE_LIBS := $(LIBGLADE_2_0_LIBS) + +DBUS_CFLAGS := $(DBUS_1_CFLAGS) +DBUS_LIBS := $(DBUS_1_CFLAGS) + +GSTREAMER_CFLAGS := $(GSTREAMER_0_10_CFLAGS) $(GSTREAMER_PLUGINS_BASE_0_10_CFLAGS) +GSTREAMER_LIBS := $(GSTREAMER_0_10_LIBS) $(GSTREAMER_PLUGINS_BASE_0_10_LIBS) -lgstinterfaces-0.10 + +GNOME_VFS_CFLAGS := $(GNOME_VFS_2_0_CFLAGS) +GNOME_VFS_LIBS := $(GNOME_VFS_2_0_LIBS) + +GDK_CFLAGS := $(GDK_2_0_CFLAGS) +GDK_LIBS := $(GDK_2_0_LIBS) + +CFLAGS := $(call toc2.call.remove-dupes,-g -O2 -Wall -Werror $(DBUS_CFLAGS) $(GTK_CFLAGS) $(GLADE_CFLAGS) $(GSTREAMER_CFLAGS) $(GNOME_VFS_CFLAGS) $(GDK_CFLAGS)) +LDFLAGS := $(call toc2.call.remove-dupes,-lpthread $(DBUS_LIBS) $(GTK_LIBS) $(GLADE_LIBS) $(GSTREAMER_LIBS) $(GNOME_VFS_LIBS) $(GDK_LIBS)) + +OBJS = $(SOURCES:%.c=%.o) + +package.dist_files += $(SOURCES) $(SOURCES:%.c=%.h) cheese_config.h.at +#package.clean_files += cheese $(OBJS) +package.distclean_files += cheese_config.h +package.install.bins := cheese + +######################################################################## +# Build binaries: +cheese.BIN.OBJECTS = $(OBJS) +$(call toc2.call.rules.c-bin,cheese) +######################################################################## + +all: cheese.BIN + diff --git a/cairo-custom.c b/src/cairo-custom.c index 021e9b6f..021e9b6f 100644 --- a/cairo-custom.c +++ b/src/cairo-custom.c diff --git a/cairo-custom.h b/src/cairo-custom.h index d8fbf135..d8fbf135 100644 --- a/cairo-custom.h +++ b/src/cairo-custom.h @@ -2,7 +2,8 @@ #include <glib.h> -#define VERSION "0.1.0" +#include "cheese_config.h" + //FIXME: provide option to choose the folder #define SAVE_FOLDER_DEFAULT "images/" //FIXME: provide option to choose the naming of the photos diff --git a/src/cheese_config.h.at b/src/cheese_config.h.at new file mode 100644 index 00000000..affe7da4 --- /dev/null +++ b/src/cheese_config.h.at @@ -0,0 +1,9 @@ +#ifndef GNOME_CHEESE_CONFIG_H_INCLUDED +#define GNOME_CHEESE_CONFIG_H_INCLUDED 1 + +#define CHEESE_PACKAGE_NAME "@PACKAGE_NAME@" +#define CHEESE_VERSION "@PACKAGE_VERSION@" +#define CHEESE_DATA_DIR "@CHEESE_DATA_DIR@" + +#endif // GNOME_CHEESE_CONFIG_H_INCLUDED + diff --git a/fileutil.c b/src/fileutil.c index ec8218a1..ec8218a1 100644 --- a/fileutil.c +++ b/src/fileutil.c diff --git a/fileutil.h b/src/fileutil.h index 4e225217..4e225217 100644 --- a/fileutil.h +++ b/src/fileutil.h diff --git a/pipeline-photo.c b/src/pipeline-photo.c index afc66905..afc66905 100644 --- a/pipeline-photo.c +++ b/src/pipeline-photo.c diff --git a/pipeline-photo.h b/src/pipeline-photo.h index dcfdaa56..dcfdaa56 100644 --- a/pipeline-photo.h +++ b/src/pipeline-photo.h diff --git a/thumbnails.c b/src/thumbnails.c index 3e03e129..3e03e129 100644 --- a/thumbnails.c +++ b/src/thumbnails.c diff --git a/thumbnails.h b/src/thumbnails.h index c0741204..c0741204 100644 --- a/thumbnails.h +++ b/src/thumbnails.h @@ -37,8 +37,8 @@ void on_about_cb (GtkWidget *p_widget, gpointer user_data) about = gtk_about_dialog_new(); g_object_set (about, - "name", "cheese", - "version", VERSION, + "name", CHEESE_PACKAGE_NAME, + "version", CHEESE_VERSION, "copyright", "Copyright (c) 2007\n daniel g. siegel <dgsiegel@gmail.com>", "comments", _("A cheesy program to take pictures from your webcam"), //"authors", authors, @@ -1,7 +1,7 @@ #include <glade/glade.h> -#define GLADE_FILE "cheese.glade" +#define GLADE_FILE CHEESE_DATA_DIR"/cheese.glade" //#define GLADE_FILE "/usr/share/cheese/cheese.glade" struct _widgets diff --git a/toc2.cheese.help b/toc2.cheese.help new file mode 100644 index 00000000..63a649aa --- /dev/null +++ b/toc2.cheese.help @@ -0,0 +1,3 @@ + --enable-maintainer-mode + enable maintainer-mode, which allows to build and test + directly in the src directory diff --git a/toc2.cheese.make.at b/toc2.cheese.make.at new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/toc2.cheese.make.at diff --git a/toc2/Makefile b/toc2/Makefile new file mode 100644 index 00000000..7df80d77 --- /dev/null +++ b/toc2/Makefile @@ -0,0 +1,11 @@ + +package.subdirs = sbin bin tests make +include toc2.make + +# We don't normally want to include toc's docs in non-toc trees: +ifeq (toc2,$(PACKAGE_NAME)) + subdirs: subdir-doc + package.subdirs += doc +endif + +all: subdirs diff --git a/toc2/bin/Makefile b/toc2/bin/Makefile new file mode 100644 index 00000000..515196d1 --- /dev/null +++ b/toc2/bin/Makefile @@ -0,0 +1,8 @@ +include toc2.make + +package.dist_files += atsign_parse \ + cleanup_vars \ + install-sh \ + makedist \ + removeDupeArgs \ + mkdep-toc2.c diff --git a/toc2/bin/atsign_parse b/toc2/bin/atsign_parse new file mode 100644 index 00000000..63bd6362 --- /dev/null +++ b/toc2/bin/atsign_parse @@ -0,0 +1,120 @@ +#!/usr/bin/perl +# ( ^^^^ when run with -n it tries to read in files named after the args. e.g. foo=bar) +# +# Takes command-line args in the format: +# +# foo=bar [include:bar=infile] [shell:foobar=shellcmd]... +# +# and parses stdin, replacing @foo@ with bar. +# +# All output goes to stdout. +# +# Intended to be used as a simple parser for Makefile.in-type files. +# +# Special keys type: +# +# include:KEY=filename +# +# Will try to read the file VAL and import it in place of @KEY@. +# +# shell:KEY=shellcmd +# +# Will replace KEY with the output of shellcmd. +# +# The shell: and include: substitutions happen ONE time, +# before the input stream is ever read, and not every time +# the corresponding @token@ is replaced. +# +# Optional arguments: +# +# [-f filename] will read in that file. It must be in the form +# KEY=VALUE, with one key/value per line. +# +# [-c] will enable "cleanup mode". Any @TOKENS@ in the input stream +# which were not explicitely assigned values will be parsed out +# of the output. Without this option, the raw @TOKEN@ would go +# into the output. +# +# License: public domain +# author: stephan <sgbeal@users.sourcceforge.net> +# CVS Revision: $Revision: 1.2 $ + + +BEGIN { + $STRIP_LEADING_DASHES = 1; # if set to 1 then --foo=bar is same as foo=bar + $op_cleanup = 0; # strip un-parsed @TOKENS@ from the input. + if( ! @ARGV ) { + print "Usage: $0 foo=bar [bar=foobar] [argN=valN]...\n"; + exit 1; + } + + @args = (); + ############################################################ collect args... + for( $i = 0; $i < @ARGV; $i++ ) + { + $a = $ARGV[$i]; + if( $a eq "-f" ) { + $fn = $ARGV[++$i]; + open( INFILE, $fn ) || die "Could not open input file [$fn]."; + @foo = <INFILE>; + foreach $f (@foo) { + chomp($f); push( @args, $f ); + } + close INFILE; + next; + } + if( $a eq "-c" ) { + $op_cleanup = 1; + next; + } + push( @args, $a ); + } + #print join( "\n", @args )."\n"; + + %args = (); + + foreach $a ( @args ) { + ############################################################ parse out KEY=VAL pairs + next unless $a =~ m|([^=]+)\s*=\s*(.*)|; + $key = $1; + $val = $2; + if( $STRIP_LEADING_DASHES ) { $key =~ s/^-+//; } + #print STDERR ": [$key]=[$val]\n"; + ############################################################ include:FOO=BAR + if( $key =~ m|^include:(.+)| ) { + $key = $1; + open INFILE, "<$val" or die "Cannot open file '$val', as requested by \@include:$key@!"; + @foo = <INFILE>; + close INFILE; + $val = join( "", @foo ); + } + ############################################################ shell:FOO=BAR + if( $key =~ m|^shell:(.+)| ) { + $key = $1; + $val = `$val`; + } + $args{$key} = $val; + } +} # /BEGIN + +while( <STDIN> ) { + + $loop = true; + while( $loop ) { + # loop over line until we can replace no more @tokens@ + $cp = $_; + foreach $k (keys(%args)) { + $v = $args{$k}; + next unless $_ =~ s|\@$k\@|$v|g; +# print STDERR "replacing $k --> $v\n"; + } + $loop = 0 if $cp eq $_; + } + if( $op_cleanup ) { + # parse out undefined @tokens@ + while( $_ =~ s|\@\S+\@||g ) {} + } + print; +} + +exit 0; diff --git a/toc2/bin/cleanup_vars b/toc2/bin/cleanup_vars new file mode 100644 index 00000000..f9193fea --- /dev/null +++ b/toc2/bin/cleanup_vars @@ -0,0 +1,17 @@ +#!/usr/bin/perl +# reads in a list of KEY=VAL lines and removes all but the last-set +# entries. Intended for use with cleaning up toc-exported variables. + +@IN = reverse <>; +%gots = (); +@out = (); +foreach $l (@IN) { + chomp $l; + next unless $l =~ m|^\s*(\S+)\s*=\s*(.*)|; + $key = $1; $val = $2; + next if $gots{$key}; + $gots{$key} = 1; + push( @out, $l ); +# print $l."\n"; +} +print join("\n", reverse @out),"\n"; diff --git a/toc2/bin/create_makefile_stubs.sh b/toc2/bin/create_makefile_stubs.sh new file mode 100644 index 00000000..544eb2c1 --- /dev/null +++ b/toc2/bin/create_makefile_stubs.sh @@ -0,0 +1,261 @@ +#!/bin/sh +# +# Generate stub Makefiles for toc. +# +# Usage: see help text, below + + + +dirs= +x_help= +while test x != "x$1" ; do + arg="$1" + shift + case "$arg" in + -?|--help|-help) + x_help=1 + ;; + *) test -d $arg && dirs="$dirs $arg" + ;; + esac +done +# +test x1 = "x$x_help" && { + cat <<EOF +$0: +Creates stub files for a toc environment by looking at the +contents of a directory. + +Usage: +$0 dir1 [... dirN] + +dir1 defaults to ., which should be the \$(top_srcdir) of a project +tree. + +For each dir it creates dir/Makefile.suggestion, containing guesses at +what toc-related content might be useful in the corresponding Makefile. + +If called without any options then it acts RECURSIVELY on ".". It does +not act recursively if called with directory arguments. This behaviour +is arguable, but seems to be reasonable for the use-cases to-date (all +1.5 of them ;). + +EOF + exit 0 +} + + +stderr () +{ # sends $@ to stderr + echo "#" "$@" 1>&2 +} + +slashify () +{ # converts file lists into a format which is more useful to Makefile maintainers. + # usage: echo list | slashify + perl -ne 's|\n| |g;s|\s+$||;s|\s+|%|g;s|%$|\n|;s|%| \\\n\t|g; print $_,"\n";' +} + +######################################################################## +# check_make_XXX() conventions: +# +# $1 is the directory name, but they don't really need it. A chdir is +# done before processing each dir, so all tests can safely assume pwd +# is the directory they are responsible for checking. +# +# They "should" follow the naming convention check_make_XXX so they +# can easily be handled in a loop using only their XXX parts. +######################################################################## + +######################################################################## +check_make_flexes () +{ # hanles *.flex + export flext=flex + local flexes="$(ls *.${flext} 2>/dev/null)" + test "x$flexes" != "x" && { + stderr "Adding FLEXES" + echo "############## FLEXES:" + echo "# WARNING: FLEXES stuff only works for C++-based flexers" + echo -n "FLEXES = " + echo $flexes | sed s/\.${flext}//g + echo "FLEXES_ARGS = -+ -p" + for f in $flexes; do + base=${f%%.${flext}} + echo "${base}_FLEXES_ARGS = -P${base}" + done + echo -n "OBJECTS += " + echo $flexes | sed s/\.${flext}/.${flext}.o/g + echo "include \$(TOC_MAKESDIR)/flex.make" + echo "# Run target FLEXES to process these." + echo "# REMINDER: add the generated C++ files to your SOURCES, if needed." + echo "############## /FLEXES" + } + +} +######################################################################## +check_make_c () +{ +# checks for c/c++-related stuff + + local headers="$(ls *.h *.hpp 2>/dev/null )" + test -n "$headers" && { + stderr "Adding HEADERS" + echo -n "HEADERS = "; + echo $headers | slashify + echo "DIST_FILES += \$(HEADERS)" + echo "INSTALL_PACKAGE_HEADERS += \$(HEADERS)" + echo + } + + local sources="$(ls *.c *.cpp *.c++ *.C *.cxx 2>/dev/null )" + test -n "$sources" && { + stderr "Adding SOURCES" + echo -n "SOURCES = "; + echo $sources | slashify + echo "DIST_FILES += \$(SOURCES)" + echo -n "OBJECTS = " + echo $sources | perl -pe 's|(\S+)\.\w+\s|$1.o |g' | slashify + echo + echo "CLEAN_FILES += \$(OBJECTS)" + cat <<EOF + +build_libs = 0 +LIBNAME = libfoo +ifeq (1,\$(build_libs)) + STATIC_LIBS = \$(LIBNAME) + SHARED_LIBS = \$(LIBNAME) + \$(LIBNAME)_a_OBJECTS = \$(OBJECTS) + \$(LIBNAME)_so_OBJECTS = \$(\$(LIBNAME)_a_OBJECTS) + # \$(LIBNAME)_so_VERSION = \$(PACKAGE_VERSION) + # \$(LIBNAME)_so_LDADD = + include \$(TOC_MAKESDIR)/SHARED_LIBS.make + include \$(TOC_MAKESDIR)/STATIC_LIBS.make + # Run targets STATIC_LIBS and SHARED_LIBS build these. +SHARED_LIBS: STATIC_LIBS +endif + +build_bins = 0 +BINNAME = mybin +ifeq (1,\$(build_bins)) + BIN_PROGRAMS = \$(BINNAME) + \$(BINNAME)_bin_OBJECTS = \$(OBJECTS) +# \$(BINNAME)_bin_LDADD = + include \$(TOC_MAKESDIR)/BIN_PROGRAMS.make + INSTALL_BINS += \$(BIN_PROGRAMS) + # Run target BIN_PROGRAMS to build these. +endif + +EOF + + } #end SOURCES (and friends) + + +} # end check_make_c + + +######################################################################## +check_make_extra_dist () +{ # Add some common filenames/patterns to DIST_FILES + local xtra= + # reminder: toc adds Makefile to DIST_FILES by default, because it's ALWAYS needed. + for x in README LICENSE NEWS ChangeLog \ + *.at *.qmake \ + *.sh *.pl \ + *.bat \ + *.txt *.TXT *.xml *.lyx \ + *.odt *.php *.html \ + ; do + expr "$x" : '\*' >/dev/null && continue # unexpanded wildcard + test -e $x || continue + xtra="$xtra $x" + done + + test -z "$xtra" && return + stderr "Adding extra DIST_FILES." + echo -n "DIST_FILES += " + echo $xtra | slashify + +} + +######################################################################## +check_make_subdirs () +{ # add subdirs to SUBDIRS + local ls="$(ls -d *)" + test -z "$ls" && return + + local subs= + for i in $ls; do + test -d $i || continue; + test "CVS" = "$i" && continue + stderr "Adding SUBDIR $i" + subs="$subs $i" + done + test -n "$subs" && echo "SUBDIRS = $subs" +} + + + + +# checks for existing Makefile +check_make_makefile () +{ + true +} + + + +############################################################################## +# main app driver goes here: + +test x = "x$dirs" && { + dirs="$(find . -type d | sed -e '/\/CVS/d')" +} + +test x = "x$dirs" && { + echo "Error: no subdirectories found!" + exit 1 +} + +timestamp=$(date) +for d in $dirs; do + cd $d >/dev/null || { + err=$? + echo "Error: could not cd to $d" + exit $err + } + out=Makefile.suggestion + stderr "Creating $d/$out" + { + cat <<EOF +#!/usr/bin/make -f +################################################### +# AUTO-GENERATED guess at a toc-aware Makefile, +# based off of the contents of directory: +# $d +# Created by $0 +# $timestamp +# It must be tweaked to suit your needs. +################################################### +include toc.make +EOF + for func in subdirs extra_dist flexes c ; do + check_make_${func} $d + done + cat <<EOF +all: +# Don't forget to any any SUBDIRS to 'all', if needed, with: +# all: subdir-NAME +# or: +# all: subdirs +################################################### +# end auto-generated rules +################################################### +EOF + } > $out + cd - > /dev/null +done + + +######################################################################## +# the end +######################################################################## diff --git a/toc2/bin/create_project_skeleton.sh b/toc2/bin/create_project_skeleton.sh new file mode 100644 index 00000000..00565fe5 --- /dev/null +++ b/toc2/bin/create_project_skeleton.sh @@ -0,0 +1,67 @@ +#!/bin/bash +######################################################################## +# A quick hack for generating a skeleton project for use with toc2. +# +# Must be run from the top of the toc2 source tree. +# +# + +test -f ./toc2/sbin/toc2_core.sh -a -f ./configure.toc2 || { + echo "$0 must be run from the top of the toc2 source tree." + exit 1 +} + +test -e ./toc2.toc2.make || { + echo "Configuring ..." + ./configure >/dev/null || { + echo "configure failed :(" + exit 2 + } +} + +echo "Making dist tarball..." +make dist > /dev/null || { + echo "make dist failed :(" + exit 3 +} + +tarball=$(ls -1t toc2-*.tar | head -n1) + +test x != "x${tarball}" || { + echo "Could not figure out which file is the tarball??? :(" + exit 4 +} + +distname=${tarball%%.tar} +test x = "x${distname}" && { + echo "Could not determine tarball name???" + exit 5 +} + +test -d ${distname} && rm -fr ${distname} + +tar xf ${tarball} + +cd $distname || { + echo "Could not cd to [$distname]???" + exit 6 +} +rm -fr src +rm -fr toc2/doc +skelname=ProjectSkeleton +perl -i -pe "s|PACKAGE_NAME=\S+|PACKAGE_NAME=${skelname}|" configure +mv configure.toc2 configure.${skelname} +mv toc2.toc2.make.at toc2.${skelname}.make.at +mv Makefile.skeleton Makefile + +cd - + +version=${distname##*-} +newname=toc2-skeleton-package-${version} +mv ${distname} ${newname} +newtar=${newname}.tar.gz +tar czf ${newtar} ${newname} +rm -fr ${newname} + +echo "Done..." +ls -lat ${newtar} diff --git a/toc2/bin/install-sh b/toc2/bin/install-sh new file mode 100644 index 00000000..498fd9fb --- /dev/null +++ b/toc2/bin/install-sh @@ -0,0 +1,305 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$cpprog" # note: changed from mvprog by stephan +default_mode="0755" +chmodcmd="$chmodprog ${default_mode}" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +show_help () +{ + cat <<EOF +$0 usage: + +$0 [options] source_file dest_dir + +Options: + +-c PROG + sets the copy program to PROG [default=${cpprog}] + +-d + Specifies that source_file is a directory name to create + and dest_dir is ignored (and need not be specified). + +-m MODE + Chmod specifier. During the install, the destination has + its attributes set to MODE. [default=${default_mode}] + +-o OWNER + Set owner of destination file to OWNER + +-g GROUP + Set group of destination file to GROUP. Alternately, use -o OWNER:GROUP on + platforms where chown supports that syntax. + +-s + Call ${stripprog} on the destination file. + +-? or --help + Show this help and exit with status 0. + +EOF + +} + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + -?|--help) + show_help + exit;; + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + show_help + exit 1 +else + true +fi + +# cygwin workaround: added by stephan@wanderinghorse.net for use with toc. +if [ -f "$src".exe ] ; then + src="$src.exe" + dst_suffix=".exe" + echo CYGWIN WORKAROUND: src=$src +fi + + +if [ x"$dir_arg" != x ]; then + dst="$src" + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" -o -d "$src" ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename "$src"` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +# cygwin workaround: +if [ x"$dst_suffix" != x ]; then + dst="$dst$dst_suffix" + echo "CYGWIN WORKAROUND? dst=$dst" +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd "$src" $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/toc2/bin/makedist b/toc2/bin/makedist new file mode 100644 index 00000000..c43d58ab --- /dev/null +++ b/toc2/bin/makedist @@ -0,0 +1,102 @@ +#!/usr/bin/perl +# +# A mind-numbingly stupid distribution tarball creator. +# +# todo: add some wildcard support to the file lists. +# +# stephan@s11n.net +# +# Note that is implicitely filters out some file names, +# to simplify use of the toc client-side install code. +# +# Usage: +# $0 input_file_list release_name +# +# The release name must be a single token suitable for use +# as a dir and file name. Normally this is +# package_name-package_version. +# input_file_list is a file containing relative paths to files +# which should be tarred up. All files should exist in the current +# dir or subdirs, not dirs outside of the current tree. +######################################################################## +$verbose = 0; +$dieonerror = 1; +$USAGE = "usage: $0 input_list_file release_name"; + +$DISTFILES_LIST = $ARGV[0] || die $USAGE; + +$basename = $ARGV[1] || die $USAGE; +$TARBALL = $basename; +$basename =~ s|\.tar$||; +$TARBALL .= ".tar" unless $TARBALL =~ m|\.tar$|; +execcmd( "rm -fr $basename" ) if -d $basename; +execcmd( "mkdir $basename" ); + +open DLIST, "<$DISTFILES_LIST" || die "Cannot open dist files list, $DISTFILES_LIST!"; +@list = <DLIST>; +# print @list; +close DLIST; + +@thelist = (); + +foreach $l (@list) { + next if $l =~ /^#/; + next if $l =~ m|^(.*/)?toc.q?make$|; + next if $l =~ m|\.o$|; + next if $l =~ m|/?CVS/?|; + chomp( $l ); + + next unless $l =~ /\w/; + next if $l =~ m|~$|; + + $l =~ s/^\s+//; + if( (! -f $l) && (! -d $l) ) { + stderr( "WARNING: [$l] not found!" ); + exit 1 if $dieonerror; + } + push( @thelist, $l ); + +} + +$tarfileslist = ".tar.tmp"; +open TARLIST, ">$tarfileslist"; +print TARLIST join( "\n", @thelist ); +#print STDOUT "thelist=",join( "\n", @thelist ),"\n"; +print "File count: ".@thelist."\n" if $verbose; + +$tarargs = "--files-from=$tarfileslist --exclude=CVS"; + + +execcmd( "tar cf - $tarargs | tar xf - -C \"$basename\"" ); +# ^^^^ got that? it's simpler than cp'ing the list of files to their proper subdirs. :) + +if( 0 ) { + $md5 = `which md5sum 2>/dev/null`; + if( $md5 ) { + $md5file = "$basename/md5.sums.$basename"; + print STDERR "Generating md5 sums: $md5file\n"; + # execcmd( "cd $basename; for x in \$(find . -type f); do md5sum \$x >> MD5SUMS.$basename; done" ); + execcmd( "for x in \$(cat $tarfileslist); do md5sum \$x; done > $md5file" ) + } else { + print STDERR "Warning: no md5sum binary found, so not including md5 info.\n"; + } +} + +execcmd( "rm $tarfileslist" ); +execcmd( "tar cf \"$TARBALL\" \"$basename\"" ); +execcmd( "rm -fr \"$basename\"" ); + +# print "Tarball: ".`ls -la $TARBALL`."\n"; +print "Tarball: $TARBALL\n" if $verbose; + +exit 0; +sub stderr() { + $msg = shift; + print STDERR $msg."\n"; +} + +sub execcmd() { + $cmd = shift; + print $cmd."\n" if $verbose; + `$cmd`; +} diff --git a/toc2/bin/mkdep-toc2.c b/toc2/bin/mkdep-toc2.c new file mode 100644 index 00000000..362a5818 --- /dev/null +++ b/toc2/bin/mkdep-toc2.c @@ -0,0 +1,533 @@ +/* + * Originally by Linus Torvalds. + * Smart CONFIG_* processing by Werner Almesberger, Michael Chastain. + * + * Usage: mkdep cflags -- file ... + * + * Read source files and output makefile dependency lines for them. + * I make simple dependency lines for #include <*.h> and #include "*.h". + * I also find instances of CONFIG_FOO and generate dependencies + * like include/config/foo.h. + * + * 1 August 1999, Michael Elizabeth Chastain, <mec@shout.net> + * - Keith Owens reported a bug in smart config processing. There used + * to be an optimization for "#define CONFIG_FOO ... #ifdef CONFIG_FOO", + * so that the file would not depend on CONFIG_FOO because the file defines + * this symbol itself. But this optimization is bogus! Consider this code: + * "#if 0 \n #define CONFIG_FOO \n #endif ... #ifdef CONFIG_FOO". Here + * the definition is inactivated, but I still used it. It turns out this + * actually happens a few times in the kernel source. The simple way to + * fix this problem is to remove this particular optimization. + * + * 2.3.99-pre1, Andrew Morton <andrewm@uow.edu.au> + * - Changed so that 'filename.o' depends upon 'filename.[cS]'. This is so that + * missing source files are noticed, rather than silently ignored. + * + * 2.4.2-pre3, Keith Owens <kaos@ocs.com.au> + * - Accept cflags followed by '--' followed by filenames. mkdep extracts -I + * options from cflags and looks in the specified directories as well as the + * defaults. Only -I is supported, no attempt is made to handle -idirafter, + * -isystem, -I- etc. + * + * Aug 2003: stephan beal <stephan@s11n.net> + * - removed HPATH requirement for use in the toc project (toc.sourceforge.net) + * + * Aug 2003: rusty <bozo@users.sourceforge.net> + * Other changes for use in toc/libfunUtil: + * - Add support for C++ file extensions .cc, .C, .c++, .cxx, .cpp. + * (Previously, this was doing "a" right thing, by making foo.c++ depend on + * the headers #included by foo.c++, with a "touch foo.c++" rule which + * would then cause the .o file to be out of date, but "the" right thing is + * for foo.o to depend on the headers #included by foo.c++. I guess there + * aren't many C++ files in the Linux kernel tree, ha ha.) + * + * Dec 2003: stephan@s11n.net + * Changes for toc.sourceforge.net: + * - removed the default 'touch' behaviour to avoid collissions with targets + * generated via toc. + * + * 20 Aug 2004: stephan@s11n.net + * - Removed unused hpath from main(). WTF does gcc NOW start to + * complain about that!?!?!? + * - Added some parens to keep gcc from bitching (again... why now? + * Been compiling w/o complaint for over a year). + * + * 7 April 2005: stephan@s11n.net + * - Made an -Isomedir dir lookup failure non-fatal, because it often + * happens when using a custom --prefix when configuring a tree to + * build under, e.g. ~/tmp. + * + * 8 June 2007: stephan@s11n.net + * - Added creation of empty target for files which have no explicit deps. + * This avoids the "no rule to create ..." when a file is moved/deleted.* + * + * 16 June 2007: stephan@s11n.net + * - Removed all CONFIG-related code (~150 lines), as it is not useful + * outside of the linux kernel (original home of this code) and it + * greatly decreases the readability of this code. + * + */ + +#include <ctype.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> + + +/** + TOC_MODE enables: + + - no 'touch'ing of targets, to avoid overriding + rules defined elsewhere in toc. +*/ +#define TOC_MODE 1 + +char __depname[512] = "\n\t@touch "; +#define depname (__depname+9) + +int hasdep; + +struct path_struct { + int len; + char *buffer; +}; +struct path_struct *path_array; +int paths; + + +/* Current input file */ +static const char *g_filename; + +/* + * This records all the configuration options seen. + * In perl this would be a hash, but here it's a long string + * of values separated by newlines. This is simple and + * extremely fast. + */ +char * str_config = NULL; +int size_config = 0; +int len_config = 0; + +static void +do_depname(void) +{ + if (!hasdep) { + hasdep = 1; + //printf( "depname=%s, g_filename=%s", depname, g_filename ); + printf("%s:", depname); + if (g_filename) + printf(" %s", g_filename); + } +} + + +/* + * This records all the precious .h filenames. No need for a hash, + * it's a long string of values enclosed in tab and newline. + */ +char * str_precious = NULL; +int size_precious = 0; +int len_precious = 0; + + + +/* + * Grow the precious string to a desired length. + * Usually the first growth is plenty. + */ +void grow_precious(int len) +{ + while (len_precious + len > size_precious) { + if (size_precious == 0) + size_precious = 2048; + str_precious = realloc(str_precious, size_precious *= 2); + if (str_precious == NULL) + { perror("malloc"); exit(1); } + } +} + + + +/* + * Add a new value to the precious string. + */ +void define_precious(const char * filename) +{ + int len = strlen(filename); + grow_precious(len + 4); + *(str_precious+len_precious++) = '\t'; + memcpy(str_precious+len_precious, filename, len); + len_precious += len; + memcpy(str_precious+len_precious, " \\\n", 3); + len_precious += 3; +} + + + +/* + * Handle an #include line. + */ +void handle_include(int start, const char * name, int len) +{ + struct path_struct *path; + int i; + + for (i = start, path = path_array+start; i < paths; ++i, ++path) { + memcpy(path->buffer+path->len, name, len); + path->buffer[path->len+len] = '\0'; + if (access(path->buffer, F_OK) == 0) { + do_depname(); + printf(" \\\n %s", path->buffer); + return; + } + } + +} + + + +/* + * Add a path to the list of include paths. + */ +void add_path(const char * name) +{ + struct path_struct *path; + char resolved_path[PATH_MAX+1]; + const char *name2; + + if (strcmp(name, ".")) { + name2 = realpath(name, resolved_path); + if (!name2) { + return; /* added by stephan@s11n.net, because i don't care about this failure. */ +/* fprintf(stderr, "realpath(%s) failed, %m\n", name); */ +/* exit(1); */ + } + } + else { + name2 = ""; + } + + path_array = realloc(path_array, (++paths)*sizeof(*path_array)); + if (!path_array) { + fprintf(stderr, "cannot expand path_arry\n"); + exit(1); + } + + path = path_array+paths-1; + path->len = strlen(name2); + path->buffer = malloc(path->len+1+256+1); + if (!path->buffer) { + fprintf(stderr, "cannot allocate path buffer\n"); + exit(1); + } + strcpy(path->buffer, name2); + if (path->len && *(path->buffer+path->len-1) != '/') { + *(path->buffer+path->len) = '/'; + *(path->buffer+(++(path->len))) = '\0'; + } +} + + + + + +/* + * Macros for stunningly fast map-based character access. + * __buf is a register which holds the current word of the input. + * Thus, there is one memory access per sizeof(unsigned long) characters. + */ + +#if defined(__alpha__) || defined(__i386__) || defined(__ia64__) || defined(__x86_64__) || defined(__MIPSEL__) \ + || defined(__arm__) +#define LE_MACHINE +#endif + +#ifdef LE_MACHINE +#define next_byte(x) (x >>= 8) +#define current ((unsigned char) __buf) +#else +#define next_byte(x) (x <<= 8) +#define current (__buf >> 8*(sizeof(unsigned long)-1)) +#endif + +#define GETNEXT { \ + next_byte(__buf); \ + if ((unsigned long) next % sizeof(unsigned long) == 0) { \ + if (next >= end) \ + break; \ + __buf = * (unsigned long *) next; \ + } \ + next++; \ +} + +/* + * State machine macros. + */ +#define CASE(c,label) if (current == c) goto label +#define NOTCASE(c,label) if (current != c) goto label + +/* + * Yet another state machine speedup. + */ +#define MAX2(a,b) ((a)>(b)?(a):(b)) +#define MIN2(a,b) ((a)<(b)?(a):(b)) +#define MAX4(a,b,c,d) (MAX2(a,MAX2(b,MAX2(c,d)))) +#define MIN4(a,b,c,d) (MIN2(a,MIN2(b,MIN2(c,d)))) + + + +/* + * The state machine looks for (approximately) these Perl regular expressions: + * + * m|\/\*.*?\*\/| + * m|\/\/.*| + * m|'.*?'| + * m|".*?"| + * m|#\s*include\s*"(.*?)"| + * m|#\s*include\s*<(.*?>"| + * + * About 98% of the CPU time is spent here, and most of that is in + * the 'start' paragraph. Because the current characters are + * in a register, the start loop usually eats 4 or 8 characters + * per memory read. The MAX4 and MIN4 tests dispose of most + * input characters with 1 or 2 comparisons. + */ +void state_machine(const char * map, const char * end) +{ + const char * next = map; + const char * map_dot; + unsigned long __buf = 0; + + for (;;) { +start: + GETNEXT +__start: + if (current > MAX4('/','\'','"','#')) goto start; + if (current < MIN4('/','\'','"','#')) goto start; + CASE('/', slash); + CASE('\'', squote); + CASE('"', dquote); + CASE('#', pound); + goto start; + +/* // */ +slash_slash: + GETNEXT + CASE('\n', start); + NOTCASE('\\', slash_slash); + GETNEXT + goto slash_slash; + +/* / */ +slash: + GETNEXT + CASE('/', slash_slash); + NOTCASE('*', __start); +slash_star_dot_star: + GETNEXT +__slash_star_dot_star: + NOTCASE('*', slash_star_dot_star); + GETNEXT + NOTCASE('/', __slash_star_dot_star); + goto start; + +/* '.*?' */ +squote: + GETNEXT + CASE('\'', start); + NOTCASE('\\', squote); + GETNEXT + goto squote; + +/* ".*?" */ +dquote: + GETNEXT + CASE('"', start); + NOTCASE('\\', dquote); + GETNEXT + goto dquote; + +/* #\s* */ +pound: + GETNEXT + CASE(' ', pound); + CASE('\t', pound); + CASE('i', pound_i); + goto __start; + +/* #\s*i */ +pound_i: + GETNEXT NOTCASE('n', __start); + GETNEXT NOTCASE('c', __start); + GETNEXT NOTCASE('l', __start); + GETNEXT NOTCASE('u', __start); + GETNEXT NOTCASE('d', __start); + GETNEXT NOTCASE('e', __start); + goto pound_include; + +/* #\s*include\s* */ +pound_include: + GETNEXT + CASE(' ', pound_include); + CASE('\t', pound_include); + map_dot = next; + CASE('"', pound_include_dquote); + CASE('<', pound_include_langle); + goto __start; + +/* #\s*include\s*"(.*)" */ +pound_include_dquote: + GETNEXT + CASE('\n', start); + NOTCASE('"', pound_include_dquote); + handle_include(0, map_dot, next - map_dot - 1); + goto start; + +/* #\s*include\s*<(.*)> */ +pound_include_langle: + GETNEXT + CASE('\n', start); + NOTCASE('>', pound_include_langle); + handle_include(1, map_dot, next - map_dot - 1); + goto start; + } +} + + + +/* + * Generate dependencies for one file. + */ +void do_depend(const char * filename, const char * command) +{ + int mapsize; + int pagesizem1 = getpagesize()-1; + int fd; + struct stat st; + char * map; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr,"cannot open file: %s\n",filename); + return; + } + + fstat(fd, &st); + if (st.st_size == 0) { + fprintf(stderr,"%s is empty\n",filename); + close(fd); + return; + } + + mapsize = st.st_size; + mapsize = (mapsize+pagesizem1) & ~pagesizem1; + map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0); + if ((long) map == -1) { + fprintf(stderr,"mmap failed\n"); + close(fd); + return; + } + if ((unsigned long) map % sizeof(unsigned long) != 0) + { + fprintf(stderr, "do_depend: map not aligned\n"); + exit(1); + } + + hasdep = 0; + state_machine(map, map+st.st_size); + if (hasdep) { + puts(command); + if (*command) + define_precious(filename); + } + else + { + // Create empty target to avoid "no rule to create ..." when we delete/rename a file: + printf("%s:\n", filename); + } + + munmap(map, mapsize); + close(fd); +} + + + +/* + * Generate dependencies for all files. + */ +int main(int argc, char **argv) +{ + int len; + add_path("."); /* for #include "..." */ + while (++argv, --argc > 0) { + if (strncmp(*argv, "-I", 2) == 0) { + if (*((*argv)+2) ) { + add_path((*argv)+2); + } + else { + ++argv; + --argc; + } + } + else if (strcmp(*argv, "--") == 0) { + break; + } + } + + while (--argc > 0) { + const char * filename = *++argv; +#if TOC_MODE + const char * command = ""; +#else + const char * command = __depname; +#endif + g_filename = 0; + len = strlen(filename); + memcpy(depname, filename, len+1); + if (len > 2 && filename[len-2] == '.') { + if (filename[len-1] == 'c' || + filename[len-1] == 'S' || + filename[len-1] == 'C') { + depname[len-1] = 'o'; + g_filename = filename; + command = ""; + } + } + else if (len > 3 && filename[len-3] == '.') { + if (filename[len-2] == 'c' && filename[len-1] == 'c') { + depname[len-2] = 'o'; + depname[len-1] = '\0'; + g_filename = filename; + command = ""; + } + } + else if (len > 4 && filename[len-4] == '.') { + if ( filename[len-3] == 'c' && // check for c++/cxx/cpp + ( + (filename[len-2] == '+' && filename[len-1] == '+') || + (filename[len-2] == 'x' && filename[len-1] == 'x') || + (filename[len-2] == 'p' && filename[len-1] == 'p') + ) + ) { + depname[len-3] = 'o'; + depname[len-2] = '\0'; + g_filename = filename; + command = ""; + } + } + do_depend(filename, command); + } + if (len_precious) { + *(str_precious+len_precious) = '\0'; + printf(".PRECIOUS:%s\n", str_precious); + } + return 0; +} diff --git a/toc2/bin/removeDupeArgs b/toc2/bin/removeDupeArgs new file mode 100644 index 00000000..d323c938 --- /dev/null +++ b/toc2/bin/removeDupeArgs @@ -0,0 +1,29 @@ +#!/usr/bin/perl + +# Expects a list of command-line arguments, from which it removes any +# duplicates after the first instance of any given entry. +# Intended to be used to clean up INCLUDES and LDADD-like entries. +# +# Example: +# $0 a b c b b c d e a +# would print: +# a b c d e + + +%cache = (); + +@args = (); +while( @ARGV ) { + $a = $ARGV[0]; + shift; + next if $cache{$a}; + $cache{$a} = 1; + push( @args, $a ); +} + +foreach $a (@args) { + print $a," "; +} +print "\n"; + + diff --git a/toc2/doc/Makefile b/toc2/doc/Makefile new file mode 100644 index 00000000..dfe116ee --- /dev/null +++ b/toc2/doc/Makefile @@ -0,0 +1,4 @@ +#!/usr/bin/make -f + +include toc2.make +package.dist_files += toc2-manual.odt diff --git a/toc2/doc/naming-conventions.txt b/toc2/doc/naming-conventions.txt new file mode 100644 index 00000000..64ab6c7f --- /dev/null +++ b/toc2/doc/naming-conventions.txt @@ -0,0 +1,41 @@ + +======================================================================== +Shell code: + + + functions: toc2_xxx + vars: TOC2_XXX + +======================================================================== +Makefile: + +All toc2-related vars start with 'toc2.'. Package-specific stuff +starts with 'package.'. + +e.g.: + + $(toc2.home) + $(package.name) + $(package.dist_files) + + +toc2 $(call)able funcs: + + $(toc2.call.xxx) + +binaries: + + $(toc2.bins.xxx) + +toc2 flags: + + $(toc2.flags.xxx) + +dirs: + + $(toc2.dirs.xxx) + +emoticons: + + $(toc.emoticons.xxx) + diff --git a/toc2/doc/toc2-manual.odt b/toc2/doc/toc2-manual.odt Binary files differnew file mode 100644 index 00000000..41c17309 --- /dev/null +++ b/toc2/doc/toc2-manual.odt diff --git a/toc2/doc/toc2.make b/toc2/doc/toc2.make new file mode 100644 index 00000000..e9571348 --- /dev/null +++ b/toc2/doc/toc2.make @@ -0,0 +1,149 @@ +#!/do/not/make +######################################################################## +# toc2.make.at: template makefile for toc2.make, a core concept of the +# toc2 build process. This is filtered at the end of the configure +# process. toc2.make must be included by your Makefiles, like so: +# +# include toc2.make +# +# Each makefile which does that will get a toc2.make created during +# the configure process. Each toc2.make is specific to that sub-dir +# (more specifically, each subdir at the same depth gets the same +# toc2.make). +# +# All of the "at-vars" in this file are expected to come in +# via the configure process, either from core tests or from +# the core itself. +# +# Ideally this file should be free of project-specific code: +# put that in $(toc2.top_srcdir)/toc2.$(package.name).make.at and +# in then $(toc2.top_srcdir)/configure.$(package.name) run: +# toc_test_require toc2_project_makefile +######################################################################## +default: all +all: +FORCE: ; @true + +######################################################################## +# $(package.name) and $(package.version) are the penultimate +# variables, holding the package name and version. They must not +# contain spaces, and some characters may confuse other tools. Most +# notable, a '+' in the name is likely to break the makedist tool. +package.version = 0.1.2 +package.name = cheese + +######################################################################## +# $(SHELL) must be BASH, but the path might be system-specific. +SHELL = /bin/bash +##### prefix and DESTDIR are for autotools 'make install' compatibility +prefix ?= /usr/local +DESTDIR ?= + +ifneq (,$(COMSPEC)) +$(warning Smells like Windows!) +toc2.flags.smells_like_windows := 1 +toc2.platform.file_extensions.dll = .DLL# maintenance reminder: this must stay upper-case! +toc2.platform.file_extensions.lib = .a# yes, use .a for cygwin +toc2.platform.file_extensions.exe = .EXE# maintenance reminder: this must stay upper-case! +else +toc2.flags.smells_like_windows := 0 +toc2.platform.file_extensions.dll = .so +toc2.platform.file_extensions.lib = .a +toc2.platform.file_extensions.exe =# no whitespace, please +endif + +toc2.files.makefile := $(word 1,$(MAKEFILE_LIST))# accommodate Makefile/GNUmakefile +$(toc2.files.makefile): + +######################################################################## +# $(toc2.flags.quiet) is used by some toc2 code to enable/disable +# verbose output. Set it to 1 to enable it, or any other value to +# disable it. +toc2.flags.quiet ?= $(if @TOC2_BUILD_QUIETLY@,@TOC2_BUILD_QUIETLY@,0) + +toc2.top_srcdir = ../.. + +##### include configure-created code: +toc2.makefile.config_vars = $(toc2.top_srcdir)/toc2.$(package.name).configure.make +$(toc2.makefile.config_vars):# created by configure process +include $(toc2.makefile.config_vars) + + +toc2.project_makefile = $(wildcard $(toc2.top_srcdir)/toc2.$(package.name).make) +toc2.project_makefile_at = $(wildcard $(toc2.top_srcdir)/toc2.$(package.name).make.at) + +toc2.home ?= /home/dgsiegel/projects/cheese/toc2 +# todo: check if this is under $(toc2.top_srcdir), so we can make this path relative. + +toc2.dirs.makefiles = $(toc2.home)/make +toc2.dirs.bin = $(toc2.home)/bin +toc2.dirs.sbin = $(toc2.home)/sbin +toc2.dirs.relative_to_top = toc2/doc +# e.g., in lib/foo, toc2.dirs.relative_to_top == lib/foo + +toc2.make = toc2.make +# deprecated TOP_toc2.make = $(toc2.top_srcdir)/$(toc2.make) + +##### some core utilities: +toc2.bins.awk = /bin/gawk +toc2.bins.perl = /usr/bin/perl +toc2.bins.sed = /bin/sed +toc2.bins.tar = /bin/tar +toc2.bins.gzip = /bin/gzip +toc2.bins.bzip = /bin/bzip2 +toc2.bins.zip = /usr/bin/zip +toc2.bins.ar = $(AR) +toc2.bins.installer = /home/dgsiegel/projects/cheese/toc2/bin/install-sh +toc2.bins.makedist = /home/dgsiegel/projects/cheese/toc2/bin/makedist + + +# The emoticons are now exported directly by toc2_core.sh to toc2.PACKAGE.configure.make: +# toc2.emoticons.okay=[1m:-)[m +# toc2.emoticons.warning=[1m:-O[m +# toc2.emoticons.error=[1m:-([m +# toc2.emoticons.grief=@TOC2_EMOTICON_GRIEF@ +# toc2.emoticons.wtf=@TOC2_EMOTICON_WTF@ + +toc2.clean_files += $(wildcard .toc2.* core *~) +toc2.distclean_files += $(toc2.make) + +ifeq (.,$(toc2.top_srcdir)) + toc2.distclean_files += \ + toc2.$(package.name).make \ + toc2.$(package.name).configure.make +endif + + +include $(toc2.dirs.makefiles)/toc2-functions-core.make +include $(toc2.dirs.makefiles)/toc2-subdirs.make +include $(toc2.dirs.makefiles)/toc2-cleanup.make +include $(toc2.dirs.makefiles)/toc2-install.make +include $(toc2.dirs.makefiles)/toc2-dist.make + +######################################################################## +# A kludge to get mkdep-toc2 deleted at a proper time... only if we're +# in the top-most dir and mkdep-toc2 exists... +# This code *should* be in toc2-c.make, but that file is not globally +# included. +toc2.bins.mkdep.c := $(wildcard $(toc2.home)/bin/mkdep-toc2.c) +toc2.bins.mkdep := $(if $(toc2.bins.mkdep.c),$(toc2.top_srcdir)/$(basename $(notdir $(toc2.bins.mkdep.c))),) +######################################################################## +# Set toc2.bins.mkdep.flags to whatever -I flags you want to use for +# $(toc2.bins.mkdep). Any non-I flags are ignored by mkdep. +toc2.bins.mkdep.flags += $(INCLUDES) $(CPPFLAGS) +ifeq (.,$(toc2.top_srcdir)) + .PHONY: distclean-mkdep-toc2 + distclean-mkdep-toc2: + @test "x." = "x$(toc2.top_srcdir)" -a \ + x != 'x$(toc2.bins.mkdep)' -a \ + -e "$(toc2.bins.mkdep)" || exit 0; \ + rm -f "$(toc2.bins.mkdep)" + distclean-.: distclean-mkdep-toc2 +endif + +######################################################################## +# finally, load the project-specific code: +ifneq (,$(toc2.project_makefile)) + include $(toc2.project_makefile) +endif + diff --git a/toc2/make/Makefile b/toc2/make/Makefile new file mode 100644 index 00000000..9f3d0c97 --- /dev/null +++ b/toc2/make/Makefile @@ -0,0 +1,6 @@ +#!/usr/bin/make -f +default: all +include toc2.make +package.dist_files += $(filter-out toc2.make,$(wildcard *.make *.at makerules.*)) + + diff --git a/toc2/make/c-bins.make b/toc2/make/c-bins.make new file mode 100644 index 00000000..eed7aa76 --- /dev/null +++ b/toc2/make/c-bins.make @@ -0,0 +1,60 @@ +#!/do/not/make +# ^^^ help out emacs, so it knows what edit mode i want. +# +# toc makefile snippet to link binaries +######################################################################## +# +# Usage: +# define these vars: +# c-bins.list = bin1 [bin2 ... binN] +# c-bins.LDADD (optional - list of libs to link to all c-bins.list) +# c-bins.OBJECTS (optional - list of .o files to link to all c-bins.list) +# +# For each FOO in c-bins, define: +# FOO.bin.OBJECTS = list of .o files for FOO +# FOO.bin.LDADD = optional arguments to pass to linker, e.g. -lstdc++ +# +# Reminder: when linking binaries which will use dlopen() at some point, you +# should add -rdynamic to the xxx.bin.LDADD flags. Without this, symbols won't be +# visible by dlsym(), and some types of global/ns-scope objects won't get +# initialized. +# +# Then include this file: +# +# include $(toc2.dirs.makefiles)/toc2-c-bins.make +# +# and add 'c-bins' somewhere in your dependencies, e.g.: +# +# all: c-bins +# +# This file depends on functions defined in toc2-c.make. +######################################################################## + +c-bins.makefile = $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) + +ifeq (,$(c-bins.list)) +$(error c-bins.list must be defined before including this file (read this file for the full docs)) +endif + +ifeq (1,$(toc2.flags.smells_like_windows)) + package.clean_files += $(wildcard *.exe.stackdump) +endif + +c-bins.DEPSFILE = .toc2.c-bins.make + +c-bins.RULES_GENERATOR = $(toc2.dirs.makefiles)/makerules.c-bins + +c-bins.COMMON_DEPS += $(toc.2.files.makefile) $(c-bins.makefile) $(c-bins.objects) +ifeq (1,$(toc2.flags.making_clean)) +$(c-bins.DEPSFILE): ; @true +else +$(c-bins.DEPSFILE): $(toc.2.files.makefile) $(c-bins.RULES_GENERATOR) $(c-bins.makefile) + @echo "Generating c-bins rules: $(c-bins.list)"; \ + $(call toc2.call.generate-rules,c-bins,$(c-bins.list)) > $@ +endif +# REMINDER: we MUST include the file, even if doing clean, so that the +# bins cleanup rules actually get performed. +-include $(c-bins.DEPSFILE) +deps: $(c-bins.DEPSFILE) +bins: +c-bins: bins diff --git a/toc2/make/c-dlls.make b/toc2/make/c-dlls.make new file mode 100644 index 00000000..584201c2 --- /dev/null +++ b/toc2/make/c-dlls.make @@ -0,0 +1,100 @@ +#!/do/not/make +# Links objects into a dynamically-linked library using $(CXX) +# (only tested with g++). +# +# Usage: +# +# c-dlls.list = foo +# c-dlls.OBJECTS = # optional list of .o files to link to all $(c-dlls.list) +# # optional: c-dlls.DO_INSTALL = 0# If you do NOT want INSTALL rules created for any +# of the $(c-dlls.list). Default = 1. +# foo.DLL.OBJECTS = list of object files to link to foo.so +# foo.DLL.LDADD = # optional libraries passed to linker (e.g., -lstdc++) +# foo.DLL.VERSION = # optional Major.Minor.Patch # e.g. "1.0.1" it MUST match this format, but +# need not be numeric. Default is no version number. +# foo.DLL.INSTALL_DEST = # optional installation path. Defaults to $(package.install.dlls.dest) +# foo.DLL.DO_INSTALL = 0 # optional: suppresses generation of installation rules. +# i.e., foo.so will not be installed. Default = $(c-dlls.DO_INSTALL) +# foo.DLL.SONAME = foo.so.NUMBER # optional: explicitely defines the -soname tag +# include $(toc2.dirs.makefiles)/toc2-c-dlls.make +# +# If foo.DLL.VERSION is not set then no version number is used, and the +# conventional "versioned symlinks" are not created. This is normally +# used when linking plugins, as opposed to full-fledged libraries. +# +# Run: +# all: c-dlls +# +# Effect: +# Creates foo.so, and optionally foo.so<version>, by linking +# $(foo.DLL.OBJECTS). It also sets up install/uninstall rules for +# handling the various version-number symlinks conventionally used +# to link mylib.so.1.2.3 to mylib.so. +######################################################################## + +ifeq ($(c-dlls.list),) + $(error c-dlls.list must be defined before including this file (read this file for the full docs)) +endif + +c-dlls.makefile := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) + +######################################################################## +# toc2-link-c-dll call()able function +# $1 = basename +# $2 = extra args for the linker +toc2-link-c-dll = { soname=$(1).so; wholename=$${soname}.$($(1).DLL.VERSION.MAJOR).$($(1).DLL.VERSION.MINOR).$($(1).DLL.VERSION.PATCH); \ + if test x = "x$($(1).DLL.SONAME)"; then stamp=$${soname}.$($(1).DLL.VERSION.MAJOR); \ + else stamp=$($(1).DLL.SONAME); fi; \ + test x = "x$($(1).DLL.VERSION.MAJOR)" && { wholename=$${soname}; stamp=$(1).so;}; \ + cmd="$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $${wholename} --export-dynamic -shared \ + -Wl,-soname=$${stamp} $($(1).DLL.OBJECTS) $(c-dlls.OBJECTS) $(c-dlls.LDADD) $($(1).DLL.LDADD) $(2)"; \ + if [[ x1 = x$(toc2.flags.quiet) ]]; then echo "Linking DLL [$(1)]..."; else echo $$cmd; fi; \ + $$cmd || exit; \ + test x = "x$($(1).DLL.VERSION.MAJOR)" || { \ + ln -fs $${wholename} $${soname}.$($(1).DLL.VERSION.MAJOR).$($(1).DLL.VERSION.MINOR); \ + ln -fs $${wholename} $${soname}.$($(1).DLL.VERSION.MAJOR); \ + ln -fs $${wholename} $${soname}; \ + }; \ + } +# symlinking methods: +# method 1: +# ln -fs $${wholename} $${soname}.$($(1).DLL.VERSION.MAJOR).$($(1).DLL.VERSION.MINOR); \ +# ln -fs $${soname}.$($(1).DLL.VERSION.MAJOR).$($(1).DLL.VERSION.MINOR) $${soname}.$($(1).DLL.VERSION.MAJOR); \ +# ln -fs $${soname}.$($(1).DLL.VERSION.MAJOR) $${soname}; \ +# method 1.5: +# link1=$${soname}.$($(1).DLL.VERSION.MAJOR).$($(1).DLL.VERSION.MINOR); ln -fs $${wholename} $$link1; \ +# link2=$${soname}.$($(1).DLL.VERSION.MAJOR); ln -fs $$link1 $$link2; \ +# link3=$${soname}; ln -fs $$link2 $$link3; \ +# method 2: +# ln -fs $${wholename} $${soname}.$($(1).DLL.VERSION.MAJOR).$($(1).DLL.VERSION.MINOR); \ +# ln -fs $${wholename} $${soname}.$($(1).DLL.VERSION.MAJOR); \ +# ln -fs $${wholename} $${soname}; \ + + +# for l in $${soname} \ +# $${soname}.$($(1).DLL.VERSION.MAJOR) \ +# $${soname}.$($(1).DLL.VERSION.MAJOR).$($(1).DLL.VERSION.MINOR) \ +# ; do \ +# ln -fs $${wholename} $$l; \ +# done; \ + +# c-dlls.SOFILES = $(patsubst %,%.so,$(c-dlls)) + +c-dlls.RULES_GENERATOR := $(toc2.dirs.makefiles)/makerules.c-dlls + +c-dlls.DEPSFILE := .toc2.c-dlls.make +ifneq (1,$(toc2.flags.making_clean)) +$(c-dlls.DEPSFILE): Makefile $(c-dlls.makefile) $(c-dlls.RULES_GENERATOR) + @echo "Generating c-dlls rules: $(c-dlls.list)"; \ + $(call toc2.call.generate-rules,c-dlls,$(c-dlls.list)) > $@ +else +$(c-dlls.DEPSFILE): ;@true +endif +# REMINDER: we MUST include the file, even if doing clean, so that the +# dll cleanup rules actually get performed. +-include $(c-dlls.DEPSFILE) +deps: $(c-dlls.DEPSFILE) + +# package.clean_files += $(c-dlls.SOFILES) $(wildcard $(patsubst %,%.*,$(c-dlls.SOFILES))) +c-dlls: libs + diff --git a/toc2/make/doxygen.make b/toc2/make/doxygen.make new file mode 100644 index 00000000..e00755b9 --- /dev/null +++ b/toc2/make/doxygen.make @@ -0,0 +1,97 @@ +#!/do/not/make +# a (big) snippet to build API docs using doxygen +# +# Edit the file Doxyfile template, Doxyfile.at, using +# @at-token@ conventions. +# +# Define: +# doxygen.inputs = list of dirs to recurse into for doxygen +# OPTIONAL: doxygen.predef = predfined C vars +# +# Sample: +# INCLUDES_DIRS = $(addprefix $(top_includesdir)/,lib1 otherlib) +# doxygen.predef = \ +# HAVE_CONFIG_H=1 +# doxygen.inputs = $(INCLUDES_DIRS) +# +# Of course your Doxyfile.at must have the appropriate @tokens@ in it, +# but the one shipped with this file is already set up for you. + +ifeq (,$(toc2.bins.doxygen)) + toc2.bins.doxygen := $(call toc2.call.find-program,doxygen) +endif + +ifeq (,$(toc2.bins.doxygen)) + $(error The variable toc2.bins.doxygen must be set before including this file.) +endif + +doxygen.doxyfile = Doxyfile +doxygen.dirs.out ?= html +doxygen.doxyfile.at = Doxyfile.at +doxygen.index = Doxygen-index.txt +package.dist_files += $(doxygen.doxyfile.at) $(doxygen.index) + +doxygen.install-dir.basename ?= doxygen-$(PACKAGE_NAME)-$(PACKAGE_VERSION) +docs: doxygen +install: install-doxygen + +doxygen.bins.dot := $(call toc2.call.find-program,dot) +ifeq (,$(doxygen.bins.dot)) + doxygen.use_dot := 0 +else + doxygen.use_dot ?= 0# dot significantly slows down the build +endif + +ifeq (1,$(doxygen.use_dot)) + doxygen.use_dot.text := YES +else + doxygen.use_dot.text := NO +endif + +doxygen.inputs ?= $(toc2.top_srcdir) +doxygen.flags.atparse ?= \ + DOXYGEN_INPUT="$(doxygen.index) $(doxygen.inputs)" +doxygen.flags.atparse += \ + top_srcdir="$(toc2.top_srcdir)" \ + PERL="$(toc2.bins.perl)" \ + PACKAGE_NAME="$(package.name)" \ + PACKAGE_VERSION="$(package.version)" \ + PREDEFINED="$(doxygen.predef)" \ + HTML_OUTPUT_DIR="$(doxygen.dirs.out)" \ + USE_DOT="$(doxygen.use_dot.text)" + +doxygen.makefile := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) +$(doxygen.makefile): +$(toc2.top_srcdir)/configure: +$(doxygen.doxyfile): $(doxygen.makefile) $(doxygen.doxyfile.at) $(toc2.files.makefile) $(toc2.top_srcdir)/configure + @$(call toc2.call.atparse-file,$(doxygen.doxyfile.at),$@, \ + $(doxygen.flags.atparse) \ + ) + +toc2.doxygen.clean_files = $(doxygen.doxyfile) $(doxygen.dirs.out) latex +$(call toc2.call.define-cleanup-set,toc2.doxygen) + +package.install.doxygen.dest = $(DESTDIR)$(package.install.docs.dest) + +doxygen: $(doxygen.dirs.out) +$(doxygen.dirs.out): clean-set-toc2.doxygen $(doxygen.doxyfile) + @echo "Running doxygen..."; \ + if [[ x0 != "x$(doxygen.use_dot)" ]]; then \ + echo "Warning: 'dot' is enabled, so this might take a while."; \ + fi + @$(toc2.bins.doxygen) + @echo "Doxygen HTML output is in '$(doxygen.dirs.out)'." +doxygen.finaldest = $(package.install.doxygen.dest)/$(doxygen.install-dir.basename) +install-doxygen: doxygen + @echo "Installing HTML docs to $(doxygen.finaldest)" + @test -d $(package.install.doxygen.dest) || exit 0; rm -fr $(package.install.doxygen.dest) + @mkdir -p $(package.install.doxygen.dest) + @cp -r $(doxygen.dirs.out) $(doxygen.finaldest) + +uninstall-doxygen: + @echo "Uninstalling doxgen-generated docs: $(doxygen.finaldest)" + @-test -d $(doxygen.finaldest) || exit 0; rm -fr $(doxygen.finaldest) + +uninstall: uninstall-doxygen + +# all: docs diff --git a/toc2/make/file-filters.make b/toc2/make/file-filters.make new file mode 100644 index 00000000..3c9041b3 --- /dev/null +++ b/toc2/make/file-filters.make @@ -0,0 +1,98 @@ +#!/do/not/make +# A toc snippet to provide generic file filtering support. (Originally +# written to filter a namespace name in some C++ code.) +# Depends on the script makerules.file-filters, plus some toc-related +# conventions. +# +# stephan@s11n.net, 1 Dec 2003 +# +# Usage: +# +# Define: +# file-filters = filterX filterY +# These are logical names for filter sets, and should be unique with a Makefile, +# especially, there should be no targets with the names in $(file-filters). +# +# either: +# file-filters.bin = /path/to/filter/app + args +# or: +# filterX.filter.bin = /path/to/filter/app + args (defaults to 'sed') +# +# filterX.filter.rules = -e 's|rules for your filter|...|' (FILTER_BIN must accept this +# as a command-line argument) +# +# filterX.filter.sources = list of input files, all of which must have some common prefix. +# +# filterX.filter.renameexpr = sed code to translate x.filter.sources to target filenames. Gets +# applied to each name in x.filter.sources. If this uses the $ pattern you must +# use $$ instead, e.g. s/$$/.out/. BE CAREFUL! +# +# filterX_FILTER_DEPS = optional list of extra deps. Automatically added are +# all input/control files used in creating the rules, including Makefile. +# +# +# Generated files: +# - are named .toc.file-filters.* +# - are added to $(CLEAN_FILES) +# - are not changed unless out-of-date, so they are dependencies-safe. +# - get their own target names. This may cause collisions with other targets, +# but presumably only one target is responsible for creating any given +# file. +# +# +######################################################################################### +# BUG WARNING: BUG WARNING: BUG WARNING: BUG WARNING: BUG WARNING: BUG WARNING: +# +# It works by creating intermediary makefiles (.toc.file-filters.*), so: +# +# When you remove/rename entries from file-filters (as your project changes) you +# will need to 'rm .toc.file-filters.*' in order to be able to run make again, as some +# pre-generated rules may become invalidated and generate now-bogus errors which will +# kill make before it can run any targets (e.g., clean). +# +######################################################################################### +# Sample usage: +# file-filters = namespace filter2 +# # optional: namespace.filter.bin = $(toc2.bins.perl) -p +# namespace.filter.rules = -e 's|PACKAGE_NAMESPACE|$(PACKAGE_NAMESPACE)|g' +# namespace.filter.sources = $(wildcard src/*.cpp src/*.h) +# namespace.filter.renameexpr = s,src/,, +# ... similar for filter2.filter.xxx +# include $(toc2.dirs.makefiles)/file-filters.make +# +# That will filter src/*.{cpp,h} to ./*.{cpp,h}, replacing PACKAGE_NAMESPACE +# with $(PACKAGE_NAMESPACE) +# +# To process it, either: +# all: file-filters mytarget othertarget +# or: +# all: filter-namespace mytarget filter-filter2 othertarget +# or: +# all: mytarget othertarget +# +######################################################################################### + +file-filters.makefile := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) +$(file-filters.makefile): + +ifeq (,$(file-filters.list)) +$(error $(file-filters.makefile): you must define file-filters.list, plus some other vars, before including this file! Read the docs in this file) +endif + +file-filters.bin ?= $(toc2.bins.sed) + +file-filters.RULES_GENERATOR = $(dir $(file-filters.makefile))/makerules.file-filters +$(file-filters.RULES_GENERATOR): + +file-filters.incfile := .toc2.file-filters.make +# toc2.clean_files += $(file-filters.incfile) +$(file-filters.incfile): $(toc2.files.makefile) $(file-filters.RULES_GENERATOR) $(file-filters.makefile) +ifeq (1,$(toc2.flags.making_clean)) + @echo "$(MAKECMDGOALS): skipping file-filters rules generation." +else + @echo "Generating file-filters rules."; \ + $(call toc2.call.generate-rules,file-filters,$(file-filters.list)) > $@ +endif +-include $(file-filters.incfile) + +file-filters: diff --git a/toc2/make/makerules.c-bins b/toc2/make/makerules.c-bins new file mode 100644 index 00000000..295fd61d --- /dev/null +++ b/toc2/make/makerules.c-bins @@ -0,0 +1,35 @@ +#!/bin/sh +# creates some makefile code for the $(BIN_PROGRAMS) var + +test -z "$1" && { + echo "usage: $0 appone [apptwo ...]" + exit 1 +} +cat <<EOF +######################################################################## +# Auto-generated by $0 +# $(date) +c-bins.COMMON_DEPS += $0 +EOF +for t in $@; do + cat <<EOF +######################################################################## +# Start auto-generated rules for binary ${t}... +ifeq (,\$(${t}.BIN.OBJECTS)) + \$(error ${t}.BIN.OBJECTS must be set for the ${t}.BIN build rules!) +endif +ifeq (1,\$(toc2.flags.smells_like_windows)) + ${t}.BIN.LDADD += -lcygwin +endif +\$(${t}.BIN.OBJECTS): \$(c-bins.COMMON_DEPS) +${t}.BIN = ${t}\$(toc2.platform.file_extensions.exe) +\$(${t}.BIN): \$(${t}.BIN.OBJECTS) + @\$(call toc2.call.link-bin-o,\$@,\$(${t}.BIN.OBJECTS) \$(${t}.BIN.LDADD) \$(c-bins.LDADD) \$(c-bins.OBJECTS)) +package.clean_files += \$(${t}.BIN) + +${t}.BIN: \$(${t}.BIN) +bins: \$(${t}.BIN) +# end auto-generated rules for binary ${t} +######################################################################## +EOF +done diff --git a/toc2/make/makerules.c-dlls b/toc2/make/makerules.c-dlls new file mode 100644 index 00000000..c751fa2c --- /dev/null +++ b/toc2/make/makerules.c-dlls @@ -0,0 +1,73 @@ +#!/bin/sh +# creates some makefile code for the $(c-dlls) var +# Intended for use with toc2-c-dlls.make. + +# maintenance note: the non-versioned DLL case is not currently +# handled by the makefile code, so it's effectively a no-op here. + +test -z "$1" && { + echo "usage: $0 lib1 [lib2 ...]" + exit 1 +} + +cat <<! +######################################################################## +# Automatically generated by $0 +# $(date) +c-dlls.COMMON_DEPS = $0 \$(c-dlls.DEPSFILE) \$(c-dlls.OBJECTS) \$(c-dlls.makefile) \$(toc2.files.makefile) +c-dlls.DO_INSTALL ?= 1 +! + +for t in $@; do + sofile=$t'$(toc2.platform.file_extensions.dll)' +cat <<EOF +######################################################################## +# Start rules for DLL ${t} +ifneq (,\$(${t}.DLL.VERSION)) + ${t}.DLL.VERSION.MAJOR ?= \$(word 1,\$(subst ., ,\$(${t}.DLL.VERSION))) + ${t}.DLL.VERSION.MINOR ?= \$(word 2,\$(subst ., ,\$(${t}.DLL.VERSION))) + ${t}.DLL.VERSION.PATCH ?= \$(word 3,\$(subst ., ,\$(${t}.DLL.VERSION))) +endif + +${t}.DLL := ${sofile} +${t}.DLL.soname ?= \$(${t}.DLL.\$(${t}.DLL.VERSION.MAJOR)) +package.clean_files += \$(${t}.DLL) \$(wildcard \$(${t}.DLL).*) + +\$(${t}.DLL): \$(c-dlls.COMMON_DEPS) \$(${t}.DLL.OBJECTS) + @\$(call toc2-link-c-dll,${t}) +ifneq (.DLL,\$(toc2.platform.file_extensions.dll)) + ${t}.DLL: \$(${t}.DLL) +endif +${t}.DLL.DO_INSTALL ?= \$(c-dlls.DO_INSTALL) +${t}.DLL.INSTALL_DEST ?= \$(package.install.dlls.dest) + +ifeq (1,\$(${t}.DLL.DO_INSTALL)) +# ^^^ disable install if ${t}.DLL.DO_INSTALL is set to non-1 value + ifneq (,\$(${t}.DLL.VERSION)) + # ^^^ this DLL has a version number, so we need special rules for de/installation + install-so-\$(${t}.DLL): + @\$(call toc2.call.install-dll,\$(${t}.DLL),\$(${t}.DLL.VERSION.MAJOR),\$(${t}.DLL.VERSION.MINOR),\$(${t}.DLL.VERSION.PATCH),\$(${t}.DLL.INSTALL_DEST)) + + uninstall-so-\$(${t}.DLL): + @\$(call toc2.call.uninstall,\$(${t}.DLL) \$(${t}.DLL).\$(${t}.DLL.VERSION.MAJOR) \$(${t}.DLL).\$(${t}.DLL.VERSION.MAJOR).\$(${t}.DLL.VERSION.MINOR) \$(${t}.DLL).\$(${t}.DLL.VERSION.MAJOR).\$(${t}.DLL.VERSION.MINOR).\$(${t}.DLL.VERSION.PATCH),\$(${t}.DLL.INSTALL_DEST)) + else + # ^^^ non-versioned DLL... + install-so-\$(${t}.DLL): + @\$(call toc2.call.install,\$(${t}.DLL),\$(${t}.DLL.INSTALL_DEST),\$(package.install.dlls.install-flags)) + uninstall-so-\$(${t}.DLL): + @\$(call toc2.call.uninstall,\$(${t}.DLL),\$(${t}.DLL.INSTALL_DEST)) + endif + # ^^^ end versioned-or-non-versioned block + + install-dlls: install-so-\$(${t}.DLL) + uninstall-dlls: uninstall-so-\$(${t}.DLL) + +endif +# ^^^^ ${t}.DLL.DO_INSTALL + +libs: \$(${t}.DLL) + +# end rules for DLL ${t} +######################################################################## +EOF +done diff --git a/toc2/make/makerules.file-filters b/toc2/make/makerules.file-filters new file mode 100644 index 00000000..bb70dbb0 --- /dev/null +++ b/toc2/make/makerules.file-filters @@ -0,0 +1,101 @@ +#!/bin/bash +# creates makefile rules for use with file-filters.make + +# usage: $0 filtername [filtername2 ...] +# where filternameN is a filter defined in a client +# Makefile's $(file-filters.list) var. + +# This code, my friends, contains some mind-bending, completely +# unmaintainable shell-within-make-within-shell stuff. + +test -z "$@" && { + echo "usage: $0 filtername [filtername2 ...]" + exit 1 +} + +thisapp="\$(toc2.dirs.makefiles)/makerules.file-filters" +filters_makefile="\$(toc2.dirs.makefiles)/file-filters.make" + +cat <<EOF +############################## file-filters rules: +${thisapp}: ; @true +${filters_makefile}: ; @true +file-filters.TMPFILE = .toc2.file-filters.tmp +EOF + +error_prefix="${filters_makefile}:" + +for f in $@; do +fprefix=${f}.filter. +cat <<EOF +############################## file-filters: ${f} +${f}.filter.deps += \$(toc2.files.makefile) ${thisapp} ${filters_makefile} +${f}.filter.bin ?= \$(file-filters.bin) + +ifeq (,\$(${f}.filter.renameexpr)) +\$(error ${error_prefix} ${f}.filter.renameexpr must be set to a sed expression. e.g. s/^prefix//) +endif +ifeq (,\$(${f}.filter.sources)) +\$(error ${error_prefix} ${f}.filter.sources must be set to a list of input source files) +endif +ifeq (,\$(${f}.filter.bin)) +\$(error ${error_prefix} ${f}.filter.bin must be set to filter application. e.g. perl or sed) +endif +ifeq (,\$(${f}.filter.rules)) +\$(error ${error_prefix} ${f}.filter.rules must be a set of rules passable to ${f}.filter.bin. e.g. for perl: -e 's|\btoken\b|replacement|g') +endif + +${fprefix}MAKEFILE = .toc2.file-filters.${f}.make +# ${fprefix}clean_files += \$(${fprefix}MAKEFILE) + +\$(${fprefix}MAKEFILE): \$(file-filters.makefile) +ifeq (1,\$(toc2.flags.making_clean)) + @echo "\$(MAKECMDGOALS): skipping ${f}.filter.sources rules generation." +else + @echo "Generating ${f}.filter.sources rules."; \\ + for i in \$(${f}.filter.sources); do \\ + tgt="\$\$(echo \$\${i} | sed -e '\$(${f}.filter.renameexpr)')"; \\ + test "\$\$tgt" = "\$\${i}" -o -z "\$\$tgt" && { \\ + echo "${f}.filter.sources: name translation for the output file failed: sed rule [\$(${f}.filter.renameexpr)] for [\$\${i}] --> [\$\${tgt}]" 1>&2; \\ + exit 1; \\ + }; \\ + echo "${fprefix}clean_files += \$\${tgt}"; \\ + echo "\$\${tgt}_INPUT = \$\${i}"; \\ + echo "${fprefix}output.rules += \$\${tgt}"; \\ + echo "\$\${tgt}: \$\${i} \$(${f}.filter.deps)"; \\ + done > \$@ +endif +-include \$(${fprefix}MAKEFILE) +# This suddenly strikes me as odd: writing shell code to generate makefile code which will end +# generating makefile code which we then re-import into make. +# Thus all the confusion regarding the \ and $ characters. + +\$(${fprefix}output.rules): %:\$(%_INPUT)#<--- i can't believe this works! + @echo -n "file-filters '${f}': "; \\ + \$(${f}.filter.bin) \$(${f}.filter.rules) < \$(\$(*)_INPUT) > \$(file-filters.TMPFILE); \\ + cmp -s \$(file-filters.TMPFILE) \$@ && rm \$(file-filters.TMPFILE); \\ + test -f \$(file-filters.TMPFILE) \\ + && { mv \$(file-filters.TMPFILE) \$@; echo "[updated] \$@"; } \\ + || { echo "[up to date] \$@"; }; +# Note: the above target will always run if some non-input-file +# dependency is newer. That happens, for example, as i edit this shell +# script ;). Since i am a big advocate of "better rebuild than wonder +# if we're building the newest code", we're limited to two choices: +# +# a) touch $@, engendering immediate always-rebuild behaviour +# on files which depend on our output files. +# b) do nothing, and *potentially* get always-rebuild behaviour. +# +# Since only build tree maintainers should actually trigger this case, +# i've decided on taking route (b). Clients who actually see this +# happen can fix it with a 'make clean' or simply removing the +# filtered files in question and allowing them to be recreated. + +filter-${f}: \$(${fprefix}output.rules) + +\$(call toc2.call.define-cleanup-set,${f}.filter) +file-filters: filter-${f} + +EOF + +done diff --git a/toc2/make/scratchpad.make b/toc2/make/scratchpad.make new file mode 100644 index 00000000..057865c5 --- /dev/null +++ b/toc2/make/scratchpad.make @@ -0,0 +1,41 @@ +#!/do/not/make + +$(error do not include this file! It is a placeholder/scratchpad!) + +######################################################################## +# $(call toc2.call.prepare-c-deps[,source_file_list]) +# [$1] = a single C/C++ source file, defaults to a wildcard search +# For each file F in $1, F.d is created, "-include"d, and added to +# toc2.clean_files. +# If MAKECMDGOALS contains 'clean' then the deps are not generated. +# If $(toc2.bins.mkdep) is empty then this function is a no-op. +# +# Maintenance reminder: Unfortunately we can't mix 'if' and 'define' +# blocks, so we do a bit of ugly work in the $(1).d target here. +# +# $(call toc2.eval.prepare-c-deps-impl,source_file) is the internal +# implementation of toc2.call.prepare-c-deps, and should NOT be called +# by client code. $1=a SINGLE C/C++ file name. +define toc2.eval.prepare-c-deps-impl + $(1): + $(basename $(1)).o: $(1).d + $(1).d: $(1) $(toc2.bins.mkdep) + @$(if $(toc2.bins.mkdep),\ + $(if $(filter clean,$(MAKECMDGOALS)),@true,\ + $(toc2.bins.mkdep) $(toc2.bins.mkdep.flags) -- $(1) > $$@),); \ + echo '$$$$(warning DEPENDENCIES: including $$@)' >> $$@ + toc2.clean_files += $(1).d + $(eval -include $(1).d) +endef +define toc2.call.prepare-c-deps + $(foreach SRC,\ + $(if $(1),$(1),$(wildcard *.cpp *.c *.c++ *.C)),\ + $(eval $(call toc2.eval.prepare-c-deps-impl,$(SRC)))) +endef + +#define toc2.call.rule.c-deps +#%$(1).d: %$(1) +# $(toc2.bins.mkdep.rule-c) +##toc2.clean_files += *$(1).d +#endef +#$(foreach EXT,.c .cpp .c++,$(eval $(call toc2.call.rule.c-deps))) diff --git a/toc2/make/symlink-files.make b/toc2/make/symlink-files.make new file mode 100644 index 00000000..6de21a0f --- /dev/null +++ b/toc2/make/symlink-files.make @@ -0,0 +1,31 @@ +#!/do/not/make +# +# snippet to symlink files to a common dir. +# +# Usage: +# symlink-files.list = $(wildcard *.h) +# symlink-files.dest = $(top_srcdir)/include/whereever +# include /path/to/symlink-files.make +# run: +# all: symlink-files.list +# +# The symlinks are cleaned up during clean/distclean. + +ifeq (,$(symlink-files.list)) +$(error You must define symlink-files.list before including this makefile.) +endif +ifeq (,$(symlink-files.dest)) +$(error You must define both symlink-files.dest before including this makefile.) +endif + +symlink-files.makefile := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) + +symlink-files: FORCE + @$(call toc2.call.install-symlink,$(symlink-files.list),$(symlink-files.dest),-m 0644) +symlink-files.list: symlink-files +symlink-files-clean: FORCE + @echo "Cleaning symlinks." + @-touch foo.cleanlocal; rm foo.cleanlocal $(wildcard $(addprefix $(symlink-files.dest)/,$(symlink-files.list))) + +clean-.: symlink-files-clean +distclean-.: symlink-files-clean diff --git a/toc2/make/toc2-c.make b/toc2/make/toc2-c.make new file mode 100644 index 00000000..9af68f64 --- /dev/null +++ b/toc2/make/toc2-c.make @@ -0,0 +1,222 @@ +#!/do/not/make +######################################################################## +# This file contains C/C++-related functions for the toc2 framework. + +toc2.makefile.c := $(word $(words MAKEFILE_LIST),$(MAKEFILE_LIST)) +$(toc2.makefile.c): + +toc2.clean_files += *.o + +######################################################################## +# If $(toc2.bins.mkdep.c) exists then assume we want to use it to create +# deps info for C/C++ stuff... +ifneq (,$(toc2.bins.mkdep.c)) + toc2.bins.mkdep := $(toc2.top_srcdir)/$(basename $(notdir $(toc2.bins.mkdep.c))) + $(toc2.bins.mkdep.c): + $(toc2.bins.mkdep): $(toc2.bins.mkdep.c) + $(CC) -o $@ $< +else + toc2.bins.mkdep :=# no C/C++ deps support +endif + + + +######################################################################## +# $(call toc2.bins.mkdep,input_files,dest_file) resolves to 'true' +# during the 'clean' target else it resolves to a command for +# generating deps file dest_file from input_files. +ifneq (,$(toc2.bins.mkdep)) + define toc2.bins.mkdep.rule-c + $(if $(filter clean,$(MAKECMDGOALS)),true,\ + $(toc2.bins.mkdep) $(toc2.bins.mkdep.flags) -- $(2) > $(1); \ + echo '$(1): $(2)' >> $(1); echo '$(1):' >> $(1)) + endef +else + toc2.bins.mkdep.rule-c := true +endif + + +######################################################################## +# $(call toc2.call.compile-o-c,dest_obj,source(s)) +# Compiles one or more C files to a .o file. +# $1 = destination .o file +# $2 = source c file(s) +# If you want to pass object-specific flags to this compile then create +# an empty target like this: +# my.o: CFLAGS+=... +# Unfortunately, make does not allow you to pass more than one +# target-specific variable. +# Alternately, define $(1).CFLAGS = ... +define toc2.call.compile-o-c + @$(call toc2.bins.mkdep.rule-c,$(1).d,$(2)) + @$(call toc2.call.setx-unless-quiet,"COMPILE C [$(2)] ..."); \ + $(COMPILE.c) $(INCLUDES) -o $(1) $(2) +endef +%.o: %.c $(toc2.bins.mkdep) + @$(call toc2.call.compile-o-c,$@,$<) + +######################################################################## +# $(call toc2.call.compile-o-c++,dest_obj,source(s)) +# Compiles one or more C++ files to a .o file. +# $1 = destination .o file +# $2 = source c++ file(s) +# If you want to pass object-specific flags to this compile then create +# an empty target like this: +# my.o: CXXFLAGS+=... +# Unfortunately, make does not allow you to pass more than one +# target-specific variable per target, but you can pass multiples +# by making multiple empty targets: +# my.o: CXXFLAGS+=-DFOO=1 +# my.o: CXXFLAGS+=-DBAR=2 +# Alternately, define $(1).CXXFLAGS = ... +define toc2.call.compile-o-c++ + @$(call toc2.bins.mkdep.rule-c,$(1).d,$(2)) + @$(call toc2.call.setx-unless-quiet,"COMPILE C++ [$(2)] ..."); \ + $(COMPILE.cpp) $(INCLUDES) -o $(1) $(2) +endef +######################################################################## +# Uses toc3.call.compile-o-c++ to compile $@ from $<. +%.o: %.cpp $(toc2.bins.mkdep) $(toc2.makefile.c) + @$(call toc2.call.compile-o-c++,$@,$<) +######################################################################## +# Uses toc3.call.compile-o-c++ to compile $@ from $<. +%.o: %.c++ $(toc2.bins.mkdep) $(toc2.makefile.c) + @$(call toc2.call.compile-o-c++,$@,$<) +toc2.clean_files += *.d# i hate this wildcard here, but i don't see a way around it right now +toc2.bins.mkdep.dfiles := $(wildcard *.d) +$(if $(toc2.bins.mkdep.dfiles),$(eval include $(toc2.bins.mkdep.dfiles)),) + +######################################################################## +# $(call toc2.call.link-bin-o,dest_bin,source_objects) +# Links binary $(1) from $(2). +# $1 = destination binary +# $2 = source object file(s) +# To pass binary-specific linker flags, do: +# $(1): LDFLAGS+=... +define toc2.call.link-bin-o + $(call toc2.call.setx-unless-quiet,"LINK [$(1)] ..."); \ + $(LINK.cpp) $(LDFLAGS) -o $(1) $(2) +endef +# WTF does LINK.xx contain the CFLAGS/CPPFLAGS/CXXFLAGS??? +######################################################################## +# Uses toc2.call.link-bin-o to link $@ from $<. +%: %.o $(toc2.makefile.c) + @$(call toc2.call.link-bin-o,$@,$<) + + +######################################################################## +# toc2.eval.rules.c-bin is intended to be called like so: +# $(eval $(call toc2.eval.rules.c-bin,MyApp)) +# +# It builds a binary named $(1) by running $(CXX) and passing it: +# +# INCLUDES, $(1).BIN.INCLUDES +# CFLAGS, $(1).BIN.CFLAGS +# CXXFLAGS, $(1).BIN.CXXFLAGS +# CPPFLAGS, $(1).BIN.CPPFLAGS +# LDFLAGS, $(1).BIN.LDADD +# $(1).BIN.OBJECTS $(1).BIN.SOURCES +# +# Note that we have to pass both CFLAGS and CPPFLAGS because .SOURCES might +# contain either of C or C++ files. +define toc2.eval.rules.c-bin +$(1).BIN := $(1)$(toc2.platform.file_extensions.exe) +$(1).BIN: $$($(1).BIN) +# Many developers feel that bins should not be cleaned by 'make +# clean', but instead by distclean, but i'm not one of those +# developers. i subscribe more to the school of thought that distclean +# is for cleaning up configure-created files. +# As always: hack it to suit your preference: +package.clean_files += $$($(1).BIN) +$$($(1).BIN): CFLAGS+=$$($(1).BIN.CFLAGS) +$$($(1).BIN): CPPFLAGS+=$$($(1).BIN.CPPFLAGS) +$$($(1).BIN): CXXFLAGS+=$$($(1).BIN.CXXFLAGS) +$$($(1).BIN): INCLUDES+=$$($(1).BIN.INCLUDES) +$$($(1).BIN): LDFLAGS+=$$($(1).BIN.LDADD) +$$($(1).BIN): $$($(1).BIN.SOURCES) $$($(1).BIN.OBJECTS) $(toc2.bins.mkdep) $(toc2.makefile.c) + @test x = "x$$($(1).BIN.OBJECTS)$$($(1).BIN.SOURCES)" && { \ + echo "toc2.eval.rules.c-bin: $$@.bin: $(1).BIN.OBJECTS and/or $(1).BIN.SOURCES is undefined!"; \ + exit 1; }; true + @test x != 'x$$($(1).BIN.SOURCES)' && {\ + $(call toc2.bins.mkdep.rule-c,$$(@).d,$$($(1).BIN.SOURCES)); }; true + @$(call toc2.call.setx-unless-quiet,"CXX [$$@] ..."); \ + $$(CXX) -o $$@ \ + $$(INCLUDES) \ + $$(CFLAGS) \ + $$(CXXFLAGS) \ + $$(CPPFLAGS) \ + $$(LDFLAGS) \ + $$($(1).BIN.OBJECTS) $$($(1).BIN.SOURCES) +bins: $$($(1).BIN) +endef +######################################################################## +# $(call toc2.call.rules.c-bin,[list]) calls and $(eval)s +# toc2.eval.rules.c-bin for each entry in $(1) +define toc2.call.rules.c-bin +$(foreach bin,$(1),$(eval $(call toc2.eval.rules.c-bin,$(bin)))) +endef +# end ShakeNMake.CALL.RULES.bin and friends +######################################################################## + + + +######################################################################## +# $(call toc2.eval.rules.dll,dll_basename) builds builds +# $(1)$(toc2.platform.file_extensions.dll) from object files defined by +# $(1).DLL.OBJECTS and $(1).DLL.SOURCES. Flags passed on to the linker +# include: +# +# LDFLAGS, $(1).DLL.LDADD, -shared -export-dynamic +# $(1).DLL.CPPFLAGS, $(1).DLL.OBJECTS, $(1).DLL.SOURCES +# +# Also defines the var $(1).dll, which expands to the filename of the DLL, +# (normally $(1)$(toc2.platform.file_extensions.dll)). +define toc2.eval.rules.c-dll +#$(if $($(1).DLL.OBJECTS)$($(1).DLL.SOURCES),,\ +# $(error toc2.eval.rules.c-dll $$(1)=$(1): either $(1).DLL.OBJECTS and/or $(1).DLL.SOURCES must be set.)) +$(1).DLL = $(1)$(toc2.platform.file_extensions.dll) +ifneq (.DLL,$(toc2.platform.file_extensions.dll)) +$(1).DLL: $$($(1).DLL) +endif +toc2.clean_files += $$($(1).DLL) +$$($(1).DLL): $$($(1).DLL.SOURCES) +$$($(1).DLL): $$($(1).DLL.OBJECTS) +$$($(1).DLL): $(toc2.bins.mkdep) $(toc2.makefile.c) + @test x = "x$$($(1).DLL.OBJECTS)$$($(1).DLL.SOURCES)" && { \ + echo "toc2.eval.rules.c-dll: $$@: $(1).DLL.OBJECTS and/or $(1).DLL.SOURCES are/is undefined!"; exit 1; }; \ + $(call toc2.call.setx-unless-quiet,"CXX [$$@] ..."); \ + $$(CXX) -o $$@ -shared -export-dynamic $$(LDFLAGS) \ + $$($(1).DLL.LDADD) $$($(1).DLL.OBJECTS) $$($(1).DLL.SOURCES) \ + $$($(1).DLL.CPPFLAGS) +endef +######################################################################## +# $(call toc2.call.rules.c-dll,basename_list) calls and $(eval)s +# toc2.eval.rules.c-dll for each entry in $(1) +define toc2.call.rules.c-dll +$(foreach dll,$(1),$(eval $(call toc2.eval.rules.c-dll,$(dll)))) +endef +# end toc2.call.rules.dll and friends +######################################################################## + + +######################################################################## +# $(call toc2.eval.rules.c-lib,libname) creates rules to build static +# library $(1)$(toc2.platform.file_extensions.lib) from +# $(1).LIB.OBJECTS. +define toc2.eval.rules.c-lib +$(1).LIB = $(1)$(toc2.platform.file_extensions.lib) +ifneq (.LIB,$(toc2.platform.file_extensions.lib)) + $(1).LIB: $$($(1).LIB) +endif +toc2.clean_files += $$($(1).LIB) +$$($(1).LIB): $$($(1).LIB.OBJECTS) $(toc2.makefile.c) + @test x = "x$$($(1).LIB.OBJECTS)" && { \ + echo "toc2.eval.rules.c-lib: $$@: $(1).LIB.OBJECTS is undefined!"; exit 1; }; true + @$(call toc2.call.setx-unless-quiet,"AR [$$@] ..."); \ + $$(toc2.bins.ar) crs $$@ $$($(1).LIB.OBJECTS) +endef +define toc2.call.rules.c-lib +$(foreach liba,$(1),$(eval $(call toc2.eval.rules.c-lib,$(liba)))) +endef +# end toc2.eval.rules.c-lib +######################################################################## diff --git a/toc2/make/toc2-cleanup.make b/toc2/make/toc2-cleanup.make new file mode 100644 index 00000000..ccc84cc8 --- /dev/null +++ b/toc2/make/toc2-cleanup.make @@ -0,0 +1,73 @@ +#!/do/not/make +######################################################################## +# cleanup-related rules for the toc2 framework. + +toc2.clean_files ?= +toc2.distclean_files ?= +package.clean_files ?= +package.distclean_files ?= + +ifneq (,$(strip $(filter distclean clean,$(MAKECMDGOALS)))) + toc2.flags.making_clean = 1 +else + toc2.flags.making_clean = 0 +endif + +###################################################################### +# $(call toc2.call.clean-files,file_list) +# +# Deletes all files/dirs passed in via $(1). BE CAREFUL, as all +# entries are UNCEREMONIOUSLY DELETED!!! +toc2.call.clean-files = \ + test "x$(strip $(1))" = "x" && exit 0; \ + if test x1 != 'x$(toc2.flags.quiet)'; then \ + deep=0; while [[ $$deep -lt $(MAKELEVEL) ]]; do echo -n " "; deep=$$((deep+1)); done; \ + echo "Cleaning up: [$(1)]"; \ + fi; \ + for x in $(1) ""; do test -z "$${x}" && continue; \ + test -w $$x || continue; \ + rmargs="-f"; test -d $$x && rmargs="-fr"; \ + rm $$rmargs $$x || exit; \ + done; \ + exit 0 + +######################################################################## +# $(eval $(call toc2.call.cleanup-template,clean|distclean,file_list)) +# For toc2 internal use only. +# $(1) should be one of 'clean' or 'distclean'. +# $(2) is a file/dir list. BE CAREFUL: all entries will be +# UNCEREMONIOUSLY DELETED when make $(1) is called! +define toc2.call.cleanup-template +.PHONY: $(1) $(1)-. +.PHONY: $(1)-subdirs +$(1)-subdirs: + @$$(call toc2.call.make-subdirs,$$(package.subdirs),$(1)) +$(1)-.: +$(1): $(1)-subdirs $(1)-. +# /$(1) +######################################################################## +endef +# Create clean: +$(eval $(call toc2.call.cleanup-template,clean)) +# Create distclean: +$(eval $(call toc2.call.cleanup-template,distclean)) + +######################################################################## +# $(call toc2.call.define-cleanup-set,SET_NAME) +# Adds target clean-set-SET_NAME as a prerequisite of clean-. and +# creates that target to clean up files defined in +# SET_NAME.clean_files. It does the same for distclean. +# This can be used to get around command-line length limitations when +# cleaning up large numbers of files by defining new cleanup sets. +define toc2.eval.define-cleanup-set + clean-set-$(1): + @$$(call toc2.call.clean-files,$$(wildcard $$($(1).clean_files))) + clean-.: clean-set-$(1) + distclean-set-$(1): + @$$(call toc2.call.clean-files,$$(wildcard $$($(1).distclean_files))) + distclean-.: clean-set-$(1) distclean-set-$(1) +endef +toc2.call.define-cleanup-set = $(eval $(call toc2.eval.define-cleanup-set,$(1))) + +$(call toc2.call.define-cleanup-set,toc2) +$(call toc2.call.define-cleanup-set,package) diff --git a/toc2/make/toc2-dist.make b/toc2/make/toc2-dist.make new file mode 100644 index 00000000..ab3c3ffa --- /dev/null +++ b/toc2/make/toc2-dist.make @@ -0,0 +1,139 @@ +#!/do/not/make +######################################################################## +# This file contains rules for the 'make dist' features of the toc2 +# framework. +# +# Maintenance notes: +# +# - Make dist is intended to be run only from the $(toc2.top_srcdir) +# directory. Starting the dist process from sub-dir will have +# undefined results. +# +# - The order that the dest: prerequisites are declared is very +# significant. Don't change these without a good reason. +# +# - The toc2-dist-print-package-dist-files stuff requires a sub-make +# so that we can properly expand all var refs and shell-style +# wildcards in $(package.dist_files). +######################################################################## + +package.dist_files += $(firstword $(MAKEFILE_LIST)) + +ifneq (dist,$(MAKECMDGOALS)) + toc2.flags.making_dist = 1 +else + toc2.flags.making_dist = 0 +endif + +toc2.dist.file_list = $(toc2.top_srcdir)/.toc2.package.dist_files +ifeq (.,$(toc2.top_srcdir)) + toc2.clean_files += $(wildcard $(toc2.dist.file_list)) +endif + +ifeq (,$(wildcard $(toc2.bins.makedist))) + $(error toc2.bins.makedist must be set to the path of the toc2 makedist app (normally $(toc2.home)/bin/makedist)) +endif + +ifeq (.,$(toc2.top_srcdir)) + toc2.dist.pre-cleanup: ; @-rm -f $(toc2.dist.file_list) + toc2.dist.post-cleanup: ; @-rm -f $(toc2.dist.file_list) + dist: toc2.dist.pre-cleanup + # .INTERMEDIATE and .DELETE_ON_ERROR don't seem to be doing what + # i think they should??? + .INTERMEDIATE: $(toc2.dist.file_list) + .DELETE_ON_ERROR: $(toc2.dist.file_list) +endif + + +######################################################################## +# internal target for parsing out package.dist_files entries... +toc2-dist-print-package-dist-files: + @echo $(sort $(package.dist_files)) + +dist-.: + @$(MAKE) --no-print-directory toc2-dist-print-package-dist-files \ + | perl -pe 's|(\S+) ?|./$(if $(toc2.dirs.relative_to_top),$(toc2.dirs.relative_to_top)/,)$$1\n|g' \ + | sed -e '/^$$/d' \ + >> $(toc2.dist.file_list) + + +$(toc2.dist.file_list): FORCE $(toc2.files.makefile) + test x = "x$(package.dist_files)" && exit 0; \ + pwd=$$(pwd); \ + echo "Adding package.dist_files to [$@]..."; \ + for f in "" $(package.dist_files); do test x = "x$$f" && continue; \ + echo $$pwd/$$f; \ + done >> $@ + +dist-postprocess:# implement this in client-side code if you want to do something +dist: subdirs-dist dist-. dist-postprocess + +ifeq (.,$(toc2.top_srcdir)) + ############################################################ + # create $(package.dist_name).tar + toc2.bins.md5sum := $(call toc2.call.find-program,md5sum) + package.dist_name ?= $(package.name)-$(package.version) + package.dist_tarball ?= $(package.dist_name).tar + toc2.clean_files += $(package.dist_tarball) + $(package.dist_tarball): FORCE + @echo -n "Making dist tarball [$(package.dist_tarball)] ... "; \ + $(toc2.bins.makedist) $(toc2.dist.file_list) $(package.dist_name) + @test x = 'x$(toc2.bins.md5sum)' && exit 0; \ + ''$(toc2.bins.md5sum) < $@ > $@.md5 + @echo "$(toc2.emoticons.okay)" + dist: $(package.dist_tarball) + toc2.clean_files += $(package.dist_tarball).md5 + + ############################################################ + # create $(package.dist_name).tar.gz + ifneq (,$(toc2.bins.gzip)) + package.dist_tarball_gz := $(package.dist_tarball).gz + toc2.clean_files += $(package.dist_tarball_gz) + $(package.dist_tarball_gz): $(package.dist_tarball) + @echo -n "Creating $@... "; \ + $(toc2.bins.gzip) -c $< > $@ || exit $$? + @test x = 'x$(toc2.bins.md5sum)' && exit 0; \ + ''$(toc2.bins.md5sum) < $@ > $@.md5 + @echo "$(toc2.emoticons.okay)" + dist: $(package.dist_tarball_gz) + toc2.clean_files += $(package.dist_tarball_gz).md5 + endif # gzip + + ############################################################ + # create $(package.dist_name).tar.bz2 + #ifneq (,$(toc2.bins.bzip)) + # package.dist_tarball_bz := $(package.dist_tarball).bz2 + # toc2.clean_files += $(package.dist_tarball_bz) + # $(package.dist_tarball_bz): $(package.dist_tarball) + #@echo -n "Creating $@... "; \ + # $(toc2.bins.bzip) -c $< > $@ || exit $$? + #@test x = 'x$(toc2.bins.md5sum)' && exit 0; \ + # ''$(toc2.bins.md5sum) < $@ > $@.md5 + #@echo "$(toc2.emoticons.okay)" + # dist: $(package.dist_tarball_bz) + # toc2.clean_files += $(package.dist_tarball_bz).md5 + #endif # bzip + + ############################################################ + # create $(package.dist_name).zip + #ifneq (,$(toc2.bins.zip)) + # package.dist_tarball_zip := $(package.dist_name).zip + # toc2.clean_files += $(package.dist_tarball_zip) + # $(package.dist_tarball_zip): $(package.dist_tarball) + #@echo -n "Creating $@... "; \ + # test -e $@ && rm -f $@; \ + # test -d $(package.dist_name) && rm -fr $(package.dist_name); \ + # tar xf $(package.dist_tarball); \ + # $(toc2.bins.zip) -qr $@ $(package.dist_name) || exit $$?; + #@rm -fr $(package.dist_name) + #@test x = 'x$(toc2.bins.md5sum)' && exit 0; \ + # ''$(toc2.bins.md5sum) < $@ > $@.md5 + #@echo "$(toc2.emoticons.okay)" + # dist: $(package.dist_tarball_zip) + # toc2.clean_files += $(package.dist_tarball_zip).md5 + #endif # zip + + toc2.dist.show-dist-tars: + @ls -la $(package.dist_name).* + dist: dist-postprocess toc2.dist.show-dist-tars toc2.dist.post-cleanup +endif # . == $(toc2.top_srcdir) diff --git a/toc2/make/toc2-functions-core.make b/toc2/make/toc2-functions-core.make new file mode 100644 index 00000000..360b1391 --- /dev/null +++ b/toc2/make/toc2-functions-core.make @@ -0,0 +1,115 @@ +#!/do/not/make +# ^^^ let's help out emacs :/ +######################################################################## +# This file contains more-or-less generic call()able Make functions +# for use with the toc2 framework. +######################################################################## + +######################################################################## +# $(call toc2.call.setx-unless-quiet,verbose string) +# An internal hack to enable "quiet" output. $(1) is a string which +# is shown ONLY if toc2.flags.quiet!=1 +define toc2.call.setx-unless-quiet +if [[ x1 = "x$(toc2.flags.quiet)" ]]; then echo $(1); else set -x; fi +endef +# Reminder: using set -x is not the same as doing echo $(1) because +# set -x normalizes backslashed newline, extra spaces, and other +# oddities of formatting. +######################################################################## + +###################################################################### +# toc2.call.atparse-file call()able: +# Similar to the toc2_atparse_file shell function of the same name, +# except for different arguments: Filters an input file using toc's +# at-parser (e.g., @TOKENS@), and sends output to $2. +# Args: +# $1 = input template +# $2 = output file +# $3 = list of properties, e.g. FOO=bar BAR=foo +toc2.bins.atparser = $(toc2.dirs.bin)/atsign_parse +$(toc2.bins.atparser): +ifeq (,$(wildcard $(toc2.bins.atparser))) +$(error Could not find toc2.bins.atparser at $(toc2.bins.atparser)!) +endif +toc2.call.atparse-file = \ + echo -n 'toc2.call.atparse-file: $(1) --> $(2)'; $(toc2.bins.atparser) $(3) < $(1) > $(2); echo + + +###################################################################### +# toc2.call.generate-rules() callable: +# $1 = rules name, e.g., INSTALL_XXX, BIN_PROGRAMS, etc. +# $2 = arguments to pass to makerules.$(1) +# Sample: +# .toc2.foo.deps: +# $(toc2.call.generate-rules,FOO,arg1=val1 -arg2) +# Executes script $(toc2.dirs.makefiles)/makerules.FOO, passing it $(2). +# That script is expected to generate Make code, which the caller can +# then include. This workaround was made for cases where $(eval) isn't +# desired. (Originally it was a partial substitute for a missing +# $(eval) when using Make < 3.80, but toc2 explicitly requires 3.80+.) +toc2.call.generate-rules = $(SHELL) $(toc2.dirs.makefiles)/makerules.$(1) $(2) +# the $(SHELL) prefix here is a kludge: systems where /bin/sh is Bourne +# fail to build, but the nature of the errors makes it quite difficult +# to track down where the failure is. The side-effect of this kludge +# is that makerules.FOO *must* be a shell script (as opposed to a Perl +# script or whatever). :/ +######################################################################## + + +######################################################################## +# $(call toc2.call.remove-dupes,list) +# Returns a string equal to list with duplicate entries removed. It does +# not sort the list. +# Implementation code by Christoph Schulz +toc2.call.remove-dupes = $(if $1,$(strip $(word 1,$1) $(call $0,$(filter-out $(word 1,$1),$1)))) + + +######################################################################## +# $(call toc2.call.find-files,wildcard-pattern,path) +# Returns a string containing ALL files or dirs in the given path +# which match the wildcard pattern. The path may be colon- or +# space-delimited. Spaces in path elements or filenames is of +# course evil and will Cause Grief. If either $1 or $2 are empty +# then $(error) is called. +toc2.call.find-files = $(wildcard \ + $(addsuffix /$(if $1,$1,$(error toc2.call.find-files requires a wildcard argument for $$1)), \ + $(subst :, , \ + $(subst ::,:.:, \ + $(patsubst :%,.:%, \ + $(patsubst %:,%:.,$(if $2,$2,$(error toc2.call.find-files ($$1=$1) requires a PATH as arg $$2)))))))) +######################################################################## +# $(call toc2.call.find-programs,wildcard[,path]) +# Returns a list of ALL files/dirs matching the given wildcard in the +# given path (default=$(PATH)). +toc2.call.find-programs = $(call toc2.call.find-files,$1,$(if $2,$2,$(PATH))) +######################################################################## +# $(call toc2.call.find-file,wildcard-pattern,path) +# Returns a string containing the FIRST file in the given path +# which matches the wildcard pattern. If the path is empty or not +# given then $(error) is called. +toc2.call.find-file = $(firstword $(call toc2.call.find-files,$1,$2)) +######################################################################## +# $(call toc2.call.find-program,wildcard[,path]) +# Returns the FIRST file/dir matching the given wildcard in the given +# path (default=$(PATH)). +toc2.call.find-program = $(firstword $(call toc2.call.find-programs,$1,$2)) + +######################################################################## +# $(call toc2.call.include,makefile-base-name) +# This is essentially the same as: +# include $(toc2.dirs.makefiles)/makefile-base-name.make +# but this is arguably more maintainable. +toc2.call.include = $(eval include $(toc2.dirs.makefiles)/$(1).make) +toc2.call.-include = $(eval -include $(toc2.dirs.makefiles)/$(1).make) + +######################################################################## +# A simple help facility, taken from "Managing Projects with GNU Make, +# Third Edition": +.PHONY: list-targets +list-targets-noop:# don't ask +list-targets: + @$(MAKE) --print-data-base --question list-targets-noop | \ + grep -v -e '^no-such-target' -e '^makefile' | \ + awk '/^[^.%][-A-Za-z0-9_]*:/{ print substr($$1, 1, length($$1)-1) }' | \ + sort | \ + pr --omit-pagination --columns=2 diff --git a/toc2/make/toc2-install.make b/toc2/make/toc2-install.make new file mode 100644 index 00000000..ab07c332 --- /dev/null +++ b/toc2/make/toc2-install.make @@ -0,0 +1,207 @@ +#!/do/not/make +######################################################################## +# A toc2 subsystem for creation of installation sets... +# +# these rules only work with GNU Make 3.80 and higher... +# +# To be included from the shared toc makefile. It uses +# $(toc2.home)/bin/install-sh to perform the installation but could +# easily be adapted to use an arbitrary installer. +# +# Sample usage: +# package.install.bins = mybin myotherbin # installs to $(prefix)/bin +# package.install.libs = mylib.a myotherlib.a # installs to $(prefix)/lib +# +# There's a whole lot more to know, if you wanna poke around the code. +# +# Design note: the traditional xxx-local targets aren't really +# necessary. If someone wants to customize install they can simply do +# this: +# +# install: my-install +# my-install: +# .... +# +# For each X in $(toc2.install.target_basenames) the following targets +# are created: +# +# install-X: +# uninstall-X: +# install-X-symlink: +# +# Files will be installed to $(package.install.X.dest) using install +# arguments $(package.install.X.install-flags). All of these vars are +# set up by default, but may be customized: +# +# package.install.bins.dest = $(prefix)/$(package.name)/bin +# package.install.bins.install-flags = -m 0755 +# +# Installation can be further customized by using $(call toc2.call.install...) +# and the related functions. + +ifeq (,$(wildcard $(toc2.bins.installer))) + toc2.bins.installer := $(call toc2.call.find-program,install-sh,$(toc2.home)/bin) +endif + +ifeq (,$(wildcard $(toc2.bins.installer))) +$(error install.make requires that the variable toc2.bins.installer be set. Try $(toc2.home)/bin/install-sh.) +endif + + +######################################################################## +# $(call toc2.call.install.grep_kludge,file_name) +# This is an ancient kludge force [un]install to silently fail without an +# error when passed an empty file lists. This was done because saner +# approaches to checking this failed to work on some older machines. +toc2.call.install.grep_kludge = echo $(1) "" | grep -q '[a-zA-Z0-9]' || exit 0 + +######################################################################## +# $(call toc2.call.install,file_list,destdir[,install-sh-flags]) +# Installs files $(1) to $(DESTDIR)$(2). $(3) is passed on to +# $(toc2.bins.installer). +toc2.call.install = $(call toc2.call.install.grep_kludge,$(1)); \ + tgtdir="$(DESTDIR)$(2)"; \ + test -d "$$tgtdir" || mkdir -p "$${tgtdir}" \ + || { err=$$?; echo "$(@): mkdir -p $${tgtdir} failed"; exit $$err; }; \ + for b in $(1) ""; do test -z "$$b" && continue; \ + b=$$(basename $$b); \ + target="$${tgtdir}/$$b"; \ + cmp "$$target" "$$b" > /dev/null 2>&1 && continue; \ + cmd="$(toc2.bins.installer) $(3) $$b $$target"; echo $$cmd; $$cmd || exit; \ + done + +######################################################################## +# $(call toc2.call.uninstall,file_list,source_dir) +# removes all files listed in $(1) from target directory $(DESTDIR)$(2). +# +# Maintenance reminder: +# The while/rmdir loop is there to clean up empty dirs left over by +# the uninstall. This is very arguable but seems more or less +# reasonable. The loop takes care to stop when it reaches $(DESTDIR), +# since DESTDIR is presumably (but not necessarily) created by another +# authority. +toc2.call.uninstall = $(call toc2.call.install.grep_kludge,$(1)); \ + tgtdir="$(DESTDIR)$(2)"; \ + test -e "$${tgtdir}" || exit 0; \ + for b in $(1) ""; do test -z "$$b" && continue; \ + fp="$${tgtdir}/$$b"; test -e "$$fp" || continue; \ + cmd="rm $$fp"; echo $$cmd; $$cmd || exit $$?; \ + done; \ + tgtdir="$(2)"; \ + while test x != "x$${tgtdir}" -a '/' != "$${tgtdir}" -a -d "$(DESTDIR)$${tgtdir}"; do \ + rmdir $(DESTDIR)$${tgtdir} 2>/dev/null || break; \ + echo "Removing empty dir: $(DESTDIR)$${tgtdir}"; \ + tgtdir=$${tgtdir%/*}; \ + done; true + +# toc2.call.install-symlink call()able: +# works similarly to toc2.call.install, but symlinks back to the install source, +# instead of copying. Arg $3 is ignored. +# Note that symlinks must be linked to absolute paths here, because we cannot +# easily/reliably make a relative path from the target directory back to +# the install source: +toc2.call.install-symlink = $(call toc2.call.install.grep_kludge,$(1)); \ + test -d $(2) || mkdir -p "$(2)" || \ + { err=$$?; echo "$(@): mkdir -p $(2) failed"; exit $$err; }; \ + for b in $(1) ""; do test -z "$$b" && continue; \ + target=$(2)/$$b; \ + test $$target -ef $$b && continue; \ + echo "Symlinking $$target"; ln -s -f $$PWD/$$b $$target || exit $$?; \ + done + +######################################################################## +# toc2.call.install-dll: installs foo.so.X.Y.Z and symlinks foo.so, +# foo.so.X and foo.so.Y to it, in traditional/common Unix style. +# $1 = so name (foo.so) +# $2-4 = Major, Minor, Patch version numbers +# $5 = destination directory +toc2.call.install-dll = $(call toc2.call.install.grep_kludge,$(1)); \ + test -d $(5) || mkdir -p $(5) || exit; \ + wholename=$(1).$(2).$(3).$(4); \ + target=$(5)/$$wholename; \ + test $$wholename -ef $$target || { \ + echo "Installing/symlinking $$target"; \ + cmd="$(toc2.bins.installer) -s $$wholename $$target"; \ + $$cmd || exit $$?; \ + }; \ + cd $(5); \ + for i in $(1) $(1).$(2) $(1).$(2).$(3); do \ + test -e $$i && rm -f $$i; \ + cmd="ln -fs $$wholename $$i"; echo $$cmd; \ + $$cmd || exit $$?; \ + done +## symlinking method number 2: +## { set -x; \ +## ln -fs $(1).$(2).$(3).$(4) $(1).$(2).$(3); \ +## ln -fs $(1).$(2).$(3) $(1).$(2); \ +## ln -fs $(1).$(2) $(1); \ +## } + +toc2.install.flags.nonbins = -m 0644 +toc2.install.flags.bins = -s -m 0755 +toc2.install.flags.bin-scripts = -m 0755 +toc2.install.flags.dlls = -m 0755 + +install: subdirs-install +uninstall: subdirs-uninstall +install-symlink: subdirs-install-symlink + +.PHONY: install-subdirs +install-subdirs: subdirs-install +.PHONY: install-subdirs-symlink +install-subdirs-symlink: subdirs-install-symlink +.PHONY: uninstall-subdirs +uninstall-subdirs: subdirs-uninstall + +######################################################################## +# $(eval $(call toc2.call.setup_install_rules,SET_NAME,dest_dir,install_flags)) +define toc2.call.setup_install_rules +$(if $(1),,$(error toc2.call.setup_install_rules requires an install set name as $$1)) +$(if $(2),,$(error toc2.call.setup_install_rules requires an installation path as $$2)) + +$(if $(package.install.$(1).dupecheck),$(error toc2.call.setup_install_rules: rules for $1 have already been created. \ + You cannot create them twice.)) +package.install.$(1).dupecheck := 1 +package.install.$(1).dest ?= $(2) +package.install.$(1).install-flags ?= $(3) + +.PHONY: install-$(1) +install-$(1): + @test x = "x$$(package.install.$(1))" && exit 0; \ + $$(call toc2.call.install,$$(package.install.$(1)),$$(package.install.$(1).dest),$$(package.install.$(1).install-flags)) +install: install-$(1) + +.PHONY: install-$(1)-symlink +install-$(1)-symlink: + @test x = "x$$(package.install.$(1))" && exit 0; \ + $$(call toc2.call.install-symlink,$$(package.install.$(1)),$$(package.install.$(1).dest)) + +.PHONY: uninstall-$(1) +uninstall-$(1): + @test x = "x$$(package.install.$(1))" && exit 0; \ + $$(call toc2.call.uninstall,$$(package.install.$(1)),$$(package.install.$(1).dest)) +uninstall: uninstall-$(1) +endef +# set up the initial install locations and install flags: +toc2.install.target_basenames := bins sbins \ + bin-scripts \ + libs dlls \ + package_libs package_dlls \ + headers package_headers \ + package_data docs \ + man1 man2 man3 man4 \ + man5 man6 man7 man8 man9 +$(eval $(call toc2.call.setup_install_rules,bins,$(prefix)/bin,$(toc2.install.flags.bins))) +$(eval $(call toc2.call.setup_install_rules,bin-scripts,$(prefix)/bin,$(toc2.install.flags.bin-scripts))) +$(eval $(call toc2.call.setup_install_rules,sbins,$(prefix)/sbin,$(toc2.install.flags.bins))) +$(eval $(call toc2.call.setup_install_rules,libs,$(prefix)/lib,$(toc2.install.flags.nonbins))) +$(eval $(call toc2.call.setup_install_rules,dlls,$(prefix)/lib,$(toc2.install.flags.dlls))) +$(eval $(call toc2.call.setup_install_rules,package_libs,$(prefix)/lib/$(package.name),$(toc2.install.flags.nonbins))) +$(eval $(call toc2.call.setup_install_rules,package_dlls,$(prefix)/lib/$(package.name),$(toc2.install.flags.dlls))) +$(eval $(call toc2.call.setup_install_rules,headers,$(prefix)/include,$(toc2.install.flags.nonbins))) +$(eval $(call toc2.call.setup_install_rules,package_headers,$(prefix)/include/$(package.name),$(toc2.install.flags.nonbins))) +$(eval $(call toc2.call.setup_install_rules,package_data,$(prefix)/share/$(package.name),$(toc2.install.flags.nonbins))) +$(eval $(call toc2.call.setup_install_rules,docs,$(prefix)/share/doc/$(package.name),$(toc2.install.flags.nonbins))) +# Set up man page entries... +$(foreach NUM,1 2 3 4 5 6 7 8 9,$(eval $(call \ + toc2.call.setup_install_rules,man$(NUM),man/man$(NUM),$(toc2.install.flags.nonbins)))) diff --git a/toc2/make/toc2-subdirs.make b/toc2/make/toc2-subdirs.make new file mode 100644 index 00000000..a0c0cd1a --- /dev/null +++ b/toc2/make/toc2-subdirs.make @@ -0,0 +1,61 @@ +#!/do/not/make +# ^^^ help out emacs +# Makefile snippet to traverse subdirs. +# Sample usage: +# package.subdirs = foo bar +# include toc2.make +# all: subdirs +# +# NOTES: +# +# - package.subdirs must be defined BEFORE including this file. This is a +# side-effect of the implementation: make expands this var +# at compile time, so to say, so it can build the proper subdir +# targets. Adding to the package.subdirs var later doesn't affect which targets +# get created, but ARE necessary for targets like install-subdirs :/. +# +# - You can add subdirectories post-include by doing this: +# subdirs: subdir-XXXX +# where XXX is a directory, but that has the disadvantage of not adding +# the subdir to the, e.g., cleanup or install list when those traverse +# subdirs. +# +# - You can also use: +# subdirs: subdirs-XXX +# which runs XXX in all $(package.subdirs). +# +# DO NOT put "." in the package.subdirs! Instead, client Makefiles completely +# control dir build order via dependencies. + +######################################################################## +# $(call toc2.call.make-subdirs,dirs_list[,target_name=all]) +# Walks each dir in $(1), calling $(MAKE) $(2) for each one. +# +# $1 = list of dirs +# $2 = make target +# +# Note that this approach makes parallel builds between the dirs in +# $(1) impossible, so it should only be used for targets where +# parallelizing stuff may screw things up or is otherwise not desired +# or not significant. +toc2.call.make-subdirs = \ + test "x$(1)" = "x" -o "x." = "x$(1)" && exit 0; \ + tgt="$(if $(2),$(2),all)"; \ + make_nop_arg=''; \ + test 1 = 1 -o x1 = "x$(toc2.flags.quiet)" && make_nop_arg="--no-print-directory"; \ + for b in $(1) "x"; do test ".x" = ".$$b" && break; \ + pwd=$$(pwd); \ + deep=0; while [[ $$deep -lt $(MAKELEVEL) ]]; do echo -n " "; deep=$$((deep+1)); done; \ + echo "Making '$$tgt' in $${PWD}/$${b}"; \ + $(MAKE) -C $${b} $${make_nop_arg} $${tgt} || exit; \ + cd $$pwd || exit; \ + done + +.PHONY: subdirs $(package.subdirs) +$(package.subdirs): + @$(call toc2.call.make-subdirs,$@,all) +subdirs: $(package.subdirs) +subdir-%:# run all in subdir $* + @$(call toc2.call.make-subdirs,$*,all) +subdirs-%:# run target % in $(package.subdirs) + @$(call toc2.call.make-subdirs,$(package.subdirs),$*) diff --git a/toc2/make/toc2.make.at b/toc2/make/toc2.make.at new file mode 100644 index 00000000..45523c01 --- /dev/null +++ b/toc2/make/toc2.make.at @@ -0,0 +1,149 @@ +#!/do/not/make +######################################################################## +# toc2.make.at: template makefile for toc2.make, a core concept of the +# toc2 build process. This is filtered at the end of the configure +# process. toc2.make must be included by your Makefiles, like so: +# +# include toc2.make +# +# Each makefile which does that will get a toc2.make created during +# the configure process. Each toc2.make is specific to that sub-dir +# (more specifically, each subdir at the same depth gets the same +# toc2.make). +# +# All of the "at-vars" in this file are expected to come in +# via the configure process, either from core tests or from +# the core itself. +# +# Ideally this file should be free of project-specific code: +# put that in $(toc2.top_srcdir)/toc2.$(package.name).make.at and +# in then $(toc2.top_srcdir)/configure.$(package.name) run: +# toc_test_require toc2_project_makefile +######################################################################## +default: all +all: +FORCE: ; @true + +######################################################################## +# $(package.name) and $(package.version) are the penultimate +# variables, holding the package name and version. They must not +# contain spaces, and some characters may confuse other tools. Most +# notable, a '+' in the name is likely to break the makedist tool. +package.version = @PACKAGE_VERSION@ +package.name = @PACKAGE_NAME@ + +######################################################################## +# $(SHELL) must be BASH, but the path might be system-specific. +SHELL = @SHELL@ +##### prefix and DESTDIR are for autotools 'make install' compatibility +prefix ?= @prefix@ +DESTDIR ?= + +ifneq (,$(COMSPEC)) +$(warning Smells like Windows!) +toc2.flags.smells_like_windows := 1 +toc2.platform.file_extensions.dll = .DLL# maintenance reminder: this must stay upper-case! +toc2.platform.file_extensions.lib = .a# yes, use .a for cygwin +toc2.platform.file_extensions.exe = .EXE# maintenance reminder: this must stay upper-case! +else +toc2.flags.smells_like_windows := 0 +toc2.platform.file_extensions.dll = .so +toc2.platform.file_extensions.lib = .a +toc2.platform.file_extensions.exe =# no whitespace, please +endif + +toc2.files.makefile := $(word 1,$(MAKEFILE_LIST))# accommodate Makefile/GNUmakefile +$(toc2.files.makefile): + +######################################################################## +# $(toc2.flags.quiet) is used by some toc2 code to enable/disable +# verbose output. Set it to 1 to enable it, or any other value to +# disable it. +toc2.flags.quiet ?= $(if @TOC2_BUILD_QUIETLY@,@TOC2_BUILD_QUIETLY@,0) + +toc2.top_srcdir = @TOC2_TOP_SRCDIR@ + +##### include configure-created code: +toc2.makefile.config_vars = $(toc2.top_srcdir)/toc2.$(package.name).configure.make +$(toc2.makefile.config_vars):# created by configure process +include $(toc2.makefile.config_vars) + + +toc2.project_makefile = $(wildcard $(toc2.top_srcdir)/toc2.$(package.name).make) +toc2.project_makefile_at = $(wildcard $(toc2.top_srcdir)/toc2.$(package.name).make.at) + +toc2.home ?= @TOC2_HOME@ +# todo: check if this is under $(toc2.top_srcdir), so we can make this path relative. + +toc2.dirs.makefiles = $(toc2.home)/make +toc2.dirs.bin = $(toc2.home)/bin +toc2.dirs.sbin = $(toc2.home)/sbin +toc2.dirs.relative_to_top = @TOC2_RELATIVE_DIR@ +# e.g., in lib/foo, toc2.dirs.relative_to_top == lib/foo + +toc2.make = toc2.make +# deprecated TOP_toc2.make = $(toc2.top_srcdir)/$(toc2.make) + +##### some core utilities: +toc2.bins.awk = @AWK@ +toc2.bins.perl = @PERL@ +toc2.bins.sed = @SED@ +toc2.bins.tar = @TAR@ +toc2.bins.gzip = @GZIP@ +toc2.bins.bzip = @BZIP@ +toc2.bins.zip = @ZIP@ +toc2.bins.ar = $(AR) +toc2.bins.installer = @toc2.bins.installer@ +toc2.bins.makedist = @toc2.bins.makedist@ + + +# The emoticons are now exported directly by toc2_core.sh to toc2.PACKAGE.configure.make: +# toc2.emoticons.okay=@TOC2_EMOTICON_OKAY@ +# toc2.emoticons.warning=@TOC2_EMOTICON_WARNING@ +# toc2.emoticons.error=@TOC2_EMOTICON_ERROR@ +# toc2.emoticons.grief=@TOC2_EMOTICON_GRIEF@ +# toc2.emoticons.wtf=@TOC2_EMOTICON_WTF@ + +toc2.clean_files += $(wildcard .toc2.* core *~) +toc2.distclean_files += $(toc2.make) + +ifeq (.,$(toc2.top_srcdir)) + toc2.distclean_files += \ + toc2.$(package.name).make \ + toc2.$(package.name).configure.make +endif + + +include $(toc2.dirs.makefiles)/toc2-functions-core.make +include $(toc2.dirs.makefiles)/toc2-subdirs.make +include $(toc2.dirs.makefiles)/toc2-cleanup.make +include $(toc2.dirs.makefiles)/toc2-install.make +include $(toc2.dirs.makefiles)/toc2-dist.make + +######################################################################## +# A kludge to get mkdep-toc2 deleted at a proper time... only if we're +# in the top-most dir and mkdep-toc2 exists... +# This code *should* be in toc2-c.make, but that file is not globally +# included. +toc2.bins.mkdep.c := $(wildcard $(toc2.home)/bin/mkdep-toc2.c) +toc2.bins.mkdep := $(if $(toc2.bins.mkdep.c),$(toc2.top_srcdir)/$(basename $(notdir $(toc2.bins.mkdep.c))),) +######################################################################## +# Set toc2.bins.mkdep.flags to whatever -I flags you want to use for +# $(toc2.bins.mkdep). Any non-I flags are ignored by mkdep. +toc2.bins.mkdep.flags += $(INCLUDES) $(CPPFLAGS) +ifeq (.,$(toc2.top_srcdir)) + .PHONY: distclean-mkdep-toc2 + distclean-mkdep-toc2: + @test "x." = "x$(toc2.top_srcdir)" -a \ + x != 'x$(toc2.bins.mkdep)' -a \ + -e "$(toc2.bins.mkdep)" || exit 0; \ + rm -f "$(toc2.bins.mkdep)" + distclean-.: distclean-mkdep-toc2 +endif + +######################################################################## +# finally, load the project-specific code: +ifneq (,$(toc2.project_makefile)) + include $(toc2.project_makefile) +endif + diff --git a/toc2/sbin/Makefile b/toc2/sbin/Makefile new file mode 100644 index 00000000..d4c6ab16 --- /dev/null +++ b/toc2/sbin/Makefile @@ -0,0 +1,5 @@ +#!/usr/bin/make -f +include toc2.make + +package.dist_files += toc2_core.sh toconfigure configure.sample + diff --git a/toc2/sbin/configure.sample b/toc2/sbin/configure.sample new file mode 100644 index 00000000..a1f2e7a2 --- /dev/null +++ b/toc2/sbin/configure.sample @@ -0,0 +1,13 @@ +#!/bin/bash +# you must set PACKAGE_NAME and PACKAGE_VERSION, and their values +# must be filesystem-friendly (i.e., only alph-numeric, dots and underscores) +# because they are used to create various files (e.g. mypackage-1.0.7.tar.gz) + +PACKAGE_NAME=ExamplePackageName +PACKAGE_VERSION=$(date +%Y%m%d) +export PACKAGE_NAME PACKAGE_VERSION + +# toconfigure kicks off the core toc process, which eventually calls +# configure.${PACKAGE_NAME}. Do all of your package-specific +# checks in configure.${PACKAGE_NAME}. +. toc/sbin/toconfigure $@ diff --git a/toc2/sbin/toc2_core.sh b/toc2/sbin/toc2_core.sh new file mode 100644 index 00000000..2ecff73a --- /dev/null +++ b/toc2/sbin/toc2_core.sh @@ -0,0 +1,863 @@ +#!/do/not/bash +######################################################################## +# This file is sourced by configure. Do not run it standalone: +# it is designed to be sources from the toconfigure script. +# +# It contains the implementation of the toc2 API. +# +# All global vars defined in this file are, unless otherwise noted, +# considered private - configure is not supposed to touch them +# directly, nor are test scripts. +# +# Sourcing this file from anywhere other than toconfigure will have +# undefined results. +# +######################################################################## +# maintenance notes: +# +# vars expected from toconfigure: +# TOC2_HOME - path to toc's top dir +# TOC2_TOP_SRCDIR - directory we want to configure from (e.g., top-most +# dir of a source tree). + +TOC2_QUIET=${TOC2_QUIET-0} +TOC2_LOUD=${TOC2_LOUD-0} + +export prefix=${prefix-${TOC2_PREFIX-/usr/local}} +# prefix will be overridden by the command-line arg --prefix=/path +TOC2_INCLUDESDIR=${TOC2_TOP_SRCDIR}/include +TOC2_TESTSDIR=${TOC2_HOME}/tests +TOC2_MAKEFILES_DIR=$TOC2_HOME/make + +TOC2_ATSIGN_PARSER=$TOC2_HOME/bin/atsign_parse # utility to replace @TOKENS_LIKE_THIS_ONE@ in streams. + +TOC2_DEBUG=${TOC2_DEBUG-0} + +TOC2_SHARED_MAKEFILE=toc2_shared.make + +declare -a CONFIG_DOT_MAKE_ARRAY # array holds key=val strings for makefiles +declare -a CONFIG_DOT_H_ARRAY # array holds key=val strings for config.h.at + +# TOC2_DELETE_TEMP="test 1 = 1" # set to a false condition to disable deletion of some temp files (for debuggering) + +TOC2_TIMESTAMP=${TOC2_TOP_SRCDIR}/.toc2.configtimestamp +touch ${TOC2_TIMESTAMP} + + +{ # eye candy, mostly stolen from mod_ssl configure script: + which awk >/dev/null && { + case $TERM in + xterm|xterm*|vt220|vt220*) + TOC2_BOLD_=`echo dummy | awk '{ printf("%c%c%c%c", 27, 91, 49, 109); }'` # that is frigging clever, no? + _TOC2_BOLD=`echo dummy | awk '{ printf("%c%c%c", 27, 91, 109); }'` + ;; + vt100|vt100*) + TOC2_BOLD_=`echo dummy | awk '{ printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }'` + _TOC2_BOLD=`echo dummy | awk '{ printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }'` + ;; + default) + TOC2_BOLD_='' + _TOC2_BOLD='' + ;; + esac + } + + _TOC2_BOLD=${_TOC2_BOLD-""} + TOC2_BOLD_=${TOC2_BOLD_-""} + toc2_boldecho () + { + local args= + for i in n e; do + if test "$1" = "-${i}"; then + args="$args $1" + shift + fi + done + echo $args "${TOC2_BOLD_}${@}${_TOC2_BOLD}" + } + toc2_boldcat () + { + echo "${TOC2_BOLD_}" + cat + echo "${_TOC2_BOLD}" + } +} # end eye candy + +TOC2_ERR_OK=0 +TOC2_ERR_ERROR=1 + +# OKAY, ERROR and WARNING are "core" emoticons: +TOC2_EMOTICON_OKAY="${TOC2_BOLD_}:-)${_TOC2_BOLD}" +TOC2_EMOTICON_ERROR="${TOC2_BOLD_}:-(${_TOC2_BOLD}" +TOC2_EMOTICON_WARNING="${TOC2_BOLD_}:-O${_TOC2_BOLD}" + +# "unofficial" emoticons: +TOC2_EMOTICON_GRIEF="${TOC2_BOLD_}:'-(${_TOC2_BOLD}" +TOC2_EMOTICON_WTF="${TOC2_BOLD_}:-?${_TOC2_BOLD}" + + +toc2_debug () +{ + test "$TOC2_DEBUG" -ne 0 || return 0; + echo "toc2_debug: " "$@" 1>&2 + return 0 +} + +toc2_die () +{ # $1 = error code (defaults to $?) + # $2+ = optional informational text + # sample: toc2_test mytest || toc2_die $? "mytest failed." + err=${1-$?} + shift + echo -n "${TOC2_EMOTICON_ERROR} " + toc2_boldecho "toc2_die: exiting with error code $err." + test -n "$1" && toc2_boldecho "$@" + exit $err +} + + +toc2_quietly () +{ + # outputs $@ if ${TOC2_QUIET} = 0 + # returns 1 if it does not output anything + # It it is passed no parameters it reads in from stdin, + # thus you can: + # toc2_quietly <<EOF + # blah blah blah + # EOF + test "x${TOC2_QUIET-0}" != "x0" && return 1 + test -n "$1" && { + echo "$@" + return 0 + } + cat + return 0 +} + +toc2_loudly () +{ + # outputs $@ if ${TOC2_LOUD} != 0 + # returns 1 if it does not output anything + # It it is passed no parameters it reads in from stdin, + # thus you can: + # toc2_loudly <<EOF + # blah blah blah + # EOF + test "x${TOC2_LOUD-0}" = "x0" && return 1 + test -n "$1" && { + echo "$@" + return 0 + } + cat + return 0 +} + +######################################################################## +# _TOC2_ATEXIT holds the path to this app's "atexit" code, which is +# executed at app exit. +_TOC2_ATEXIT=$TOC2_TOP_SRCDIR/.toc2.atexit.sh +trap 'echo "rm $_TOC2_ATEXIT" >> $_TOC2_ATEXIT; $SHELL $_TOC2_ATEXIT; exit;' 0 1 2 3 +# ^^^^^ the 'exit' in the trap is to force a SIGINT/SIGHUP to cause an exit. +# On a trap 0 the exit is redundant yet harmless. +######################################################################## +# toc2_atexit() is used to provide 'trap' functionality within the TOC framework. +# Client code should NEVER use trap directly, because trap does not offer +# a way to append trap commands. i.e., if clients add a trap they will override +# the framework's trap, which won't be nice. +# $@ must be a list of commands to run at app shutdown. +# Returns 0 unless there is a usage error, in which case it returns non-zero. +# Note that complex string quoting will probably not survive the quote-conversion +# process involved in function calls and parameter passing, so if you need to +# run complex commands at exit, send them to a script and then register that +# script to be run via toc2_atexit(). +# +# Commands are run in the order they are registered, NOT in reverse order +# (as in C's atexit()). +# +# NEVER call exit from within atexit code! +toc2_atexit() +{ + toc2_debug toc2_atexit "$@" + test "x" = "x$1" && { + echo "toc2_atexit() usage error: \$@ must contain commands to run at app shutdown." + return 1 + } + echo "$@" >> $_TOC2_ATEXIT + return 0 +} + + +toc2_dump_make_properties () +{ # Dumps the current properties from the makefile array to stdout + local i=0 + while test $i -lt ${#CONFIG_DOT_MAKE_ARRAY[@]}; do + echo ${CONFIG_DOT_MAKE_ARRAY[$i]} + i=$((i + 1)) + done | ${TOC2_HOME}/bin/cleanup_vars + return 0 +} + +toc2_dump_config_h_properties () +{ # Dumps the current properties from the config.h array to stdout + local i=0 + while test $i -lt ${#CONFIG_DOT_H_ARRAY[@]}; do + echo ${CONFIG_DOT_H_ARRAY[$i]} + i=$((i + 1)) + done | ${TOC2_HOME}/bin/cleanup_vars + return 0 +} + +toc2_get_make () +{ # gets a key which has been previously set + # via toc2_export_make. The value is not echoed, but is in the + # global var ${TOC2_GET_MAKE}. Returns 0 if it finds the var + # and 1 if it does not. + # + # $1 = name of var. + # [$2] = if 1 then the result is echoed. If 2 then $1=${TOC2_GET_MAKE} + # is echoed. Default behaviour is to not output anything. + # A pneumonic for $2: 1 stands for one part (the value) and 2 + # stands for 2 parts (the key and the value). + TOC2_GET_MAKE= + local i=${#CONFIG_DOT_MAKE_ARRAY[@]} + local arg="$1" + local theval= + local ret=1 + i=$((i - 1)) + while test $i -ge 0; do + foo=${CONFIG_DOT_MAKE_ARRAY[$i]} + local k="${foo%%=*}" + local v="${foo#*=}" + test "$arg" = "$k" && { + ret=0 + theval="$v" + break + } + i=$((i - 1)) + done + TOC2_GET_MAKE="$theval" + test "x$2" = "x1" && echo ${TOC2_GET_MAKE} + test "x$2" = "x2" && echo $arg="${TOC2_GET_MAKE}" + toc2_debug toc2_get_make "$@": "$arg=$theval" + return $ret +} + +toc2_atfilter_as_makefile () +{ # filters file $1 using the vars currently set for the shared makefile. + # $1 = template file + # $2 = target file + local tmpl=$1 + local target=$2 + local tmpfile=.toc2.atfilter_as_makefile + toc2_dump_make_properties > $tmpfile + toc2_atfilter_file $tmpfile $tmpl $target + local err=$? + rm $tmpfile + return $err +} + + +toc2_create_make () +{ + # todo: completely refactor this func, splitting it up into + # several functions. + # + # Creates toc2.make echo "Creating ${TOC2_SHARED_MAKEFILE} and + # its friends... " + + + # create toc2.make for everyone who looks like they need it: + #echo "${TOC2_GENDMAKE_OUT}: " + toc2_test toc2_make | toc2_die $? "Error creating toc2.make!" + + return 0 +} # end function toc2_create_make + + +{ # function toc2_find_in_path: shell function to find an app in a given path + # usage: + # toc2_find_in_path appname [/path1:/path/two:path3/foo/bar] + # + # To keep you from having to run a subshell to assign it to a var, + # it it sets the global var TOC2_FIND_IN_PATH to the full path + # of $1 (which may be empty, meaning it was not found). + # + # Sample usage: + # toc2_find_in_path ls && LS=${TOC2_FIND_RESULT} + # or (newer way): + # toc2_find_in_path ls && LS=${TOC2_FIND_RESULT} + # + # Using ${TOC2_FIND_RESULT} is more maintainable in config tests + # because this function is used by all toc2_find_XXX functions, + # and you can rely on that variable to be set no matter which + # of those functions you use. + # + # Note that TOC2_FIND_RESULT is re-set on every call to this + # function, so copy its return value instead of referencing + # TOC2_FIND_RESULT, especially if you are calling functions + # which may, indirectly, call this function. + # + # It returns 1 if ${TOC2_FIND_RESULT} is empty (i.e., if it found anything), + # else it returns 0. + toc2_find_in_path () + { + toc2_debug toc2_find_in_path "$@" + TOC2_FIND_RESULT= # holds the quasi-return value + local app=$1 + shift + local path="$@" + test -n "$path" || path="$PATH" + + # EXPERIMENTAL --with-FOO=/path/to/foo support +# local foo +# local bar +# bar=$(echo $app | tr '[\-\.\\/+]' '[_____]') +# # ^^^ there's Grief waiting to happen here :/ +# eval foo=\$configure_with_${bar} +# test x${foo} != x -a x${foo} != x0 -a x${foo} != x1 && { +# toc2_loudly -n " Using explicit --with-$app: $foo" +# app="${foo}" +# path="" +# } + # /experiment + + # strange: when run as: toc2_find_in_path ls $PATH + # path is space-separated! + # echo path=$path + local oldifs=$IFS + IFS=" :;" + local found= + test -e "$app" && found=$app || for p in $path; do + fullp=$p/$app + test -e $fullp || continue + found=$fullp + break + done + #test -n "$found" || echo "App $app not found in path $path" 1>&2 + TOC2_FIND_RESULT="$found" + # echo $found + IFS=$oldifs + if [ -r "$found" ] ; then + TOC2_FIND_RESULT="$found" + return 0 + else + TOC2_FIND_RESULT= + return 1 + fi + } +} # end funcion toc2_find_in_path + +{ # config manipulators + + # function add_config_{make,h}: helper functions for setting configuration args + # These docs are only here to make these functions appear to contain + # more arcane functionity than their sleek implementations might otherwise + # imply. + # + # Only call these funcs with one key/val pair at a time, to allow for + # proper handling of foo="something with spaces in it" + # + # usage: toc2_export_make VAR="VAR's value, presumably." + toc2_export_make () + { + toc2_debug "toc2_export_make: $@" + CONFIG_DOT_MAKE_ARRAY[${#CONFIG_DOT_MAKE_ARRAY[@]}]="$@" + } + toc2_export_config_h () + { + toc2_debug "toc2_export_config_h: $@" + CONFIG_DOT_H_ARRAY[${#CONFIG_DOT_H_ARRAY[@]}]="$@" + } + toc2_add_config () + { + toc2_export_make "$@" + toc2_export_config_h "$@" + } + toc2_export () + { # the ultimate in laziness: toc2_add_config plus shell export. + toc2_debug toc2_export "$@" + toc2_add_config "$@" + local args="$@" + local k="${args%%=*}" + local v="${args##*=}" + eval "export $k='$v'" + } + +} # end config manipulator + +toc2_find_test () +{ # Sets TOC2_FIND_RESULT to the absolute path of the toc test named $1 + # Returns 0 if it finds a file, else 1. + toc2_find_in_path $1 . || \ + toc2_find_in_path $1.sh . || \ + toc2_find_in_path ${TOC2_TESTSDIR}/$1 || \ + toc2_find_in_path ${TOC2_TESTSDIR}/$1.sh +} + + +{ # function toc2_run test_name [args to pass to test] + # Runs a test and returns its return code. + # + # If $1 is an existing file, that file is treated + # as the test, and sourced, otherwise a lookup + # algorithm is used to find test_name.sh. + # + # Normally clients should use toc2_test or toc2_test_require instead + # of this function. + TOC2_RUN_DEPTH=0 + toc2_run () + { + TOC2_RUN_DEPTH=$((TOC2_RUN_DEPTH + 1)) + local depth=${TOC2_RUN_DEPTH} + toc2_debug "toc2_run " "$@" + local testname=$1 #${TOC2_FIND_RESULT} + #TOC2_DIR=${TOC2_TESTSDIR} + local path= + local desc= + toc2_find_test $testname && { + path=${TOC2_FIND_RESULT} + desc=$(sed -ne 's|\#.*toc2_run_description.*= *\(.*\)|\1|p;' ${TOC2_FIND_RESULT}); + # note: ^^^ sed expr should end with 'q', but then i can only read the top-most line, + # and i like to have a shebang as the top-most line to help out emacs :/ + } || { + toc2_die 127 toc2_run cannot find script for test $testname. + } + shift +# if test ${TOC2_LOUD} = 1; then + + local showname="$testname" + test "x${TOC2_LOUD-0}" != "x0" -a "x$1" != "x" && showname="$showname $@" + toc2_loudly -n "[$depth]" + i=1; + while test $i -le $depth; do + echo -n "${TOC2_BOLD_}=?=${_TOC2_BOLD_}" + i=$((i + 1)) + done + toc2_boldecho -n " [$showname] " + test -n "$desc" && eval "echo -n $desc" + # ^^^ the eval allows us to use $VARS in toc2_run_description. as a + # side-effect, however, you must escape ><| in toc2_run_description! + echo + local err=0 + toc2_source_test $testname "$@" + err=$? + if test ${TOC2_FAIL_FAST-0} = 1 -a $err != 0; then + toc2_die $err "toc2_run: TOC2_FAIL_FAST is set, and test $testname returned a non-zero error code." + fi + TOC2_RUN_DEPTH=$((TOC2_RUN_DEPTH - 1)) + return $err + } + + toc2_repeat_echo () + { # Internal helper. Echoes its arguments ($2-$N) $1 times. + local rep=$1 + shift + while [ $rep -ge 1 ] ; do + echo "$@" " " + rep=$((rep - 1)) + done + } + + toc2_test () + { # runs toc2_run and warns if there was an error. + # It does not exit - it passes back the error code from the test. + toc2_debug toc2_test "$@" + local testname=$1 + local depth=$((TOC2_RUN_DEPTH + 1)) + toc2_run "$@" || { + local ret=$? + toc2_loudly -n "[${depth}] " + toc2_repeat_echo 5 -n "${TOC2_EMOTICON_WARNING}" + toc2_boldecho -n "[$testname]" " " + toc2_repeat_echo 5 -n "${TOC2_EMOTICON_WARNING}" + echo + return $ret + } + toc2_quietly "${TOC2_EMOTICON_OKAY} [$testname]" + return 0 + } + + toc2_test_require () + { # calls toc2_run and exits if it returns !0 + toc2_debug toc2_test_require "$@" + local testname=$1 + local depth=$((TOC2_RUN_DEPTH + 1)) + toc2_run "$@" || { + local ret=$? + toc2_loudly -n "[${depth}] " + toc2_repeat_echo 5 -n "${TOC2_EMOTICON_ERROR}" + toc2_boldecho -n "[$testname]" " " + toc2_repeat_echo 5 -n "${TOC2_EMOTICON_ERROR}" + echo + exit $ret + } + toc2_quietly "${TOC2_EMOTICON_OKAY} [$testname]" + return 0 + } + + toc2_source_test () + { # sources the given test script and returns its error code. + # it accepts a filename or X, where X should resolve to ${TOC2_HOME}/tests/X.sh. + local test=$1 + shift + toc2_find_test $test || toc2_die $? "toc2_source_test: $test not found!" + local sh=${TOC2_FIND_RESULT} + #echo "toc2_find_test: $test sh=$sh" + local err=0 + toc2_debug "toc2_source_test sourcing [$sh $@]" + . $sh "$@" + err=$? + return $err + } + + toc2_find () + { + # toc2_find works like toc2_test, but searches for the app $1 + # in path ${2-${PATH}}. It returns 1 if it finds no file, else zero. + # It "returns" the found file in the global var ${TOC2_FIND_RESULT}. + local bin="$1" + shift + local path="${@-${PATH}}" + # toc2_quietly -n -e "? find $bin\t" + toc2_find_in_path $bin "$path" || { + echo -n "${TOC2_EMOTICON_WARNING} $bin" + toc2_loudly -n " not found in $path" + echo + return 1 + } + local str="${TOC2_EMOTICON_OKAY} $bin" +# test "x${TOC2_QUIET-0}" = "x0" && str="${TOC2_EMOTICON_OKAY}" + test "x${TOC2_LOUD-0}" != "x0" && str="$str: ${TOC2_FIND_RESULT}" + toc2_quietly "$str" + return 0 + } + + toc2_find_require () + { # Same as toc2_find(), except this one exits on error + toc2_find "$@" || toc2_die $? toc2_find_require "$@" + return 0 + } + + +} # end toc2_run functions + + +{ + toc2_replace_file () + { # toc2_replace_file: helper to check if a file is changed, and replace it if it is + # usage: toc2_replace_file target tmpfile + # tmpfile is deleted if target is the same as tmpfile, else it replaces target. + # The fact that it echos text is a side-effect of other parts of this code, + # so don't rely 100% on that "feature". i.e., it echos to fit in with common usage + # of this function, not because its a logical part of the interface :/. + # + # It returns 0 if it replaces $1 with $2. It returns 1 if $1 does + # not need replacing ($1 and $2 are not different). + # + # + # It exits if it cannot mv or rm a file: that is considered a filesystem/rights-level + # problem which needs to be addressed immediately. + # + # + local tgt="$1" + local tmp="$2" + toc2_debug toc2_replace_file $tgt $tmp + test -f "$tmp" || { + echo "toc2_replace_file: argument 2 ($2): could not find file." + exit 1 + } + if test -f "$tgt"; then + if cmp -s "$tgt" "$tmp"; then + toc2_debug "toc2_replace_file: $tgt is up to date. Deleting $tmp." + #echo "toc2_replace_file: $tgt fstate=up to date" + rm -f "$tmp" + return 1 + fi + fi + mv -f "$tmp" "$tgt" || { + toc2_die 2 "toc2_replace_file error: toc2_replace_file: Could not move [$tmp] to [$tgt]!" + } + return 0 + } +} # end toc2_replace_file + +{ + toc2_atfilter_file () + { + # uses the @-parser to filter a template file. + # It returns !0 only if $TOC2_ATSIGN_PARSER throws an error. + # $1 = file containing properties to @-filter. + # $2 = input template (e.g. toc2_shared.make.at) + # $3 = output file (e.g. toc2_shared.make). It is only changed if + # needed, so it is dependencies-safe. + local pfile="$1" + local tmpl="$2" + local ofile="$3" + test -f "$pfile" || toc2_die $? "toc2_atfilter_file: \$1: file not found: $pfile" + test -f "$tmpl" || toc2_die $? "toc2_atfilter_file: \$2: file not found: $tmpl" + local tmpfile=$ofile.tmp.toc2_atfilter_file + ${TOC2_ATSIGN_PARSER} -f "$pfile" < "$tmpl" > "$tmpfile" || { + local err=$? + echo "toc2_atfilter_file(): @-parsing failed: error $err " + echo ${TOC2_EMOTICON_ERROR} + return $err + } + echo -en "\t\t\t$ofile ... " + + fstate="created" + test -f "$ofile" && fstate="updated" + toc2_replace_file "$ofile" "$tmpfile" || fstate="up to date" + echo -en "\r${TOC2_EMOTICON_OKAY} $fstate" + echo + return 0 + } +} # end toc2_atfilter_file + + + +toc2_makerelative () +{ # Makes a relative path from a pair of paths. + # Usage: toc2_makerelative /foo/bar/one/two /foo/bar + # It tries to make a relative path from $1, which must + # be a sub-path (or the same as) of $2. + # Sets global var TOC2_MAKERELATIVE to the "return value". + # In the above example, it should = ./../.. + local startat="${1-$PWD}" + local relto="${2-${TOC2_TOP_SRCDIR}}" + test -n "$relto" || $relto="$PWD" + test -f "$startat" && startat="$(dirname $startat)" + local dn=$startat/bogus + local dn="${dn%*/*}" + local rel="." + while test -n "$dn" -a "$dn" != "$relto" -a "$dn" != "/"; do + rel="$rel/.." + dn="${dn%*/*}" + done + TOC2_MAKERELATIVE="${rel##./}" +} + + + +toc2_endconfigure () +{ # ends the configuration process, processing the files + # which need to be @-parsed + toc2_boldecho "==== Creating configuration-dependent files..." + { + toc2_test_require toc2_make + } + local clean="$(ls .toc2.* 2> /dev/null)" + test "x$clean" != x && rm $clean + echo ========================================================================= + return 0 +} + +toc2_parseargs () +{ # parses $@ for arguments toc can work with. + toc2_debug "toc2_parseargs: Handling command-line arguments: $@" + # mostly stolen from the qt 3.1.0 configure script :) + local i=0 + local -a passon # clone of $@ to pass on to TOC2_PARSEARGS_CALLBACK + local configure_args + local xtra= + echo "$@" | grep -q \\--prefix= || xtra="--prefix=${prefix}" +# while [ "$#" -gt 0 ]; do + for arg in ${xtra} "$@"; do +# local arg="$1"; shift + passon[${i}]="$arg" + i=$((i + 1)) + local VAR= + local VAL= + #echo arg=$arg + case $arg in + --help|-?|--?|-help) + cat<<-EOF + Usage: + $0 [--prefix=/path] [--argument=value] [--arg2=val2] ... + + Standard arguments include: +EOF +# ^^^^ note usage of hard tabs in the cat data! + +cat <<EOF | perl -ne '$|=1; next unless m|\w|; m/\t*(.*)\s*\|\s*(.*)/; print " $1\n\t\t$2\n";' + --help or -? | Show this help. + --help-tests | Show a selection list of test-specific help. + --prefix=/path | Top-most path for installation. Default=${prefix} + --enable-FEATURE=... | Exports config variable configure_enable_FEATURE. + --enable-FEATURE | Equivalent to --enable-FEATURE=1. + --disable-FEATURE | Equivalent to --enable-FEATURE=0. + --with-FEATURE=... | Sets the config variable configure_with_FEATURE. + --with-FEATURE | Equivalent to --with-FEATURE=1. + --without-FEATURE | Equivalent to --with-FEATURE=0. + --XXX=YYY | Exports config variable XXX=YYY. + --XXX | Equivalent to --XXX=1. + --toc-quiet,--quiet | Makes configure run more quietly. + --toc-loud, --loud | configure will output some otherwise superfluous information. + --verbose | Enables --loud and disables --quiet. + --toc-fail-fast | Causes configure to abort if toc2_test returns non-zero. + --toc-debug | Enables debugging output in the configure framework. +EOF +# ^^^^ note usage of hard tabs in the cat data! +cat <<EOF + + Many configure tests use --XXX and --with/enable-XXX. Try using +--help-testname to get test-specific help. e.g. --help-gnu_cpp_tools +or --help-zlib. (This does not work for all tests: try --help-tests +if it does not work for a given test.) + +EOF + + + local help=${TOC2_TOP_SRCDIR}/toc2.${PACKAGE_NAME}.help + test -f $help && { + echo -e "\nHelp options specific to ${PACKAGE_NAME}:\n" + local foo=$(head -1 $help) + local sh=${foo#\#\!} + local hash=${foo%%\!*} + test "x#" = "x$hash" -a "x$hash" != "x$sh" -a "x$sh" != "x" || { + # lookie like no script of some sort. + sh=cat + } + $sh $help + echo "" # just for looks. + } + local help=toc2.${PACKAGE_NAME}.help.sh + test -f $help && { + echo "" + echo "Help options specific to this package:" + cat $help + echo "" # just for looks. + } + + exit 0 + ;; # finally end --help + --prefix=*) + # reserved. + VAR=$(echo $arg | sed "s,^--\(.*\)=.*,\1,;") + VAL=$(echo $arg | sed "s,^--.*=\(.*\),\1,") + ;; + --loud|--toc-loud) + VAR=TOC2_LOUD + VAL=1 + ;; + --verbose) + TOC2_QUIET=0 + TOC2_LOUD=1 + export TOC2_QUIET TOC2_LOUD + ;; + --quiet|--toc-quiet) + VAR=TOC2_QUIET + VAL=1 + ;; + --TOC-[-_]*|--toc[-_]*) + # reserved. + VAR=$(echo $arg | sed "s,^--\(.*\)=.*,\1,;s,-,_,g;s/^__//;" | tr '[a-z\-]' '[A-Z_]') + VAL=$(echo $arg | sed "s,^--.*=\(.*\),\1,;/^--/d;") + test -n "$VAL" || VAL=1 + ;; + --enable-*=*|--with-*=*) + # sets configure_with_XXX or configure_enable_XXX + VAR=$(echo "$arg" | sed "s,^--\(.*\)=.*,\1,;s,-,_,g") + VAL=$(echo "$arg" | sed "s,^--.*=\(.*\),\1,") + VAR=configure_${VAR} + ;; + --enable-*|--with-*) + # sets configure_with_XXX=1 or configure_enable_XXX=1 + VAR=configure_$(echo $arg | sed "s,^--\(.*\),\1,;s,-,_,g") + VAL=1 + ;; + --disable-*) + # sets configure_enable_XXX=0 + VAR=configure_$(echo $arg | sed "s,^--disable\(.*\),enable\1,;s,-,_,g") + # This needs to be 0, not "", because otherwise you wind up + # with "#define HAVE_FOO" when it's been unset, which is not + # desirable. This way, at least you get "#define HAVE_FOO 0". + VAL=0 + ;; + --without-*) + # sets configure_with_XXX=0 + VAR=configure_$(echo $arg | sed "s,^--without\(.*\),with\1,;s,-,_,g") + # This needs to be 0, not "", because otherwise you wind up + # with "#define HAVE_FOO" when it's been unset, which is not + # desirable. This way, at least you get "#define HAVE_FOO 0". + VAL=0 + export $VAR="$VAL" + ;; + --*=*) # SOOOOOOO arguable + # sets XXX=YYY + VAR=$(echo $arg | sed "s,^--\(.*\)=.*,\1,;s,-,_,g") + VAL=$(echo $arg | sed "s,^--.*=\(.*\),\1,") + ;; + --*) # this is soooooo arguable + # sets XXX=1 + VAR=$(echo $arg | sed "s,^--\(.*\),\1,;s,-,_,g;") + VAL=1 + ;; + *) + toc2_boldecho "WARNING: unrecognized option: $arg" + ;; + esac + toc2_debug toc2_parseargs: $arg "VAR=$VAR VAL=$VAL" + test -n "$VAR" -a -n "$VAL" && { + toc2_debug "toc2_parseargs: exporting [$VAR]=$VAL" + export $VAR="$VAL" + toc2_export "$VAR=$VAL" +# foo=$(echo $VAL | sed -e "s,',\\\\',g") + configure_args="$configure_args --$VAR=\"$VAL\"" + } + done + toc2_add_config CONFIGURE_ARGUMENTS="$configure_args" # <---- !!!!experimental!!!! + test "x${TOC2_PARSEARGS_CALLBACK}" != "x" && { + ${TOC2_PARSEARGS_CALLBACK} "${passon[@]}" + return $? + } + return 0 +} # end parseargs + + +######################################################################## +# We do some initial sanity checking here, but any tree-specific +# checks must be done from configure. +toc2_parseargs "$@" + +toc2_loudly 'Loud mode enabled.' + +toc2_source_test toc2_tests_help || exit 0 + +toc2_export_make toc2.emoticons.okay="${TOC2_EMOTICON_OKAY}" +toc2_export_make toc2.emoticons.error="${TOC2_EMOTICON_ERROR}" +toc2_export_make toc2.emoticons.grief="${TOC2_EMOTICON_GRIEF}" +toc2_export_make toc2.emoticons.wtf="${TOC2_EMOTICON_WTF}" +toc2_export_make toc2.emoticons.warning="${TOC2_EMOTICON_WARNING}" + + +echo "Configuring build environment." + +toc2_quietly <<-EOF +${TOC2_BOLD_}Emoticon legend:${_TOC2_BOLD} + ${TOC2_EMOTICON_OKAY} Good News. + ${TOC2_EMOTICON_ERROR} Bad News. + ${TOC2_EMOTICON_GRIEF} Really Bad News. + ${TOC2_EMOTICON_WTF} WTF? + ${TOC2_EMOTICON_WARNING} A warning, possibly even Bad News, but we do not yet + know if it is fatal: this is build tree dependent. + + Note that not all config test failures are fatal: it will stop if + it fails a test which it /needs/ to pass. +EOF + +toc2_export_make toc2.flags.quiet=${TOC2_QUIET-0} + +toc2_test_require toc2_core_tests || { + err=$? + echo "Core toc sanity test failed (err=$err). This tree is not toc-capable. ${TOC2_EMOTICON_ERROR}" + exit $err +} + +toc2_grep_tests() +{ # a client-helper func to grep a list of toc test names from an input file. + # It echos the list of tests + test -z "$1" && toc2_die 1 "toc2_grep_tests: error: \$1 must be a filename." + sed -n -e 's/^ *//;/^toc2_test/p;' $1 | cut -d' ' -f 2 +} + +return 0 diff --git a/toc2/sbin/toconfigure b/toc2/sbin/toconfigure new file mode 100644 index 00000000..2700491c --- /dev/null +++ b/toc2/sbin/toconfigure @@ -0,0 +1,140 @@ +#!/do/not/bash +# Source tree configure script, toc-style. +# The latest code is at http://toc.sourceforge.net/ +# +# Do not run this directly: wrap it up in a script called 'configure', +# stick it into your top-level build tree, set some environment vars, +# and source it. See the configure from the toc distribution for a +# quick starting point. +# +# Requires the the Bourne Again SHell, GNU Make, plus a skew of other open-source utilities +# which are typically installed on any Unix-type system. +# +# $Revision: 1.2 $ +# +# This whole thing is subject to change at any minute. +# +# Notes about this configure process: +# Project-wide vars are currently defined in: +# - this file +# - toc.${PACKAGE_NAME}.make.at +# - And check the top-level Makefile, to be certain :/ +# +# +# Any options you pass on the command line, like: +# ./configure --prefix=/opt +# will be filtered through the shared makefile and config.h. +# +# This tool still requires quite a few things, but it will not aim to be all things +# to all projects. Customize as you see fit. +# +# Note: there are no guarantees that any exit codes mean anything specific! + +test -z "${PACKAGE_VERSION}" -a -z "${PACKAGE_NAME}" && { + echo "toconfigure: environment vars PACKAGE_NAME and PACKAGE_VERSION must be set." + exit 1 +} +configure=${TOC2_CONFIGURE_SCRIPT-./configure} +test -f "$configure" || { + echo "toconfigure: could not find [$configure]!" + exit 2 +} + +grep -i "toc" $configure > /dev/null || { + # this is kind of a callback, actually, since we should only be + # sourced from configure. + echo "Your configure script does not appear to be toc-aware. It shouldn't be sourcing this file." + exit 3 +} + +TOC2_TOP_SRCDIR=${PWD} +TOC2_HOME=${TOC2_HOME-"${TOC2_TOP_SRCDIR}/toc"} + +test -d "${TOC2_HOME}" || { + echo "The toc home directory, TOC2_HOME, not found. Set that variable to the top-most path to your toc installation, or unset it to use the default of ./toc" + exit 4 +} +export TOC2_TOP_SRCDIR +export TOC2_HOME +export PATH=${TOC2_HOME}/bin:${PATH} + +{ # set up the core + CORE_SH=${TOC2_HOME}/sbin/toc2_core.sh + . ${CORE_SH} "$@" || { # core toc functions and initial sanity test + echo "toconfigure: Pain! Suffering! Loading ${CORE_SH} failed!" + exit 5 + } +} + +test x1 = "x${new_project}" && { +# ./configure --new-project +cat <<EOF +********************************************************************** + +Creating Makefile stubs for new project! + +This process will create a file called Makefile.suggestion in each +subdirectory. These files may be renamed to Makefile and tweaked to +suit the needs of your project. + +********************************************************************** +EOF + echo "Press ENTER to continue or Ctrl-C to quit." + read + ${TOC2_HOME}/bin/create_makefile_stubs.sh + return +} + + +toc2_export PACKAGE_NAME="${PACKAGE_NAME}" +toc2_export PACKAGE_VERSION="${PACKAGE_VERSION}" +toc2_export TOC2_HOME="${TOC2_HOME}" +toc2_export TOC2_EMOTICON_OKAY=${TOC2_EMOTICON_OKAY} +toc2_export TOC2_EMOTICON_ERROR=${TOC2_EMOTICON_ERROR} +toc2_export TOC2_EMOTICON_WARNING=${TOC2_EMOTICON_WARNING} + +# include package-specific configure script. This eases upgrading a project's toc: +pkgconfig=${PACKAGE_CONFIGURE_SCRIPT-configure.${PACKAGE_NAME}} +test -f $pkgconfig && { + . $pkgconfig + err=$? + test $err -eq 0 || { + echo "toconfigure: error: $pkgconfig returned [non-zero] error code $err." + exit $err + } +} +# toc2_test toc_project_makefile "Looking for toc.${PACKAGE_NAME}.make" +toc2_add_config SHELL=$(which bash) + +# toc2_test_require toc2_configure_finalcheck +# toc2_configre_finalcheck is arguable :/ + + + +##### end the configuration process and write out our files... +toc2_endconfigure + + +# if $POSTCONFIG exists it is run as our final step: +POSTCONFIG=${TOC2_TOP_SRCDIR}/postconfig.${PACKAGE_NAME} +test -f ${POSTCONFIG} && { + . ${POSTCONFIG} || { + err=$? + echo "${POSTCONFIG} returned non-zero exit status: $?" + return $err + } +} + +package_configure=${TOC2_TOP_SRCDIR}/toc2.${PACKAGE_NAME}.configure.make +toc2_dump_make_properties | perl -pe 's|^(\w+)=|$1 ?= |' > ${package_configure} + +find . -type f -name '.toc.*' | xargs rm -f &>/dev/null # these sometimes cause weird behaviour after a reconfigure + +cat <<-EOF + ========================================================================= + ${TOC2_EMOTICON_OKAY} Build configuration complete. You may now run make (or gmake). + Be sure to read any messages from the tests run by configure. + ========================================================================= +EOF +# ^^^^ note the intentional use of hard tabs in the cat <<-EOF, above. + diff --git a/toc2/tests/Makefile b/toc2/tests/Makefile new file mode 100644 index 00000000..540c7bea --- /dev/null +++ b/toc2/tests/Makefile @@ -0,0 +1,8 @@ +#!/usr/bin/make -f + +package.subdirs = cpp c +include toc2.make + +package.dist_files += $(wildcard *.sh *.at) + +all: subdirs diff --git a/toc2/tests/PACKAGE_NAME-config.at b/toc2/tests/PACKAGE_NAME-config.at new file mode 100644 index 00000000..243344ab --- /dev/null +++ b/toc2/tests/PACKAGE_NAME-config.at @@ -0,0 +1,86 @@ +#!/bin/sh +# +# This gets filtered at configure-time to create +# ${PACKAGE_NAME}-config. + + +version="@PACKAGE_VERSION@" +ldadd="@CLIENT_LDADD@" +includes="@CLIENT_INCLUDES@" +prefix="@prefix@" + +usage() { + cat <<EOF 1>&2 + +$0: shows information useful for configuring/building @PACKAGE_NAME@ +client applications. + +Usage: +$0 [options] + +Options: +--libs : prints linker information about what libs clients should link to. + [${ldadd}] +--includes : prints INCLUDES information + [$includes] +--prefix : prints the library's installation prefix + [$prefix] +--version : prints the library's version + [$version] +--toc2-make : prints a makefile snippet suitable for use with toc2 makefiles +--toc2-config : prints a snippet suitable for a toc2 configure script +--toc2-eval : like --toc2-config, but the output may be directly eval()ed. +EOF +} + +foo=$1 +test "x" = "x$1" && { + usage + exit 1; +} + +for arg in "$@"; do + + case $arg in + --help|-?|-h) + usage + ;; + --libs) + echo $ldadd + ;; + --includes) + echo $includes + ;; + --prefix) + echo $prefix + ;; + --version) + echo $version + ;; + --toc2-make) + cat <<EOF +@PACKAGE_PREFIX@CLIENT_LDADD=$ldadd +@PACKAGE_PREFIX@CLIENT_INCLUDES=$includes +@PACKAGE_PREFIX@LIBRARY_VERSION=$version +EOF + ;; + --toc2-config) + cat <<EOF +toc2_export @PACKAGE_PREFIX@CLIENT_LDADD="$ldadd" +toc2_export @PACKAGE_PREFIX@CLIENT_INCLUDES="$includes" +toc2_export @PACKAGE_PREFIX@LIBRARY_VERSION="$version" +EOF + ;; + --toc2-eval) + cat <<EOF +toc2_export @PACKAGE_PREFIX@CLIENT_LDADD="$ldadd" ; +toc2_export @PACKAGE_PREFIX@CLIENT_INCLUDES="$includes" ; +toc2_export @PACKAGE_PREFIX@LIBRARY_VERSION="$version" ; +EOF + ;; + *) + echo "Unrecognized option: $arg" + exit 2 + ;; + esac +done diff --git a/toc2/tests/PACKAGE_NAME-config.sh b/toc2/tests/PACKAGE_NAME-config.sh new file mode 100644 index 00000000..7eddec38 --- /dev/null +++ b/toc2/tests/PACKAGE_NAME-config.sh @@ -0,0 +1,62 @@ +#!/do/not/bash +# toc2_run_description = creating ${PACKAGE_NAME}-config +# toc2_begin_help = +# +# This test creates a script, ${top_srcdir}/${PACKAGE_NAME}-config, +# useful for trees building libraries. Clients of your library (in +# particular, their configure scripts) can get information about how +# to compile and link against your library via this script. +# +# Sample usage: +# toc2_test_require package_config infile \ +# PACKAGE_PREFIX=LIBMYLIB_ \ +# CLIENT_LDADD="-L${prefix}/lib -lmylib" \ +# CLIENT_INCLUDES="-I${prefix}/include" +# +# +# All variables passed to this test are passed directly on to +# ${TOC2_HOME}/bin/atsign_parse, with the exception of $1: if $1 is an +# existing file it is stripped from the list and use as an input +# template, otherwise it is passed on. +# +# A default template file for the script is provided with this test, +# toc/tests/PACKAGE_NAME-config.at, and it is used if $1 is not an +# existing file. The default template depends on the arguments +# show in the usage sample above. Client-provided templates can +# of course use whatever variables they like. +# +# In the default template, PACKAGE_PREFIX is a prefix which gets +# prepended to some variable names in the output, to allow +# package-config scripts from multiple libraries to produce +# non-colliding output. This value must be a single token, and should +# probably be something like LIBMYLIB_. +# +# Run the generated ${PACKAGE_NAME}-config script to see +# what it does. +# +# Remember to add ${PACKAGE_NAME}-config to the INSTALL_BINS +# and DISTCLEAN_FILES variables in your ${top_srcdir}/Makefile! +# +# = toc2_end_help + +infile="$1" + +if [ ! -e "$infile" ] ; then + infile=${TOC2_HOME}/tests/PACKAGE_NAME-config.at +else + shift +fi + +ofile=${PACKAGE_NAME}-config + +${TOC2_HOME}/bin/atsign_parse \ + PACKAGE_NAME="${PACKAGE_NAME}" \ + PACKAGE_VERSION="${PACKAGE_VERSION}" \ + prefix="${prefix}" \ + "$@" \ + < $infile > ${ofile} || { + err=$? + echo "Error filtering $infile to $ofile!" + return $err +} +chmod +x ${ofile} diff --git a/toc2/tests/atfilter_file.sh b/toc2/tests/atfilter_file.sh new file mode 100644 index 00000000..490dc047 --- /dev/null +++ b/toc2/tests/atfilter_file.sh @@ -0,0 +1,11 @@ +#!/do/not/bash +# toc2_run_description = creating $2 + +test x = "x$2" && { + echo "Error: this test requires args \$1 and \$2:" + echo "\$1 = input (template) file." + echo "\$2 = output file." + return 1 +} + +toc2_atfilter_as_makefile $1 $2 diff --git a/toc2/tests/awk.sh b/toc2/tests/awk.sh new file mode 100644 index 00000000..6de3bdba --- /dev/null +++ b/toc2/tests/awk.sh @@ -0,0 +1,6 @@ +# toc2_run_description = looking for gawk/awk/nawk + +err=0 +toc2_find gawk || toc2_find awk || toc2_find nawk || err=1 +toc2_export_make AWK=$TOC2_FIND_RESULT +return $err diff --git a/toc2/tests/c/Makefile b/toc2/tests/c/Makefile new file mode 100644 index 00000000..2659590b --- /dev/null +++ b/toc2/tests/c/Makefile @@ -0,0 +1,6 @@ + +include toc2.make + +package.dist_files += $(wildcard *.c) + +all: diff --git a/toc2/tests/c/check_for_dlopen_and_friends.c b/toc2/tests/c/check_for_dlopen_and_friends.c new file mode 100644 index 00000000..b74ef807 --- /dev/null +++ b/toc2/tests/c/check_for_dlopen_and_friends.c @@ -0,0 +1,34 @@ +/** + Quick check for dlopen(), dlclose() and dlsym(). + + toc usage: + + toc_test_require path/to/this/file -ldl -export-dynamic + */ +#include <dlfcn.h> +#include <stdlib.h> +void foo_function() {} + +int main() +{ + typedef void (*func)(); + void * soh = dlopen( 0, RTLD_NOW | RTLD_GLOBAL ); + if( ! soh ) + { + printf( "%s\n", dlerror() ); + return 1; + } + void * sym = (func) dlsym( soh, "foo_function" ); + if( 0 == sym ) + { + printf( "%s\n", dlerror() ); + return 2; + } + int err = dlclose( soh ); + if( err ) + { + printf( "%s\n", dlerror() ); + return err; + } + return 0; +} diff --git a/toc2/tests/c/check_for_ltdlopen_and_friends.c b/toc2/tests/c/check_for_ltdlopen_and_friends.c new file mode 100644 index 00000000..cce965b2 --- /dev/null +++ b/toc2/tests/c/check_for_ltdlopen_and_friends.c @@ -0,0 +1,30 @@ +/** + Quick check for lt_dlopen(), lt_dlclose() and lt_dlsym(). + + toc usage: + + toc_test_require path/to/this/file -lltdl -export-dynamic + */ +#include <ltdl.h> +#include <stdlib.h> +void foo_function() {} + +int main() +{ + typedef void (*func)(); + void * soh = 0; + lt_dlinit(); + soh = lt_dlopen( 0 ); // , RTLD_NOW | RTLD_GLOBAL ); + if( ! soh ) + { + printf( "could not open main app: %s\n", lt_dlerror() ); + return 1; + } + void * sym = (func) lt_dlsym( soh, "foo_function" ); + if( 0 == sym ) + { + printf( "could not find test symbol: %s\n", lt_dlerror() ); + return 2; + } + return 0; +} diff --git a/toc2/tests/c/check_for_pthread.c b/toc2/tests/c/check_for_pthread.c new file mode 100644 index 00000000..9176d59a --- /dev/null +++ b/toc2/tests/c/check_for_pthread.c @@ -0,0 +1,14 @@ +#include <pthread.h> +// link with -lpthread +#include <stdio.h> + +void * thread_callback( void * arg ) +{ + printf( "Doing nothing.\n" ); +} +int main() +{ + pthread_t thread = 0; + int thret = pthread_create( &thread, NULL, thread_callback, NULL ); + return 0; +} diff --git a/toc2/tests/cpp/Makefile b/toc2/tests/cpp/Makefile new file mode 100644 index 00000000..4ee7f6be --- /dev/null +++ b/toc2/tests/cpp/Makefile @@ -0,0 +1,6 @@ + +include toc2.make + +package.dist_files += $(wildcard *.cpp *.c) + +all: diff --git a/toc2/tests/cpp/check_setenv_in_cpp.cpp b/toc2/tests/cpp/check_setenv_in_cpp.cpp new file mode 100644 index 00000000..3bac5d84 --- /dev/null +++ b/toc2/tests/cpp/check_setenv_in_cpp.cpp @@ -0,0 +1,16 @@ +#include <stdlib.h> + +/** +On the solaris boxes i have i can't compile this as c++, but can as c, +using gcc 2.95.3: + +/opt/gnu/bin/gcc toc/tests/cpp/check_setenv_in_cpp.cpp -c -o .toc.try_compile.o +toc/tests/cpp/check_setenv_in_cpp.cpp: In function `int main()': +toc/tests/cpp/check_setenv_in_cpp.cpp:9: implicit declaration of function `int setenv(...)' + + */ +int main() +{ + setenv( "foo", "foo", 1 ); + return 0; +} diff --git a/toc2/tests/cpp/check_stl_newstyle.cpp b/toc2/tests/cpp/check_stl_newstyle.cpp new file mode 100644 index 00000000..97df29a6 --- /dev/null +++ b/toc2/tests/cpp/check_stl_newstyle.cpp @@ -0,0 +1,8 @@ +#include <sstream> + +int main() +{ + std::ostringstream os; + os << "foo"; + return 0; +} diff --git a/toc2/tests/cpp/gcc_2_95_typename_problem.cpp b/toc2/tests/cpp/gcc_2_95_typename_problem.cpp new file mode 100644 index 00000000..bb204c72 --- /dev/null +++ b/toc2/tests/cpp/gcc_2_95_typename_problem.cpp @@ -0,0 +1,44 @@ +#include <map> +using namespace std; + +#ifndef TYPENAME +#define TYPENAME typename +// gcc 3.x accepts typename, gcc 2.95.3 does not +#endif + +template <typename T> +struct Foo +{ + typedef T TT; + typedef Foo<TT> ThisType; + typedef map<ThisType::TT,ThisType::TT> map_type; + + /** + gcc 2.95.3 will do something like the following: + stl_check.cpp: In method `void Foo<T>::check_for_gcc2_9_failure(const map<T,T,less<_Key>,allocator<_Tp1> > &)': + stl_check.cpp:15: no class template named `map' in `struct Foo<T>' + stl_check.cpp:16: no class template named `map' in `struct Foo<T>' + + gcc 3.x (3.3pre, at least) swallows it nicely. + + The problem here is the 'typename' part: without that gcc + 2.95.3 compiles it fine. gcc 3, however, warns that + "implicite typenames are deprecated", and this kills my + builds (i always use -Werror :/). + */ + void check_for_gcc2_9_failure() + { + ThisType::map_type map; + TYPENAME ThisType::map_type::const_iterator it = map.begin(); + TYPENAME ThisType::map_type::const_iterator et = map.end(); + for( ; it != et; ++it ) {} + } +}; + +int main() +{ + typedef Foo<int> Fii; + Fii fii; + fii.check_for_gcc2_9_failure(); + return 0; +} diff --git a/toc2/tests/create_pkg-config_data.sh b/toc2/tests/create_pkg-config_data.sh new file mode 100644 index 00000000..b21ee736 --- /dev/null +++ b/toc2/tests/create_pkg-config_data.sh @@ -0,0 +1,96 @@ +#!/do/not/bash +# toc2_run_description = creating ${PACKAGE_NAME}.pc +# toc2_begin_help = +# +# This test creates a data file for pkg-config, useful for trees +# building libraries. With this data clients of your library can get +# information about how to compile and link against your library via +# the pkg-config tool. + +# The output file is called ./${PACKAGE_NAME}.pc, and should be added +# to the top-level makefile's INSTALL_PKGCONFIG and DISTCLEAN_FILES vars. +# It will be installed to ${prefix}/lib/pkgconfig. + +# Sample usage: +# toc2_test_require create_pkg-config + +# Please see 'man pkg-config' for more information about pkg-config +# conventions. + +# This test makes use of the following environment variables: +# +# - PACKAGE_FRIENDLY_NAME = a "friendly-form" name of the package. +# Defaults to the toc-conventional PACKAGE_NAME. +# +# - PACKAGE_VERSION = toc-conventional +# +# - PACKAGE_DESCRIPTION = a description of the package. e.g., "A tool to +# do Blah." +# +# - PACKAGE_LDADD = list of linker flags required to link against this +# package, include -L and -l options. e.g. -L/usr/X11R6/lib +# Note that -L${prefix}/lib is automatically added ONLY if this +# var is NOT set. +# Corresponds to pkg-config's Libs entry. +# +# - PACKAGE_CFLAGS = list of C preprocessor flags needed to compile +# against this package. e.g., -I/usr/X11R6/include +# Note that -I${prefix}/include is automatically added ONLY if this +# var is NOT set. +# Corresponds to pkg-config's CFlags entry. +# +# - PACKAGE_CONFLICTS = pkg-config 'Conflicts:' info string +# +# - PACKAGE_REQUIRES = pkg-config 'Requires:' info string +# +# Note that configure code may need append additional information to +# the output to the generated file, like "my_module_version", and +# other not-always-used entries. +# +# Achtung: this test will return with an error in some cases even +# when it creates the output file. For example, if PACKAGE_DESCRIPTION +# is not set then it will do so, primarily to verbosely warn the user +# to set it. +# +# Remember to add ${PACKAGE_NAME}.pc to the INSTALL_PKGCONFIG +# and DISTCLEAN_FILES variables in your ${top_srcdir}/Makefile! +# +# = toc2_end_help + +_ret=0 +for i in PACKAGE_DESCRIPTION; do + test x = "x$(eval echo \${$i})" && { + toc2_boldecho "Warning: variable not set: $i" + _ret=1 + } + +done + +pkgconfdir=${prefix}/lib/pkgconfig +echo "x${PKG_CONFIG_PATH}" | grep "${pkgconfdir}" >/dev/null || { +cat <<EOF +${TOC2_BOLD_}Warning: the dir [$pkgconfdir] is not in the current +PKG_CONFIG_PATH. This means that pkg-config may not be able to find +${PACKAGE_NAME}.pc after installation.${_TOC2_BOLD} +EOF + +} +unset pkgconfdir + +cat <<EOF > ${PACKAGE_NAME}.pc +# created by toc's create_pkg-config_data test. $(date) +prefix=${prefix} +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: ${PACKAGE_FRIENDLY_NAME-${PACKAGE_NAME}} +Description: ${PACKAGE_DESCRIPTION} +Version: ${PACKAGE_VERSION} +Requires: ${PACKAGE_REQUIRES} +Libs: ${PACKAGE_LDADD-"-L\${libdir}"} +Cflags: ${PACKAGE_CFLAGS-"-I\${includedir}"} + +EOF + +return $_ret diff --git a/toc2/tests/doxygen.sh b/toc2/tests/doxygen.sh new file mode 100644 index 00000000..71efbbb5 --- /dev/null +++ b/toc2/tests/doxygen.sh @@ -0,0 +1,37 @@ +#!/do/not/bash +# toc2_run_description = looking for doxygen, API doc generation tool. +# toc2_begin_help = +# +# Looks for doxygen in the ${PATH} or the binary specified using +# --with-doxygen=/path/to/doxygen. It calls toc2_export for the +# following vars: +# +# - DOXYGEN_BIN=/path/to/doxygen, or empty string if we got +# --without-doxygen or a bad value for --with-doxygen=... +# +# It returns zero if it finds doxygen, else non-zero. +# +# = toc2_end_help + +if test "x${configure_with_doxygen}" = "x0"; then + echo "doxygen support has been explicitely disabled." + toc2_export DOXYGEN_BIN= + return 1 +fi + +if test "x${configure_with_doxygen}" = x || test "x${configure_with_doxygen}" = x1; then + toc2_find_in_path doxygen "$PATH" && DOXYGEN_BIN=${TOC2_FIND_RESULT} +elif test "x${configure_with_doxygen}" = x0; then + DOXYGEN_BIN= +else + if test -x ${configure_with_doxygen}; then + DOXYGEN_BIN="${configure_with_doxygen}" + else + # I hate shell scripts!! + echo '--with-doxygen "'"${configure_with_doxygen}"'" isn'"'t executable!" + toc2_export DOXYGEN_BIN= + return 1 + fi +fi +toc2_export DOXYGEN_BIN="$DOXYGEN_BIN" +return 0 diff --git a/toc2/tests/find_appconfig.sh b/toc2/tests/find_appconfig.sh new file mode 100644 index 00000000..14f88e77 --- /dev/null +++ b/toc2/tests/find_appconfig.sh @@ -0,0 +1,52 @@ +#!/do/not/bash +# toc2_run_description = looking for $1-config + +# toc2_begin_help = +# This test searches for $1-config in the path $2. +# The search path defaults to ${prefix}/bin:$PATH. +# +# +# The config var ${1}_config is exported, and will contain the path of +# the config app or empty if it was not found. Note that any "-" +# characters in $1 are converted to "_" for this purpose. + +# FIND_APPCONFIG is also exported to the path of the found config app, +# but will be reset on each call to this function. It is intended to +# be helpful when running this test in loops, e.g., for x in foo bar; +# do ... done + +# Example: +# +# toc2_test_require find_appconfig my-lib +# +# will search for my-lib-config in ${prefix}/bin:$PATH +# and will export ${my_lib_config} to the path where it +# is found. +# +# = toc2_end_help + +_app=${1} + +test x = "x$_app" && { + cat <<EOF +Usage error: this test requires the base name of a lib or app as it's +first argument, and an optional PATH as it's second argument. +Example: + toc2_test_require find_appconfig gtk +will search for gtk-config in ${prefix}/bin:$PATH +EOF + return 1 + +} + +_spath=${2-${prefix}/bin:$PATH} + +toc2_find ${_app}-config $_spath +_app=$(echo $_app | sed -e s/-/_/g) +toc2_export ${_app}_config=${TOC2_FIND_RESULT} +toc2_export FIND_APPCONFIG=${TOC2_FIND_RESULT} +unset _app +unset _spath +test x != "x${TOC2_FIND_RESULT}" +return $? + diff --git a/toc2/tests/find_header.sh b/toc2/tests/find_header.sh new file mode 100644 index 00000000..13d4a417 --- /dev/null +++ b/toc2/tests/find_header.sh @@ -0,0 +1,45 @@ +#!/do/not/bash +# toc2_run_description = Looking for header file $1 +# toc2_begin_help = +# +# Searches for a header file, passed as $1, +# in the search path $2. $2 defaults to: +# ${prefix}/include:/usr/include:/usr/local/include +# +# After running this the variable TOC2_FIND_RESULT +# holds the position of the file, or is empty +# if the file is not found. +# +# The environment variable FIND_HEADER_PATH is set to +# to path where $1 was found. Note that it is reset +# on every call to this test, and is not toc2_exported. +# +# = toc2_end_help + + +test x = "x$1" && { + cat <<EOF +Usage error: + \$1 should be the name of a header file. + \$2 is an optional search path. +EOF + return 1 +} + +header=$1 +shift +defname=HAVE_$(echo ${header} | tr '[a-z/.]' '[A-Z__]') +toc2_find $header ${@-${prefix}/include:/usr/include:/usr/local/include} +export FIND_HEADER_PATH="${TOC2_FIND_RESULT%%/$header}" +if test -n "${FIND_HEADER_PATH}"; then + toc2_export ${defname}=1 +else + toc2_export ${defname}=0 +fi +unset header +test x != "x${TOC2_FIND_RESULT}" +return $? + + + + diff --git a/toc2/tests/gcc_build_and_run.sh b/toc2/tests/gcc_build_and_run.sh new file mode 100644 index 00000000..f75b20eb --- /dev/null +++ b/toc2/tests/gcc_build_and_run.sh @@ -0,0 +1,49 @@ +# toc2_run_description = $@ +# +# toc2_begin_help = +# +# Tries to compile $@ using ${CC} and returns the error code which the +# compiler returns. $@ may be made up of any flags which you want to +# pass to the compiler, such as -I/some/path. Do not pass -c nor +# -o, as those are handled by this test. +# +# This code uses ${INCLUDES}. You can easily set it only for the +# duration of this test by doing something like the following: +# +# INCLUDES="-I/path1 -I/path2" toc2_test_require gcc_build_and_run myfile.c +# +# This is an alternative to using the more verbose approach of saving +# INCLUDES, adjusting it, calling this test and re-setting INCLUDES. +# +# = toc2_end_help + + +toc2_get_make CC +CC=${TOC2_GET_MAKE} +test "x$CC" = x && { + echo "This test requires that the config variable CC have been set to point to gcc." + echo "Try running the gnu_cpp_tools test, or another test which sets C/C++-related variables, or call toc2_export_make CC=/path/to/gcc." + return 1 +} + +tmpprefix=.toc2.build_and_run +binfile=./$tmpprefix +compiler_out=$tmpprefix.out +cmd="$CC ${INCLUDES} $@ -o $binfile" +echo $cmd > $compiler_out +$cmd >> $compiler_out 2>&1 +err=$? +test x0 = x$err || { + echo "Compiler output is in $compiler_out (but will be erased the next time this test is run!)." + return $err + err=$? +} +echo $binfile >> $compiler_out +$binfile >> $compiler_out 2>&1 +err=$? +test x0 != x$err && { + echo "output is in $compiler_out (but will be erased the next time this test is run!)." +} || { + rm $binfile $compiler_out +} +return $err diff --git a/toc2/tests/gcc_try_compile.sh b/toc2/tests/gcc_try_compile.sh new file mode 100644 index 00000000..4a075759 --- /dev/null +++ b/toc2/tests/gcc_try_compile.sh @@ -0,0 +1,48 @@ +# toc2_run_description = $@ +# +# toc2_begin_help = +# +# Tries to compile $@ using ${CC} and returns the error code which the +# compiler returns. $@ may be made up of any flags which you want to +# pass to the compiler, such as -I/some/path. +# +# This code uses ${INCLUDES}. You can easily set it only for the +# duration of this test by doing something like the following: +# +# INCLUDES="-I/path1 -I/path2" toc2_test_require gcc_try_compile myfile.c +# +# This is an alternative to using the more verbose approach of saving +# INCLUDES, adjusting it, calling this test and re-setting INCLUDES. +# +# = toc2_end_help + + +#test x"$@" = x && { +# ^^^ this no workie when, e.g., -I... is passed in, because -I is a flag used by test :/ +# echo "usage: try_compile cc_flag|file1.{c,cpp...} [cc_flag|file2...]" +# return 1 +#} + +toc2_get_make CC +CC=${TOC2_GET_MAKE} +test "x$CC" = x && { + echo "This test requires that the config variable CC have been set to point to gcc." + echo "Try running the gnu_cpp_tools test, or another test which sets C/C++-related variables, or call toc2_export_make CC=/path/to/gcc." + return 1 +} + +tmpprefix=.toc.try_compile +dotofile=$tmpprefix.o +compiler_out=$tmpprefix.out +cmd="$CC ${INCLUDES} $@ -c -o $dotofile" +echo $cmd > $compiler_out +$cmd >> $compiler_out 2>&1 +err=$? + +test -f $dotofile && rm $dotofile +test $err != 0 && { + echo "Compiler output is in $compiler_out (but will be erased the next time this test is run!)." +} || { + rm $compiler_out +} +return $err diff --git a/toc2/tests/gnu_cpp_tools.sh b/toc2/tests/gnu_cpp_tools.sh new file mode 100644 index 00000000..0a865cb2 --- /dev/null +++ b/toc2/tests/gnu_cpp_tools.sh @@ -0,0 +1,97 @@ +# toc2_run_description = looking for GNU C/C++ compiler/linker tools. +# toc2_begin_help = +# It takes the following configure arguments: +# --enable-debug causes stuff to be built -g instead of -02. This is a +# little weird, but you can control the optimization level +# with --enable-debug="-O3 -fno-inline" etc. +# --enable-warn causes stuff to be built -Wall. To turn on -Werror, do: --enable-warn="-Wall -Werror" etc. +# --enable-werror same as --enable-warn="-Wall -Werror" +# +# It calls toc2_export for the following: +# - CC /path/to/gcc? +# - LD /path/to/ld +# - LDD /path/to/ldd +# - CXX /path/to/g++ +# - AR /path/to/ar +# - NM /path/to/nm (optional component) +# - STRIP /path/to/strip (optional component) +# - INCLUDES probably empty +# - CPPFLAGS probably empty +# - CFLAGS_OPT same as OPT (prefered for naming's sake) +# - WARN -Wall (or some other value specified by --enable-warn or --enable-werror) +# - CFLAGS probably empty (or maybe -pipe) +# - CXXFLAGS probably empty (or maybe -pipe) +# - LDFLAGS probably empty +# = toc2_end_help + +CC= + +: ${configure_enable_debug=0} +: ${configure_enable_warn=0} +: ${configure_enable_werror=0} + +for foo in \ + ar-AR gcc-CC g++-CXX ld-LD ldd-LDD \ + ; do + key=${foo%%-*} + var=${foo##*-} + toc2_find $key || { + echo "Couldn't find required app: $key in PATH [$PATH]" + return 1 + } + toc2_export $var=${TOC2_FIND_RESULT} +done + +for foo in \ + nm-NM strip-STRIP \ + ; do + key=${foo%%-*} + var=${foo##*-} + toc2_find $key + toc2_export $var="${TOC2_FIND_RESULT}" +done + + +toc2_export INCLUDES="$INCLUDES" +toc2_export CPPFLAGS="$CPPFLAGS" +if test "x${configure_enable_debug}" = x1; then + CFLAGS_OPT="-g -DDEBUG -D_DEBUG $CFLAGS_OPT" +elif test "x${configure_enable_debug}" = x0; then + # What's a sensible default here? -O2? Put it first in the hopes + # that any values already in $CFLAGS_OPT will take precedence. + CFLAGS_OPT="-O2 $CFLAGS_OPT -DNDEBUG" +else + # They specified some flags. + CFLAGS_OPT="$configure_enable_debug" +fi + +toc2_export CFLAGS_OPT="$CFLAGS_OPT" + +if test "x${configure_enable_warn}" = x1; then + WARN="-Wall $WARN" +elif test "x${configure_enable_warn}" = x0; then + WARN= +else + # They specified some flags. + WARN="$configure_enable_warn" +fi + +if test "x${configure_enable_werror}" != x0; then + if test "x${configure_enable_werror}" = x1; then + WARN="-Wall -Werror $WARN" + else + WARN="$WARN ${configure_enable_werror}" + fi +fi + + + +toc2_export WARN="$WARN" + +# Presumably we could determine whether -pipe works instead of assuming +# it does... +CFLAGS="-pipe $CFLAGS ${WARN} ${CFLAGS_OPT}" +CXXFLAGS="-pipe $CXXFLAGS ${WARN} ${CFLAGS_OPT}" +toc2_export CFLAGS="$CFLAGS" +toc2_export CXXFLAGS="$CXXFLAGS" +toc2_export LDFLAGS="$LDFLAGS" diff --git a/toc2/tests/gnu_find.sh b/toc2/tests/gnu_find.sh new file mode 100644 index 00000000..f403eb1a --- /dev/null +++ b/toc2/tests/gnu_find.sh @@ -0,0 +1,12 @@ +# toc2_run_description = search for GNU find + + +toc2_find find || return 1 +app=${TOC2_FIND_RESULT} +"$app" --version | grep -i GNU > /dev/null || { + echo "Your 'find' ($app) appears to be non-GNU." + return 1 +} +toc2_export_make FIND=$app +return 0 + diff --git a/toc2/tests/gnu_make.sh b/toc2/tests/gnu_make.sh new file mode 100644 index 00000000..1b94f7dc --- /dev/null +++ b/toc2/tests/gnu_make.sh @@ -0,0 +1,9 @@ +# toc2_run_description = search for a genuine GNU make, the Make of makes. + +toc2_find gmake || toc2_find make || return +toc2_export MAKE=${TOC2_FIND_RESULT} +"$MAKE" --version | grep -qi GNU > /dev/null || { + echo "Your make appears to be non-GNU." + return 1 +} + diff --git a/toc2/tests/gnu_tar.sh b/toc2/tests/gnu_tar.sh new file mode 100644 index 00000000..fa4e3a4e --- /dev/null +++ b/toc2/tests/gnu_tar.sh @@ -0,0 +1,32 @@ +# toc2_run_description = search for a genuine GNU tar +# toc2_begin_help = +# Looks for a genuine GNU tar. It first looks for gtar, and then tar, and checks +# the binary to see if it is a GNU version. +# It honors the configure argument --with-tar=/path/to/tar. +# +# Exports: +# - TAR_BIN=/path/to/tar (or empty string) +# - TAR=/path/to/tar (same as TAR_BIN, but deprecated) +# +# = toc2_end_help + +toc2_export TAR= +toc2_export TAR_BIN= + +gtar=${configure_with_TAR-gtar} +toc2_find $gtar || toc2_find tar || { + echo "tar/gtar not found in PATH" + return 1 +} +gtar=$TOC2_FIND_RESULT +"$gtar" --version | grep -i GNU > /dev/null || { + echo "Your 'tar' ($gtar) appears to be non-GNU." + return 1 +} + +toc2_find ${TOC2_HOME}/make/TARBALL.make +toc2_export TARBALL_MAKE=${TOC2_FIND_RESULT} +toc2_export TAR=$gtar +toc2_export TAR_BIN=$gtar + +return 0
\ No newline at end of file diff --git a/toc2/tests/libdl.sh b/toc2/tests/libdl.sh new file mode 100644 index 00000000..1c0a308e --- /dev/null +++ b/toc2/tests/libdl.sh @@ -0,0 +1,28 @@ +# toc2_run_description = looking for libdl +# toc2_begin_help = +# +# Looks for libdl. It exports the following config variables: +# +# HAVE_LIBDL = 0 or 1 +# HAVE_DLFCN_H = currently always the same as HAVE_LIBDL. +# LDADD_LIBDL = empty or "-ldl -rdynamic", possibly with -L/path... +# LDADD_DL = same as LDADD_LIBDL +# +# Note that LDADD_LIBDL is specific to the libdl test, whereas LDADD_DL is used +# by both the libdl and libltdl tests, and possibly other libdl-like tests. +# +# = toc2_end_help + +err=1 + +if toc2_test gcc_build_and_run \ + ${TOC2_HOME}/tests/c/check_for_dlopen_and_friends.c -rdynamic -ldl ; then + err=0 + toc2_export HAVE_LIBDL=1 + toc2_export HAVE_DLFCN_H=1 + toc2_export HAVE_DLOPEN=1 + toc2_export LDADD_LIBDL="-ldl -rdynamic" + toc2_export LDADD_DL="${LDADD_LIBDL}" +fi + +return $err diff --git a/toc2/tests/libexpat.sh b/toc2/tests/libexpat.sh new file mode 100644 index 00000000..0f8d2624 --- /dev/null +++ b/toc2/tests/libexpat.sh @@ -0,0 +1,61 @@ +#!/do/not/bash +# toc2_run_description = checking for expat XML parser... +# toc2_begin_help = +# +# Exports the variable HAVE_LIBEXPAT to 0 or 1. +# If --without-libexpat is passed to configure then this test +# sets HAVE_LIBEXPAT to 0 and returns success. +# +# = toc2_end_help + + + +if [ x0 = "x${configure_with_libexpat}" ]; then + echo "libexpat disabled explicitely with --without-libexpat." + toc2_export HAVE_LIBEXPAT=0 + return 0 +fi + +src=check4expat.c +cat <<EOF > $src +// taken from expat's outline.c example, expat 1.95.7 +#include <stdio.h> +#include <expat.h> + +#define BUFFSIZE 8192 + +char Buff[BUFFSIZE]; + +int Depth; + +static void XMLCALL +start(void *data, const char *el, const char **attr) +{} +static void XMLCALL +end(void *data, const char *el) +{} + +int +main(int argc, char *argv[]) +{ + XML_Parser p = XML_ParserCreate(NULL); + if (! p) { + fprintf(stderr, "Couldn't allocate memory for parser\n"); + exit(-1); + } + + XML_SetElementHandler(p, start, end); + return 0; +} + +EOF + +workie=1 +toc2_test gcc_build_and_run $src -lexpat || workie=0 + +rm $src + +toc2_export HAVE_LIBEXPAT=${workie} +unset workie +test 1 = ${HAVE_LIBEXPAT} +return $? diff --git a/toc2/tests/libltdl.sh b/toc2/tests/libltdl.sh new file mode 100644 index 00000000..d035d02d --- /dev/null +++ b/toc2/tests/libltdl.sh @@ -0,0 +1,33 @@ +# toc2_run_description = looking for libltdl +# toc2_begin_help = +# +# Looks for libltdl. It calls toc2_export for the +# following variables: +# +# HAVE_LIBLTDL = 0 or 1 +# LDADD_LIBLTDL = -lltdl or empty +# LDADD_DL = empty or "-lltdl -rdynamic", possibly with -L/path... +# +# Note that LDADD_LIBLTDL is specific to the libltdl test, whereas +# LDADD_DL is used by both the libdl and libltdl tests. +# +# = toc2_end_help +# Many thanks to Roger Leigh for introducing me to ltdl! + +toc2_add_config HAVE_LIBLTDL=0 +toc2_add_config LDADD_LIBLTDL= +toc2_export LDADD_DL= + +err=1 + +if toc2_test gcc_build_and_run ${TOC2_HOME}/tests/c/check_for_ltdlopen_and_friends.c -rdynamic -lltdl; then + err=0 + toc2_export HAVE_LIBLTDL=1 + toc2_export LDADD_LIBLTDL="-lltdl -rdynamic" + toc2_export LDADD_DL="${LDADD_LIBLTDL}" +fi + +return $err + + + diff --git a/toc2/tests/pkg-config-exists.sh b/toc2/tests/pkg-config-exists.sh new file mode 100644 index 00000000..009e0033 --- /dev/null +++ b/toc2/tests/pkg-config-exists.sh @@ -0,0 +1,51 @@ +# toc2_run_description = $@ +# toc2_begin_help = +# +# Runs pkg-config --exists $1 and returns the result. +# If $2 is set then it is assumed to be a minimum version number +# and pkg-config --atleast-version $2 $1 is called. If $2 is set +# and the version test fails then this test returns non-zero. +# +# If the test succeeds then it calls toc2_export_make for two +# variables whos names are calculated based on $1. That is, +# $1 is upper-cased and any [.+-] symbols are converted to +# underscores. Then _CFLAGS and _LIBS are appended and the +# values of pkg-config --cflags $1 and --libs $1 are used +# as values. For example: +# +# toc2_test_require pkg-config-exists foobar-0.10 0.10.13 +# +# If that passes, it will export: +# +# FOOBAR_0_10_CFLAGS=$(pkg-config --cflags foobar-0.10) +# FOOBAR_0_10_LIBS=$(pkg-config --libs foobar-0.10) +# +# = toc2_end_help +function pkg_config_check () { + + if pkg-config --exists $1; then + if [ ! -z "$2" ]; then + if pkg-config --atleast-version $2 $1; then + toc2_loudly "${TOC2_EMOTICON_OKAY} found $1 >= $2" + fi + else + toc2_loudly "${TOC2_EMOTICON_OKAY} found $1" + fi + varname=$(echo $1 | tr -s '[a-z.+\-]' '[A-Z___]') + toc2_export_make ${varname}_CFLAGS="$(pkg-config --cflags $1)" || toc2_die $? "toc2_export_make ${varname} failed" + toc2_export_make ${varname}_LIBS="$(pkg-config --libs $1)" || toc2_die $? "toc2_export_make ${varname} failed" + else + echo + if [ -z "$2" ]; then + # die "$1 was not found" + return 1 + else + return 2 + # die "$1 >= $2 was not found" + fi + fi +} + +pkg_config_check "$@" +return $? + diff --git a/toc2/tests/toc2_core_tests.sh b/toc2/tests/toc2_core_tests.sh new file mode 100644 index 00000000..601e5dce --- /dev/null +++ b/toc2/tests/toc2_core_tests.sh @@ -0,0 +1,72 @@ +#!/do/not/bash +# toc2_run_description = Looking for required build components... +# toc2_begin_help = +# To be sourced from toc2_core.sh. This is the core sanity checker for +# toc. Any test which MUST pass for a tree to be considered +# toc-capable may be placed in here. +# = toc2_end_help + +toc2_run toc2_running_under_cygwin +# toc2_quietly "Looking for required build components:" +for x in \ + bash=SHELL \ + cat=CAT \ + cut=CUT \ + ls=LS \ + perl=PERL \ + sed=SED \ + xargs=XARGS \ + ; do + f=${x%%=*} + v=${x##*=} + toc2_find $f || { + echo "configure couldn't find required app: $f" + return 1 + } + test "x$v" = "xXtocX" && continue + toc2_export_make $v=${TOC2_FIND_RESULT} +done + +toc2_find less || toc2_find more || { + echo "Found neither 'more' nor 'less'!!!" + return 1 +} + +toc2_find_require install-sh ${TOC2_HOME}/bin +# toc2_export_make toc2.bins.installer="\$(top_srcdir)/${TOC2_FIND_RESULT##${PWD}/}" +toc2_export_make toc2.bins.installer="${TOC2_FIND_RESULT}" + +toc2_find_require makedist ${TOC2_HOME}/bin +toc2_export_make toc2.bins.makedist="${TOC2_FIND_RESULT}" +# it's very arguable to make makedist a required component :/ + +for x in \ + awk \ + gnu_make \ + gnu_find \ + gnu_tar \ + ; do + toc2_test $x || { + echo "${TOC2_EMOTICON_ERROR} $x test failed." + return 1 + } +done + +#toc2_test gnu_install || { +# boldecho "Didn't find GNU install. You won't be able to do a 'make install'." +#} + +toc2_quietly "Looking for optional build components:" +for x in \ + gzip=GZIP \ + bzip2=BZIP \ + zip=ZIP \ + ; do + f=${x%%=*} + v=${x##*=} + foo=configure_with_${f} + toc2_find $f + toc2_export_make $v=${TOC2_FIND_RESULT} +done + +return 0 diff --git a/toc2/tests/toc2_make.sh b/toc2/tests/toc2_make.sh new file mode 100644 index 00000000..78f86438 --- /dev/null +++ b/toc2/tests/toc2_make.sh @@ -0,0 +1,62 @@ +#!/do/not/bash +# toc2_run_description = creating included makefiles +# Do not run this test manually: it is run by the toc core. + + +TOC2_MAKE=toc2.make + +toc2_export_make TOC2_MAKE=${TOC2_MAKE} + +# set -x +toc2_make_toc2_make () +{ + # use a function because bash doesn't allow local vars outside of functions. + local usage="usage: arg1==target makefile basename. arg2=input template" + local themake=${1?$usage} + local themakein=${2?$usage} + echo "Creating $themake ... " + local makeprops=${TOC2_TOP_SRCDIR}/.toc.make.tmp + toc2_dump_make_properties > $makeprops + local thedir + local tocmake + local relpath + local shortform + local tocmakeprops + for d in $(find ${TOC2_TOP_SRCDIR} -name Makefile -o -name 'GNU[Mm]akefile' -o -name Makefile.toc \ + | xargs grep -E -l "include.+${themake}" | sort -u); do + #echo "d=$d" >&2 + thedir=$(dirname $d) + tocmake=${thedir}/$themake + toc2_makerelative $thedir + relpath=${TOC2_MAKERELATIVE} + tocmake=${tocmake##$TOC2_TOP_SRCDIR/} # make it short, for asthetic reasons :/ + shortform=${thedir##${PWD}/} + test "$shortform" = "$PWD" && shortform= # top-most dir +# echo "tocmake=$tocmake relpath=$relpath shortform=$shortform" + + tocmakeprops=${cmake}.props + cp $makeprops $tocmakeprops + cat <<EOF >> $tocmakeprops +TOC2_TOP_SRCDIR=${relpath##./} +TOC2_RELATIVE_DIR=${shortform##./} +EOF + toc2_atfilter_file $tocmakeprops $themakein $tocmake \ + || toc2_die $? "Error creating $themake!" + rm $tocmakeprops + touch $tocmake # required for proper auto-reconfigure :/ + done +} + +toc2_make_toc2_make ${TOC2_MAKE} ${TOC2_HOME}/make/${TOC2_MAKE}.at +err=$? +test $err != 0 && { + echo "Error creating ${TOC2_MAKE} makefiles!" + return $err +} + +return $err + + + + + diff --git a/toc2/tests/toc2_project_makefile.sh b/toc2/tests/toc2_project_makefile.sh new file mode 100644 index 00000000..6d494584 --- /dev/null +++ b/toc2/tests/toc2_project_makefile.sh @@ -0,0 +1,25 @@ +#!/do/not/bash + +# Creates toc.${PACKAGE_NAME}.make from toc.${PACKAGE_NAME}.make.at +# This file is sought by toc2.make (but is always optional). + +mf=${1-toc2.${PACKAGE_NAME}.make} +tmpl=$mf.at +test -f $tmpl || { + toc2_export_make toc2_include_project_makefile=0 +cat <<EOF +No project-specific makefile found at [$mf]. +This is not technically a problem, but please ensure that your +tree does not need this file. If it does not, then please +call 'touch $tmpl' to create an empty one. +EOF + return 1 +} + +toc2_atfilter_as_makefile $tmpl $mf || { + err=$? + echo "Error filtering $tmpl!" + return $err +} + +# toc2_export_make toc2_include_project_makefile="\$(top_srcdir)/${mf}" diff --git a/toc2/tests/toc2_running_under_cygwin.sh b/toc2/tests/toc2_running_under_cygwin.sh new file mode 100644 index 00000000..17203e6c --- /dev/null +++ b/toc2/tests/toc2_running_under_cygwin.sh @@ -0,0 +1,13 @@ +# toc2_run_description = building under cygwin? + +test -d /cygdrive/c +err=$? +if test $err = 0 ; then + toc2_add_config SMELLS_LIKE_CYGWIN=1 + echo "Detected cygwin." +else + toc2_add_config SMELLS_LIKE_CYGWIN=0 +fi +return $err + + diff --git a/toc2/tests/toc2_tests_help.sh b/toc2/tests/toc2_tests_help.sh new file mode 100644 index 00000000..84175ea8 --- /dev/null +++ b/toc2/tests/toc2_tests_help.sh @@ -0,0 +1,68 @@ +#!/do/not/bash +# toc2_run_description = checks for --help-X and tries to do something about it. +# toc2_begin_help = +# +# toc2_tests_help looks for vars named help_* and tries to find help text for +# tests matching that pattern (that is, help_foo looks for help for test foo). +# To add help to your test wrap it in a block which begins with +# the text 'toc2_begin_help =' and end it with '= toc2_end_help' +# +# This test returns zero only if no --help-X options are specified. +# +# The --help-TESTNAME options do not properly work with tests which: +# +# - do not live directly in toc/tests +# - contain minus signs in their names +# +# The workaround is to use --help-tests, which will provide you with a selection +# list of all tests under toc/tests and it's subdirectories. +# +# = toc2_end_help + +toc2_show_test_help () +{ + local scr=${1?first argument must be a filename} + test -f $scr || toc2_die 127 "Test $scr not found!" + sed -n '/^# *toc2_begin_help *=/,/^#\ *= *toc2_end_help/p' $scr | \ + sed '/^# *toc2_begin_help *=/d;/^# *= *toc2_end_help/d;s/^# */ /;' +} + + +toc2_select_test_help () +{ + local tests=$(cd ${TOC2_HOME}/tests; find . -type f -name '*.sh' | xargs grep -l toc2_begin_help | sort | sed -e "s,\./,,;s,\.sh,,;") + PS3="Select a test to show it's help: " + select T in $tests; do + echo "Help for '$T' test:" + toc2_show_test_help ${TOC2_HOME}/tests/${T}.sh + break + # i'd like to loop, but the selection list is only shown on the first run, + # and quickly scrolls off the screen, making a 'break' the only usable option. + done +} + + +if test x1 = x${help_tests} ; then + toc2_select_test_help + return 1 +fi + +helps="$(env | grep '^help_')" +test -n "$helps" || return 0 +for h in $helps; do + test=${h##help_} + test=${test%%=*} + echo "help for test: $test" + toc2_find_test $test || { + echo "Error: cannot find test $test." + return 1 + } + scr=${TOC2_FIND_RESULT} + grep -q "toc2_begin_help" $scr || { + echo "No help text found." + continue + } + toc2_show_test_help $scr +done + +return 1 diff --git a/toc2/tests/user_is_stephan_beal.sh b/toc2/tests/user_is_stephan_beal.sh new file mode 100644 index 00000000..711b83bf --- /dev/null +++ b/toc2/tests/user_is_stephan_beal.sh @@ -0,0 +1,24 @@ +#!/do/not/bash +# toc2_run_description = If you appear to be stephan beal, set up some common stuff... + + +test xstephan = "x${USER}" || return 1 + +got=0 + +for h in cheyenne ludo jareth hoggle owl; do + test x$h = "x${HOSTNAME}" && { got=1; break; } +done + +test $got = 0 && return 1 + +echo "Setting up stephan's always-used settings..." + +{ # for gnu_cpp_tools toc test: + echo "Enabling debug/werror/wall." + export configure_enable_debug=1 + export configure_enable_werror=1 + export configure_enable_wall=1 +} + +return 0 |