"makefile.gnu-intel" for the pngcrush application by Glenn Randers-Pehrson (a primary developer / maintainer of libpng).

  1. Download the UNIX-line-endings source file.
  2. Download also the new supplementary makefile-include required by default (for Cygwin builds only at present).
  3. Download the patch made against pngcrush-1.5.8
At present this makefile system has only been tested on Cygwin. It is hoped that shortly it will be confirmed to work well using the MinGW platform as well. After that, it is the author's ambition to make it effective on GNU/Linux for Intel PCs, too.

Check out a "build log" which further explains what this makefile does.

time of last modification:   
Fri 24 May at 10:52:30 PM UTC


# Makefile.gnu-intel for pngcrush using gcc and (g)make.
#   by Soren Andersen <libertador@flashmail.com>
#   derivative of "Makefile.gcc" by Glenn Randers-Pehrson.
# Last modified: Friday, May 24, 2002 6:52 PM
#
# Invoke this makefile from a shell prompt after studying carefully all 
# the comments below; for example:
#
#   $ make -f Makefile.gnu-intel [SRCDIR='some/path/spec', etc.]
#
# This makefile builds all the libpng and zlib object files, the pngcrush
# object, and links it all together to create the pngcrush executable. No
# library-building takes place. This makefile generates a *version-named*
# executable to provide for installation of multiple versions and multiple
# 'flavors' of pngcrush without clobbering previous build-versions. Argue
# 'VERSIONING=no' on the command line if desired to cancel this behavior.

VERSIONING ?= yes

mcg := $(MAKECMDGOALS)
QUIETMAKE := $(if $(filter clean,$(mcg))$(filter test,$(mcg)) \
 $(filter install,$(mcg)),1,0)
# begin host-cpu detection  -------------------------------------------------
# This makefile is supposed to be distributed with a supplemental file
# named "get-hostcpu-makefileinclude.gnu." If you did not receive it,
# you can check at:   http://home.att.net/~perlspinr/makefiles
# Warning: this also impacts performance and binary portability -- this
# makefile system builds the exe to *run* on the machine it's *built* on!
# Do not carelessly distribute binaries built with this makefile to other
# machines.

# Leave this next line alone. It's here at the beginning for a reason.
#all: build-setup-info
 ifneq "$(VERSIONING)" "no"
# You can override or avoid this by arguing "x86" (where x=3|4|5|6, etc)
# to "VERSIONING" on the command line, if you want to build for a different
# Intel-compatible CPU ('386', etc) or just want to speed the build up a bit.
   ifeq "$(filter %86,$(VERSIONING))" ""
include $(CURDIR)/made_cpu_tool.tm~
         ifndef made_cpu_tool
include get-hostcpu-makefileinclude_v1.gnu
         endif
HOST_CPU := $(strip $(shell ./makefile_hostcpu.exe 2>/dev/null))
         ifeq "$(HOST_CPU)" ""
HOST_CPU = 386
           ifneq "$(QUIETMAKE)" "1"
$(warning Failed shell call to makefile_hostcpu.exe! Please diagnose and re-run make)
           endif
         else
           ifneq "$(QUIETMAKE)" "1"
$(warning Building for CPU "$(HOST_CPU)")
           endif
         endif
   else
override HOST_CPU = $(VERSIONING)
   endif
# OK, now you can look again.
 endif
# end cpu-detection section -------------------------------------------------


PNGCRUSH = pngcrush

#  USER CONFIGURATION REQUIRED HERE:
# !!! change BINPATH sub-path to suit desired install location. !!!
BINPATH    ?= usr/local/bin
DESTDIR    ?= /

# Zlib and libPNG sources are part of the pngcrush distribution. If
# it is desired to build pngcrush with a different version of the libs
# than it came with, the following macros make this quite simple --
#  **provided that** you remove the library source files from the
# pngcrush directory. If you do not, the following will not achieve
# anything different. REMEMBER not to remove "pngconf.h" as this is
# a *custom* version -- but all the other libpng or zlib files must go.
#  The nitty-gritty of pngcrush is just these four files:
#
#   cexcept.h   pngconf.h
#   pngcrush.c  pngcrush.h
#
# TODO: See the bottom of this file for a list of files to remove.

# Supply a path to the libpng source on the command line, if desired,
# or change it here:

LIBPNG_SRC ?= .

# Supply a path to the zlib source on the command line, if desired,
# or change it here:

ZLIB_SRC   ?= .

# If using libpng source from a different dir, this will find *our*
# "pngconf.h" (which is the only differing libpng source file for
# pngcrush's use of libpng: because it #includes "pngcrush.h"; and
# this means you had better delete all other libpng sourcefiles from
# your pngcrush source directory if doing things this way!):

SRCDIR   ?= .
pcr_version = gcc -E -dM $(SRCDIR)/pngcrush.c  \
|grep 'PNGCRUSH_VERSION' |sed 's,.*\([0-9]\)\.\([0-9]\)\.\([0-9]\).*,\1\2\3,'
VPATH     = $(SRCDIR) $(ZLIB_SRC) $(LIBPNG_SRC)
INCLH     := $(subst . . ,. ,$(VPATH))
INCLUDES1 := $(word 1,$(INCLH))
INCLUDES2 := $(wordlist 2,$(words $(INCLH)),$(INCLH))
CPPFLAGS  := $(addprefix -I,$(INCLUDES1) - $(INCLUDES2))
PCR_VER := $(strip $(shell $(pcr_version)))
  ifeq "$(PCR_VER)" ""
$(error Cannot extract pngcrush version number from source code! Terminating now.)
  else
   ifneq "$(QUIETMAKE)" "1"
$(warning Initiating build of pngcrush version: "$(PCR_VER)")
   endif
  endif

# ---------------------------------------------------
# the following needs to match something like this:
#  gcc version 2.95.3-7 (mingw experimental)
#    or this:
#  gcc version 2.95.3-5 (cygwin special)
# ---------------------------------------------------
define MinCyg_GCC
sed -n /'^gcc version '/s',.*\<\([A-Za-z]*\)\> \(special\|experimental\).*',\\1,p
endef
define Any_GCC
sed -n /'^gcc version '/s',.*\<\([A-Za-z]*\)\>.*',\\1,p
endef

ASK_SHELL_FIND_GCC := $(shell gcc -v 2>&1 | $(MinCyg_GCC))
 ifeq "$(ASK_SHELL_FIND_GCC)" ""
ASK_SHELL_FIND_GCC := $(shell gcc -v 2>&1 | $(Any_GCC))
 endif
 ifneq "$(ASK_SHELL_FIND_GCC)" ""
GCC_FLAVOR := $(strip $(ASK_SHELL_FIND_GCC))
AS_VERSION := $(strip $(shell as --version |grep 'GNU assembler'))
 endif

