HOW TO INSTALL NETPBM
---------------------

For most typical platforms, you can just do

    ./configure

followed by

    make

To build all the programs.  Then

    make package

to gather all the installable parts into a specified directory, and 
finally

    ./installnetpbm

to install it into your system.  

If you have a Debian-like system, that uses Dpkg for package management,
it's better to create a Debian package file and install it as follows in
place of the 'installnetpbm' step above.

    make deb
    dpkg --install netpbm-sf-*.deb

More information on building and installing on Debian are in the file
buildtools/debian/README in the source tree.


The 'configure' program is not GNU Autoconf -- it is a simple program
specific to Netpbm that prompts you for information about your system.
If your system is not typical enough, you'll have to do a little more
work, as described below under "custom building."

You need to use GNU Make even if nothing else on your system is GNU,
because the Netpbm make files exploit many advanced features of GNU
Make.  Often, systems have both GNU Make and a native Make.  In this
case, GNU Make is named 'gmake'.  If you don't have it yet, see
www.gnu.org/software.  GNU Make is free, easy to install, and works
just about anywhere.

The only tricky part about installing is setting up the shared
libraries that are part of Netpbm.  Simply putting the library files
in place may not be enough.  If you get mysterious "file not found"
kinds of errors and are not an expert with shared libraries, see the
section "SHARED LIBRARIES" below.

The --keep-going option to Make is handy, because it causes Make to
make anything it can, as opposed to quitting as soon as something goes
wrong.  With so many parts having so many requirements, it's not
unusual for a few things to fail to build, but that doesn't affect
everything else.  You can work on the failed parts and repeat the make
and it will attempt to build whatever it hasn't successfully built
yet.


CHECKING THE BUILD
------------------

The package comes with a test facility, which you can run after packaging,
against the package you created.  The typical sequence is

    make

    make package

    make check

    ./installnetpbm

To capture all the messages from "make check" do:

    make check > test.log  2>&1

The test facility was new in Netpbm 10.61 (December 2012).

For further information on the tests read the document TESTS.


OVERRIDING INTERNAL LIBRARIES
-----------------------------

There are a few esoteric libraries that are distributed separately from Netpbm
but of which Netpbm contains a copy too, for convenience.  The build normally
uses the internal Netpbm copy, but you can configure the build to use a
version of the library that is installed on your system.

For the JBIG library, set the JBIGLIB and JBIGHDR_DIR variables in
config.mk to the appropriate values.

For the Utah Raster Toolkit (aka URT aka RLE) library, set the URTLIB and
URTHDR_DIR vairables in config.mk to the appropriate values.

The appropriate value for the xxxLIB variable is the full file name of the
link library (e.g. "/usr/local/lib/jbigkit/libjbig.so") or just the file name
part of it (e.g. "libjbig.so") if the library is in your linker's default
search path.

The appropriate value for the xxxHDR_DIR variable is the full directory name
of the directory that contains the interface header files for the library
identified by the xxxLIB variable (E.g. "usr/local/include/jbigkit") or a null
string if those header files are in your compiler's default search path.

If you use the 'configure' program, be sure to edit config.mk _after_ you
run 'configure', since 'configure' generates config.mk.


COMPILED-IN BUILD DATETIME AND USER
-----------------------------------

By default, the Netpbm build system builds the datetime that you built it
into libnetpbm, so the --version global command line option can display it.
It's actually just when you began building from a clean build tree; if you
modify code and rebuild, the build datetime does not change.

This is problematic for any of various reasons you might want to compare two
versions of libnetpbm, or anything of which it is part, for equality.  Two
libnetpbms that are identical except that they were built at different times
would compare as different.

Furthermore, as version information, the modification datetime of the source
code is often more useful than the build datetime.

For these reasons, it is possible to change this timestamping behavior by
setting the environment variable 'SOURCE_DATE_EPOCH'.  That is supposed to be
the POSIX datetime value (decimal number of seconds since 1969, excluding leap
seconds) for when the source code was last modified.  When you set this,
before doing 'make' for the first time in a clean build tree, the resulting
libnetpbm contains that information and not build datetime information, and
the --version global option causes a different message.

The name and meaning of the environment variable is taken from a standard
described at https://reproducible-builds.org/specs/source-date-epoch/ on March
16, 2017.

