about summary refs log tree commit diff
path: root/GNUmakefile
blob: 489d6888bd6c77667cb422f61422a990659d2777 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# Makefile for Netpbm
 
# Configuration should normally be done in the included file config.mk.

# Targets in this file:
#
#   nonmerge:     Build everything, in the source directory.
#   merge:        Build everything as merged executables, in the source dir
#   package:      Make a package of Netpbm files ready to install
#   
#   The default target is either "merge" or "nonmerge", as determined by
#   the DEFAULT_TARGET variable set by config.mk.

# About the "merge" target: Normally the Makefiles build separate
# executables for each program.  However, on some systems (especially
# those without shared libraries) this can mean a lot of space.  In
# this case you might try building a "merge" instead.  The idea here
# is to link all the programs together into one huge executable, along
# with a tiny dispatch program that runs one of the programs based on
# the command name with which it was invoked.  You install the merged
# executable with a file system link for the name of each program it
# includes.  This is much more important when you're statically
# linking than when you're using shared libraries.  On a Sun3 under
# SunOS 3.5, where shared libraries are not available, the space for
# executables went from 2970K to 370K in an older Netpbm.  On a
# GNU/Linux IA32 system with shared libraries in 2002, it went from
# 2949K to 1663K.

# To build a "merge" system, just set DEFAULT_TARGET to "merge" instead
# of "nomerge" in config.mk.  In that case, you should probably also
# set NETPBMLIBTYPE to "unixstatic", since a shared library doesn't do you 
# much good.

# The CURDIR variable presents a problem because it was introduced in
# GNU Make 3.77.  We need the CURDIR variable in order for our 'make
# -C xxx -f xxx' commands to work.  If we used the obvious alternative
# ".", that wouldn't work because it would refer to the directory
# named in -C, not the directory the make file you are reading is
# running in.  The -f option is necessary in order to have separate
# source and object directories.

ifeq ($(CURDIR)x,x)
all package install:
	@echo "YOU NEED AT LEAST VERSION 3.77 OF GNU MAKE TO BUILD NETPBM."
	@echo "Netpbm's makefiles need the CURDIR variable that was "
	@echo "introduced in 3.77.  Your version does not have CURDIR."
	@echo
	@echo "You can get a current GNU Make via http://www.gnu.org/software"
	@echo 
	@echo "If upgrading is impossible, try modifying GNUMakefile and "
	@echo "common.mk to replace \$(CURDIR) with \$(shell /bin/pwd) "
else


# srcdir.mk defines SRCDIR .
include srcdir.mk
BUILDDIR = $(CURDIR)
SUBDIR = 
VPATH=.:$(SRCDIR)

include $(BUILDDIR)/config.mk

PROG_SUBDIRS = converter analyzer editor generator other
PRODUCT_SUBDIRS = lib $(PROG_SUBDIRS)
SUPPORT_SUBDIRS = urt buildtools

SUBDIRS = $(PRODUCT_SUBDIRS) $(SUPPORT_SUBDIRS)

SCRIPTS = manweb
MANUALS1 = netpbm
NOMERGEBINARIES = netpbm

OBJECTS = netpbm.o

default: $(DEFAULT_TARGET)
	echo "EXISTENCE OF THIS FILE MEANS NETPBM HAS BEEN BUILT." \
	  >build_complete
	@echo ""
	@echo "Netpbm is built.  The next step is normally to package it "
	@echo "for installation by running "
	@echo ""
	@echo "    make package pkgdir=DIR"
	@echo ""
	@echo "to copy all the Netpbm files you need to install into the "
	@echo "directory DIR.  Then you can proceed to install."

all: nonmerge

.PHONY: nonmerge
nonmerge: $(PRODUCT_SUBDIRS:%=%/all)

# Parallel make (make --jobs) is not smart enough to coordinate builds
# between submakes, so a naive parallel make would cause certain
# targets to get built multiple times simultaneously.  That is usually
# unacceptable.  So we introduce extra dependencies here just to make
# sure such targets are already up to date before the submake starts,
# for the benefit of parallel make.  Note that we ensure that parallel
# make works for 'make all' in the top directory, but it may still fail
# for the aforementioned reason for other invocations.

