This is a make file inclusion, to be included in all the
Netpbm make files.
This file is meant to contain rules that are substantially the same
in each of the pbm, pgm, ppm, and pnm subdirectory makes, to avoid
duplication of effort.
The following variables must be set in any make file that uses these
rules:
SRCDIR: The top level directory of Netpbm source code.
BUILDDIR: The top level directory into which Netpbm is built (built,
not installed).
SUBDIR: The directory, relative to BUILDDIR, of the current directory.
It is also the directory, relative to SRCDIR, of source directory that
corresponds to the current directory. Note that you build in the
current directory, using files from the source directory.
SUBDIRS: list of subdirectories in which certain targets (e.g. 'clean')
should be made recursively.
PKGDIR_DEFAULT: The place to put the packaged stuff for 'make package'
if the user doesn't put "pkgdir=" on the Make command line.
PKGMANDIR: The subdirectory (e.g. "man" or "share/man" of the package
directory root in which man pages should be packaged.
OBJECTS: .o files to be built from .c files with the standard rule.
PORTBINARIES: list of conventional executables to be built with the standard
rule
MATHBINARIES: obsolete.
DATAFILES: list of files that should be installed in the "data" directory.
NETPBMLIBSUFFIX: the suffix, e.g. "so" for the main libraries we build,
whatever type they may be.
STATICLIBSUFFIX: the suffix, e.g. "a" on a static library. This need
not be defined if the user doesn't want to build a static libraries in
addition to the main libraries.
BINARIES: list of all the executables that need to be installed.
INSTALL: command to use to copy files to where they belong
INSTALL_PERM_BIN: file permissions for installed binaries
INSTALL_PERM_LIB: ...same for libraries
INSTALL_PERM_MAN: ...same for man pages
MERGE_OBJECTS: list of object files that go into the merged executable
from the current directory (not subdirectories). All of these are to
be built with the standard rule for merged objects. These names are
relative to the current make directory (must not start with / ).
MERGEBINARIES: list of the programs that, in a merge build, are invoked
via the merged Netpbm program
CC: C compiler command
CFLAGS_CONFIG: C compiler options from config.mk.
CFLAGS_TARGET: C compiler options for a particular target
LD: linker command
LINKERISCOMPILER: 'Y' if the linker invoked by LD is actually a compiler
front end, so takes linker options in a different format
LIBS or LOADLIBES: names of libraries to be added to all links
COMP_INCLUDES: Compiler option string to establish the search path for
component-specific include files when compiling things or computing
dependencies (make dep). Header files from this part of the search
path take precedence over general Netpbm header files and external
library header files.
EXTERN_INCLUDES: Like COMP_INCLUDES, but for external libraries, e.g.
libjpeg. All header files from the Netpbm source tree take precedence
over these.
In addition, there is CADD, which is extra C compilation options and
is intended to be set on a make command line (e.g. 'make CADD=-g')
for options that apply just to a particular build.
In addition, there is CFLAGS, which is extra C compilation options and is
expected to be set via the make command line for a particular build.
Likewise, LDFLAGS for link-edit options.
In addition, there is CFLAGS_PERSONAL, which is extra C
compilation options and is expected to be set via environment variable
for options that are particular to the person doing the build and not
specific to Netpbm.
include $(SRCDIR)/version.mk
.DELETE_ON_ERROR is a special predefined Make target that says to delete
the target if a command in the rule for it fails. That's important,
because we don't want a half-made target sitting around looking like it's
fully made.
.DELETE_ON_ERROR:
-I importinc/netpbm is a backward compatibility thing. Really, the source
file should refer to e.g. "netpbm/pam.h" but for historical reasons, most
refer to "pam.h" and we'll probably never have the energy to convert them
all. The reason the file exists as importinc/netpbm/pam.h rather than just
importinc/pam.h (as it did originally) is that it lives on a user's system
as <netpbm/pam.h>, and therefore all exported header files do say
"<netpbm/pam.h>.
ifneq ($(ALL_INTERNAL_HEADER_FILES_ARE_QUALIFIED),Y)
LEGACY_NETPBM_INCLUDE = -Iimportinc/netpbm
else
LEGACY_NETPBM_INCLUDE =
endif
NETPBM_INCLUDES := -Iimportinc $(LEGACY_NETPBM_INCLUDE) -I$(SRCDIR)/$(SUBDIR)
-I. is needed when builddir != srcdir
INCLUDES = -I. $(COMP_INCLUDES) $(NETPBM_INCLUDES) $(EXTERN_INCLUDES)
ifeq ($(NETPBMLIBTYPE),unixstatic)
NETPBMLIBFNAME = libnetpbm.$(STATICLIBSUFFIX)
else
NETPBMLIBFNAME = $(NETPBMSHLIBPREFIX)netpbm$(DLLVER).$(NETPBMLIBSUFFIX)
endif
NETPBMLIB = $(BUILDDIR)/lib/$(NETPBMLIBFNAME)
BUNDLED_URTLIB = $(BUILDDIR)/urt/librle.a
LIBS and LOADLIBES are commonly set as environment variables.
LOADLIBES is used by GNU Make's implicit .c->.o rule. LIBS is used by
GNU Autoconf.
LDLIBS = $(LOADLIBES) $(LIBS)
'pkgdir' is meant to be set on the make command line. Results are
disastrous if PKGDIR is a relative directory, and I don't know any
way to detect that case and fail, so I just add a '/' to the front
if it isn't already there.
ifneq ($(pkgdir)x,x)
PKGDIR = $(patsubst //%,/%, /$(pkgdir))
else
PKGDIR = $(PKGDIR_DEFAULT)
endif
'resultdir', like 'pkgdir' is meant to be supplied from the make
command line. Unlike 'pkgdir' we allow relative paths.
ifneq ($(resultdir)x,x)
RESULTDIR = $(resultdir)
else
RESULTDIR = $(RESULTDIR_DEFAULT)
endif
===========================================================================
We build a directory full of symbolic links to the intra-Netpbm public
header files just so the compile commands don't have to be littered
with long -I's.
===========================================================================
Note that the "root" headers are in the root of the build tree, not
the source tree. All generated headers are in the root directory and
all root directory headers are generated.
IMPORTINC_ROOT_HEADERS := pm_config.h inttypes_netpbm.h version.h
IMPORTINC_LIB_HEADERS := \
pm.h pbm.h pgm.h ppm.h pnm.h pam.h pbmfont.h ppmcmap.h \
pammap.h colorname.h ppmfloyd.h ppmdraw.h pm_system.h ppmdfont.h \
pm_gamma.h lum.h dithers.h pamdraw.h
IMPORTINC_LIB_UTIL_HEADERS := \
bitarith.h bitio.h bitreverse.h filename.h intcode.h floatcode.h io.h \
matrix.h mallocvar.h \
nsleep.h nstring.h pm_c_util.h runlength.h shhopt.h token.h
IMPORTINC_HEADERS := \
$(IMPORTINC_ROOT_HEADERS) \
$(IMPORTINC_LIB_HEADERS) \
$(IMPORTINC_LIB_UTIL_HEADERS)
IMPORTINC_ROOT_FILES := $(IMPORTINC_ROOT_HEADERS:%=importinc/netpbm/%)
IMPORTINC_LIB_FILES := $(IMPORTINC_LIB_HEADERS:%=importinc/netpbm/%)
IMPORTINC_LIB_UTIL_FILES := $(IMPORTINC_LIB_UTIL_HEADERS:%=importinc/netpbm/%)
importinc: \
$(IMPORTINC_ROOT_FILES) \
$(IMPORTINC_LIB_FILES) \
$(IMPORTINC_LIB_UTIL_FILES) \
The reason we mkdir importinc/netpbm every time instead of just having
importinc depend on it and a rule to make it is that as a dependency, it
would force importinc to rebuild when importinc/netpbm has a more recent
modification date, which it sometimes would.
$(IMPORTINC_ROOT_FILES):importinc/netpbm/%:$(BUILDDIR)/%
mkdir -p importinc/netpbm
rm -f $@
$(SYMLINK) $< $@
$(IMPORTINC_LIB_FILES):importinc/netpbm/%:$(SRCDIR)/lib/%
mkdir -p importinc/netpbm
rm -f $@
$(SYMLINK) $< $@
$(IMPORTINC_LIB_UTIL_FILES):importinc/netpbm/%:$(SRCDIR)/lib/util/%
mkdir -p importinc/netpbm
rm -f $@
$(SYMLINK) $< $@
We build the symbolic links to header files in the current directory
just so the compile commands don't have to be littered with -I's.
bmp.h tga.h:%:$(SRCDIR)/converter/%
rm -f $@
$(SYMLINK) $< $@
ifneq ($(OMIT_VERSION_H_RULE),1)
$(BUILDDIR)/version.h:
$(MAKE) -C $(dir $@) $(notdir $@)
endif
ifneq ($(OMIT_CONFIG_RULE),1)
$(BUILDDIR)/config.mk: $(SRCDIR)/config.mk.in
$(MAKE) -C $(dir $@) $(notdir $@)
$(BUILDDIR)/pm_config.h:
$(MAKE) -C $(dir $@) $(notdir $@)
endif
ifneq ($(OMIT_INTTYPES_RULE),1)
$(BUILDDIR)/inttypes_netpbm.h:
$(MAKE) -C $(dir $@) -f $(SRCDIR)/GNUmakefile $(notdir $@)
endif
Note that any time you do a make on a fresh Netpbm source tree,
Make notices that 'config.mk', which the make files include, does not
exist and runs the "config.mk" target, which runs Configure.
If the "config" target were to run Configure as well, it would get run
twice in a row if you did a 'make config' on a fresh Netpbm source tree.
But we don't want to make "config" just a no-op, because someone might
try it after config.mk already exists, in order to make a new
config.mk. Issuing a message as follows seems to make sense in
both cases.
.PHONY: config
config:
@echo "To reconfigure the build, run 'configure'"
Rule to make C source from lex source.
%.c:%.l
$(LEX) -t $< >$(notdir $@)
Rule to make regular object files, e.g. pnmtojpeg.o.
The NDEBUG macro says to build code that assumes there are no bugs.
This makes the code go faster. The main thing it does is tell the C library
to make assert() a no-op as opposed to generating code to check the
assertion and crash the program if it isn't really true. You can add
-UNDEBUG (in any of various ways) to override this.
CFLAGS_ALL = \
-DNDEBUG $(CPPFLAGS) $(CFLAGS_CONFIG) $(CFLAGS_TARGET) $(CFLAGS_PERSONAL) $(CFLAGS) $(CADD)
ifeq ($(WANT_SSE),Y)
# The only two compilers we've seen that have the SSE capabilities that
# WANT_SSE requests are GCC and Clang, and they both have these options and
# require them in order for <emmintrin.h> to compile. On some systems
# (x86_64, in our experience), these options are default, but on more
# traditional systems, they are not. Note: SSE2 macro tells whether
# -msse2 is in effect.
CFLAGS_SSE = -msse -msse2
else
CFLAGS_SSE =
endif
$(OBJECTS): %.o: %.c importinc
Note that the user may have configured -I options into CFLAGS or CPPFLAGS.
Note about -o: There used to be systems that couldn't handle a space
between flag and value. But we found a Solaris gcc on 2003.09.02 that
actually fails without the space (it invokes Solaris 'as' with the
following command, which generates a "no input filename" error:
'/usr/ccs/bin/as -V -Qy -s -o/tmp/hello.o /var/tmp/ccpiNnia.s')
This rule has had the space since way before that, so it looks like
the space is no longer a problem for anyone.
We have to get this all on one line to make make messages neat
$(CC) -c $(INCLUDES) $(CFLAGS_ALL) -o $@ $<
libopt is a utility program used in the make file below.
LIBOPT = $(BUILDDIR)/buildtools/libopt
ifneq ($(OMIT_BUILDTOOL_RULE),1)
$(LIBOPT) $(TYPEGEN): $(BUILDDIR)/buildtools FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/buildtools/Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
endif
ifneq ($(OMIT_LIBRARY_RULE),1)
$(NETPBMLIB): $(BUILDDIR)/lib FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
endif
ifneq ($(OMIT_URT_RULE),1)
$(BUNDLED_URTLIB): $(BUILDDIR)/urt FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/urt/Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
endif
$(BUILDDIR)/icon/netpbm.o: $(BUILDDIR)/icon FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/icon/Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
Here are some notes from Nelson H. F. Beebe on April 16, 2002:
There are at least three incompatible kinds of command-line options
that tell the compiler to instruct the linker to save library paths in
the executable:
-Wl,-rpath,/path/to/dir gcc, g++, FreeBSD, SGI, Sun compilers
-rpath /path/to/dir Compaq/DEC, SGI compilers
-Rdir:dir:dir Portland Group, Sun compilers
Notice that SGI and Sun support two such flavors.
Plus, Scott Schwartz observed on March 25, 2003 that while his
compiler understands -Wl, his linker does not understand -rpath.
His compiler is "Sun WorkShop 6 update 2 C 5.3 2001/05/15".
Plus, Mike Saunders found in December 2003 that his Solaris 8 system
(uname -a says 'SunOS cannonball.method.cx 5.8 Generic_108528-14
sun4u sparc SUNW,Ultra-1') with Gcc 2.95.3 requires the syntax
-Wl,-R,/path/to/dir
This is apparently because Gcc invokes this linker for Saunders:
ld: Software Generation Utilities - Solaris Link Editors: 5.8-1.273
I'd say there are also Solaris systems where Gcc invokes the GNU linker
and then the option would be -Wl,-rpath...
The Sun Ld fails in a weird way when you pass it -rpath instead of -R:
ld: Software Generation Utilities - Solaris Link Editors: 5.9-1.382
ld: fatal: option -dn and -P are incompatible
On IA32 Linux, at least, GNU ld takes -rpath. It also has a -R option,
but it is something else.
Alan Fry and Snowcrash demonstrated in 2006.11 that neither -rpath
nor -R are recognized options on Mac OS X 'ld'.
says that on Mac OS X, libraries aren't searched for in directories,
but rather specified by full name, so that rpath doesn't make any
sense. On Mac OS X, you use -install_name when you linkedit shared
library S to give the complete installed name of S. This goes into
S so that when something linkedits with S, the complete installed
name of S goes into the object that uses S.
ifeq ($(NEED_RUNTIME_PATH),Y)
ifneq ($(NETPBMLIB_RUNTIME_PATH)x,x)
ifeq ($(LINKERISCOMPILER),Y)
# Before Netpbm 10.14 (March 2003), it looks like we used -R
# instead of -Wl,-rpath on all but a few selected platforms as configured
# by Configure. But that doesn't make sense, because we also used
# LD=$(CC) always. Beebe's notes and Saunders' observation above
# above indicate that we need
# -Wl,... everywhere that a compiler is used, whether native or GNU,
# to link.
RPATH = -Wl,$(RPATHOPTNAME),$(NETPBMLIB_RUNTIME_PATH)
else
RPATH = $(RPATHOPTNAME)$(NETPBMLIB_RUNTIME_PATH)
endif
endif
endif
Rules for conventional single-object file executables
Before Netpbm 10.21 (March 2004), we kept separate lists of binaries
that require the math library and those that don't, so the binaries
that don't need it wouldn't have to link it. But now libnetpbm
contains gamma correction routines, so it needs the math library,
and that means every Netpbm binary needs the math library, whether
it calls those routines or not. So we will phase out the separate
lists, and for now we treat them identically.
Note that GNU C library sometimes defines math functions as inline
functions, so linking the math library isn't really necessary. Late
model GNU C libraries do this only if you specify the -ffast-math
Gcc option (as told by the FAST_MATH preprocessor macro).
Earlier ones do it regardless of FAST_MATH.
MATHLIB ?= -lm
Note that LDFLAGS might contain -L options, so order is important.
LDFLAGS is commonly set as an environment variable.
Some of the target-specific libraries are internal Netpbm libraries
(such as libfiasco), which use Libnetpbm. So we put $(NETPBMLIB)
after LDFLAGS_TARGET.
LDFLAGS_ALL = $(WINICON_OBJECT) \
$(LDFLAGS_TARGET) $(shell $(LIBOPT) $(NETPBMLIB)) \
$(LDFLAGS) $(LDLIBS) $(MATHLIB) $(RPATH) $(LADD)
$(PORTBINARIES) $(MATHBINARIES): %: %.o \
$(NETPBMLIB) $(LIBOPT) $(WINICON_OBJECT)
$(LD) -o $@$(EXE) $@.o $(ADDL_OBJECTS) $(LDFLAGS_ALL)
MERGE STUFF
.o2 is our suffix for an object file that has had it's main() changed
to e.g. main_pamcut(). We use them for the merge build.
%.o2: %.c importinc
Note that the user may have configured -I options into CFLAGS.
$(CC) -c $(INCLUDES) -DNDEBUG $(CPPFLAGS) $(CFLAGS) \
"-Dmain=main_$*" \
$(CFLAGS_MERGE) $(CFLAGS_PERSONAL) $(CADD) -o $@ $<
The "merge try list" is a file full of TRY macro invocations, one for
each Netpbm program in this directory or any subdirectory that can be
invoked via the merged Netpbm program. You will find it #included in
netpbm.c.
mergetrylist: $(SUBDIRS:%=%/mergetrylist)
cat /dev/null $(SUBDIRS:%=%/mergetrylist) >$@
$(SRCDIR)/buildtools/make_merge.sh $(MERGEBINARIES) >>$@
The "merge list" is a list of all the object files from this directory and
any subdirectories that have to be linked into the merged Netpbm program.
They are absolute paths.
mergelist: $(SUBDIRS:%=%/mergelist) $(MERGE_OBJECTS)
cat /dev/null $(SUBDIRS:%=%/mergelist) >$@
echo $(MERGE_OBJECTS:%=$(CURDIR)/%) >>$@
merge.o is the object file that contains all the code in this directory
that needs to be linked into the merged Netpbm program. This is not used
today, but some day it will be used instead of mergelist (above).
ifeq ($(MERGE_OBJECTS),)
MERGE_O_OBJECTS = empty.o
else
MERGE_O_OBJECTS = $(MERGE_OBJECTS)
endif
merge.o: $(SUBDIRS:%=%/merge.o) $(MERGE_O_OBJECTS)
$(LDRELOC) -o $@ $^
empty.o is useful in doing a merge build. Every directory must be able to
produce a merge.o file, but not every directory has anything to contribute
to the merge.
empty.o: %.o: %.c
$(CC) -c $(CFLAGS_PERSONAL) $(CADD) $< -o $@
empty.c:
cat /dev/null >empty.c
PACKAGING / INSTALLING
Some maintenance notes about $(INSTALL): Some install programs can
install multiple files in one shot; others can take only one file at
a time. Some have a -c option; others ignore -c. Some can take
permissions in mnemonic form (u=rwx,go=rx); others can't, but all
take the encoded form (755). Some have a -d option to install
directories and never install them implicitly. Others create
directories only implicitly. Installbsd and OSF1 Install need a
space in "-m 755". Others don't care. 2000.05.17. OSF1 Install
takes only one parameter: the source file. It picks a destination
directory by default, or you can specify it with a -f option.
2000.06.15
DJGPP can do SYMKINKs for programs but not for ordinary files, so
it define SYMLINKEXE, other system don't need it
ifeq ($(SYMLINKEXE)x,x)
SYMLINKEXE := $(SYMLINK)
endif
An implicit rule for $(PKGDIR)/% does not work because it causes Make
sometimes to believe the directory it creates from this rule is an unneeded
intermediate file and try to delete it later. So we explicitly list the
possible directories under $(PKGDIR):
PKGMANSUBDIRS = man1 man3 man5 web
PKGSUBDIRS = bin include include/netpbm lib link misc \
$(PKGMANSUBDIRS:%=$(PKGMANDIR)/%)
$(PKGSUBDIRS:%=$(PKGDIR)/%):
$(SRCDIR)/buildtools/mkinstalldirs $@
.PHONY: install.merge
install.merge: $(NOMERGEBINARIES:%=%_installbin) $(SCRIPTS:%=%_installscript) \
$(MERGEBINARIES:%=%_installmerge) $(SUBDIRS:%=%/install.merge)
%_installmerge: $(PKGDIR)/bin
cd $(PKGDIR)/bin ; rm -f $(@:%_installmerge=%)
cd $(PKGDIR)/bin ; $(SYMLINKEXE) netpbm$(EXE) $(@:%_installmerge=%)
.PHONY: install.bin
install.bin: $(BINARIES:%=%_installbin) $(SCRIPTS:%=%_installscript) \
$(SUBDIRS:%=%/install.bin)
Note that on Cygwin, the executables are actually pbmmake.exe, etc.
Make and Install know that pbmmake.exe counts as pbmmake.
INSTALLBIN_TARGETS = $(BINARIES:%=%_installbin) netpbm_installbin
.PHONY: $(INSTALLBIN_TARGETS)
$(INSTALLBIN_TARGETS): $(PKGDIR)/bin
$(INSTALL) -c $(STRIPFLAG) -m $(INSTALL_PERM_BIN) \
$(@:%_installbin=%) $<
$(SCRIPTS:%=%_installscript): $(PKGDIR)/bin
$(INSTALL) -c -m $(INSTALL_PERM_BIN) \
$(SRCDIR)/$(SUBDIR)/$(@:%_installscript=%) $<
.PHONY: install.data
install.data: $(DATAFILES:%=%_installdata) $(SUBDIRS:%=%/install.data)
.PHONY: $(DATAFILES:%=%_installdata)
$(DATAFILES:%=%_installdata): $(PKGDIR)/misc
$(INSTALL) -c -m $(INSTALL_PERM_DATA) \
$(SRCDIR)/$(SUBDIR)/$(@:%_installdata=%) $<
.PHONY: clean
ifneq ($(EXE)x,x)
EXEPATTERN = *$(EXE)
else
EXEPATTERN =
endif
clean: $(SUBDIRS:%=%/clean) thisdirclean
.PHONY: thisdirclean
thisdirclean:
-rm -f .o .o2 .a .so .so. .dll .dylib .cat ~ .i .s \
$(EXEPATTERN) .def .lnk \
core .core mergelist mergetrylist .c1 empty.c \
$(BINARIES) pm_types.h
-rm -rf importinc
.PHONY: distclean
distclean: $(SUBDIRS:%=%/distclean) thisdirclean
rm -f depend.mk
DEP_SOURCES = $(wildcard .c .cpp *.cc)
.PHONY: dep
dep: $(SUBDIRS:%=%/dep) importinc
We use -MG here because of compile.h and version.h. They need not exist
before the first make after a clean.
ifneq ($(DEP_SOURCES)x,x)
$(CC) -MM -MG $(INCLUDES) $(DEP_SOURCES) >depend.mk
endif
Note: if I stack all these subdirectory targets into one rule, I get
weird behavior where e.g. make install-nonmerge causes all the
%/install.bin makes to happen recursively, but then lib/install.lib
is considered up to date and doesn't get rebuilt.
%/install.bin:
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
%/install.lib:
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
%/install.data:
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
%/install.merge:
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
$(SUBDIRS:%=%/all): %/all: $(CURDIR)/%
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
$(SUBDIRS:%=%/mergetrylist): %/mergetrylist: $(CURDIR)/% FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
$(SUBDIRS:%=%/mergelist): %/mergelist: $(CURDIR)/% FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
$(SUBDIRS:%=%/merge.o): %/merge.o: $(CURDIR)/% FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
$(SUBDIRS:%=%/clean): %/clean: $(CURDIR)/%
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
$(SUBDIRS:%=%/distclean): %/distclean: $(CURDIR)/%
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
$(SUBDIRS:%=%/dep): %/dep: $(CURDIR)/%
$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)
Here is the rule to create the subdirectories. If you're building in the
source tree, they already exist, but in a separate build directory, they may
not.
ifneq ($(SUBDIR)x,x)
This hack stops us from having a warning due to the same target twice
when we're in the top level directory (because buildtools, etc are in
SUBDIRS).
DIRS2 = $(BUILDDIR)/buildtools $(BUILDDIR)/lib $(BUILDDIR)/urt
endif
$(SUBDIRS:%=$(CURDIR)/%) $(DIRS2):
mkdir $@
The automatic dependency generation is a pain in the butt and
totally unnecessary for people just installing the distributed code,
so to avoid needless failures in the field and a complex build, the
rule to generate depend.mk automatically simply creates an
empty file. A developer may do 'make dep' to create a
depend.mk full of real dependencies.
depend.mk:
cat /dev/null >$@
include depend.mk
FORCE: