Building the Projects
Both homework assignments use GNU Make as the build system. This guide covers all the make targets and compilation options available.Quick Reference
Understanding the Build System
Directory Structure
The Makefile creates and uses these directories:The
build/ and bin/ directories are created automatically by make and are excluded from git via .gitignore. Never commit compiled files to your repository.What Gets Compiled
Eachmake command builds two executables:
Main Program
PNG Homework:
ZLIB Homework:
bin/pngZLIB Homework:
bin/zlibThe main program executable that implements the command-line interface described in the assignment.Test Suite
PNG Homework:
ZLIB Homework:
bin/png_testsZLIB Homework:
bin/zlib_testsThe Criterion test suite that runs unit tests on your functions.Make Targets Explained
make or make all
The default target that compiles everything:
- Creates
build/andbin/directories if they don’t exist - Compiles all
.cfiles insrc/to.oobject files inbuild/ - Links object files to create
bin/pngexecutable - Compiles test files and links them with your code to create
bin/png_tests
-std=gnu11- Use GNU C11 standard-Wall- Enable all common warnings-Werror- Treat warnings as errors-Wno-unused-function- Allow unused static functions-MMD- Generate dependency files for automatic recompilation-fcommon- Allow multiple definitions of globals (compatibility)
- PNG homework:
-lz(zlib compression library) - ZLIB homework: No external libraries (you implement compression yourself!)
- Both:
-lcriterion(for test suite only)
make debug
Compiles with debugging support and verbose output:
-g- Include debugging symbols for GDB-DDEBUG- Enable DEBUG macro (activates debug output)-DCOLOR- Enable colored output-DERROR -DSUCCESS -DWARN -DINFO- Enable message macros
- When you need to use GDB to step through your code
- When you want to see debug messages from the
debug()macro - During active development to see what your code is doing
make clean
Removes all compiled files:
- Entire
build/directory (all.oand.dfiles) - Entire
bin/directory (all executables)
- Before doing a fresh build to ensure everything recompiles
- When switching between debug and non-debug builds
- When you’ve modified header files and want to ensure all dependencies rebuild
- Before submitting to ensure your code compiles from scratch
Common Build Workflows
Regular Development
Incremental Compilation
After modifying source files, just run make again. It only recompiles changed files:
Testing Specific Functionality
Before Submitting to CodeGrade
Clean Build
Ensure everything compiles from scratch in non-debug mode:This simulates what CodeGrade will do.
Understanding Compilation Output
Successful Build
Compilation Errors
src/png_reader.c:45:12- File, line number, columnerror:- This is a compilation error (not just a warning)implicit declaration- Function used without being declared- Fix: Add
#include "util.h"or declare the function
Warning Messages
Makefile Structure (For Reference)
Here’s what the Makefile does:Automatic Dependency Tracking
The Makefile uses-MMD to generate .d dependency files:
.d files track which header files each .c file includes. If you modify a header file, make automatically recompiles all source files that depend on it.
Example: If you modify include/png_chunks.h, make will automatically recompile all .c files that #include "png_chunks.h".
Troubleshooting Build Issues
”No such file or directory” - Missing Include
“Undefined reference” - Linking Error
.c file.
”Multiple definition” - Duplicate Symbols
.c files.
Fix: Use extern in header, define once in a .c file.
Build Hangs or Is Very Slow
Next Steps
Run Tests
Learn how to run Criterion tests on your compiled code
Debug Your Code
Use GDB and other tools to find and fix bugs