GCC command-line cheatsheet from first compilation to debugging, linking, optimization, and production builds.
GCC Cheatsheet
Section titled “GCC Cheatsheet”GCC is the GNU Compiler Collection. For ordinary projects:
| Command | Use It For |
|---|---|
gcc | Compile and link C programs |
g++ | Compile and link C++ programs; automatically links the C++ standard library |
cpp | Run only the C/C++ preprocessor |
gcov | Read coverage data generated by GCC |
The basic pattern is:
gcc [options] input.c -o outputg++ [options] input.cpp -o outputExamples on this page use Unix-style executable names (./app). On Windows with MinGW, run the output as app.exe.
1. Beginner: Compile and Run
Section titled “1. Beginner: Compile and Run”First C Program
Section titled “First C Program”#include <stdio.h>
int main(void) { puts("Hello, GCC!"); return 0;}gcc hello.c -o hello # Compile and link./hello # Run on Linux/macOSFirst C++ Program
Section titled “First C++ Program”#include <iostream>
int main() { std::cout << "Hello, GCC!\n";}g++ hello.cpp -o hello # Use g++ for C++ linking./helloEssential Commands
Section titled “Essential Commands”| Command | Meaning |
|---|---|
gcc main.c | Build C program as a.out (a.exe on some Windows setups) |
gcc main.c -o app | Name the output executable app |
gcc -std=c17 main.c -o app | Compile using the C17 language standard |
g++ -std=c++20 main.cpp -o app | Compile C++20 source |
gcc --version | Print GCC version |
gcc -v main.c -o app | Show commands and paths used while building |
Recommended Learning Build
Section titled “Recommended Learning Build”gcc -std=c17 -Wall -Wextra -Wpedantic -g main.c -o app| Flag | Purpose |
|---|---|
-std=c17 | Select a defined C standard |
-Wall | Enable many common warnings |
-Wextra | Enable additional useful warnings |
-Wpedantic | Warn about non-standard language extensions |
-g | Include debug information for a debugger |
Warnings are not failures by default. Fix warnings instead of ignoring them.
2. How Compilation Works
Section titled “2. How Compilation Works”GCC usually performs four stages:
source.c -> preprocessed source -> assembly -> object file -> executable preprocessing compile assemble link| Stage | GCC Option | Typical Output | What Happens |
|---|---|---|---|
| Preprocess | -E | .i | Expands #include, #define, and conditional compilation |
| Compile | -S | .s | Translates C/C++ into assembly |
| Assemble | -c | .o | Produces machine-code object file without linking |
| Link | default final step | executable/library | Resolves functions and combines object files/libraries |
gcc -E hello.c -o hello.i # Stop after preprocessinggcc -S hello.c -o hello.s # Stop after generating assemblygcc -c hello.c -o hello.o # Stop after object filegcc hello.o -o hello # Link object into executableKeep Intermediate Files
Section titled “Keep Intermediate Files”gcc -save-temps hello.c -o helloThis is useful when learning, investigating macros, or inspecting generated assembly.
3. Common Option Reference
Section titled “3. Common Option Reference”Input and Output
Section titled “Input and Output”| Option | Example | Purpose |
|---|---|---|
-o file | -o calculator | Set output filename |
-c | gcc -c util.c | Compile only; do not link |
-E | gcc -E config.c | Preprocess only |
-S | gcc -S math.c | Generate assembly |
-x language | gcc -x c input.txt | Treat input as a particular language |
-pipe | gcc -pipe main.c | Use pipes between compilation stages where supported |
Standards
Section titled “Standards”| Language | Common Selection |
|---|---|
| C90 | -std=c90 |
| C11 | -std=c11 |
| C17 | -std=c17 |
| GNU C17 extensions | -std=gnu17 |
| C++17 | -std=c++17 |
| C++20 | -std=c++20 |
| GNU C++20 extensions | -std=gnu++20 |
-std=c17 is stricter and more portable; -std=gnu17 also allows GNU extensions commonly used on Linux.
Macros and Include Paths
Section titled “Macros and Include Paths”| Option | Example | Purpose |
|---|---|---|
-DNAME | -DDEBUG | Define macro with value 1 |
-DNAME=value | -DPORT=8080 | Define macro with a value |
-UNAME | -UDEBUG | Undefine a macro |
-I dir | -Iinclude | Add header search directory |
-iquote dir | -iquote src/include | Search directory for quoted includes only |
-isystem dir | -isystem vendor/include | Add system header directory with reduced warning noise |
#ifdef DEBUGfprintf(stderr, "x = %d\n", x);#endifgcc -DDEBUG -Iinclude src/main.c -o app4. Warnings and Diagnostics
Section titled “4. Warnings and Diagnostics”Sensible Warning Sets
Section titled “Sensible Warning Sets”# Everyday C developmentgcc -std=c17 -Wall -Wextra -Wpedantic -Wconversion -Wshadow main.c -o app
# Everyday C++ developmentg++ -std=c++20 -Wall -Wextra -Wpedantic -Wconversion -Wshadow main.cpp -o app
# Continuous integration: reject newly introduced warningsgcc -std=c17 -Wall -Wextra -Wpedantic -Werror main.c -o app| Option | Catches or Controls |
|---|---|
-Wall | Frequently useful warnings such as unused values and suspicious constructs |
-Wextra | Additional parameter, comparison, and initializer warnings |
-Wpedantic | Extensions beyond the selected standard |
-Wconversion | Implicit conversions that may alter a value |
-Wsign-conversion | Signed/unsigned conversions |
-Wshadow | Declarations hiding earlier names |
-Wformat=2 | Stricter printf/scanf format checking |
-Wundef | Unknown identifiers used in preprocessor #if expressions |
-Werror | Treat warnings as errors |
-Wno-error=name | Keep one warning non-fatal under -Werror |
-Wall does not mean every possible warning. Strong warning flags can be noisy on legacy or third-party code, so introduce them deliberately.
More Readable Errors
Section titled “More Readable Errors”gcc -fdiagnostics-color=always -fdiagnostics-show-option main.c -o appgcc -fmax-errors=5 main.c -o app| Option | Purpose |
|---|---|
-fdiagnostics-color=always | Colorize compiler output when the terminal supports it |
-fdiagnostics-show-option | Show the warning flag associated with a message |
-fmax-errors=n | Stop after n errors |
5. Debug Builds
Section titled “5. Debug Builds”Debug Build Recipe
Section titled “Debug Build Recipe”gcc -std=c17 -Wall -Wextra -Wpedantic -g -O0 main.c -o appgdb ./app| Option | Purpose |
|---|---|
-g | Generate debugger information |
-ggdb | Generate debugging information tailored for GDB |
-O0 | Turn off most optimization for straightforward stepping |
-Og | Optimize while preserving a useful debugging experience |
-fno-omit-frame-pointer | Make stack traces/profiling easier on many targets |
For most active debugging, this is a useful balance:
gcc -std=c17 -Wall -Wextra -g3 -Og -fno-omit-frame-pointer main.c -o appUseful Debug Tools
Section titled “Useful Debug Tools”gdb ./app # Interactive debuggergcc -E main.c | less # Inspect expanded macros/includesgcc -S -fverbose-asm main.c # Assembly with compiler commentsgcc -H -c main.c # Print included header hierarchy6. Finding Memory and Undefined-Behavior Bugs
Section titled “6. Finding Memory and Undefined-Behavior Bugs”Sanitizers add runtime checks. Use them in testing and debugging builds, not as your usual optimized production binary.
Address and Undefined Behavior Sanitizers
Section titled “Address and Undefined Behavior Sanitizers”gcc -std=c17 -Wall -Wextra -g -Og \ -fsanitize=address,undefined -fno-omit-frame-pointer \ main.c -o app
./app| Sanitizer | Option | Detects Examples |
|---|---|---|
| AddressSanitizer | -fsanitize=address | Out-of-bounds access, use-after-free, some leaks |
| UndefinedBehaviorSanitizer | -fsanitize=undefined | Invalid shifts, signed overflow, misaligned access |
| LeakSanitizer | -fsanitize=leak | Heap allocations not released |
| ThreadSanitizer | -fsanitize=thread | Data races in multithreaded programs |
Do not combine -fsanitize=thread with -fsanitize=address in the same executable. Sanitizer availability and behavior depend on the target platform and GCC installation.
Static Analysis
Section titled “Static Analysis”gcc -std=c17 -Wall -Wextra -fanalyzer -c main.c-fanalyzer explores paths through code to report issues such as double-free, null dereference, and some resource leaks. It can be slower and may need judgment when reviewing results.
7. Multiple Source Files
Section titled “7. Multiple Source Files”Small Project Layout
Section titled “Small Project Layout”project/ include/math_utils.h src/main.c src/math_utils.c# One command: compile and link everythinggcc -std=c17 -Wall -Wextra -Iinclude \ src/main.c src/math_utils.c -o app
# Separate compilation: rebuild only changed filesgcc -std=c17 -Wall -Wextra -Iinclude -c src/main.c -o main.ogcc -std=c17 -Wall -Wextra -Iinclude -c src/math_utils.c -o math_utils.ogcc main.o math_utils.o -o appHeader Dependency Generation
Section titled “Header Dependency Generation”When a header changes, its dependent source files must be rebuilt. GCC can generate dependency rules for make:
gcc -std=c17 -Wall -Wextra -MMD -MP -Iinclude -c src/main.c -o main.o| Option | Purpose |
|---|---|
-MMD | Write a .d dependency file for user headers |
-MP | Add dummy targets so removed headers do not break old dependency files |
-MF file | Choose dependency output file |
-MT target | Choose dependency rule target name |
8. Linking Libraries
Section titled “8. Linking Libraries”Link a System Library
Section titled “Link a System Library”gcc main.c -lm -o app # Link libm for functions such as sqrt() on Unix-like systemsgcc main.c -pthread -o app # Compile/link POSIX threads where supported| Option | Purpose |
|---|---|
-lNAME | Link a library named like libNAME.so or libNAME.a |
-Ldir | Add a library search directory |
-pthread | Enable and link thread support on compatible systems |
-Wl,option | Pass comma-separated option(s) to the linker |
For traditional linkers, put libraries after object files that need them:
gcc main.o geometry.o -Llib -lshape -lm -o appCreate a Static Library
Section titled “Create a Static Library”gcc -std=c17 -O2 -Iinclude -c src/math_utils.c -o math_utils.oar rcs libmathutils.a math_utils.ogcc main.o -L. -lmathutils -o appStatic libraries are copied into the final executable as required during linking.
Create a Shared Library on Linux
Section titled “Create a Shared Library on Linux”gcc -std=c17 -O2 -fPIC -Iinclude -c src/math_utils.c -o math_utils.ogcc -shared math_utils.o -o libmathutils.sogcc main.o -L. -lmathutils -Wl,-rpath,'$ORIGIN' -o app| Option | Purpose |
|---|---|
-fPIC | Generate position-independent code commonly required for shared libraries |
-shared | Produce a shared library rather than an executable |
-Wl,-rpath,... | Embed a runtime library search path; use with care when packaging |
Shared-library commands and filename conventions differ on Windows and macOS.
9. Optimization and Release Builds
Section titled “9. Optimization and Release Builds”Optimization Levels
Section titled “Optimization Levels”| Option | Typical Use | Notes |
|---|---|---|
-O0 | Initial debugging | Fast compile; easiest source-level stepping |
-Og | Debugging with reasonable performance | Keeps many debugging expectations intact |
-O1 | Light optimization | Smaller optimization cost |
-O2 | General release build | Strong default for many applications |
-O3 | Benchmark-driven performance work | Can increase size; measure results |
-Os | Optimize for size | Useful for constrained binaries |
-Ofast | Aggressive performance | May relax language/IEEE math guarantees |
Release Build Recipe
Section titled “Release Build Recipe”gcc -std=c17 -O2 -DNDEBUG -Wall -Wextra main.c -o app-DNDEBUG disables the standard assert() macro. Use it only when removing runtime assertions is appropriate for the release.
Link-Time Optimization (LTO)
Section titled “Link-Time Optimization (LTO)”gcc -std=c17 -O2 -flto -c main.c -o main.ogcc -std=c17 -O2 -flto -c util.c -o util.ogcc -O2 -flto main.o util.o -o app-flto allows optimization across translation units. Use it consistently for compile and link steps, then measure compile time, binary size, and performance.
Target-Specific Code Generation
Section titled “Target-Specific Code Generation”gcc -O2 -march=native main.c -o app-march=native may use instructions available only on the build machine. It is useful for local performance tests, but usually wrong for binaries distributed to different computers.
10. Coverage and Profiling
Section titled “10. Coverage and Profiling”Code Coverage with gcov
Section titled “Code Coverage with gcov”gcc -std=c17 -O0 -g --coverage main.c -o app./appgcov main.c--coverage instruments the program and produces files that gcov uses to show which source lines executed. Run representative tests before reading coverage.
Profile-Guided Optimization (PGO)
Section titled “Profile-Guided Optimization (PGO)”# 1. Build an instrumented programgcc -O2 -fprofile-generate main.c -o app
# 2. Run realistic workloads./app input.txt
# 3. Rebuild using measured behaviorgcc -O2 -fprofile-use main.c -o appPGO is useful only when the training runs resemble real use. Keep profile data aligned with the same source and build configuration.
11. Preprocessor Workflows
Section titled “11. Preprocessor Workflows”Define Build Configurations
Section titled “Define Build Configurations”gcc -DDEBUG -DLOG_LEVEL=2 main.c -o debug_appgcc -DNDEBUG -DAPP_VERSION='"1.2.0"' main.c -o release_app#if defined(DEBUG) #define LOG(message) fprintf(stderr, "%s\n", message)#else #define LOG(message) ((void)0)#endifInspect Predefined Macros
Section titled “Inspect Predefined Macros”gcc -dM -E - < /dev/null # Unix shell: built-in C macrosgcc -std=c17 -dM -E - < /dev/null # Include selected standard modeOn PowerShell, a comparable empty input pipeline is:
'' | gcc -std=c17 -dM -E -Include Search and Macro Investigation
Section titled “Include Search and Macro Investigation”gcc -E -Iinclude src/main.c -o main.igcc -v -E -x c /dev/null # Print configured include search paths on Unixgcc -H -Iinclude -c src/main.c # Trace headers being included12. C Versus C++ with GCC
Section titled “12. C Versus C++ with GCC”| Task | C | C++ |
|---|---|---|
| Compile and link | gcc main.c -o app | g++ main.cpp -o app |
| Standard | -std=c17 | -std=c++20 |
| Object compile | gcc -c file.c | g++ -c file.cpp |
| Link object files containing C++ | Prefer g++ | g++ *.o -o app |
GCC can compile a .cpp file when invoked as gcc, but the final link step does not automatically add the C++ standard library. Use g++ for C++ executables:
g++ -std=c++20 main.cpp widget.cpp -o appLink C Code into C++
Section titled “Link C Code into C++”#ifdef __cplusplusextern "C" {#endif
int add(int a, int b);
#ifdef __cplusplus}#endifextern "C" prevents C++ name mangling for APIs implemented in C.
13. Hardening and Production Checks
Section titled “13. Hardening and Production Checks”For applications that accept untrusted input, compiler flags can add defense in depth. The suitable combination depends on target operating system, libc, deployment requirements, and performance budget.
gcc -std=c17 -O2 -Wall -Wextra \ -fstack-protector-strong -D_FORTIFY_SOURCE=2 \ -fPIE -pie main.c -o app| Option | Purpose |
|---|---|
-fstack-protector-strong | Add stack corruption checks to more vulnerable functions |
-D_FORTIFY_SOURCE=2 | Add some checked libc operations when optimization and libc support are available |
-fPIE -pie | Build a position-independent executable for address randomization support |
-Wl,-z,relro,-z,now | Request additional ELF/Linux linker hardening |
Sanitizers help find bugs during testing; hardening options help make some bugs harder to exploit in deployed builds. Neither replaces input validation, correct ownership, or testing.
14. Advanced Compiler Inspection
Section titled “14. Advanced Compiler Inspection”Ask GCC About Available Options
Section titled “Ask GCC About Available Options”gcc --help=warningsgcc --help=optimizersgcc --help=targetgcc -Q -O2 --help=optimizers-Q -O2 --help=optimizers is useful for inspecting which optimization switches GCC enables for the selected compiler and target.
Inspect Assembly Output
Section titled “Inspect Assembly Output”gcc -std=c17 -O2 -S main.c -o main.sgcc -std=c17 -O2 -S -masm=intel main.c -o main.s # Supported on x86 targetsgcc -std=c17 -O2 -fverbose-asm -S main.c -o main.sSymbols and Binary Information on Unix-like Systems
Section titled “Symbols and Binary Information on Unix-like Systems”nm app # List symbolsobjdump -d app # Disassemblereadelf -h app # ELF header informationldd app # Shared library dependencies on LinuxThese commands are provided by binutils or the operating system rather than by GCC itself.
15. A Practical Makefile with GCC
Section titled “15. A Practical Makefile with GCC”CC := gccCPPFLAGS := -IincludeCFLAGS := -std=c17 -Wall -Wextra -Wpedantic -MMD -MPLDLIBS :=
TARGET := appSOURCES := src/main.c src/math_utils.cOBJECTS := $(SOURCES:.c=.o)DEPENDS := $(OBJECTS:.o=.d)
.PHONY: all debug release clean
all: debug
debug: CFLAGS += -g -Og -fsanitize=address,undefined -fno-omit-frame-pointerdebug: LDFLAGS += -fsanitize=address,undefineddebug: $(TARGET)
release: CFLAGS += -O2 -DNDEBUGrelease: $(TARGET)
$(TARGET): $(OBJECTS) $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
src/%.o: src/%.c $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
clean: rm -f $(TARGET) $(OBJECTS) $(DEPENDS)
-include $(DEPENDS)Run:
make debugmake cleanmake releaseFor larger projects, build into a separate directory so debug and release object files cannot be accidentally mixed.
16. Common Errors and Fixes
Section titled “16. Common Errors and Fixes”| Message or Symptom | Likely Cause | Typical Fix |
|---|---|---|
fatal error: foo.h: No such file or directory | Header search path missing | Add -Ipath/to/headers or fix include |
undefined reference to 'foo' | Declaration found, implementation not linked | Add its .o file or -l library |
undefined reference to 'sqrt' | Math library not linked on Unix-like system | Put -lm after object/source files |
multiple definition of 'x' | Global definition placed in multiple files/headers | Put extern declaration in header and one definition in a .c file |
C++ undefined reference to std::... | Linked C++ program using gcc | Link with g++ |
| Program crashes only at runtime | Memory bug or undefined behavior | Rebuild with -g -fsanitize=address,undefined |
| Debugger skips lines or variables vanish | Optimization changes program layout | Use -Og or -O0 for debugging |
| Works locally, fails on another CPU | Built with host-specific instructions | Avoid -march=native for distributed binaries |
Link Command Ordering
Section titled “Link Command Ordering”# Good: objects first, dependent libraries latergcc main.o -L. -lutils -lm -o app
# Can fail with traditional static linking ordergcc -lutils -lm main.o -o app17. Copy-Paste Build Recipes
Section titled “17. Copy-Paste Build Recipes”C Development
Section titled “C Development”gcc -std=c17 -Wall -Wextra -Wpedantic -Wconversion -g -Og main.c -o appC Debugging with Sanitizers
Section titled “C Debugging with Sanitizers”gcc -std=c17 -Wall -Wextra -g -Og \ -fsanitize=address,undefined -fno-omit-frame-pointer \ main.c -o appC Release
Section titled “C Release”gcc -std=c17 -Wall -Wextra -O2 -DNDEBUG main.c -o appC++ Development
Section titled “C++ Development”g++ -std=c++20 -Wall -Wextra -Wpedantic -g -Og main.cpp -o appBuild with Headers and Multiple Files
Section titled “Build with Headers and Multiple Files”gcc -std=c17 -Wall -Wextra -Iinclude \ src/main.c src/io.c src/math_utils.c -o appCompile Objects and Link Separately
Section titled “Compile Objects and Link Separately”gcc -std=c17 -Wall -Wextra -Iinclude -c src/io.c -o io.ogcc -std=c17 -Wall -Wextra -Iinclude -c src/main.c -o main.ogcc main.o io.o -o app18. Learning Path and Quick Recall
Section titled “18. Learning Path and Quick Recall”Beginner
Section titled “Beginner”- Compile one
.cfile withgcc file.c -o app. - Always enable
-Wall -Wextraand select a standard such as-std=c17. - Learn what preprocessing, compilation, assembly, and linking do.
- Use
-g -Ogand a debugger instead of adding endless print statements.
Intermediate
Section titled “Intermediate”- Split a program into headers and source files, compiling with
-c. - Link libraries with
-Land-l, and understand link ordering. - Add dependency generation using
-MMD -MPin a Makefile. - Run sanitizer builds regularly and fix every real diagnostic.
Advanced
Section titled “Advanced”- Inspect generated assembly and optimization choices.
- Measure
-O2,-O3, LTO, and PGO rather than assuming they are faster. - Build shared/static libraries and control their public API.
- Add platform-appropriate hardening and automated warning/sanitizer builds.
Recall Card
Section titled “Recall Card”Build C: gcc -std=c17 -Wall -Wextra file.c -o appBuild C++: g++ -std=c++20 -Wall -Wextra file.cpp -o appCompile only: gcc -c file.c -o file.oLink: gcc main.o util.o -lm -o appDebug: gcc -g -Og file.c -o appSanitize: gcc -g -Og -fsanitize=address,undefined file.c -o appRelease: gcc -O2 -DNDEBUG file.c -o appPreprocess: gcc -E file.c -o file.iAssembly: gcc -O2 -S file.c -o file.sCoverage: gcc --coverage file.c -o app && ./app && gcov file.c