Search topics...
Build SystemsPipeline & Compilationfoundational

Walk me through what happens when you press "Build" on a typical embedded C project.

0 upvotes
Practice with AISoon
Study the fundamentals first — Build Systems topic page

Four programs run in sequence per source file. First the preprocessor expands #include directives and #define macros, producing a single .i text file with everything substituted. Then the compiler translates that to target assembly — this is where optimization flags like -Os do their work, producing a .s file. The assembler turns assembly into a relocatable object file (.o) with sections, a symbol table, and relocation entries — but no final addresses yet.

After all source files have been compiled, the linker does three things: resolves symbols across all .o files and libraries (every "undefined" symbol must match a "defined" symbol somewhere), applies relocations with the chosen final addresses, and places sections per the linker script. The output is the ELF binary.

For embedded targets, objcopy then converts ELF to a flat binary or Intel HEX file for flashing. The whole chain — preprocess, compile, assemble, link — is what gcc invokes when you give it .c files and an -o output.

The interview-relevant lesson: compilation is per-translation-unit (one .c at a time, in isolation), but linking is whole-program. Most "weird build errors" are at the linker step because that's where cross-file consistency is checked.

Source: Build Systems Q&A