Likewise, the Netpbm build system builds the identity of the party who did the
build in libnetpbm.  This is normally a userid, the output of the 'whoami'
program, unless overridden by USER or LOGNAME environment variables.  You can
also override 'whoami', USER, and LOGNAME with the COMPILED_BY environment
variable.  This value is just for display, so it need not be a userid; any
single word that does not contain quotation marks is acceptable.


AUTOMATING THE BUILD
--------------------

The build is already as automatic as Netpbm developers know how to make
it without sacrificing your ability to build it a wide variety of ways.
But if you're building for a specific range of applications, e.g. a
particular standard system configuration, then you may want to write 
programs to automate the build further.

PLEASE don't do this by writing a program that invokes Netpbm's Configure
program and tries to maintain a dialogue with Configure.  This is more work
than you need to do and you will be disappointed with Configure's 
unpredictability, especially from one release to the next.  Configure is
specifically intended to talk to an intelligent human being.

Rather, just write a program to generate the file config.mk.  That's
all Configure does in the end anyway.  Like Configure, your program can
simply copy config.mk.in and add overrides to the bottom.  Or you
can just package up a complete config.mk and not run any program at
all at build time.  Comments in config.mk.in explain the entire
contents.  You can also run Configure interactively and use its output
as an example.


COMPILER REQUIREMENTS
---------------------

The compiler must be able to compile C99 code.


THE PREREQUISITE LIBRARIES
--------------------------

Netpbm uses lots of external libraries, but you don't necessarily have
to install them all.  See http://netpbm.sourceforge.net/prereq.html .
You do, however, have to tell Configure accurately whether you have the
library installed and if so, where.


WINDOWS
-------

For notes on building Netpbm on Windows using Cygwin, see the file
README.CYGWIN.  With Cygwin, you can build Netpbm programs that use
Cygwin or Netpbm programs that use Mingw.

Netpbm has also been built for Windows using Djgpp, as late as 2001.

See also the general installation instructions above.

Mingw Modification
-------------------

With at least some versions of MinGW, you have to make a small change to
_mingw.h or you get a compilation failure for invalid syntax in that file
where it expands the macro _XOPEN_SOURCE.

The problem is that many Netpbm programs declare that they need a C library
that conforms to any version of the X/Open (XPG, XSI, SUS) standard.  The way
they do that is, in accordance with the earliest version of that standard, by
defining the macro _XOPEN_SOURCE with a null (zero-length) body.  But MinGW is
not designed to work with programs that request anything earlier than Issue
(version) 5 of this standard, and in fact _mingw.h will not compile if the
macro expands to something other than a number.

But it is easy to add pre-Issue 5 function to MinGW and having done so, your
MinGW installation will also work with lots of other code.  All you have to do
is change

  if _XOPEN_SOURCE < 500

to

  if (_XOPEN_SOURCE + 0) < 500

in _mingw.h.  This is the trick other C libraries use.

(A user proposed that this change be distributed in _mingw.h, in April 2017 on
the mingw-users mailing list, but the maintainer was opposed to accommodating
programs written for the older standards).

If you cannot change _mingw.h, you can alternatively change Netpbm.  Find all
instances of

  #define _XOPEN_SOURCE

and change them to

  #define _XOPEN_SOURCE 0


MAKING ONLY THE PARTS YOU NEED
------------------------------

If you don't need the whole package, but just want one tool in it that you
heard about, you can make just that one.  For example, to make Pnmtojpeg,
just do

  configure
  cd converter/other
  make pnmtojpeg

It will build Pnmtojpeg and any of its dependencies, but nothing else.
You have to install it manually.  

When you build just one program, you should request a static Netpbm
library in the configure step, because for just one program, the
shared library would be pure masochism.


CUSTOM BUILDING
---------------

This section explains how to customize the installation in the case
that your platform is, or your requirements are, not among the simple
cases that 'configure' understands.  'configure' is really just a
convenient way to build the config.mk file, and in the most
general case, you build that file manually.

config.mk contains settings for various things that vary from
one system to the next, like file paths.  Start with the distributed
file config.mk.in.  Copy it as config.mk, then edit it.
Search for your platform name (Solaris, SunOS, NetBSD, Cygwin, BeOS,
and Tru64 are among those mentioned) to see recommended settings for
your platform.

If your system is even too exotic to accommodate with settings in
config.mk, you may need to modify things in the main make files
or pm_config.h.in.

