Basic decoder library for PNG images, tested with http://www.schaik.com/pngsuite/
Built in Alpine Linux using:
- GCC 12.2.1 / Mingw GCC 12.2.0
- GNU Make 4.4.1
- CMake 3.26.5
The following are summary notes on how to build the project using different build tools. All commands are run from the project root folder.
To build a static binary using the GCC compiler:
cc -c src/logger.o -iquoteinclude -o build/obj/logger.o
cc -c src/filter.c -iquoteinclude -o build/obj/filter.o
cc -c src/png.c-iquoteinclude -o build/obj/png.o
cc -c src/zlib.c-iquoteinclude -o build/obj/zlib.o
ar -rcs build/lib/libpng.a build/obj/logger.o build/obj/filter.o build/obj/png.o build/obj/zlib.o
cc -c src/main.c -iquoteinclude -o build/obj/main.o
cc build/obj/main.o -static -Lbuild/lib -lpng -o build/bin/png_static
Symbols in an object file can be listed using the nm command:
nm build/obj/png.o
To build a shared library and linked binary using the GCC compiler:
cc -fPIC -c src/logger.c -iquoteinclude -o build/obj/logger.s.o
cc -fPIC -c src/filter.c -iquoteinclude -o build/obj/filter.s.o
cc -fPIC -c src/png.c -iquoteinclude -o build/obj/png.s.o
cc -fPIC -c src/zlib.c -iquoteinclude -o build/obj/zlib.s.o
cc -shared build/obj/png.s.o build/obj/logger.s.o build/obj/filter.s.o build/obj/zlib.s.o -o build/lib/libpng.so
cc -c src/main.c -iquoteinclude -o build/obj/main.o
cc build/obj/main.o -Lbuild/lib -lpng -Wl,--enable-new-dtags,-rpath,build/lib -o build/bin/png_dynamic
See https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html.
If the shared library has not been installed as part of the filesystem, the linked executable will not be able to find it. In this case the location of the shared library location can be specified either with the LD_LIBRARY_PATH
environment variable or by hardcoding the path into the executable using RPATH
or RUNPATH
.
Shared library paths are searched in the following order:
RPATH
(deprecated)LD_LIBRARY_PATH
RUNPATH
- Standard directories
To check the shared library dependencies for an executable, use ldd:
ldd png2ppm
Build using RPATH:
cc build/obj/main.o -Lbuild/lib -lpng -Wl,-rpath,build/lib -o build/bin/png_dynamic
Build using RUNPATH:
cc build/obj/main.o -Lbuild/lib -lpng -Wl,--enable-new-dtags,-rpath,build/lib -o build/bin/png_dynamic
To check the executable header and inspect RPATH
:
readelf -d build/bin/png_dynamic | grep PATH
The path to the shared library may also be loaded dynamically at runtime by the executable.
cc main.c -o build/bin/png_runtime
In the example provided the path is hardcoded as a relative path to the runtime folder; i.e. the binary must be run from the same folder as the shared library.
To cross compile for Windows using Mingw64, replace the c compiler and archiver with the equivalent tools:
CC=x86_64-w64-mingw32-cc
AR=x86_64-w64-mingw32-ar
A Makefile is included with build options for static, shared and runtime loaded libary builds. The build instructions are as follows:
make static
Outputs to build/bin.
make dynamic
Outputs to build/bin and build/lib.
make runtime
Outputs to build/bin and build/lib.
make test
Builds the static target as well as unit tests. Outputs unit test executable to build/test.
make clean
Deletes build folder.
By default the required test images are copied to build/bin/test_images. The default image path assumes unit tests are running from within the build/bin directory. To change this, use the munit --param option to change the path stored in the "images" parameter. e.g.
./test --param images /home/user/Pictures/PNG-test-images
To cross-compile for Windows include the CC and AR variables when running make:
make CC=x86_64-w64-mingw32-cc AR=x86_64-w64-mingw32-ar static
The following CMake presets are available:
- windows_static
- windows_shared
- windows_runtime
- linux_static
- linux_shared
- linux_runtime
These handle the output paths and configuration for Linux/Windows builds, assuming the appropriate GCC/Mingw tools are installed.
To build with CMake:
cmake --preset linux_static
cmake --build --preset linux_static