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: api.h
void func1(void); void func2(void); void func3(void);
File: main.c
#include <stdio.h> #include "api.h" int main(void) { func1(); func2(); func3(); printf("main\n"); return 0; }
File: lib1/func1.c
#include <stdio.h> #include "api.h" void func1(void) { printf("func1\n"); }
File: lib1/sublib/func2.c
#include <stdio.h> #include "api.h" void func2(void) { printf("func2\n"); }
File: lib2/func3.c
#include <stdio.h> #include "api.h" void func3(void) { printf("func3\n"); }
Prepare Makefiles
File: 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
SUBLOC = lib1 SUBDIRS = sublib noinst_LIBRARIES = func1.a func1_a_SOURCES = func1.c func1_a_CPPFLAGS = -I.. EXTRA_DIST = Makefile include ../antimake.mk
File: lib1/sublib/Makefile
SUBLOC = lib1/sublib noinst_LIBRARIES = func2.a func2_a_SOURCES = func2.c func2_a_CPPFLAGS = -I../.. EXTRA_DIST = Makefile include ../../antimake.mk
File: lib2/Makefile
SUBLOC = lib2 noinst_LIBRARIES = func3.a func3_a_SOURCES = func3.c func3_a_CPPFLAGS = -I$(top_srcdir) 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 api.h lib1 lib2 main.c prog
$ ./prog
func1
func2
func3
main
We can now install it:
$ make install DESTDIR=./inst
--> 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 ./inst/usr/local/bin
$ ls ./inst/usr/local/bin
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 api.h lib1 main.c test-subdirs-1.0.tar.gz
antimake.mk inst lib2 prog
$ 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 api.h inst 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 api.h inst lib2 test-subdirs-1.0.tar.gz
antimake.mk build lib1 main.c
$ ls build
Makefile antimake.mk lib1 lib2 prog
Done!