If you figure out how to install on other platforms, contact the
Netpbm maintainer to have the 'configure' program or these
instructions improved for the next person.

If you want to use a compiler other than your system default, set
the CC value in config.mk to the shell command name for your compiler,
e.g.

  CC=clang-3

You can also override it on the Make command line, which is especially
useful if you want to build some parts with one compiler and other parts
with another compiler:

  $ make pamflip CC=clang-3

To get appropriate defaults when you run 'configure', you can also set what
compiler Configure assumes you will be using to build, with an environment
variable:

  $ CC=clang-3 ./configure

Likewise, you can add compiler flags with a CFLAGS make variable, either set
in config.mk or on the make command line and you can get better get more
appropriate defaults from Configure if you pass the same CFLAGS to Configure
via environment variable.  LDFLAGS (linker options) and CPPFLAGS (C
preprocessor options) are similar.

  $ make CFLAGS=-O0


AUTOMATED AND CUSTOM INSTALLATION
---------------------------------

If you want to have a program install Netpbm, don't use 'installnetpbm'.  Just
write your own program to install from the package that 'make package'
generates.  That package is just a directory full of files, and you should be
able to tell by inspection what to do with those files (copy to /bin, etc).
If not, there is a README file in the package that explains everything.  Your
install program will probably just be shell script that issues about five
commands.

Likewise, even if you're installing interactively, if the Installnetpbm
program doesn't install the way you want, just install manually from the
package, using a few commands such as 'cp'.


INSTALLATION - SHARED LIBRARIES
-------------------------------

There are over 240 programs in the Netpbm package and they do a lot of
common things.  In order to avoid the expense of copying the code for
those common things into every program, Netpbm places them in a shared
library: libnetpbm.  When you invoke a Netpbm program, your system
notices that it needs this library and accesses it too.

The tricky part of installing the shared (runtime) library is telling
your system where to find it in the event that you invoke a Netpbm
program.  And that varies from one system to the next.