$(SUBDIRS:%=%/all) lib/util/all: pm_config.h inttypes_netpbm.h version.h
$(PROG_SUBDIRS:%=%/all): lib/all $(SUPPORT_SUBDIRS:%=%/all)
lib/all: lib/util/all

.PHONY: lib/util/all
lib/util/all:
	mkdir -p lib/util
	$(MAKE) -C lib/util -f $(SRCDIR)/lib/util/Makefile \
	    SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) all

OMIT_CONFIG_RULE = 1
OMIT_VERSION_H_RULE = 1
OMIT_INTTYPES_RULE = 1
include $(SRCDIR)/common.mk

$(BUILDDIR)/config.mk: $(SRCDIR)/config.mk.in
	$(SRCDIR)/configure $(SRCDIR)/config.mk.in


# typegen is a utility program used by the make file below.
TYPEGEN = $(BUILDDIR)/buildtools/typegen

# endiangen is a utility program used by the make file below.
ENDIANGEN = $(BUILDDIR)/buildtools/endiangen

$(TYPEGEN) $(ENDIANGEN): $(BUILDDIR)/buildtools
	$(MAKE) -C $(dir $@) -f $(SRCDIR)/buildtools/Makefile \
	    SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) 

inttypes_netpbm.h: $(TYPEGEN)
	$(TYPEGEN) >$@

# We run a couple of programs on the build machine in computing the
# contents of pm_config.h.  We need to give the user a way not to do
# that or to override the results, because it doesn't work if he's
# cross compiling.

pm_config.h: \
  $(SRCDIR)/pm_config.in.h config.mk inttypes_netpbm.h \
  $(ENDIANGEN)
# Note that this rule depends on the effect of the .DELETE_ON_ERROR
# target we get from common.mk
	echo '/* pm_config.h GENERATED BY A MAKE RULE */' >$@
	echo '#ifndef PM_CONFIG_H' >>$@
	echo '#define PM_CONFIG_H' >>$@
ifeq ($(INTTYPES_H)x,x)
	echo '/* Don't need to #include any inttypes.h-type thing */
else
  ifeq ($(INTTYPES_H),"inttypes_netpbm.h")
	cat inttypes_netpbm.h >>$@
  else
	echo '#include $(INTTYPES_H)' >>$@
  endif
endif
ifeq ($(HAVE_INT64),Y)
	echo "#define HAVE_INT64 1" >>$@
else
	echo "#define HAVE_INT64 0" >>$@
endif	
ifeq ($(DONT_HAVE_PROCESS_MGMT),Y)
	echo "#define HAVE_FORK 0" >>$@
else
	echo "#define HAVE_FORK 1" >>$@
endif
	echo '/* pm_config.h.in FOLLOWS ... */' >>$@
	cat $(SRCDIR)/pm_config.in.h >>$@
	$(ENDIANGEN) >>$@
	echo '#endif' >>$@


MAJOR := $(NETPBM_MAJOR_RELEASE)
MINOR := $(NETPBM_MINOR_RELEASE)
POINT := $(NETPBM_POINT_RELEASE)
version.h: $(SRCDIR)/version.mk
	@rm -f $@
	@echo "/* Generated by make file rule */" >>$@
	@echo "#define NETPBM_VERSION" \
	  \"Netpbm $(MAJOR).$(MINOR).$(POINT)"\"" >>$@


.PHONY: install
install:
	@echo "After doing a 'make', do "
	@echo ""
	@echo "  make package pkgdir=DIR"
	@echo ""
	@echo "to copy all the Netpbm files you need to install into the "
	@echo "directory DIR."
	@echo ""
	@echo "Then, do "
	@echo ""
	@echo "  ./installnetpbm"
	@echo
	@echo "to install from there to your system via an interactive.  "
	@echo "dialog.  Or do it manually using simple copy commands and "
	@echo "following instructions in the file DIR/README"

.PHONY: package package_build init_package advise_installnetpbm
package: build_complete package_build advise_installnetpbm

build_complete:
# The regular build creates this file as its last act, so if it doesn't exist,
# that means either the user skipped the build step, or the build failed.
	@echo "You must build Netpbm before you can package Netpbm. "
	@echo "The usual way to do this is to type 'make' with no arguments."
	@echo "If you did that, then the build apparently failed.  There "
	@echo "should have been error messages indicating why.  If you "
	@echo "can't fix the build problem, you can do 'make --keep-going' "
	@echo "to force the build to continue with other parts that "
	@echo "it may be able to build successfully, then do "
	@echo "'make package --keep-going' to package whatever was "
	@echo "successfully built."
	@echo
	@false;

