From: Marko Kreen Date: Tue, 29 Nov 2011 19:53:30 +0000 (+0200) Subject: Tests & demos for antimake X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=0d4b22214f0cdca4c46df5be1672e09d7d2111ed;p=libusual.git Tests & demos for antimake --- diff --git a/Makefile b/Makefile index 67eba46..2e1d4ad 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,11 @@ sparse: config.mak # generate api documentation dox: + rm -rf doc/html/mk + #rm -rf mk/temos/html doxygen doc/Doxyfile + $(MAKE) -C mk/temos + cp -rp mk/temos/html doc/html/mk # # rest is for pgutil_kwlookup generation diff --git a/doc/mainpage.dox b/doc/mainpage.dox index 0e61c4a..88cc190 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -23,6 +23,10 @@ * for some special case than complex code that tries to handle * everything at once. * + * @section antimake Antimake build system. + * + * Build system demos and docs. + * * @section modules Module list. * * diff --git a/mk/temos/Makefile b/mk/temos/Makefile new file mode 100644 index 0000000..2ed65d3 --- /dev/null +++ b/mk/temos/Makefile @@ -0,0 +1,72 @@ +# +# This Makefile does not use Antimake because it must work +# even when Antimake is broken. +# + +TEMOS = \ + antimake1 antimake2 antimake3 antimake4 antimake5 antimake6 \ + libusual1 libusual2 libusual3 libusual4 libusual5 libusual6 \ + + + +OUT = $(addsuffix .txt,$(addprefix output/, $(TEMOS))) +HTML = $(addsuffix .html,$(addprefix html/, $(TEMOS))) \ + html/index.html html/antimake.html + +ExpFile = $(subst .temo,.txt,$(subst src/,expected/,$(1))) +OutFile = $(subst .temo,.txt,$(subst src/,output/,$(1))) + +V ?= 0 +ifeq ($(V),0) +E = @echo +Q = @ +else +E = @true +Q = +endif + +all: qtest + +.PHONY: all test ack clean html + +html: $(HTML) + +am: + rm -f html/anti* + make + +ftest: clean qtest +qtest: $(OUT) + @diff -urN expected output > regressions.diff || { \ + less regressions.diff; \ + echo "FAIL: Result does not match expected output"; \ + exit 1; \ + } + $(Q) rm -f regressions.diff + $(E) "All OK" + +#../antimake.mk ../../m4/usual.m4 +output/%.txt: src/%.temo libtemo.sh + @mkdir -p output + @printf "$< ... " + @bash $< > $@ && { cmp -s $@ $(call ExpFile,$<) && echo ok || echo failed; } \ + || { echo "$< failed:" ; tail $(call OutFile,$<); exit 1; } + +html/%.html: output/%.txt + @mkdir -p html + asciidoc -o $@ $< + +ack: + cp output/*.txt expected/ + +clean: + rm -rf tmp html output regressions.diff + +html/index.html: index.txt + @mkdir -p html + asciidoc -o $@ $< + +html/antimake.html: ../antimake.txt + @mkdir -p html + asciidoc -a toc -o $@ $< + diff --git a/mk/temos/expected/antimake1.txt b/mk/temos/expected/antimake1.txt new file mode 100644 index 0000000..9ee5165 --- /dev/null +++ b/mk/temos/expected/antimake1.txt @@ -0,0 +1,116 @@ + += Test Antimake = + + +== Simplest usage == + + +Here we avoid use of any autotools. + + +First, this is the source file: + +.File: hello.c +[source,c] +----------------------------------- +#include + +int main(void) +{ + printf("Hello, world\n"); + return 0; +} +----------------------------------- + +Here is corresponding Makefile: + +.File: Makefile +[source,makefile] +----------------------------------- +# This is target list - it's name describes target type +# and how it is installed, it's value target files to be built. +# bin - the targets will be installed under $(bindir) +# PROGRAMS - the target is executable built from many sources +bin_PROGRAMS = hello + +# The target 'hello'-s source file list. +hello_SOURCES = hello.c + +# Run Antimake +include antimake.mk +----------------------------------- + +Also install Antimake and we are ready to build: + +--------------------------------- +$ cp ../../antimake.mk . +$ ls +Makefile antimake.mk hello.c +--------------------------------- + +Build the project + +--------------------------------- +$ make + CC hello.c + CCLD hello +$ ls +Makefile antimake.mk hello hello.c +$ ./hello +Hello, world +--------------------------------- + +We can even install it already: + +--------------------------------- +$ make install prefix=/opt + INSTALL hello /opt/bin +$ ls /opt/bin +hello prog +--------------------------------- + +For creating source package, we need to provide additional info: + +.File: Makefile +[source,makefile] +----------------------------------- +# Package name and version for tarball filename +PACKAGE_NAME = myhello +PACKAGE_VERSION = 1.0 + +# Non-source files to put into tarball +EXTRA_DIST = Makefile antimake.mk + +bin_PROGRAMS = hello +hello_SOURCES = hello.c +include antimake.mk +----------------------------------- + +Now we can create package that can be given to others. + +--------------------------------- +$ make dist + CHECK dist-gzip + MKDIR myhello-1.0 + COPY myhello-1.0 + PACK myhello-1.0.tar.gz +$ ls +Makefile antimake.mk hello hello.c myhello-1.0.tar.gz +$ tar tzf myhello-1.0.tar.gz | sort +myhello-1.0/ +myhello-1.0/Makefile +myhello-1.0/antimake.mk +myhello-1.0/hello.c +--------------------------------- + +Clean the tree + +--------------------------------- +$ make clean + CLEAN hello +$ ls +Makefile antimake.mk hello.c myhello-1.0.tar.gz +--------------------------------- + +Done! + diff --git a/mk/temos/expected/antimake2.txt b/mk/temos/expected/antimake2.txt new file mode 100644 index 0000000..abd4e87 --- /dev/null +++ b/mk/temos/expected/antimake2.txt @@ -0,0 +1,252 @@ + += Test Antimake SUBDIRS = + + +Antimake variable `SUBDIRS` list names of directories that the Make +needs to recurse into. Each of them contains stand-alone Makefile +that directs building in that subdirs. + +- Plus: you can call 'make' while being in subdir to build only local targets. +- Minus: dependencies between subdirs do not work. + + +== Setup source tree == + + +Setup directories, install Antimake + +--------------------------------- +$ mkdir -p lib1/sublib lib2 +$ cp ../../antimake.mk . +--------------------------------- + +Prepare sources + +.File: main.c +[source,c] +----------------------------------- +#include + +int main(void) +{ + func1(); + func2(); + func3(); + printf("main\n"); + return 0; +} +----------------------------------- +.File: lib1/func1.c +[source,c] +----------------------------------- +#include + +void func1(void) +{ + printf("func1\n"); +} +----------------------------------- +.File: lib1/sublib/func2.c +[source,c] +----------------------------------- +#include + +void func2(void) +{ + printf("func2\n"); +} +----------------------------------- +.File: lib2/func3.c +[source,c] +----------------------------------- +#include + +void func3(void) +{ + printf("func3\n"); +} +----------------------------------- + +Prepare Makefiles + +.File: Makefile +[source,makefile] +----------------------------------- +PACKAGE_NAME = test-subdirs +PACKAGE_VERSION = 1.0 + +SUBDIRS = lib1 lib2 + +bin_PROGRAMS = prog +prog_SOURCES = main.c +prog_LDADD = lib1/func1.a lib1/sublib/func2.a lib2/func3.a + +EXTRA_DIST = Makefile antimake.mk + +include antimake.mk +----------------------------------- +.File: lib1/Makefile +[source,makefile] +----------------------------------- +SUBLOC = lib1 +SUBDIRS = sublib + +noinst_LIBRARIES = func1.a +func1_a_SOURCES = func1.c + +EXTRA_DIST = Makefile + +include ../antimake.mk +----------------------------------- +.File: lib1/sublib/Makefile +[source,makefile] +----------------------------------- +SUBLOC = lib1/sublib + +noinst_LIBRARIES = func2.a +func2_a_SOURCES = func2.c + +EXTRA_DIST = Makefile + +include ../../antimake.mk +----------------------------------- +.File: lib2/Makefile +[source,makefile] +----------------------------------- +SUBLOC = lib2 + +noinst_LIBRARIES = func3.a +func3_a_SOURCES = func3.c + +EXTRA_DIST = Makefile + +include ../antimake.mk +----------------------------------- + +== Building == + + +Build the project + +--------------------------------- +$ make + --> lib1 + --> lib1/sublib + CC func2.c + AR func2.a + RANLIB func2.a + <-- lib1/sublib + CC func1.c + AR func1.a + RANLIB func1.a + <-- lib1 + --> lib2 + CC func3.c + AR func3.a + RANLIB func3.a + <-- lib2 + CC main.c + CCLD prog +$ ls +Makefile antimake.mk lib1 lib2 main.c prog +$ ./prog +func1 +func2 +func3 +main +--------------------------------- + +We can even install it already: + +--------------------------------- +$ make install prefix=/opt + --> lib1 + --> lib1/sublib +make[2]: Nothing to be done for `install'. + <-- lib1/sublib + <-- lib1 + --> lib2 +make[1]: Nothing to be done for `install'. + <-- lib2 + INSTALL prog /opt/bin +$ ls /opt/bin +hello prog +--------------------------------- + +Now we can create package that can be given to others. + +--------------------------------- +$ make dist + CHECK dist-gzip + MKDIR test-subdirs-1.0 + COPY test-subdirs-1.0 + PACK test-subdirs-1.0.tar.gz +$ ls +Makefile antimake.mk lib1 lib2 main.c prog test-subdirs-1.0.tar.gz +$ tar tzf test-subdirs-1.0.tar.gz | sort +test-subdirs-1.0/ +test-subdirs-1.0/Makefile +test-subdirs-1.0/antimake.mk +test-subdirs-1.0/lib1/ +test-subdirs-1.0/lib1/Makefile +test-subdirs-1.0/lib1/func1.c +test-subdirs-1.0/lib1/sublib/ +test-subdirs-1.0/lib1/sublib/Makefile +test-subdirs-1.0/lib1/sublib/func2.c +test-subdirs-1.0/lib2/ +test-subdirs-1.0/lib2/Makefile +test-subdirs-1.0/lib2/func3.c +test-subdirs-1.0/main.c +--------------------------------- + +Clean the tree + +--------------------------------- +$ make clean + --> lib1 + --> lib1/sublib + CLEAN func2.a + <-- lib1/sublib + CLEAN func1.a + <-- lib1 + --> lib2 + CLEAN func3.a + <-- lib2 + CLEAN prog +$ ls +Makefile antimake.mk lib1 lib2 main.c test-subdirs-1.0.tar.gz +--------------------------------- + +Test O= + +--------------------------------- +$ mkdir -p build +$ make O=build + MKDIR Create lib1 + --> lib1 + MKDIR Create lib1/sublib + --> lib1/sublib + CC ../../../lib1/sublib/func2.c + AR func2.a + RANLIB func2.a + <-- lib1/sublib + CC ../../lib1/func1.c + AR func1.a + RANLIB func1.a + <-- lib1 + MKDIR Create lib2 + --> lib2 + CC ../../lib2/func3.c + AR func3.a + RANLIB func3.a + <-- lib2 + CC ../main.c + CCLD prog +$ ls +Makefile antimake.mk build lib1 lib2 main.c test-subdirs-1.0.tar.gz +$ ls build +Makefile antimake.mk lib1 lib2 prog +--------------------------------- + +Done! + diff --git a/mk/temos/expected/antimake3.txt b/mk/temos/expected/antimake3.txt new file mode 100644 index 0000000..87dc7b2 --- /dev/null +++ b/mk/temos/expected/antimake3.txt @@ -0,0 +1,261 @@ + += Test Antimake EMBED_SUBDIRS = + + +Antimake variable `EMBED_SUBDIRS` list names of directories that +contains Makefile fragmants that are to be embedded into current +Makefile. + +- Plus: Proper dependencies, work well with parallel Make. +- Minus: Cannot go into subdir and run make there. +- Minus: Fragments are not stand-alone, so need some care when writing. + + +== Intro to EMBED_SUBDIRS == + + +To better understand what EMBED_SUBDIRS does, let\'s start with simple +case - single Makefile that references files under subdir: + +--------------------------------- +$ mkdir -p src +$ cp ../../antimake.mk . +--------------------------------- +.File: Makefile +[source,makefile] +----------------------------------- +bin_PROGRAMS = src/myprog +src_myprog_SOURCES = src/myprog.c +include antimake.mk +----------------------------------- +.File: src/myprog.c +[source,c] +----------------------------------- +#include + +int main(void) +{ + printf("myprog\n"); + return 0; +} +----------------------------------- +--------------------------------- +$ make + CC src/myprog.c + CCLD src/myprog +$ ./src/myprog +myprog +$ make clean + CLEAN src/myprog +--------------------------------- + +Now you can put the lines that reference files under `src/` +also into `src` and include that from top-level Makefile: + +.File: src/Makefile.inc +----------------------------------- +bin_PROGRAMS = src/myprog +src_myprog_SOURCES = src/myprog.c +----------------------------------- +.File: Makefile +[source,makefile] +----------------------------------- +include src/Makefile.inc +include antimake.mk +----------------------------------- +--------------------------------- +$ make + CC src/myprog.c + CCLD src/myprog +$ ./src/myprog +myprog +--------------------------------- + +This works but the problem is that although the Makefile is local, +it still sees files from top-Makefile-level. So that is what `EMBED_SUBDIRS` +helps with - it allow to use local filenames in Makefile fragment, +and it converts them to top-level filenames when including. It knows +only few type of variables it needs to convert: + +- target filenames in primares lists (*_PROGRAMS, *_LIBRARIES, etc) +- target_SOURCES: foo_SOURCES -> sub_dir_foo_SOURCES with filename conversion +- other target variables: `foo_*` -> `sub_dir_foo_*` without filename conversion +- EXTRA_DIST, CLEANFILES, DISTCLEANFILES, MAINTAINERCLEANFILES + +Any other variables stay untouched, and obviously they can mess up top-level variables. +So the included Makefile should be as clean as possible. + + +== Setup source tree for EMBED_SUBDIRS == + + +Setup directories, install Antimake + +--------------------------------- +$ mkdir -p lib1/sublib lib2 +$ cp ../../antimake.mk . +--------------------------------- + +Prepare sources + +.File: main.c +[source,c] +----------------------------------- +#include + +int main(void) +{ + func1(); + func2(); + func3(); + printf("main\n"); + return 0; +} +----------------------------------- +.File: lib1/func1.c +[source,c] +----------------------------------- +#include + +void func1(void) +{ + printf("func1\n"); +} +----------------------------------- +.File: lib1/sublib/func2.c +[source,c] +----------------------------------- +#include + +void func2(void) +{ + printf("func2\n"); +} +----------------------------------- +.File: lib2/func3.c +[source,c] +----------------------------------- +#include + +void func3(void) +{ + printf("func3\n"); +} +----------------------------------- + +Prepare Makefiles + +.File: Makefile +[source,makefile] +----------------------------------- +PACKAGE_NAME = test-subdirs +PACKAGE_VERSION = 1.0 + +EMBED_SUBDIRS = lib1 lib1/sublib lib2 + +bin_PROGRAMS = prog +prog_SOURCES = main.c +prog_LDADD = lib1/func1.a lib1/sublib/func2.a lib2/func3.a + +EXTRA_DIST = Makefile antimake.mk + +include antimake.mk +----------------------------------- +.File: lib1/Makefile.am +----------------------------------- +noinst_LIBRARIES = func1.a +func1_a_SOURCES = func1.c + +EXTRA_DIST = Makefile.am +----------------------------------- +.File: lib1/sublib/Makefile.am +----------------------------------- +noinst_LIBRARIES = func2.a +func2_a_SOURCES = func2.c +EXTRA_DIST = Makefile.am +----------------------------------- +.File: lib2/Makefile.am +----------------------------------- +noinst_LIBRARIES = func3.a +func3_a_SOURCES = func3.c + +EXTRA_DIST = Makefile.am +----------------------------------- + +== Building == + + +Build the project + +--------------------------------- +$ make + CC main.c + CC lib1/func1.c + AR lib1/func1.a + RANLIB lib1/func1.a + CC lib1/sublib/func2.c + AR lib1/sublib/func2.a + RANLIB lib1/sublib/func2.a + CC lib2/func3.c + AR lib2/func3.a + RANLIB lib2/func3.a + CCLD prog +$ ls +Makefile antimake.mk lib1 lib2 main.c prog src +$ ./prog +func1 +func2 +func3 +main +--------------------------------- + +We can even install it already: + +--------------------------------- +$ make install prefix=/opt + INSTALL prog /opt/bin +$ ls /opt/bin +hello prog +--------------------------------- + +Now we can create package that can be given to others. + +--------------------------------- +$ make dist + CHECK dist-gzip + MKDIR test-subdirs-1.0 + COPY test-subdirs-1.0 + PACK test-subdirs-1.0.tar.gz +$ ls +Makefile antimake.mk lib1 lib2 main.c prog src test-subdirs-1.0.tar.gz +$ tar tzf test-subdirs-1.0.tar.gz | sort +test-subdirs-1.0/ +test-subdirs-1.0/Makefile +test-subdirs-1.0/antimake.mk +test-subdirs-1.0/lib1/ +test-subdirs-1.0/lib1/Makefile.am +test-subdirs-1.0/lib1/func1.c +test-subdirs-1.0/lib1/sublib/ +test-subdirs-1.0/lib1/sublib/Makefile.am +test-subdirs-1.0/lib1/sublib/func2.c +test-subdirs-1.0/lib2/ +test-subdirs-1.0/lib2/Makefile.am +test-subdirs-1.0/lib2/func3.c +test-subdirs-1.0/main.c +--------------------------------- + +Clean the tree + +--------------------------------- +$ make clean + CLEAN prog + CLEAN lib1/func1.a + CLEAN lib1/sublib/func2.a + CLEAN lib2/func3.a + CLEAN clean +$ ls +Makefile antimake.mk lib1 lib2 main.c src test-subdirs-1.0.tar.gz +--------------------------------- + +Done! + diff --git a/mk/temos/expected/antimake4.txt b/mk/temos/expected/antimake4.txt new file mode 100644 index 0000000..4913888 --- /dev/null +++ b/mk/temos/expected/antimake4.txt @@ -0,0 +1,134 @@ + += Using Antimake with autoconf = + + +Autoconf setup + +.File: autogen.sh +[source,shell] +----------------------------------- +libtoolize -i -q +aclocal -I../../../m4 +autoconf +rm -rf autom4te.cache ltmain.sh aclocal.m4 + +# fetch Antimake template from libusual +cp ../../antimake.mk antimake.mk.in +----------------------------------- +.File: configure.ac +[source,autoconf] +----------------------------------- +AC_INIT([actest], [0.1]) +AC_CONFIG_SRCDIR([prog.c]) +AC_PREREQ([2.59]) + +AC_USUAL_INIT +AC_USUAL_PROGRAM_CHECK + +AC_OUTPUT([antimake.mk]) +----------------------------------- + +Here is the source we want to build: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include + +int main(void) +{ + printf("hello\n"); + return 0; +} +----------------------------------- + +Antimake based Makefile + +.File: Makefile +[source,makefile] +----------------------------------- +# the automake-style build description for 'prog' +noinst_PROGRAMS = prog +prog_SOURCES = prog.c + +EXTRA_DIST = Makefile $(MAINTAINERCLEANFILES) + +# clean configured files +DISTCLEANFILES = config.status config.log antimake.mk + +# clean generated files +MAINTAINERCLEANFILES = configure config.guess config.sub install-sh antimake.mk.in + +# launch Antimake +include antimake.mk +----------------------------------- + +Build the project + +--------------------------------- +$ sh ./autogen.sh +$ ./configure +[...] +$ make + CC prog.c + CCLD prog +$ ls +Makefile autogen.sh config.status configure.ac prog.c +antimake.mk config.guess config.sub install-sh +antimake.mk.in config.log configure prog +$ ./prog +hello +--------------------------------- + +Create distribution package + +--------------------------------- +$ make dist + CHECK dist-gzip + MKDIR actest-0.1 + COPY actest-0.1 + PACK actest-0.1.tar.gz +$ tar tzf actest-0.1.tar.gz | sort +actest-0.1/ +actest-0.1/Makefile +actest-0.1/antimake.mk.in +actest-0.1/config.guess +actest-0.1/config.sub +actest-0.1/configure +actest-0.1/install-sh +actest-0.1/prog.c +--------------------------------- + +Test the distribution package and separate build dir + +--------------------------------- +$ mkdir -p test +$ cd test +$ tar xf ../actest-0.1.tar.gz +$ mkdir build +$ cd build +$ ../actest-0.1/configure +[...] +$ make + CC ../actest-0.1/prog.c + CCLD prog +$ ls +Makefile antimake.mk config.log config.status prog +$ ./prog +hello +$ cd ../.. +--------------------------------- + +Clean up + +--------------------------------- +$ make maintainer-clean + CLEAN prog + MAINTAINERCLEAN maintainer-clean +$ ls +Makefile actest-0.1.tar.gz autogen.sh configure.ac prog.c test +--------------------------------- + +Done + diff --git a/mk/temos/expected/antimake5.txt b/mk/temos/expected/antimake5.txt new file mode 100644 index 0000000..59ce102 --- /dev/null +++ b/mk/temos/expected/antimake5.txt @@ -0,0 +1,194 @@ + += Shared libraries and autoconf = + + +Autoconf setup + +.File: autogen.sh +[source,shell] +----------------------------------- +libtoolize -i -q +aclocal -I../../../m4 +autoconf +rm -rf autom4te.cache aclocal.m4 + +# fetch Antimake template from libusual +cp ../../antimake.mk antimake.mk.in +----------------------------------- +.File: configure.ac +[source,autoconf] +----------------------------------- +AC_INIT([actest], [0.1]) +AC_CONFIG_SRCDIR([prog.c]) +AC_PREREQ([2.59]) + +LT_INIT +AC_USUAL_INIT + +AC_USUAL_PROGRAM_CHECK + +AC_OUTPUT([antimake.mk]) +----------------------------------- + +Here are the source files: + +.File: prog.c +[source,c] +----------------------------------- +void func1(void); +int main(void) +{ + func1(); + return 0; +} +----------------------------------- +.File: func.c +[source,c] +----------------------------------- +#include + +void func1(void) +{ + printf("hello from func1\n"); +} +----------------------------------- + +Antimake based Makefile + +.File: Makefile +[source,makefile] +----------------------------------- +lib_LTLIBRARIES = libtemo.la +libtemo_la_SOURCES = func.c +libtemo_la_LDFLAGS = -version-info 3:0:2 + +bin_PROGRAMS = prog +prog_SOURCES = prog.c +prog_LDADD = libtemo.la + +# clean configured files +DISTCLEANFILES = \ + config.status \ + config.log \ + antimake.mk \ + libtool + +# clean generated files +MAINTAINERCLEANFILES = \ + configure \ + config.guess \ + config.sub \ + install-sh \ + antimake.mk.in \ + ltmain.sh + +EXTRA_DIST = \ + Makefile \ + $(MAINTAINERCLEANFILES) + +# launch Antimake +include antimake.mk +----------------------------------- + +Build the project + +--------------------------------- +$ sh ./autogen.sh +$ ./configure +[...] +$ make + CC prog.c + CC func.c + CCLD libtemo.la + CCLD prog +$ ls +Makefile autogen.sh config.status configure.ac libtemo.la prog +antimake.mk config.guess config.sub func.c libtool prog.c +antimake.mk.in config.log configure install-sh ltmain.sh +$ ./prog +hello from func1 +--------------------------------- + +Create distribution package + +--------------------------------- +$ make dist + CHECK dist-gzip + MKDIR actest-0.1 + COPY actest-0.1 + PACK actest-0.1.tar.gz +$ tar tzf actest-0.1.tar.gz | sort +actest-0.1/ +actest-0.1/Makefile +actest-0.1/antimake.mk.in +actest-0.1/config.guess +actest-0.1/config.sub +actest-0.1/configure +actest-0.1/func.c +actest-0.1/install-sh +actest-0.1/ltmain.sh +actest-0.1/prog.c +--------------------------------- + +Test installation + +--------------------------------- +$ make install DESTDIR=/tmp/test-inst + INSTALL prog /tmp/test-inst/usr/local/bin + INSTALL libtemo.la /tmp/test-inst/usr/local/lib +libtool: install: warning: remember to run `libtool --finish /usr/local/lib' +$ ls +Makefile autogen.sh config.sub install-sh prog +actest-0.1.tar.gz config.guess configure libtemo.la prog.c +antimake.mk config.log configure.ac libtool +antimake.mk.in config.status func.c ltmain.sh +$ find /tmp/test-inst | sort +/tmp/test-inst +/tmp/test-inst/usr +/tmp/test-inst/usr/local +/tmp/test-inst/usr/local/bin +/tmp/test-inst/usr/local/bin/prog +/tmp/test-inst/usr/local/lib +/tmp/test-inst/usr/local/lib/libtemo.a +/tmp/test-inst/usr/local/lib/libtemo.la +/tmp/test-inst/usr/local/lib/libtemo.so +/tmp/test-inst/usr/local/lib/libtemo.so.1 +/tmp/test-inst/usr/local/lib/libtemo.so.1.2.0 +$ rm -rf /tmp/test-inst +--------------------------------- + +Test the distribution package and separate build dir + +--------------------------------- +$ mkdir -p test +$ cd test +$ tar xf ../actest-0.1.tar.gz +$ mkdir build +$ cd build +$ ../actest-0.1/configure +[...] +$ make + CC ../actest-0.1/prog.c + CC ../actest-0.1/func.c + CCLD libtemo.la + CCLD prog +$ ls +Makefile antimake.mk config.log config.status libtemo.la libtool prog +$ ./prog +hello from func1 +$ cd ../.. +--------------------------------- + +Clean up + +--------------------------------- +$ make maintainer-clean + CLEAN prog + CLEAN libtemo.la + MAINTAINERCLEAN maintainer-clean +$ ls +Makefile actest-0.1.tar.gz autogen.sh configure.ac func.c prog.c test +--------------------------------- + +Done + diff --git a/mk/temos/expected/antimake6.txt b/mk/temos/expected/antimake6.txt new file mode 100644 index 0000000..1bfdfd6 --- /dev/null +++ b/mk/temos/expected/antimake6.txt @@ -0,0 +1,432 @@ + += Antimake stress-test = + + +Autoconf setup + +.File: autogen.sh +[source,shell] +----------------------------------- +libtoolize -i -q +aclocal -I../../../m4 +autoconf +rm -rf autom4te.cache aclocal.m4 + +# fetch Antimake template from libusual +grep -Ei '@[a-z_]+@' ../../antimake.mk > build.mk.in +echo 'include $(abs_top_srcdir)/antimake.mk' >> build.mk.in +ln -sf ../../antimake.mk . +----------------------------------- +.File: configure.ac +[source,autoconf] +----------------------------------- +AC_INIT([actest], [0.1]) +AC_CONFIG_SRCDIR([esub/prog.c]) +AC_PREREQ([2.59]) +AC_USUAL_INIT +LT_INIT +AC_USUAL_PROGRAM_CHECK +AC_PROG_CXX +AC_OUTPUT([build.mk]) +----------------------------------- + +Here are the source files: + + +------------- +./prog.c +./cpptest.cpp +./sub/func1.c +./sub/esub/func2,c +./sub/sub/func3.c +./esub/func4.c +./esub/esub/func5.c +./esub/sub/func6.c +------------- + +--------------------------------- +$ mkdir -p sub/esub sub/sub esub/esub esub/sub +--------------------------------- +.File: esub/prog.c +[source,c] +----------------------------------- +#include "func1.h" +#include "func2.h" +#include "func3.h" +#include "func4.h" +#include "func5.h" +#include "func6.h" +#include +int main(void) +{ + printf("%s\n", __FILE__); + func1(); + func2(); + func3(); + func4(); + func5(); + func6(); + return 0; +} +----------------------------------- +.File: cpptest.cpp +----------------------------------- +#include + +using namespace std; +int main(void) +{ + cout << "Hello" << endl; + return 0; +} +----------------------------------- +.File: sub/func1.c +[source,c] +----------------------------------- +#include +#include "func1.h" +void func1(void) +{ + printf("%s\n", __FILE__); +} +----------------------------------- +.File: sub/func1.h +[source,c] +----------------------------------- +void func1(void); +----------------------------------- +--------------------------------- +$ sed s/1/2/ sub/func1.c > sub/esub/func2.c +$ sed s/1/2/ sub/func1.h > sub/esub/func2.h +$ sed s/1/3/ sub/func1.c > sub/sub/func3.c +$ sed s/1/3/ sub/func1.h > sub/sub/func3.h +$ sed s/1/4/ sub/func1.c > esub/func4.c +$ sed s/1/4/ sub/func1.h > esub/func4.h +$ sed s/1/5/ sub/func1.c > esub/sub/func5.c +$ sed s/1/5/ sub/func1.h > esub/sub/func5.h +$ sed s/1/6/ sub/func1.c > esub/esub/func6.c +$ sed s/1/6/ sub/func1.h > esub/esub/func6.h +--------------------------------- + +Now fill makefiles + +.File: Makefile +[source,makefile] +----------------------------------- +SUBDIRS = sub +EMBED_SUBDIRS = esub + +EXTRA_DIST = Makefile antimake.mk $(MAINTAINERCLEANFILES) + +# clean configured files +DISTCLEANFILES = \ + config.status \ + config.log \ + libtool + +# clean generated files +MAINTAINERCLEANFILES = \ + configure \ + config.guess \ + config.sub \ + install-sh \ + build.mk.in \ + ltmain.sh + +noinst_PROGRAMS = cpptest +cpptest_SOURCES = cpptest.cpp + +# launch Antimake +include build.mk +----------------------------------- +.File: sub/Makefile +[source,makefile] +----------------------------------- +SUBLOC = sub +SUBDIRS = sub +EMBED_SUBDIRS = esub + +noinst_LIBRARIES = libfunc1.a +libfunc1_a_SOURCES = func1.c func1.h + +EXTRA_DIST = Makefile +include ../build.mk +----------------------------------- +.File: sub/sub/Makefile +[source,makefile] +----------------------------------- +SUBLOC = sub/sub +EXTRA_DIST = Makefile +noinst_LIBRARIES = libfunc3.a +libfunc3_a_SOURCES = func3.c func3.h + +include ../../build.mk +----------------------------------- +.File: sub/esub/Makefile.am +----------------------------------- +noinst_LIBRARIES = libfunc2.a +libfunc2_a_SOURCES = func2.c func2.h +EXTRA_DIST = Makefile.am +----------------------------------- +.File: esub/Makefile.am +----------------------------------- +SUBDIRS = sub +EMBED_SUBDIRS = esub +EXTRA_DIST = Makefile.am + +noinst_LIBRARIES = libfunc4.a +libfunc4_a_SOURCES = func4.c func4.h + +EXTRA_PROGRAMS = prog +prog_SOURCES = prog.c +prog_LDADD = \ + -L../sub -lfunc1 \ + -L../sub/esub -lfunc2 \ + $(topdir)/sub/sub/libfunc3.a \ + -L. -lfunc4 \ + -Lsub -lfunc5 \ + esub/libfunc6.a + +prog_CFLAGS = -I../sub +prog_CPPFLAGS = \ + -I../sub/esub \ + -I$(topdir)/sub/sub \ + -I. \ + -Iesub \ + -I./sub + +----------------------------------- +.File: esub/sub/Makefile +[source,makefile] +----------------------------------- +SUBLOC = esub/sub +EXTRA_DIST = Makefile +noinst_LIBRARIES = libfunc5.a +libfunc5_a_SOURCES = func5.c func5.h +include ../../build.mk +----------------------------------- +.File: esub/esub/Makefile.am +----------------------------------- +EXTRA_DIST = Makefile.am +noinst_LIBRARIES = libfunc6.a +libfunc6_a_SOURCES = func6.c func6.h +----------------------------------- + +Build the project + +--------------------------------- +$ sh ./autogen.sh +$ ./configure +[...] +$ make + --> sub + --> sub/sub + CC func3.c + AR libfunc3.a + RANLIB libfunc3.a + <-- sub/sub + CC func1.c + AR libfunc1.a + RANLIB libfunc1.a + CC esub/func2.c + AR esub/libfunc2.a + RANLIB esub/libfunc2.a + <-- sub + --> esub/sub + CC func5.c + AR libfunc5.a + RANLIB libfunc5.a + <-- esub/sub + CC esub/func4.c + AR esub/libfunc4.a + RANLIB esub/libfunc4.a + CC esub/esub/func6.c + AR esub/esub/libfunc6.a + RANLIB esub/esub/libfunc6.a + CXX cpptest.cpp + CXXLD cpptest +$ ls +Makefile build.mk config.log configure cpptest.cpp libtool +antimake.mk build.mk.in config.status configure.ac esub ltmain.sh +autogen.sh config.guess config.sub cpptest install-sh sub +$ make esub/prog + CC esub/prog.c + CCLD esub/prog +$ ./esub/prog +esub/prog.c +func1.c +esub/func2.c +func3.c +esub/func4.c +func5.c +esub/esub/func6.c +--------------------------------- + +Create distribution package + +--------------------------------- +$ make dist + CHECK dist-gzip + MKDIR actest-0.1 + COPY actest-0.1 + PACK actest-0.1.tar.gz +$ tar tzf actest-0.1.tar.gz | sort +actest-0.1/ +actest-0.1/Makefile +actest-0.1/antimake.mk +actest-0.1/build.mk.in +actest-0.1/config.guess +actest-0.1/config.sub +actest-0.1/configure +actest-0.1/cpptest.cpp +actest-0.1/esub/ +actest-0.1/esub/Makefile.am +actest-0.1/esub/esub/ +actest-0.1/esub/esub/Makefile.am +actest-0.1/esub/esub/func6.c +actest-0.1/esub/esub/func6.h +actest-0.1/esub/func4.c +actest-0.1/esub/func4.h +actest-0.1/esub/prog.c +actest-0.1/esub/sub/ +actest-0.1/esub/sub/Makefile +actest-0.1/esub/sub/func5.c +actest-0.1/esub/sub/func5.h +actest-0.1/install-sh +actest-0.1/ltmain.sh +actest-0.1/sub/ +actest-0.1/sub/Makefile +actest-0.1/sub/esub/ +actest-0.1/sub/esub/Makefile.am +actest-0.1/sub/esub/func2.c +actest-0.1/sub/esub/func2.h +actest-0.1/sub/func1.c +actest-0.1/sub/func1.h +actest-0.1/sub/sub/ +actest-0.1/sub/sub/Makefile +actest-0.1/sub/sub/func3.c +actest-0.1/sub/sub/func3.h +--------------------------------- + +Test installation + +--------------------------------- +$ make install DESTDIR=`pwd`/inst + --> sub + --> sub/sub +make[2]: Nothing to be done for `install'. + <-- sub/sub + <-- sub + --> esub/sub +make[1]: Nothing to be done for `install'. + <-- esub/sub +$ ls +Makefile build.mk config.status cpptest libtool +actest-0.1.tar.gz build.mk.in config.sub cpptest.cpp ltmain.sh +antimake.mk config.guess configure esub sub +autogen.sh config.log configure.ac install-sh +$ find inst | sort +find: `inst': No such file or directory +--------------------------------- + +Test the distribution package and separate build dir + +--------------------------------- +$ mkdir -p test +$ cd test +$ tar xf ../actest-0.1.tar.gz +$ mkdir build +$ cd build +$ ../actest-0.1/configure +[...] +$ make + MKDIR Create sub + --> sub + MKDIR Create sub/sub + --> sub/sub + CC ../../../actest-0.1/sub/sub/func3.c + AR libfunc3.a + RANLIB libfunc3.a + <-- sub/sub + CC ../../actest-0.1/sub/func1.c + AR libfunc1.a + RANLIB libfunc1.a + CC ../../actest-0.1/sub/esub/func2.c + AR esub/libfunc2.a + RANLIB esub/libfunc2.a + <-- sub + MKDIR Create esub/sub + --> esub/sub + CC ../../../actest-0.1/esub/sub/func5.c + AR libfunc5.a + RANLIB libfunc5.a + <-- esub/sub + CC ../actest-0.1/esub/func4.c + AR esub/libfunc4.a + RANLIB esub/libfunc4.a + CC ../actest-0.1/esub/esub/func6.c + AR esub/esub/libfunc6.a + RANLIB esub/esub/libfunc6.a + CXX ../actest-0.1/cpptest.cpp + CXXLD cpptest +$ ls +Makefile build.mk config.log config.status cpptest esub libtool sub +$ make esub/prog + CC ../actest-0.1/esub/prog.c + CCLD esub/prog +$ ./esub/prog +../actest-0.1/esub/prog.c +../../actest-0.1/sub/func1.c +../../actest-0.1/sub/esub/func2.c +../../../actest-0.1/sub/sub/func3.c +../actest-0.1/esub/func4.c +../../../actest-0.1/esub/sub/func5.c +../actest-0.1/esub/esub/func6.c +$ cd ../.. +--------------------------------- + +Clean up + +--------------------------------- +$ make maintainer-clean + CLEAN esub/libfunc4.a + CLEAN esub/esub/libfunc6.a + CLEAN cpptest + CLEAN esub/prog + --> sub + CLEAN libfunc1.a + CLEAN esub/libfunc2.a + --> sub/sub + CLEAN libfunc3.a + <-- sub/sub + CLEAN clean + <-- sub + --> esub/sub + CLEAN libfunc5.a + <-- esub/sub + CLEAN clean + --> sub + CLEAN libfunc1.a + CLEAN esub/libfunc2.a + --> sub/sub + CLEAN libfunc3.a + <-- sub/sub + CLEAN clean + --> sub/sub + CLEAN libfunc3.a + MAINTAINERCLEAN maintainer-clean + <-- sub/sub + MAINTAINERCLEAN maintainer-clean + <-- sub + --> esub/sub + CLEAN libfunc5.a + MAINTAINERCLEAN maintainer-clean + <-- esub/sub + MAINTAINERCLEAN maintainer-clean +$ ls +Makefile antimake.mk build.mk cpptest.cpp sub +actest-0.1.tar.gz autogen.sh configure.ac esub test +--------------------------------- + +Done + diff --git a/mk/temos/expected/libusual1.txt b/mk/temos/expected/libusual1.txt new file mode 100644 index 0000000..c8b6490 --- /dev/null +++ b/mk/temos/expected/libusual1.txt @@ -0,0 +1,93 @@ + += Use libusual the simplest way = + + +Simplest usage would be to configure and build libusual +locally and point your projects CPPFLAGS and LDFLAGS there. + +That way you get access to not only code but also +various autoconfigued symbols without any complexities +in your project. + + +== Build libusual == + +--------------------------------- +$ git clone git://github.com/libusual/libusual.git lib +Cloning into lib... +done. +$ cd lib +$ ./autogen.sh +[...] +$ ./configure --disable-shared --prefix=/home/marko/src/libusual/mk/temos/tmp/lib/../inst +[...] +$ make +[...] +$ make install +[...] +$ cd .. +--------------------------------- + +== Build our own code == + + +Now we prepare our own code. + + +First, this is the source file: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include +#include + +int main(void) +{ + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; +} +----------------------------------- + +Here is corresponding Makefile: + +.File: Makefile +[source,makefile] +----------------------------------- +# here we describe our program +SRCS = prog.c +OBJS = $(SRCS:.c=.o) + +# here we link to libusual +CPPFLAGS = -I./inst/include +LDFLAGS = -L./inst/lib +LIBS = -lusual + +CC = gcc +CFLAGS = -O -g -Wall + +all: prog + +prog: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ +----------------------------------- + +Build the project + +--------------------------------- +$ make +gcc -O -g -Wall -I./inst/include -c -o prog.o prog.c +gcc -O -g -Wall -L./inst/lib prog.o -lusual -o prog +$ ls +Makefile inst lib prog prog.c prog.o +$ ./prog +crc: 12345678 +--------------------------------- + +Done! + diff --git a/mk/temos/expected/libusual2.txt b/mk/temos/expected/libusual2.txt new file mode 100644 index 0000000..081ce1c --- /dev/null +++ b/mk/temos/expected/libusual2.txt @@ -0,0 +1,163 @@ + += Embedding libusual as part of the source. = + + +Here we build libusual as part of top-level tree. +This gives the advantage of building only the modules +that are actually used in main tree and without the +intermediate `libusual.a` step. + +This method is for projects that are developed +in parallel with libusual. Not recommended for +casual usage. + + +== Configure libusual == + + +Here we configure libusual, but do not build it. + +--------------------------------- +$ git clone git://github.com/libusual/libusual.git lib +Cloning into lib... +done. +$ cd lib +$ ./autogen.sh +[...] +$ ./configure +[...] +$ cd .. +--------------------------------- + +== Prepare own code == + + +Here is the source that needs to be linked with libusual: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include +#include + +int main(void) +{ + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; +} +----------------------------------- + +== Old way, with plain Make == + + +Here is corresponding Makefile: + +.File: Makefile +[source,makefile] +----------------------------------- +CC = gcc +CFLAGS = -O -g -Wall + +# here we describe our program +SRCS = prog.c +OBJS = $(SRCS:.c=.o) + +# here we link to libusual +USUAL_DIR = ./lib +USUAL_LOCAL_SRCS = $(SRCS) +CPPFLAGS = $(USUAL_CPPFLAGS) +OBJS += $(USUAL_OBJS) + +# this looks what modules are used by files in USUAL_LOCAL_SRCS +# and fills the USUAL_OBJS variable based on that +include $(USUAL_DIR)/Setup.mk + +all: prog + +prog: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ + +%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + +# special rule to build +%.o: $(USUAL_DIR)/usual/%.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + +clean: + rm -f *.o prog +----------------------------------- + +Build the project + +--------------------------------- +$ make +gcc -O -g -Wall -I./lib -c -o prog.o prog.c +gcc -O -g -Wall -I./lib -c -o crc32.o lib/usual/crc32.c +gcc -O -g -Wall -I./lib -c -o base.o lib/usual/base.c +gcc -O -g -Wall prog.o ./crc32.o ./base.o -o prog +$ ls +Makefile base.o crc32.o lib prog prog.c prog.o +$ ./prog +crc: 12345678 +$ make clean +rm -f *.o prog +$ ls +Makefile lib prog.c +--------------------------------- + +It's quite complex and that is even without trying to get +dependencies rigth. See next section for preferred way. + + +== New way, with Antimake. == + + +Antimake is build framework on plain GNU Make that reads +build instructons with Automake syntax. It has also hooks +for libusual integration. + +Here is Makefile that uses Antimake: + +.File: Makefile +[source,makefile] +----------------------------------- +# the automake-style build description for 'prog' +noinst_PROGRAMS = prog +prog_SOURCES = prog.c + +# location of configured libusual +USUAL_DIR = lib + +# mention that 'prog' wants embedded libusual +prog_EMBED_LIBUSUAL = 1 + +# launch Antimake +include $(USUAL_DIR)/mk/antimake.mk +----------------------------------- + +Build the project + +--------------------------------- +$ make + CC prog.c + CC lib/usual/crc32.c + CC lib/usual/base.c + CCLD prog +$ ls +Makefile lib prog prog.c +$ ./prog +crc: 12345678 +$ make clean + CLEAN prog +$ ls +Makefile lib prog.c +--------------------------------- + +Done + diff --git a/mk/temos/expected/libusual3.txt b/mk/temos/expected/libusual3.txt new file mode 100644 index 0000000..4ec3d59 --- /dev/null +++ b/mk/temos/expected/libusual3.txt @@ -0,0 +1,118 @@ + += Using Autoconf and embedded libusual = + + + + +== Fetch libusual == + + +Here we close libusual repo, but do not configure nor build it. + +--------------------------------- +$ git clone git://github.com/libusual/libusual.git lib +Cloning into lib... +done. +--------------------------------- + +Autoconf setup + +.File: autogen.sh +[source,shell] +----------------------------------- +# use prepared autgen logic +./lib/mk/std-autogen.sh ./lib + +# fetch Antimake template from libusual +cp lib/mk/antimake.mk antimake.mk.in +----------------------------------- +.File: configure.ac +[source,autoconf] +----------------------------------- +AC_INIT([achello], [0.1], [https://libusual.github.com]) +AC_CONFIG_SRCDIR([prog.c]) +AC_CONFIG_HEADER([lib/usual/config.h]) +AC_PREREQ([2.59]) + +AC_USUAL_PORT_CHECK +AC_USUAL_PROGRAM_CHECK +AC_USUAL_HEADER_CHECK +AC_USUAL_TYPE_CHECK +AC_USUAL_FUNCTION_CHECK + +AC_OUTPUT([antimake.mk]) +----------------------------------- + +Here is the source that needs to be linked with libusual: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include +#include + +int main(void) +{ + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; +} +----------------------------------- + +Antimake based Makefile + +.File: Makefile +[source,makefile] +----------------------------------- +# the automake-style build description for 'prog' +noinst_PROGRAMS = prog +prog_SOURCES = prog.c + +# location of configured libusual +USUAL_DIR = lib + +# mention that 'prog' wants embedded libusual +prog_EMBED_LIBUSUAL = 1 + +# clean configured files +DISTCLEANFILES = config.status config.log \ + antimake.mk $(USUAL_DIR)/usual/config.h + +# clean generated files +MAINTAINERCLEANFILES = configure config.guess config.sub install-sh \ + antimake.mk.in $(USUAL_DIR)/usual/config.h.in + +# launch Antimake +include $(USUAL_DIR)/mk/antimake.mk +----------------------------------- + +Build the project + +--------------------------------- +$ sh ./autogen.sh +$ ./configure +[...] +$ make + CC prog.c + CC lib/usual/crc32.c + CC lib/usual/base.c + CCLD prog +$ ls +Makefile autogen.sh config.status configure.ac prog +antimake.mk config.guess config.sub install-sh prog.c +antimake.mk.in config.log configure lib +$ ./prog +crc: 12345678 +$ make maintainer-clean + CLEAN prog + MAINTAINERCLEAN maintainer-clean +$ ls +Makefile autogen.sh configure.ac lib prog.c +--------------------------------- + +Done + diff --git a/mk/temos/expected/libusual4.txt b/mk/temos/expected/libusual4.txt new file mode 100644 index 0000000..bb279da --- /dev/null +++ b/mk/temos/expected/libusual4.txt @@ -0,0 +1,164 @@ + += Use installed libusual = + + +Install libusual and link against it. + + +== Build libusual == + +--------------------------------- +$ git clone git://github.com/libusual/libusual.git libusual +Cloning into libusual... +done. +$ cd libusual +$ ./autogen.sh +[...] +$ ./configure --disable-static --prefix=`pwd`/../inst +[...] +$ make +[...] +$ make install +[...] +$ cd .. +$ find inst | sort +inst +inst/include +inst/include/usual +inst/include/usual/aatree.h +inst/include/usual/base.h +inst/include/usual/base_win32.h +inst/include/usual/bits.h +inst/include/usual/cbtree.h +inst/include/usual/cfparser.h +inst/include/usual/config.h +inst/include/usual/crc32.h +inst/include/usual/ctype.h +inst/include/usual/cxalloc.h +inst/include/usual/cxextra.h +inst/include/usual/daemon.h +inst/include/usual/endian.h +inst/include/usual/err.h +inst/include/usual/event.h +inst/include/usual/fileutil.h +inst/include/usual/getopt.h +inst/include/usual/hashtab-impl.h +inst/include/usual/heap.h +inst/include/usual/list.h +inst/include/usual/logging.h +inst/include/usual/lookup3.h +inst/include/usual/mbuf.h +inst/include/usual/md5.h +inst/include/usual/mdict.h +inst/include/usual/mempool.h +inst/include/usual/misc.h +inst/include/usual/netdb.h +inst/include/usual/pgutil.h +inst/include/usual/pgutil_kwlookup.h +inst/include/usual/pthread.h +inst/include/usual/regex.h +inst/include/usual/safeio.h +inst/include/usual/sha1.h +inst/include/usual/shlist.h +inst/include/usual/signal.h +inst/include/usual/slab.h +inst/include/usual/socket.h +inst/include/usual/socket_win32.h +inst/include/usual/statlist.h +inst/include/usual/string.h +inst/include/usual/strpool.h +inst/include/usual/time.h +inst/include/usual/utf8.h +inst/lib +inst/lib/libusual.la +inst/lib/libusual.so +inst/lib/libusual.so.0 +inst/lib/libusual.so.0.0.0 +inst/lib/pkgconfig +inst/lib/pkgconfig/libusual.pc +inst/share +inst/share/aclocal +inst/share/aclocal/antimake.m4 +inst/share/aclocal/usual.m4 +inst/share/libusual +inst/share/libusual/Setup.mk +inst/share/libusual/antimake.mk +inst/share/libusual/find_modules.sh +inst/share/libusual/std-autogen.sh +--------------------------------- + +== Build our own code == + + +Now we prepare our own code. + + +First, this is the source file: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include +#include + +int main(void) +{ + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; +} +----------------------------------- + +Here is corresponding Makefile: + +.File: Makefile +[source,makefile] +----------------------------------- + +CC = gcc +CFLAGS = -O -g -Wall + +# here we describe our program +SRCS = prog.c +OBJS = $(SRCS:.c=.o) + +# put libusual flags to proper place +CPPFLAGS = $(USUAL_CPPFLAGS) +LIBS = $(USUAL_LIBS) + +# use pkg-config to get libusual info +USUAL_CPPFLAGS = $(shell $(PKG_CONFIG) --cflags libusual) +USUAL_LIBS = $(shell $(PKG_CONFIG) --libs libusual) + +# temo hacks to support local install, not needed otherwise +PKG_CONFIG := PKG_CONFIG_PATH=$(CURDIR)/inst/lib/pkgconfig pkg-config +CPPFLAGS := $(subst $(CURDIR)/libusual/../,./,$(CPPFLAGS)) +LIBS := $(subst $(CURDIR)/libusual/../,./,$(LIBS)) + +all: prog + +%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + +prog: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ +----------------------------------- + +Build the project + +--------------------------------- +$ make +gcc -O -g -Wall -I./inst/include -c -o prog.o prog.c +gcc -O -g -Wall prog.o -L./inst/lib -lusual -o prog +$ ls +Makefile inst libusual prog prog.c prog.o +$ LD_LIBRARY_PATH=./inst/lib ./prog +crc: 12345678 +--------------------------------- + +Done! + diff --git a/mk/temos/expected/libusual5.txt b/mk/temos/expected/libusual5.txt new file mode 100644 index 0000000..13ea708 --- /dev/null +++ b/mk/temos/expected/libusual5.txt @@ -0,0 +1,90 @@ + += Use installed libusual with antimake. = + + +Install libusual and link against it. + + +== Build libusual == + +--------------------------------- +$ git clone git://github.com/libusual/libusual.git libusual +Cloning into libusual... +done. +$ cd libusual +$ ./autogen.sh +[...] +$ ./configure --disable-shared --prefix=`pwd`/../inst +[...] +$ make +[...] +$ make install +[...] +$ cd .. +--------------------------------- + +== Build our own code == + + +Now we prepare our own code. + + +First, this is the source file: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include +#include + +int main(void) +{ + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; +} +----------------------------------- + +Here is corresponding Makefile: + +.File: Makefile +[source,makefile] +----------------------------------- +# temo hacks to support local install, not needed otherwise +PKG_CONFIG = PKG_CONFIG_PATH=$(CURDIR)/inst/lib/pkgconfig pkg-config + +# use pkg-config to get libusual info +USUAL_CPPFLAGS = $(shell $(PKG_CONFIG) libusual --cflags) +USUAL_LDFLAGS = $(shell $(PKG_CONFIG) libusual --libs-only-L) +USUAL_LIBS = $(shell $(PKG_CONFIG) libusual --libs-only-l) + +# Generic Antimake +bin_PROGRAMS = prog +prog_SOURCES = prog.c +prog_CPPFLAGS = $(USUAL_CPPFLAGS) +prog_LDFLAGS = $(USUAL_LDFLAGS) +prog_LDADD = $(USUAL_LIBS) + +# use installed Antimake +ANTIMAKE = $(shell $(PKG_CONFIG) libusual --variable=antimake) +include $(ANTIMAKE) +----------------------------------- + +Build the project + +--------------------------------- +$ make + CC prog.c + CCLD prog +$ ls +Makefile inst libusual prog prog.c +$ ./prog +crc: 12345678 +--------------------------------- + +Done! + diff --git a/mk/temos/expected/libusual6.txt b/mk/temos/expected/libusual6.txt new file mode 100644 index 0000000..7e08c0a --- /dev/null +++ b/mk/temos/expected/libusual6.txt @@ -0,0 +1,165 @@ + += Use installed libusual with autoconf and antimake. = + + +Install libusual and link against it. + + +== Build libusual == + +--------------------------------- +$ git clone git://github.com/libusual/libusual.git libusual +Cloning into libusual... +done. +$ cd libusual +$ ./autogen.sh +[...] +$ ./configure --disable-shared --prefix=`pwd`/../inst +[...] +$ make +[...] +$ make install +[...] +$ cd .. +--------------------------------- + +== Build our own code == + + +Now we prepare our own code. + + +First, this is the source file: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include +#include + +int main(void) +{ + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; +} +----------------------------------- + +Autoconf setup + +.File: autogen.sh +[source,shell] +----------------------------------- +# use prepared autgen logic +../../std-autogen.sh ../../.. + +# fetch Antimake template from libusual +cp ../../antimake.mk antimake.mk.in +----------------------------------- +.File: extra.mk.in +----------------------------------- +USUAL_ANTIMAKE = @USUAL_ANTIMAKE@ +USUAL_CFLAGS = @USUAL_CFLAGS@ +USUAL_LIBS = @USUAL_LIBS@ +----------------------------------- +.File: configure.ac +[source,autoconf] +----------------------------------- +AC_INIT([achello], [0.1], [https://libusual.github.com]) +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_SRCDIR([prog.c]) +AC_PREREQ([2.59]) + +AC_USUAL_INIT +AC_USUAL_PROGRAM_CHECK + +PKG_CHECK_MODULES(USUAL, libusual) +_PKG_CONFIG([USUAL_ANTIMAKE], [variable=antimake], [libusual]) +AC_SUBST([USUAL_ANTIMAKE]) + +AC_OUTPUT([antimake.mk extra.mk]) +----------------------------------- + +Here is the source that needs to be linked with libusual: + +.File: prog.c +[source,c] +----------------------------------- +#include +#include +#include + +int main(void) +{ + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; +} +----------------------------------- + +Antimake based Makefile + +.File: Makefile +[source,makefile] +----------------------------------- +# the automake-style build description for 'prog' +noinst_PROGRAMS = prog +prog_SOURCES = prog.c +prog_CPPFLAGS = $(USUAL_CFLAGS) +prog_LDADD = $(USUAL_LIBS) + +# clean configured files +DISTCLEANFILES = config.status config.log extra.mk antimake.mk config.h + +# clean generated files +MAINTAINERCLEANFILES = configure config.guess config.sub install-sh \ + antimake.mk.in extra.mk.in config.h.in +EXTRA_DIST = Makefile $(MAINTAINERCLEANFILES) + +# launch Antimake +include extra.mk +include antimake.mk +----------------------------------- + +Build the project + +--------------------------------- +$ sh ./autogen.sh +$ PKG_CONFIG_PATH=`pwd`/inst/lib/pkgconfig ./configure +[...] +$ make + CC prog.c + CCLD prog +$ ls +Makefile config.guess config.status extra.mk libusual +antimake.mk config.h config.sub extra.mk.in prog +antimake.mk.in config.h.in configure inst prog.c +autogen.sh config.log configure.ac install-sh +$ ./prog +crc: 12345678 +$ make am-show-distfiles +Makefile +antimake.mk.in +config.guess +config.h.in +config.sub +configure +extra.mk.in +install-sh +prog.c +$ make maintainer-clean + CLEAN prog + MAINTAINERCLEAN maintainer-clean +$ ls +Makefile autogen.sh configure.ac inst libusual prog.c +--------------------------------- + +Done! + diff --git a/mk/temos/index.txt b/mk/temos/index.txt new file mode 100644 index 0000000..df9f901 --- /dev/null +++ b/mk/temos/index.txt @@ -0,0 +1,32 @@ += Libusual/Antimake Build Demos = + +Here are few demos showing how to use both Libusual and Antimake +in various scenarios. If you wonder why there is so many of them, +the reason is that these demos are also used as regressions tests +for various functionality. (Thus, 'temos') + +They are ordered in ascending complexity, so pick first one if you +want simplest overview. + +== Reference Documentation == + +- link:antimake.html[AntiMake documentation] + +== Using Antimake == + +- link:antimake1.html[antimake1] - Project without subdirs +- link:antimake2.html[antimake2] - Recursive subdirectories (SUBDIRS) +- link:antimake3.html[antimake3] - Non-recursive subdirectories (EMBED_SUBDIRS) +- link:antimake4.html[antimake4] - Using Autoconf. +- link:antimake5.html[antimake5] - Shared libraries with Autoconf. +- link:antimake6.html[antimake5] - Subdir stress test. + +== Using libusual == + +- link:libusual1.html[libusual1] - Local libusual: Linking against libusual.a with plain Make +- link:libusual2.html[libusual2] - Local libusual: Embedding libusual modules with/witout Antimake +- link:libusual3.html[libusual3] - Local libusual: Using top-level autoconf with Antimake +- link:libusual4.html[libusual4] - Installed libusual: Plain make +- link:libusual5.html[libusual5] - Installed libusual: Antimake +- link:libusual6.html[libusual6] - Installed libusual: Autoconf + diff --git a/mk/temos/libtemo.sh b/mk/temos/libtemo.sh new file mode 100644 index 0000000..b6141fc --- /dev/null +++ b/mk/temos/libtemo.sh @@ -0,0 +1,122 @@ + +LANG=C +LC_ALL=C +export LANG LC_ALL + +PATH=`pwd`/bin:$PATH +export PATH + +set -e +set -o pipefail + +SH="bash" + +unset MAKELEVEL MAKEFLAGS +export MAKELEVEL MAKEFLAGS + +code=0 + +# we want to test local commits +real_repo=../../.. + +# but final html should have fixed public url +show_repo=git://github.com/libusual/libusual.git + +usual_clone() { + enter_code + echo "$ git clone $show_repo" "$@" + git clone $real_repo "$@" +} + +test_start() { + rm -rf tmp + mkdir tmp + cd tmp +} + +enter_code() { + if test "$code" = "0"; then + echo "---------------------------------" + code=1 + fi +} + +leave_code() { + if test "$code" = "1"; then + echo "---------------------------------" + code=0 + fi +} + +ls() { + /bin/ls -C "$@" +} + +title() { + leave_code + echo "" + echo "=" "$@" "=" + echo "" +} + +title2() { + leave_code + echo "" + echo "==" "$@" "==" + echo "" +} + +title3() { + leave_code + echo "" + echo "===" "$@" "===" + echo "" +} + +run() { + enter_code + echo "$ $*" + case "$1" in + cd|ls|export) $* ;; + *) $SH -c "$*" 2>&1 + esac +} + +runq() { + enter_code + echo "$ $*" + echo "[...]" + $SH -c "$*" > quiet.log 2>&1 || { tail -5 quiet.log; exit 1; } + rm -f quiet.log +} + +msg() { + leave_code + echo "" + echo "$@" + echo "" +} + +longmsg() { + leave_code + echo "" + sed 's/^ //' + echo "" +} + +cat_file() { + leave_code + mkdir -p `dirname $1` + echo ".File: $1" + case "$1" in + *Makefile) echo "[source,makefile]" ;; + *.[ch]) echo "[source,c]" ;; + *.ac) echo "[source,autoconf]" ;; + *.sh) echo "[source,shell]" ;; + esac + echo "-----------------------------------" + sed 's/^ //' > $1 + cat $1 + echo "-----------------------------------" +} + diff --git a/mk/temos/src/antimake1.temo b/mk/temos/src/antimake1.temo new file mode 100644 index 0000000..a13d576 --- /dev/null +++ b/mk/temos/src/antimake1.temo @@ -0,0 +1,77 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Test Antimake + +title2 Simplest usage + +msg Here we avoid use of any autotools. + +msg First, this is the source file: +cat_file hello.c <<"EOF" + #include + + int main(void) + { + printf("Hello, world\n"); + return 0; + } +EOF + +msg Here is corresponding Makefile: + +cat_file Makefile <<"EOF" + # This is target list - it's name describes target type + # and how it is installed, it's value target files to be built. + # bin - the targets will be installed under $(bindir) + # PROGRAMS - the target is executable built from many sources + bin_PROGRAMS = hello + + # The target 'hello'-s source file list. + hello_SOURCES = hello.c + + # Run Antimake + include antimake.mk +EOF + +msg Also install Antimake and we are ready to build: +run cp ../../antimake.mk . +run ls + +msg Build the project + +run make +run ls +run ./hello + +msg We can even install it already: +run make install prefix=/opt +run ls /opt/bin + +msg For creating source package, we need to provide additional info: + +cat_file Makefile <<"EOF" + # Package name and version for tarball filename + PACKAGE_NAME = myhello + PACKAGE_VERSION = 1.0 + + # Non-source files to put into tarball + EXTRA_DIST = Makefile antimake.mk + + bin_PROGRAMS = hello + hello_SOURCES = hello.c + include antimake.mk +EOF + +msg Now we can create package that can be given to others. +run make dist +run ls +run 'tar tzf myhello-1.0.tar.gz | sort' + +msg Clean the tree +run make clean +run ls + +msg Done! diff --git a/mk/temos/src/antimake2.temo b/mk/temos/src/antimake2.temo new file mode 100644 index 0000000..c7144b4 --- /dev/null +++ b/mk/temos/src/antimake2.temo @@ -0,0 +1,144 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Test Antimake SUBDIRS + +longmsg <<-"MSG" + Antimake variable `SUBDIRS` list names of directories that the Make + needs to recurse into. Each of them contains stand-alone Makefile + that directs building in that subdirs. + + - Plus: you can call 'make' while being in subdir to build only local targets. + - Minus: dependencies between subdirs do not work. +MSG + +title2 Setup source tree + +msg Setup directories, install Antimake + +run mkdir -p lib1/sublib lib2 +run cp ../../antimake.mk . + +msg Prepare sources + +cat_file main.c <<"EOF" + #include + + int main(void) + { + func1(); + func2(); + func3(); + printf("main\n"); + return 0; + } +EOF + +cat_file lib1/func1.c <<"EOF" + #include + + void func1(void) + { + printf("func1\n"); + } +EOF + +cat_file lib1/sublib/func2.c <<"EOF" + #include + + void func2(void) + { + printf("func2\n"); + } +EOF + +cat_file lib2/func3.c <<"EOF" + #include + + void func3(void) + { + printf("func3\n"); + } +EOF + +msg Prepare Makefiles + +cat_file Makefile <<"EOF" + PACKAGE_NAME = test-subdirs + PACKAGE_VERSION = 1.0 + + SUBDIRS = lib1 lib2 + + bin_PROGRAMS = prog + prog_SOURCES = main.c + prog_LDADD = lib1/func1.a lib1/sublib/func2.a lib2/func3.a + + EXTRA_DIST = Makefile antimake.mk + + include antimake.mk +EOF + +cat_file lib1/Makefile <<"EOF" + SUBLOC = lib1 + SUBDIRS = sublib + + noinst_LIBRARIES = func1.a + func1_a_SOURCES = func1.c + + EXTRA_DIST = Makefile + + include ../antimake.mk +EOF + +cat_file lib1/sublib/Makefile <<"EOF" + SUBLOC = lib1/sublib + + noinst_LIBRARIES = func2.a + func2_a_SOURCES = func2.c + + EXTRA_DIST = Makefile + + include ../../antimake.mk +EOF + +cat_file lib2/Makefile <<"EOF" + SUBLOC = lib2 + + noinst_LIBRARIES = func3.a + func3_a_SOURCES = func3.c + + EXTRA_DIST = Makefile + + include ../antimake.mk +EOF + +title2 Building + +msg Build the project + +run make +run ls +run ./prog + +msg We can even install it already: +run make install prefix=/opt +run ls /opt/bin + +msg Now we can create package that can be given to others. +run make dist +run ls +run 'tar tzf test-subdirs-1.0.tar.gz | sort' + +msg Clean the tree +run make clean +run ls + +msg Test O= +run mkdir -p build +run make O=build +run ls +run ls build + +msg Done! diff --git a/mk/temos/src/antimake3.temo b/mk/temos/src/antimake3.temo new file mode 100644 index 0000000..8fd4b9b --- /dev/null +++ b/mk/temos/src/antimake3.temo @@ -0,0 +1,191 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Test Antimake EMBED_SUBDIRS + +longmsg <<-"MSG" + Antimake variable `EMBED_SUBDIRS` list names of directories that + contains Makefile fragmants that are to be embedded into current + Makefile. + + - Plus: Proper dependencies, work well with parallel Make. + - Minus: Cannot go into subdir and run make there. + - Minus: Fragments are not stand-alone, so need some care when writing. +MSG + +title2 Intro to EMBED_SUBDIRS + +longmsg <<-"MSG" + To better understand what EMBED_SUBDIRS does, let\'s start with simple + case - single Makefile that references files under subdir: +MSG + +run mkdir -p src +run cp ../../antimake.mk . + +cat_file Makefile <<"EOF" + bin_PROGRAMS = src/myprog + src_myprog_SOURCES = src/myprog.c + include antimake.mk +EOF + + +cat_file src/myprog.c <<"EOF" + #include + + int main(void) + { + printf("myprog\n"); + return 0; + } +EOF + +run make +run ./src/myprog +run make clean + +longmsg <<"MSG" + Now you can put the lines that reference files under `src/` + also into `src` and include that from top-level Makefile: +MSG + +cat_file src/Makefile.inc <<"EOF" + bin_PROGRAMS = src/myprog + src_myprog_SOURCES = src/myprog.c +EOF + +cat_file Makefile <<"EOF" + include src/Makefile.inc + include antimake.mk +EOF + +run make +run ./src/myprog + +longmsg <<"MSG" + This works but the problem is that although the Makefile is local, + it still sees files from top-Makefile-level. So that is what `EMBED_SUBDIRS` + helps with - it allow to use local filenames in Makefile fragment, + and it converts them to top-level filenames when including. It knows + only few type of variables it needs to convert: + + - target filenames in primares lists (*_PROGRAMS, *_LIBRARIES, etc) + - target_SOURCES: foo_SOURCES -> sub_dir_foo_SOURCES with filename conversion + - other target variables: `foo_*` -> `sub_dir_foo_*` without filename conversion + - EXTRA_DIST, CLEANFILES, DISTCLEANFILES, MAINTAINERCLEANFILES + + Any other variables stay untouched, and obviously they can mess up top-level variables. + So the included Makefile should be as clean as possible. +MSG + + +title2 Setup source tree for EMBED_SUBDIRS + +msg Setup directories, install Antimake + +run mkdir -p lib1/sublib lib2 +run cp ../../antimake.mk . + +msg Prepare sources + +cat_file main.c <<"EOF" + #include + + int main(void) + { + func1(); + func2(); + func3(); + printf("main\n"); + return 0; + } +EOF + +cat_file lib1/func1.c <<"EOF" + #include + + void func1(void) + { + printf("func1\n"); + } +EOF + +cat_file lib1/sublib/func2.c <<"EOF" + #include + + void func2(void) + { + printf("func2\n"); + } +EOF + +cat_file lib2/func3.c <<"EOF" + #include + + void func3(void) + { + printf("func3\n"); + } +EOF + +msg Prepare Makefiles + +cat_file Makefile <<"EOF" + PACKAGE_NAME = test-subdirs + PACKAGE_VERSION = 1.0 + + EMBED_SUBDIRS = lib1 lib1/sublib lib2 + + bin_PROGRAMS = prog + prog_SOURCES = main.c + prog_LDADD = lib1/func1.a lib1/sublib/func2.a lib2/func3.a + + EXTRA_DIST = Makefile antimake.mk + + include antimake.mk +EOF + +cat_file lib1/Makefile.am <<"EOF" + noinst_LIBRARIES = func1.a + func1_a_SOURCES = func1.c + + EXTRA_DIST = Makefile.am +EOF + +cat_file lib1/sublib/Makefile.am <<"EOF" + noinst_LIBRARIES = func2.a + func2_a_SOURCES = func2.c + EXTRA_DIST = Makefile.am +EOF + +cat_file lib2/Makefile.am <<"EOF" + noinst_LIBRARIES = func3.a + func3_a_SOURCES = func3.c + + EXTRA_DIST = Makefile.am +EOF + +title2 Building + +msg Build the project + +run make +run ls +run ./prog + +msg We can even install it already: +run make install prefix=/opt +run ls /opt/bin + +msg Now we can create package that can be given to others. +run make dist +run ls +run 'tar tzf test-subdirs-1.0.tar.gz | sort' + +msg Clean the tree +run make clean +run ls + +msg Done! diff --git a/mk/temos/src/antimake4.temo b/mk/temos/src/antimake4.temo new file mode 100644 index 0000000..d597511 --- /dev/null +++ b/mk/temos/src/antimake4.temo @@ -0,0 +1,91 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Using Antimake with autoconf + +msg Autoconf setup + +cat_file autogen.sh <<"EOF" + libtoolize -i -q + aclocal -I../../../m4 + autoconf + rm -rf autom4te.cache ltmain.sh aclocal.m4 + + # fetch Antimake template from libusual + cp ../../antimake.mk antimake.mk.in +EOF + +cat_file configure.ac <<"EOF" + AC_INIT([actest], [0.1]) + AC_CONFIG_SRCDIR([prog.c]) + AC_PREREQ([2.59]) + + AC_USUAL_INIT + AC_USUAL_PROGRAM_CHECK + + AC_OUTPUT([antimake.mk]) +EOF + +msg Here is the source we want to build: + +cat_file prog.c <<"EOF" + #include + #include + + int main(void) + { + printf("hello\n"); + return 0; + } +EOF + +msg Antimake based Makefile + +cat_file Makefile <<"EOF" + # the automake-style build description for 'prog' + noinst_PROGRAMS = prog + prog_SOURCES = prog.c + + EXTRA_DIST = Makefile $(MAINTAINERCLEANFILES) + + # clean configured files + DISTCLEANFILES = config.status config.log antimake.mk + + # clean generated files + MAINTAINERCLEANFILES = configure config.guess config.sub install-sh antimake.mk.in + + # launch Antimake + include antimake.mk +EOF + +msg Build the project +run sh ./autogen.sh +runq ./configure +run make +run ls +run ./prog + +msg Create distribution package +run make dist +run 'tar tzf actest-0.1.tar.gz | sort' + +msg Test the distribution package and separate build dir +run mkdir -p test +run cd test +run tar xf ../actest-0.1.tar.gz +run mkdir build +run cd build +runq ../actest-0.1/configure +run make +run ls +run ./prog +run cd ../.. + +msg Clean up +run make maintainer-clean +run ls + +msg Done + diff --git a/mk/temos/src/antimake5.temo b/mk/temos/src/antimake5.temo new file mode 100644 index 0000000..8880681 --- /dev/null +++ b/mk/temos/src/antimake5.temo @@ -0,0 +1,122 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Shared libraries and autoconf + +msg Autoconf setup + +cat_file autogen.sh <<"EOF" + libtoolize -i -q + aclocal -I../../../m4 + autoconf + rm -rf autom4te.cache aclocal.m4 + + # fetch Antimake template from libusual + cp ../../antimake.mk antimake.mk.in +EOF + +cat_file configure.ac <<"EOF" + AC_INIT([actest], [0.1]) + AC_CONFIG_SRCDIR([prog.c]) + AC_PREREQ([2.59]) + + LT_INIT + AC_USUAL_INIT + + AC_USUAL_PROGRAM_CHECK + + AC_OUTPUT([antimake.mk]) +EOF + +msg Here are the source files: + +cat_file prog.c <<"EOF" + void func1(void); + int main(void) + { + func1(); + return 0; + } +EOF + +cat_file func.c <<"EOF" + #include + + void func1(void) + { + printf("hello from func1\n"); + } +EOF + +msg Antimake based Makefile + +cat_file Makefile <<"EOF" + lib_LTLIBRARIES = libtemo.la + libtemo_la_SOURCES = func.c + libtemo_la_LDFLAGS = -version-info 3:0:2 + + bin_PROGRAMS = prog + prog_SOURCES = prog.c + prog_LDADD = libtemo.la + + # clean configured files + DISTCLEANFILES = \ + config.status \ + config.log \ + antimake.mk \ + libtool + + # clean generated files + MAINTAINERCLEANFILES = \ + configure \ + config.guess \ + config.sub \ + install-sh \ + antimake.mk.in \ + ltmain.sh + + EXTRA_DIST = \ + Makefile \ + $(MAINTAINERCLEANFILES) + + # launch Antimake + include antimake.mk +EOF + +msg Build the project +run sh ./autogen.sh +runq ./configure +run make +run ls +run ./prog + +msg Create distribution package +run make dist +run 'tar tzf actest-0.1.tar.gz | sort' + +msg Test installation +run 'make install DESTDIR=/tmp/test-inst' +run ls +run 'find /tmp/test-inst | sort' +run rm -rf /tmp/test-inst + +msg Test the distribution package and separate build dir +run mkdir -p test +run cd test +run tar xf ../actest-0.1.tar.gz +run mkdir build +run cd build +runq ../actest-0.1/configure +run make +run ls +run ./prog +run cd ../.. + +msg Clean up +run make maintainer-clean +run ls + +msg Done + diff --git a/mk/temos/src/antimake6.temo b/mk/temos/src/antimake6.temo new file mode 100644 index 0000000..3c3a256 --- /dev/null +++ b/mk/temos/src/antimake6.temo @@ -0,0 +1,240 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Antimake stress-test + +msg Autoconf setup + +cat_file autogen.sh <<"EOF" + libtoolize -i -q + aclocal -I../../../m4 + autoconf + rm -rf autom4te.cache aclocal.m4 + + # fetch Antimake template from libusual + grep -Ei '@[a-z_]+@' ../../antimake.mk > build.mk.in + echo 'include $(abs_top_srcdir)/antimake.mk' >> build.mk.in + ln -sf ../../antimake.mk . +EOF + +cat_file configure.ac <<"EOF" + AC_INIT([actest], [0.1]) + AC_CONFIG_SRCDIR([esub/prog.c]) + AC_PREREQ([2.59]) + AC_USUAL_INIT + LT_INIT + AC_USUAL_PROGRAM_CHECK + AC_PROG_CXX + AC_OUTPUT([build.mk]) +EOF + +msg Here are the source files: + +longmsg <<"EOF" + ------------- + ./prog.c + ./cpptest.cpp + ./sub/func1.c + ./sub/esub/func2,c + ./sub/sub/func3.c + ./esub/func4.c + ./esub/esub/func5.c + ./esub/sub/func6.c + ------------- +EOF + +run mkdir -p sub/esub sub/sub esub/esub esub/sub + +cat_file esub/prog.c <<"EOF" + #include "func1.h" + #include "func2.h" + #include "func3.h" + #include "func4.h" + #include "func5.h" + #include "func6.h" + #include + int main(void) + { + printf("%s\n", __FILE__); + func1(); + func2(); + func3(); + func4(); + func5(); + func6(); + return 0; + } +EOF + +cat_file cpptest.cpp <<"EOF" + #include + + using namespace std; + int main(void) + { + cout << "Hello" << endl; + return 0; + } +EOF + +cat_file sub/func1.c <<"EOF" + #include + #include "func1.h" + void func1(void) + { + printf("%s\n", __FILE__); + } +EOF + +cat_file sub/func1.h <<"EOF" + void func1(void); +EOF + +run 'sed s/1/2/ sub/func1.c > sub/esub/func2.c' +run 'sed s/1/2/ sub/func1.h > sub/esub/func2.h' +run 'sed s/1/3/ sub/func1.c > sub/sub/func3.c' +run 'sed s/1/3/ sub/func1.h > sub/sub/func3.h' +run 'sed s/1/4/ sub/func1.c > esub/func4.c' +run 'sed s/1/4/ sub/func1.h > esub/func4.h' +run 'sed s/1/5/ sub/func1.c > esub/sub/func5.c' +run 'sed s/1/5/ sub/func1.h > esub/sub/func5.h' +run 'sed s/1/6/ sub/func1.c > esub/esub/func6.c' +run 'sed s/1/6/ sub/func1.h > esub/esub/func6.h' + +msg Now fill makefiles + +cat_file Makefile <<"EOF" + SUBDIRS = sub + EMBED_SUBDIRS = esub + + EXTRA_DIST = Makefile antimake.mk $(MAINTAINERCLEANFILES) + + # clean configured files + DISTCLEANFILES = \ + config.status \ + config.log \ + libtool + + # clean generated files + MAINTAINERCLEANFILES = \ + configure \ + config.guess \ + config.sub \ + install-sh \ + build.mk.in \ + ltmain.sh + + noinst_PROGRAMS = cpptest + cpptest_SOURCES = cpptest.cpp + + # launch Antimake + include build.mk +EOF + +cat_file sub/Makefile <<"EOF" + SUBLOC = sub + SUBDIRS = sub + EMBED_SUBDIRS = esub + + noinst_LIBRARIES = libfunc1.a + libfunc1_a_SOURCES = func1.c func1.h + + EXTRA_DIST = Makefile + include ../build.mk +EOF + +cat_file sub/sub/Makefile <<"EOF" + SUBLOC = sub/sub + EXTRA_DIST = Makefile + noinst_LIBRARIES = libfunc3.a + libfunc3_a_SOURCES = func3.c func3.h + + include ../../build.mk +EOF + +cat_file sub/esub/Makefile.am <<"EOF" + noinst_LIBRARIES = libfunc2.a + libfunc2_a_SOURCES = func2.c func2.h + EXTRA_DIST = Makefile.am +EOF + +cat_file esub/Makefile.am <<"EOF" + SUBDIRS = sub + EMBED_SUBDIRS = esub + EXTRA_DIST = Makefile.am + + noinst_LIBRARIES = libfunc4.a + libfunc4_a_SOURCES = func4.c func4.h + + EXTRA_PROGRAMS = prog + prog_SOURCES = prog.c + prog_LDADD = \ + -L../sub -lfunc1 \ + -L../sub/esub -lfunc2 \ + $(topdir)/sub/sub/libfunc3.a \ + -L. -lfunc4 \ + -Lsub -lfunc5 \ + esub/libfunc6.a + + prog_CFLAGS = -I../sub + prog_CPPFLAGS = \ + -I../sub/esub \ + -I$(topdir)/sub/sub \ + -I. \ + -Iesub \ + -I./sub + +EOF + +cat_file esub/sub/Makefile <<"EOF" + SUBLOC = esub/sub + EXTRA_DIST = Makefile + noinst_LIBRARIES = libfunc5.a + libfunc5_a_SOURCES = func5.c func5.h + include ../../build.mk +EOF + +cat_file esub/esub/Makefile.am <<"EOF" + EXTRA_DIST = Makefile.am + noinst_LIBRARIES = libfunc6.a + libfunc6_a_SOURCES = func6.c func6.h +EOF + +msg Build the project +run sh ./autogen.sh +runq ./configure +run make +run ls +run make esub/prog +run ./esub/prog + +msg Create distribution package +run make dist +run 'tar tzf actest-0.1.tar.gz | sort' + +msg Test installation +run 'make install DESTDIR=`pwd`/inst' +run ls +run 'find inst | sort' + +msg Test the distribution package and separate build dir +run mkdir -p test +run cd test +run tar xf ../actest-0.1.tar.gz +run mkdir build +run cd build +runq ../actest-0.1/configure +run make +run ls +run make esub/prog +run ./esub/prog +run cd ../.. + +msg Clean up +run make maintainer-clean +run ls + +msg Done + diff --git a/mk/temos/src/libusual1.temo b/mk/temos/src/libusual1.temo new file mode 100644 index 0000000..41d9849 --- /dev/null +++ b/mk/temos/src/libusual1.temo @@ -0,0 +1,77 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Use libusual the simplest way + +longmsg <<-MSG + Simplest usage would be to configure and build libusual + locally and point your projects CPPFLAGS and LDFLAGS there. + + That way you get access to not only code but also + various autoconfigued symbols without any complexities + in your project. +MSG + +title2 Build libusual + +usual_clone lib + +run cd lib + +runq ./autogen.sh +runq ./configure --disable-shared --prefix=`pwd`/../inst +runq make +runq make install + +run cd .. + +title2 Build our own code + +msg Now we prepare our own code. + +msg First, this is the source file: +cat_file prog.c <<"EOF" + #include + #include + #include + + int main(void) + { + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; + } +EOF + +msg Here is corresponding Makefile: +cat_file Makefile <<"EOF" + # here we describe our program + SRCS = prog.c + OBJS = $(SRCS:.c=.o) + + # here we link to libusual + CPPFLAGS = -I./inst/include + LDFLAGS = -L./inst/lib + LIBS = -lusual + + CC = gcc + CFLAGS = -O -g -Wall + + all: prog + + prog: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ +EOF + +msg Build the project + +run make +run ls +run ./prog + +msg Done! diff --git a/mk/temos/src/libusual2.temo b/mk/temos/src/libusual2.temo new file mode 100644 index 0000000..5cedcd3 --- /dev/null +++ b/mk/temos/src/libusual2.temo @@ -0,0 +1,135 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Embedding libusual as part of the source. + +longmsg <<-"MSG" + Here we build libusual as part of top-level tree. + This gives the advantage of building only the modules + that are actually used in main tree and without the + intermediate `libusual.a` step. + + This method is for projects that are developed + in parallel with libusual. Not recommended for + casual usage. +MSG + +title2 Configure libusual + +msg Here we configure libusual, but do not build it. + +usual_clone lib + +run cd lib + +runq ./autogen.sh +runq ./configure + +run cd .. + +title2 Prepare own code + +msg Here is the source that needs to be linked with libusual: + +cat_file prog.c <<"EOF" + #include + #include + #include + + int main(void) + { + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; + } +EOF + +title2 Old way, with plain Make + +msg Here is corresponding Makefile: + +cat_file Makefile <<"EOF" + CC = gcc + CFLAGS = -O -g -Wall + + # here we describe our program + SRCS = prog.c + OBJS = $(SRCS:.c=.o) + + # here we link to libusual + USUAL_DIR = ./lib + USUAL_LOCAL_SRCS = $(SRCS) + CPPFLAGS = $(USUAL_CPPFLAGS) + OBJS += $(USUAL_OBJS) + + # this looks what modules are used by files in USUAL_LOCAL_SRCS + # and fills the USUAL_OBJS variable based on that + include $(USUAL_DIR)/Setup.mk + + all: prog + + prog: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ + + %.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + + # special rule to build + %.o: $(USUAL_DIR)/usual/%.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + + clean: + rm -f *.o prog +EOF + +msg Build the project +run make +run ls +run ./prog +run make clean +run ls + +longmsg <<-"MSG" + It's quite complex and that is even without trying to get + dependencies rigth. See next section for preferred way. +MSG + +title2 New way, with Antimake. + +longmsg <<-"MSG" + Antimake is build framework on plain GNU Make that reads + build instructons with Automake syntax. It has also hooks + for libusual integration. + + Here is Makefile that uses Antimake: +MSG + +cat_file Makefile <<"EOF" + # the automake-style build description for 'prog' + noinst_PROGRAMS = prog + prog_SOURCES = prog.c + + # location of configured libusual + USUAL_DIR = lib + + # mention that 'prog' wants embedded libusual + prog_EMBED_LIBUSUAL = 1 + + # launch Antimake + include $(USUAL_DIR)/mk/antimake.mk +EOF + +msg Build the project +run make +run ls +run ./prog +run make clean +run ls + +msg Done + diff --git a/mk/temos/src/libusual3.temo b/mk/temos/src/libusual3.temo new file mode 100644 index 0000000..4d2aeb0 --- /dev/null +++ b/mk/temos/src/libusual3.temo @@ -0,0 +1,95 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Using Autoconf and embedded libusual + +longmsg <<-"MSG" +MSG + +title2 Fetch libusual + +msg Here we close libusual repo, but do not configure nor build it. + +usual_clone lib + +msg Autoconf setup + +cat_file autogen.sh <<"EOF" + # use prepared autgen logic + ./lib/mk/std-autogen.sh ./lib + + # fetch Antimake template from libusual + cp lib/mk/antimake.mk antimake.mk.in +EOF + +cat_file configure.ac <<"EOF" + AC_INIT([achello], [0.1], [https://libusual.github.com]) + AC_CONFIG_SRCDIR([prog.c]) + AC_CONFIG_HEADER([lib/usual/config.h]) + AC_PREREQ([2.59]) + + AC_USUAL_PORT_CHECK + AC_USUAL_PROGRAM_CHECK + AC_USUAL_HEADER_CHECK + AC_USUAL_TYPE_CHECK + AC_USUAL_FUNCTION_CHECK + + AC_OUTPUT([antimake.mk]) +EOF + +msg Here is the source that needs to be linked with libusual: + +cat_file prog.c <<"EOF" + #include + #include + #include + + int main(void) + { + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; + } +EOF + +msg Antimake based Makefile + +cat_file Makefile <<"EOF" + # the automake-style build description for 'prog' + noinst_PROGRAMS = prog + prog_SOURCES = prog.c + + # location of configured libusual + USUAL_DIR = lib + + # mention that 'prog' wants embedded libusual + prog_EMBED_LIBUSUAL = 1 + + # clean configured files + DISTCLEANFILES = config.status config.log \ + antimake.mk $(USUAL_DIR)/usual/config.h + + # clean generated files + MAINTAINERCLEANFILES = configure config.guess config.sub install-sh \ + antimake.mk.in $(USUAL_DIR)/usual/config.h.in + + # launch Antimake + include $(USUAL_DIR)/mk/antimake.mk +EOF + +msg Build the project +run sh ./autogen.sh +runq ./configure +run make +run ls +run ./prog +run make maintainer-clean +run ls + +msg Done + diff --git a/mk/temos/src/libusual4.temo b/mk/temos/src/libusual4.temo new file mode 100644 index 0000000..e76909e --- /dev/null +++ b/mk/temos/src/libusual4.temo @@ -0,0 +1,84 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Use installed libusual + +longmsg <<-MSG + Install libusual and link against it. +MSG + +title2 Build libusual + +usual_clone libusual + +run cd libusual + +runq ./autogen.sh +runq './configure --disable-static --prefix=`pwd`/../inst' +runq make +runq make install +run cd .. +run 'find inst | sort' + +title2 Build our own code + +msg Now we prepare our own code. + +msg First, this is the source file: +cat_file prog.c <<"EOF" + #include + #include + #include + + int main(void) + { + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; + } +EOF + +msg Here is corresponding Makefile: +cat_file Makefile <<"EOF" + + CC = gcc + CFLAGS = -O -g -Wall + + # here we describe our program + SRCS = prog.c + OBJS = $(SRCS:.c=.o) + + # put libusual flags to proper place + CPPFLAGS = $(USUAL_CPPFLAGS) + LIBS = $(USUAL_LIBS) + + # use pkg-config to get libusual info + USUAL_CPPFLAGS = $(shell $(PKG_CONFIG) --cflags libusual) + USUAL_LIBS = $(shell $(PKG_CONFIG) --libs libusual) + + # temo hacks to support local install, not needed otherwise + PKG_CONFIG := PKG_CONFIG_PATH=$(CURDIR)/inst/lib/pkgconfig pkg-config + CPPFLAGS := $(subst $(CURDIR)/libusual/../,./,$(CPPFLAGS)) + LIBS := $(subst $(CURDIR)/libusual/../,./,$(LIBS)) + + all: prog + + %.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + + prog: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ +EOF + +msg Build the project + +run make +run ls +run LD_LIBRARY_PATH=./inst/lib ./prog + +msg Done! diff --git a/mk/temos/src/libusual5.temo b/mk/temos/src/libusual5.temo new file mode 100644 index 0000000..9ed2321 --- /dev/null +++ b/mk/temos/src/libusual5.temo @@ -0,0 +1,73 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Use installed libusual with antimake. + +longmsg <<-MSG + Install libusual and link against it. +MSG + +title2 Build libusual + +usual_clone libusual + +run cd libusual + +runq ./autogen.sh +runq './configure --disable-shared --prefix=`pwd`/../inst' +runq make +runq make install +run cd .. + +title2 Build our own code + +msg Now we prepare our own code. + +msg First, this is the source file: +cat_file prog.c <<"EOF" + #include + #include + #include + + int main(void) + { + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; + } +EOF + +msg Here is corresponding Makefile: +cat_file Makefile <<"EOF" + # temo hacks to support local install, not needed otherwise + PKG_CONFIG = PKG_CONFIG_PATH=$(CURDIR)/inst/lib/pkgconfig pkg-config + + # use pkg-config to get libusual info + USUAL_CPPFLAGS = $(shell $(PKG_CONFIG) libusual --cflags) + USUAL_LDFLAGS = $(shell $(PKG_CONFIG) libusual --libs-only-L) + USUAL_LIBS = $(shell $(PKG_CONFIG) libusual --libs-only-l) + + # Generic Antimake + bin_PROGRAMS = prog + prog_SOURCES = prog.c + prog_CPPFLAGS = $(USUAL_CPPFLAGS) + prog_LDFLAGS = $(USUAL_LDFLAGS) + prog_LDADD = $(USUAL_LIBS) + + # use installed Antimake + ANTIMAKE = $(shell $(PKG_CONFIG) libusual --variable=antimake) + include $(ANTIMAKE) +EOF + +msg Build the project + +run make +run ls +run ./prog + +msg Done! diff --git a/mk/temos/src/libusual6.temo b/mk/temos/src/libusual6.temo new file mode 100644 index 0000000..d37a4d9 --- /dev/null +++ b/mk/temos/src/libusual6.temo @@ -0,0 +1,127 @@ + +. ./libtemo.sh || exit 1 + +test_start + +title Use installed libusual with autoconf and antimake. + +longmsg <<-MSG + Install libusual and link against it. +MSG + +title2 Build libusual + +usual_clone libusual + +run cd libusual + +runq ./autogen.sh +runq './configure --disable-shared --prefix=`pwd`/../inst' +runq make +runq make install +run cd .. + +title2 Build our own code + +msg Now we prepare our own code. + +msg First, this is the source file: +cat_file prog.c <<"EOF" + #include + #include + #include + + int main(void) + { + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; + } +EOF + +msg Autoconf setup + +cat_file autogen.sh <<"EOF" + # use prepared autgen logic + ../../std-autogen.sh ../../.. + + # fetch Antimake template from libusual + cp ../../antimake.mk antimake.mk.in +EOF + +cat_file extra.mk.in <<"EOF" + USUAL_ANTIMAKE = @USUAL_ANTIMAKE@ + USUAL_CFLAGS = @USUAL_CFLAGS@ + USUAL_LIBS = @USUAL_LIBS@ +EOF + +cat_file configure.ac <<"EOF" + AC_INIT([achello], [0.1], [https://libusual.github.com]) + AC_CONFIG_HEADER([config.h]) + AC_CONFIG_SRCDIR([prog.c]) + AC_PREREQ([2.59]) + + AC_USUAL_INIT + AC_USUAL_PROGRAM_CHECK + + PKG_CHECK_MODULES(USUAL, libusual) + _PKG_CONFIG([USUAL_ANTIMAKE], [variable=antimake], [libusual]) + AC_SUBST([USUAL_ANTIMAKE]) + + AC_OUTPUT([antimake.mk extra.mk]) +EOF + +msg Here is the source that needs to be linked with libusual: + +cat_file prog.c <<"EOF" + #include + #include + #include + + int main(void) + { + const char *data = "CECSFXX"; + uint32_t crc; + + crc = calc_crc32(data, strlen(data), 0); + printf("crc: %08x\n", crc); + return 0; + } +EOF + +msg Antimake based Makefile + +cat_file Makefile <<"EOF" + # the automake-style build description for 'prog' + noinst_PROGRAMS = prog + prog_SOURCES = prog.c + prog_CPPFLAGS = $(USUAL_CFLAGS) + prog_LDADD = $(USUAL_LIBS) + + # clean configured files + DISTCLEANFILES = config.status config.log extra.mk antimake.mk config.h + + # clean generated files + MAINTAINERCLEANFILES = configure config.guess config.sub install-sh \ + antimake.mk.in extra.mk.in config.h.in + EXTRA_DIST = Makefile $(MAINTAINERCLEANFILES) + + # launch Antimake + include extra.mk + include antimake.mk +EOF + +msg Build the project +run sh ./autogen.sh +runq 'PKG_CONFIG_PATH=`pwd`/inst/lib/pkgconfig ./configure' +run make +run ls +run ./prog +run make am-show-distfiles +run make maintainer-clean +run ls +msg Done! +