On a GNU libc system (essentially, any Linux system), if you put the
Netpbm shared library in a conventional spot (say, /lib) and reboot
your system, chances are you will have no trouble running Netpbm
programs.  But if you want to fine tune things, read up on ld-linux.so
(GNU libc's dynamic linker) and Ldconfig and consider the
/etc/ld.so.conf file and LD_LIBRARY_PATH environment variables.  Use
'ldd' to see if you have a shared library issue.  If it shows any
shared library as "not found", you've got library trouble.

On a Solaris system, use 'crle' to set the default search path for
shared libraries (which is kept in /var/ld/ld.config).  Make sure that
path includes the directory in which you installed the Netpbm shared
library.  You can also use the LD_LIBRARY_PATH environment variable.

On AIX, the environment variable LIBPATH affects the shared library search
path.  On AIX 5.3 and newer, you can use LD_LIBRARY_PATH as well.

Besides the Netpbm shared library, libnetpbm, several of the converter
programs, e.g. Jpegtopnm, use separately distributed libraries that
understand the graphics format involved.  You need to make sure your
system knows how to find those libraries at run time too (or cause the
Netpbm build to statically bind the libraries into the Netpbm programs).

Another thing you can do is forget about library search paths and just
build into each Netpbm executable the location of the Netpbm shared
library.  (I'm talking about the classic -R linker option) You set
this up with variables in config.mk.  If you use Configure to
build config.mk, then for some platforms where this method is
common, the Configure dialog asks you what directory, if any, you want
built into Netpbm executables.

One final note: New Netpbm executables often can run OK with an old
Netpbm shared library.  This means if you don't correctly install
the new library, you may run what you think is a new Netpbm program,
but in actuality be accessing the old Netpbm library, and you may not
even notice a problem right away.  But eventually, you may find some
things not working the way they should.  Again, 'ldd' will give you 
peace of mind.


INSTALLATION WITHOUT SHARED LIBRARIES
-------------------------------------

Since shared libraries can be such a pain, and in fact some systems
don't even have them, you can build Netpbm with a static library
instead.  Just answer "static" to the static/shared question when you
run 'configure' (if you don't use 'configure', set NETPBMLIBTYPE as
directed in config.mk.in).

If you do this, you probably want to do a merge build instead of the
normal build (there's a question for that in the Configure program).
See below.


SEPARATE BUILD TREE
-------------------

While it's traditional to build a Unix package by adding object files
to the same tree with the source files, it's actually much cleaner to
keep your source tree exactly as you got it and put the built files in
a separate directory, called the build tree.

To do this, just create an empty directory and run 'configure' in it,
then 'make':

  mkdir netpbmbuild
  cd netpbmbuild
  /usr/src/netpbm/configure
  ...
  make

But if you plan to work on Netpbm source code, you'll probably find it
more convenient to build the traditional way, with a single tree for
source and build.

In the source tree, you can type 'make' in any directory to do the
default make for that directory, or make FILENAME to make the file of
that name there.  In the separate build tree, there are special
facilities to allow you to do a simple make from the _top level
directory_, but if you want to make a subcomponent or individual part,
you have to have a -f option and set SRCDIR and BLDDIR on your 'make'
command.


MERGE BUILD
-----------

There are two ways to build Netpbm: the standard or nonmerge build,
and the merge build.  There are different make file targets for them
and which one is default is controlled by the DEFAULT_TARGET make
variable in config.mk, and its value is one of the choices you
make via the Configure dialog.

The standard build is the conventional one.  The merge build is a way to
reduce disk space and other resource usage in some configurations.  These are
rare configurations, mostly antique ones.  The advent of shared libraries
largely obsoleted the merge build.  In some configurations, Netpbm uses _more_
resources with the merge build.

In the standard build, hundreds of separate programs get built: ppmtogif,
pamcomp, etc.

But the merge build creates a single large program called 'netpbm'
instead.  That single 'netpbm' program contains the functions of all
the individual programs that the standard build builds, and selects
one of them to execute based on what command name you use to invoke
'netpbm'.

For example, if you install 'netpbm' with a symbolic link to it named
'ppmtogif' and you invoke the program by typing 'ppmtogif' at a shell
prompt, 'netpbm' executes Ppmtogif.

Hence, 'make package' creates a package containing the one 'netpbm'
program and lots of symbolic links to it.  With all these links
properly installed, a typical user cannot tell the merge build from the
standard build.


DOCUMENTATION
-------------

Documentation is not packaged with the program source code.  See the
file doc/USERDOC for information on installing documentation.


COMMON PROBLEMS
---------------

Improper -config files
----------------------

The most common problem building Netpbm is one of improperly installed
prerequisite libraries, such as Libpng.  Such a library is designed to be
installed along with a -config program (e.g. libpng-config) that tells
builders of dependent packages (such as Netpbm) how to use it.  When the
-config program is wrong, you get Netpbm build failures with messages about
undefined references.

The exact nature of the problems with -config programs can be quite
involved, especially since there is no guarantee that a -config
program can do what's required of it in every situation.  But I'll
explain the basic problem.  For simplicity, I'll talk specifically
about Libpng, but the principles apply to any library that has a -config
program.

The point of libpng-config is to describe how Libpng is installed on your
particular system.  You have choices of where to install the various parts
and what prerequisites to build into them, and libpng-config is how you
communicate those choices to the Netpbm make files.

Libpng's builder automatically creates a libpng-config program for you,
but you should not think of it as part of Libpng.  It's really a
configuration file -- something that tells how your particular system
is put together.  The Libpng builder is not smart enough to know exactly
what to put in libpng-config; it just builds one that works for most
people.  The local system administrator is actually responsible for
the contents of libpng-config.

One rather complex way in which the libpng-config that the Libpng builder
builds can be wrong is that it often indicates that to link to the
Libpng library, you need a "-L /usr/lib" option (or something like that
-- an option that adds to the linker's search path a directory that is
already in it).  This is usually unnecessary because the directory is
already in the search path, and often breaks things because it puts
the directory too early in the search path.  If your libpng-config says to
link with -L /usr/lib, you should normally edit it to remove that.

As an example of how -L /usr/lib breaks things, here is a problem that is
often reported: The user has Netpbm installed on his system, but wants to
build a new one to replace it, or to use for a particular project instead of
the system version.  But the build of the new version fails with undefined
references to symbol "pm_foo".  pm_foo is a new symbol - it was added to
Netpbm in a recent release.  The version of Netpbm installed on the system is
too old to have it.  The make file obviously specifies the path to the current
libraries that the user just built in the link library search order, but the
link is picking up the old system version instead.  Why?  Because the link
options say to search /usr/lib _before_ the local build directory.  And they
do that because libpng-config erroneously says that you need a -L /usr/lib
link option to find the Libpng library.
