Use libpng16-config to Build Against the Installed PNG Library
You will finish with a small C program compiled and linked against the libpng development files already installed on the machine. The practical pattern is to ask libpng16-config for flags, pass those flags to the compiler, and check the resulting executable. The older name libpng-config is an alias on this system.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, a C compiler, and the libpng-dev package. This guide uses Ubuntu's libpng-dev:amd64 version 1.6.43-5ubuntu0.6, whose helper reports libpng version 1.6.43. Other package versions can report different paths or libraries, so query the installed helper instead of copying flags from a different host.
1. Confirm which helper is installed
Check the command and package as ordinary, read-only operations. No elevated privileges are needed:
$ command -v libpng16-config
/usr/bin/libpng16-config
$ dpkg-query -W -f='${Package} ${Version}\n' libpng-dev:amd64
libpng-dev:amd64 1.6.43-5ubuntu0.6
$ libpng16-config --version
1.6.43
The alias gives the same version and output here:
$ command -v libpng-config
/usr/bin/libpng-config
$ readlink -f "$(command -v libpng-config)"
/usr/bin/libpng16-config
Checkpoint: use libpng16-config in new build instructions so the intended ABI is visible. Keep libpng-config when maintaining an existing build that already uses that name.
2. Inspect the ordinary compiler and linker flags
Ask the helper for the flags instead of guessing the include directory or library name:
$ libpng16-config --cflags
-I/usr/include/libpng16
$ libpng16-config --libs
-lpng16
$ libpng16-config --ldflags
-lpng16
--cflags is the convenient compile-time result. It combines the preprocessor include options with any compiler options. On this installation --cppflags and --ccopts are empty, so --cflags contains only the include path. --libs supplies the library for normal dynamic linking, while --ldflags combines the linker-related groups listed by the manual.
The separate queries are useful when a build system has distinct compile and link stages. The option names are case-sensitive: --I_opts, --L_opts and --R_opts use capital letters in the documented spelling.
3. Compile a minimal libpng program
Create a temporary source file in a scratch directory. The program only includes the installed header and prints the library version compiled into that header:
$ scratch=$(mktemp -d)
$ trap 'rm -rf "$scratch"' EXIT
$ cat > "$scratch/png-version.c" <<'EOF'
#include <stdio.h>
#include <png.h>
int main(void)
{
puts(PNG_LIBPNG_VER_STRING);
return 0;
}
EOF
$ cc $(libpng16-config --cflags) "$scratch/png-version.c" \
-o "$scratch/png-version" $(libpng16-config --libs)
$ "$scratch/png-version"
1.6.43
The command substitutions insert the helper's output into the compile command. This is appropriate for output made by the trusted local helper. Do not use the same pattern with arbitrary text obtained from a download, issue tracker or user input. In a larger build, let the build system store these values and quote source paths normally.
Checkpoint: a zero exit status and the expected version prove that the header was found, the linker found libpng16, and the executable started. The temporary directory is removed when the shell exits. There is no system-wide change to undo.
4. Keep static linking separate
Pass --static before the output option whose result you want to change. On this installation it changes library output to include libpng's additional static dependencies:
$ libpng16-config --static --libs
-lpng16 -lm -lz -lm
$ libpng16-config --static --ldflags
-lpng16 -lm -lz -lm
The manual describes --static as revising subsequent outputs. It does not mean that every output changes: this machine's --static --cflags remains -I/usr/include/libpng16. Put the option before --libs or --ldflags, and do not assume that static linking is automatically preferable. It can require static archives that are not installed and can produce a binary with different update and licensing responsibilities.
For a static attempt, keep the output in the scratch directory and inspect the compiler's status:
$ cc $(libpng16-config --cflags) "$scratch/png-version.c" \
-o "$scratch/png-version-static" $(libpng16-config --static --libs)
$ printf 'compiler status: %s\n' "$?"
compiler status: 0
If this fails on another machine, read the missing archive named by the linker and install the matching development package through the normal package-management process. Do not switch to sudo merely because a library lookup failed.
5. Handle the Debian and Ubuntu libdir trap
The manual lists --libdir, but this Debian and Ubuntu helper deliberately disables it:
$ libpng16-config --libdir
libpng16-config: --libdir option is disabled in Debian/Ubuntu
$ printf 'status: %s\n' "$?"
status: 1
Do not treat that message as a reason to invent -L flags. The normal --libs output is sufficient for the installed linker configuration. If a project requires an explicit library directory, inspect that project's build logic and the compiler search path before making a system-wide change. No root access is required to run this query.
6. Diagnose the common failures
An empty result from --ccopts, --cppflags, --L_opts or --R_opts can be correct. Empty output is not a missing newline or a command failure here; the helper still returns success. Check the status immediately if a script depends on an option:
if ! cflags=$(libpng16-config --cflags); then
printf '%s\n' 'libpng16-config could not provide compiler flags' >&2
exit 1
fi
printf 'using: %s\n' "$cflags"
If the command is not found, confirm that libpng-dev is installed and use your distribution's package manager to restore it. If compilation reports that png.h is missing, compare the compiler command with libpng16-config --cflags and check that the substitution was not omitted. If linking reports an unresolved libpng symbol, check that $(libpng16-config --libs) appears after the source or object files; many Unix linkers process libraries from left to right.
Do not copy a successful command from one architecture or package release without checking its helper output. The installed command is the source of truth for this host, and the alias may resolve to a different ABI on another system.
Done means
libpng16-config --versionand the package version were checked.--cflagsand--libssupplied the compile and link settings.- A minimal program compiled, linked and ran with the reported libpng version.
--staticwas used only when static dependencies were actually wanted.- The Debian or Ubuntu
--libdirfailure was understood rather than bypassed with guessed flags. - All files were created in a temporary directory, which the shell removes on exit.