package_build: init_package install-run install-dev 

MAJOR=$(NETPBM_MAJOR_RELEASE)
MINOR=$(NETPBM_MINOR_RELEASE)
POINT=$(NETPBM_POINT_RELEASE)

init_package:
	@if [ -d $(PKGDIR) ]; then \
	  echo "Directory $(PKGDIR) already exists.  Please specify a "; \
	  echo "directory that can be created fresh, like this: "; \
	  echo "  make package PKGDIR=/tmp/newnetpbm "; \
	  false; \
	  fi
	mkdir $(PKGDIR)
	echo "Netpbm install package made by 'make package'" \
	    >$(PKGDIR)/pkginfo
	date >>$(PKGDIR)/pkginfo
	echo Netpbm $(MAJOR).$(MINOR).$(POINT) >$(PKGDIR)/VERSION
	$(INSTALL) -c -m 664 $(SRCDIR)/buildtools/README.pkg $(PKGDIR)/README
	$(INSTALL) -c -m 664 $(SRCDIR)/buildtools/config_template \
	  $(PKGDIR)/config_template

advise_installnetpbm:
	@echo
	@echo "Netpbm has been successfully packaged under directory"
	@echo "$(PKGDIR).  Run 'installnetpbm' to install it on your system."

.PHONY: install-run
ifeq ($(DEFAULT_TARGET),merge)
install-run: install-merge
else
install-run: install-nonmerge 
endif

.PHONY: install-merge install-nonmerge
install-merge: install.merge install.lib install.data \
	install.manweb install.man

install-nonmerge: install.bin install.lib install.data \
	install.manweb install.man

.PHONY: merge
merge: lib/all netpbm

MERGELIBS = 
ifneq ($(ZLIB),NONE)
  MERGELIBS += $(ZLIB)
endif
ifneq ($(JPEGLIB),NONE)
  MERGELIBS += $(JPEGLIB)
endif
ifneq ($(TIFFLIB),NONE)
  MERGELIBS += $(TIFFLIB)
endif
ifneq ($(URTLIB),NONE)
  MERGELIBS += $(URTLIB)
endif
ifneq ($(LINUXSVGALIB),NONE)
  MERGELIBS += $(LINUXSVGALIB)
endif

ifeq ($(shell libpng$(PNGVER)-config --version),)
  PNGLD = $(shell $(LIBOPT) $(LIBOPTR) $(PNGLIB) $(ZLIB))
else
  PNGLD = $(shell libpng$(PNGVER)-config --ldflags)
endif

ifeq ($(shell xml2-config --version),)
  XML2LD=
else
  XML2LD=$(shell xml2-config --libs)
endif

ifeq ($(shell pkg-config x11 --libs),)
  X11LD = $(shell $(LIBOPT) $(LIBOPTR) $(X11LIB))
else
  X11LD = $(shell pkg-config x11 --libs)
endif



# If URTLIB is BUNDLED_URTLIB, then we're responsible for building it, which
# means it needs to be a dependency:
ifeq ($(URTLIB),$(BUNDLED_URTLIB))
  URTLIBDEP = $(URTLIB)
endif

# We have two different ways to do the merge build:
#  
#   1) Each directory produces an object file merge.o containing all the code
#      in that directory and its descendants that needs to go into the 'netpbm'
#      program.  The make files do this recursively, via a link command that
#      combines multiple relocateable object files into one.  All we do here
#      at the top level is make merge.o and link it with netpbm.o and the
#      libraries.
#
#      This is the clean way, and we use it whenever we can.  But we don't
#      know how to do the link on every platform.
#
#   2) Each directory produces a list of all the object files in that 
#      directory and its descendants that need to go into the 'netpbm'
#      program.  This list is in a file called 'mergelist'.  The make files
#      do this recursively.  Here at the top level, we make mergelist and
#      then do one large link of everything listed in it, plus netpbm.o and
#      the libraries.
#
#      This doesn't require any special link command like (1), but is
#      not very clean.  The dependencies don't work right.  And at least
#      one linker (on DJGPP) can't handle that many input files.