GASDEFINE := $(if $(AS_VERSION),-DUSES_GAS_VER='"$(AS_VERSION)"', \
 $(warning Could not determine Gnu `as' assembler version.))


# some of the usual culprits...
CC    = gcc
LD    = gcc
RM    = rm -f
CP    = cp

# basic gcc flags ... before messing with this stuff, be sure
# its not already doing the right thing for you! Just try it..
CFLAGS = -O3 -Wall $(TRACE)
  ifneq "$(VERSIONING)" "no"
override CFLAGS += -mcpu="i$(HOST_CPU)"
  endif
override CFLAGS += $(CPPFLAGS)
LDFLAGS  = -Bstatic -Wl,-s
O = .o
E =

 ifeq "$(GCC_FLAVOR)" "mingw"
PLATFLAV := mingw
override CFLAGS  += -DPNG_USE_PNGGCCRD -DPNG_THREAD_UNSAFE_OK \
 $(GASDEFINE) -fnative-struct -funroll-loops -fomit-frame-pointer
override LDFLAGS +=
E = .exe
STDBIN =# who knows? It's Windows -- Don't assume anything.
 endif
 ifeq "$(GCC_FLAVOR)" "cygwin"
PLATFLAV := cyg
override CFLAGS  += -DALL_STATIC -DPNG_USE_PNGGCCRD -DPNG_THREAD_UNSAFE_OK \
 $(GASDEFINE) -funroll-loops -fomit-frame-pointer
override LDFLAGS +=
E = .exe
STDBIN = /usr/bin/
 endif
# TODO: Linux!

# (un)portability rears its head at times, better check these option flags:
MKDIR    = $(STDBIN)mkdir -p
INSTALL  = $(STDBIN)install -sv -m 755
# INSTALL = $(CP) -v


# That's it for the user-serviceable parts. ---------------------------------

LIBS  = -lm
OBJS  = pnggccrd$(O) adler32$(O) crc32$(O)  $(PNGCRUSH)$(O) \
   deflate$(O) gzio$(O) infblock$(O) infcodes$(O) inffast$(O) \
   inflate$(O) inftrees$(O) infutil$(O) \
   png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
   pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
   pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) \
   pngwtran$(O) pngwutil$(O) trees$(O) zutil$(O)

  ifeq "$(VERSIONING)" "no"
EXE := $(PNGCRUSH)$(E)
  else
EXE := $(PLATFLAV)$(addprefix -i,$(HOST_CPU))-$(PNGCRUSH)-$(PCR_VER)$(E)
  endif
EXELOG := $(patsubst %$(E),%.log,$(EXE))


# implicit make rules -------------------------------------------------------

.c$(O): png.h pngconf.h zlib.h pngcrush.h cexcept.h
     @echo $(strip $(CC) -c $(CFLAGS)) $< $(addprefix >>, $(EXELOG))
     $(strip $(CC) -c $(CFLAGS)) $<


# dependencies --------------------------------------------------------------

.PHONY: clean clean-o all install startlogging

all: startlogging build-setup-info $(EXE)

startlogging:
     @echo -e \
'-------------------------------------------------------------------- \
\n'Details of compiler and linker directives used to build \"$(EXE)\" '\n' \
     at `date -u +'%T on %x UTC'` \
'\n'Using the cc:'\n' `2>&1 $(CC) -v`'\n' \
'\n'And the linker: \"`ld -V`\"  $(addprefix >, $(EXELOG)); \
   echo -e \
'-------------------------------------------------------------------- \
\n'    $(addprefix >>, $(EXELOG))

build-setup-info:
     @echo -e '\n'Using gcc version: \"$(GCC_FLAVOR)\" to build \"$(EXE)\"  \
      with optimization for \"$(HOST_CPU)\" processor.'\n'Finding source files \
       in [search order] $(addprefix "\n   ",$(VPATH)) '\n'And looking in \
       header include paths [search order] $(addprefix "\n   ","Firstgroup:" \
       $(subst -I-,"Secondgroup:",$(CPPFLAGS)))'\n' | tee -a $(EXELOG)


$(EXE): $(OBJS)
     @echo $(strip $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)) $(addprefix >>, $(EXELOG))
     $(strip $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS))

$(PNGCRUSH)$(O): $(PNGCRUSH).c png.h pngconf.h zlib.h pngcrush.h cexcept.h


# simple testing ------------------------------------------------------------

test: test-easy
test-easy: $(EXE)
     @$(EXE) -n -v $(LIBPNG_SRC)/pngtest.png && \
       echo -e '\n'PNGCRUSH passes the "easy" test. Do a \"make test-real\" to \
       put it through a more rigorous test.'\n'

test-real: $(EXE)
     $(EXE) -p -v -v -e '.tmp' -m 0 $(LIBPNG_SRC)/pngtest.png

# installation --------------------------------------------------------------

  ifneq "$(VERSIONING)" "no"
ALIAS_TO_LATEST = ln --backup=numbered -vs $(DESTDIR)$(BINPATH)/$(EXE) \
 $(DESTDIR)$(BINPATH)/$(PNGCRUSH)$(E)
  else
ALIAS_TO_LATEST = :
  endif

install: $(EXE)
     @if test ! -d "$(DESTDIR)$(BINPATH)"; then $(MKDIR) "$(DESTDIR)$(BINPATH)" ; fi
     $(INSTALL) $(EXE) $(DESTDIR)$(BINPATH)
     $(ALIAS_TO_LATEST)


# maintenance ---------------------------------------------------------------

clean:
     -$(RM) $(EXE) $(OBJS) $(CLEANMETOO)

clean-o:
     -$(RM) $(OBJS)

# all is completed ----------------------------------------------------------