ifeq ($(LDRELOC),NONE)
  OBJECT_DEP = mergelist
  OBJECT_LIST = `cat mergelist`
else
  OBJECT_DEP = merge.o
  OBJECT_LIST = merge.o
endif

netpbm:%:%.o $(OBJECT_DEP) $(NETPBMLIB) $(URTLIBDEP) $(LIBOPT)
# Note that LDFLAGS might contain -L options, so order is important.
	$(LD) -o $@ $< $(OBJECT_LIST) \
          $(LDFLAGS) $(shell $(LIBOPT) $(NETPBMLIB) $(MERGELIBS)) \
	  $(PNGLD) $(XML2LD) $(X11LD) $(MATHLIB) $(NETWORKLD) $(LADD)

netpbm.o: mergetrylist

install.merge: local.install.merge
.PHONY: local.install.merge
local.install.merge:
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pnmnoraw
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm gemtopbm
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pnminterp
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pgmoil
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm ppmtojpeg
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm bmptoppm
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pgmnorm
	cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pnmfile

ifneq ($(NETPBMLIBTYPE),unixstatic)
install.lib: lib/install.lib
else
install.lib:
endif

.PHONY: install.manweb
install.manweb: $(PKGDIR)/man/web/netpbm.url $(PKGDIR)/bin/doc.url

$(PKGDIR)/man/web/netpbm.url: $(PKGDIR)/man/web
	echo "$(NETPBM_DOCURL)" > $@
	chmod $(INSTALL_PERM_MAN) $@

$(PKGDIR)/bin/doc.url: $(PKGDIR)/bin
	echo "$(NETPBM_DOCURL)" > $@
	chmod $(INSTALL_PERM_MAN) $@

.PHONY: install-dev
# Note that you might install the development package and NOT the runtime
# package.  If you have a special system for building stuff, maybe for 
# multiple platforms, that's what you'd do.  Ergo, install.lib is here even
# though it is also part of the runtime install.
install-dev: install.hdr install.staticlib install.lib install.sharedlibstub

.PHONY: install.hdr
install.hdr: lib/install.hdr $(PKGDIR)/include/netpbm
	$(INSTALL) -c -m $(INSTALL_PERM_HDR) \
	    $(BUILDDIR)/pm_config.h $(PKGDIR)/include/netpbm

.PHONY: lib/install.hdr
lib/install.hdr:
	$(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/Makefile \
	    SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@)

ifeq ($(STATICLIB_TOO),y)
BUILD_STATIC = y
else
  ifeq ($(NETPBMLIBTYPE),unixstatic)
    BUILD_STATIC = y
  else
    BUILD_STATIC = n
  endif
endif

.PHONY: install.staticlib
install.staticlib: 
ifeq ($(BUILD_STATIC),y)
	$(MAKE) -C lib -f $(SRCDIR)/lib/Makefile \
	SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) install.staticlib 
endif

.PHONY: install.sharedlibstub
install.sharedlibstub:
	$(MAKE) -C lib -f $(SRCDIR)/lib/Makefile \
	    SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) install.sharedlibstub 

.PHONY: check
check:
# This works on typical Linux systems
	if [ ! -d $(RESULTDIR) ]; then mkdir -pv $(RESULTDIR); fi
	cd $(RESULTDIR); \
	  PBM_TESTPREFIX=$(PKGDIR)/bin \
	  LD_LIBRARY_PATH=$(PKGDIR)/lib \
	  RGBDEF=$(SRCDIR)/lib/rgb.txt \
	  $(SRCDIR)/test/Execute-Tests 2>&1

clean: localclean

.PHONY: localclean
localclean:
	rm -f netpbm build_started build_complete
	rm -f pm_config.h inttypes_netpbm.h version.h

# Note that removing config.mk must be the last thing we do,
# because no other makes will work after that is done.
distclean: localdistclean
.PHONY: localdistclean
localdistclean: localclean
	-rm -f `find -type l`
	-rm -f TAGS
	-rm -f config.mk

# 'tags' generates/updates an Emacs tags file, anmed TAGS, in the current
# directory.  Use with Emacs command 'find-tag'.

.PHONY: tags
tags:
	find . -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" | \
	  etags -

# The following endif is for the else block that contains virtually the
# whole file, for the test of the existence of CURDIR.
endif