Conduite de Projet Cours 4 The C build process

Similar documents
Compiler Theory. (GCC the GNU Compiler Collection) Sandro Spina 2009

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

Basic C Programming. Bin Li Assistant Professor Dept. of Electrical, Computer and Biomedical Engineering University of Rhode Island

Topic 6: A Quick Intro To C

2 Compiling a C program

Have examined process Creating program Have developed program Written in C Source code

Topic 6: A Quick Intro To C. Reading. "goto Considered Harmful" History

Agenda. CS 61C: Great Ideas in Computer Architecture. Lecture 2: Numbers & C Language 8/29/17. Recap: Binary Number Conversion

CS 61C: Great Ideas in Computer Architecture. Lecture 2: Numbers & C Language. Krste Asanović & Randy Katz

C: Program Structure. Department of Computer Science College of Engineering Boise State University. September 11, /13


Language Translation. Compilation vs. interpretation. Compilation diagram. Step 1: compile. Step 2: run. compiler. Compiled program. program.

Slide Set 5. for ENCM 339 Fall Steve Norman, PhD, PEng. Electrical & Computer Engineering Schulich School of Engineering University of Calgary

C Compilation Model. Comp-206 : Introduction to Software Systems Lecture 9. Alexandre Denault Computer Science McGill University Fall 2006

Intermediate Programming, Spring 2017*

Motivation was to facilitate development of systems software, especially OS development.

Motivation was to facilitate development of systems software, especially OS development.

CSci 4061 Introduction to Operating Systems. Programs in C/Unix

fpp: Fortran preprocessor March 9, 2009

Formal Methods for C

Reliable C++ development - session 1: From C to C++ (and some C++ features)

Control flow and string example. C and C++ Functions. Function type-system nasties. 2. Functions Preprocessor. Alastair R. Beresford.

CS2141 Software Development using C/C++ Compiling a C++ Program

Lectures 5-6: Introduction to C

Outline. Compiling process Linking libraries Common compiling op2ons Automa2ng the process

Computer Components. Software{ User Programs. Operating System. Hardware

#include <stdio.h> int main() { printf ("hello class\n"); return 0; }

Chapter IV Introduction to C for Java programmers

Lectures 5-6: Introduction to C

COSC 2P91. Introduction Part Deux. Week 1b. Brock University. Brock University (Week 1b) Introduction Part Deux 1 / 14

Follow us on Twitter for important news and Compiling Programs

CMPSC 311- Introduction to Systems Programming Module: Build Processing

PRINCIPLES OF OPERATING SYSTEMS

Compilers and interpreters

GNU make... Martin Ohlerich, Parallel Programming of High Performance Systems

CS 220: Introduction to Parallel Computing. Beginning C. Lecture 2

C introduction: part 1

OBJECT ORIENTED PROGRAMMING USING C++

C and C++ 2. Functions Preprocessor. Alan Mycroft

CS Basics 15) Compiling a C prog.

9/5/17. The Design and Implementation of Programming Languages. Compilation. Interpretation. Compilation vs. Interpretation. Hybrid Implementation

SISTEMI EMBEDDED. The C Pre-processor Fixed-size integer types Bit Manipulation. Federico Baronti Last version:

Errors During Compilation and Execution Background Information

1 You seek performance 3

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

EL2310 Scientific Programming

Berner Fachhochschule Haute cole spcialise bernoise Berne University of Applied Sciences 2

Page 1. Agenda. Programming Languages. C Compilation Process

Programming Fundamentals (CS 302 ) Dr. Ihsan Ullah. Lecturer Department of Computer Science & IT University of Balochistan

CS 110 Computer Architecture. Lecture 2: Introduction to C, Part I. Instructor: Sören Schwertfeger.

C Preprocessor. Prabhat Kumar Padhy

CSCI 171 Chapter Outlines

COMP322 - Introduction to C++ Lecture 02 - Basics of C++

SISTEMI EMBEDDED. The C Pre-processor Fixed-size integer types Bit Manipulation. Federico Baronti Last version:

CMPSC 311- Introduction to Systems Programming Module: Build Processing

Running a C program Compilation Python and C Variables and types Data and addresses Functions Performance. John Edgar 2

Compiler, Assembler, and Linker

Intermediate Programming, Spring 2017*

Executables and Linking. CS449 Spring 2016

Laboratory 2: Programming Basics and Variables. Lecture notes: 1. A quick review of hello_comment.c 2. Some useful information

Practical C Issues:! Preprocessor Directives, Multi-file Development, Makefiles. CS449 Fall 2017

CSE 333 Midterm Exam 5/9/14 Sample Solution

CSCI-243 Exam 2 Review February 22, 2015 Presented by the RIT Computer Science Community

Executables and Linking. CS449 Fall 2017

SISTEMI EMBEDDED. The C Pre-processor Fixed-size integer types Bit Manipulation. Federico Baronti Last version:

Come and join us at WebLyceum

Chapter 11 Introduction to Programming in C

An Ungentle Introduction to C

C Programming Review CSC 4320/6320

cmps104a 2002q4 Assignment 2 Lexical Analyzer page 1

M2 Instruction Set Architecture

PROGRAMMAZIONE I A.A. 2017/2018

Object-Oriented Programming

Oregon State University School of Electrical Engineering and Computer Science. CS 261 Recitation 2. Spring 2016

How Compiling and Compilers Work

6.096 Introduction to C++ January (IAP) 2009

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

Advanced Programming & C++ Language

Chapter 11 Introduction to Programming in C

EL2310 Scientific Programming

CS 61C: Great Ideas in Computer Architecture Lecture 2: Introduction to C, Part I

introduction week 1 Ritsumeikan University College of Information Science and Engineering Ian Piumarta 1 / 20 imperative programming about the course

Kurt Schmidt. October 30, 2018

Programs. Function main. C Refresher. CSCI 4061 Introduction to Operating Systems

Lecture 2: C Programming Basic

What is a compiler? Xiaokang Qiu Purdue University. August 21, 2017 ECE 573

6.s096. Introduction to C and C++

COSC350 System Software

Draft. Chapter 1 Program Structure. 1.1 Introduction. 1.2 The 0s and the 1s. 1.3 Bits and Bytes. 1.4 Representation of Numbers in Memory

Important From Last Time

Chapter 11 Introduction to Programming in C

Programmation Système Cours 4 IPC: FIFO

CS2900 Introductory Programming with Python and C++ Kevin Squire LtCol Joel Young Fall 2007

CS 110 Computer Architecture. Lecture 2: Introduction to C, Part I. Instructor: Sören Schwertfeger.

A brief introduction to C programming for Java programmers

Programming for Engineers C Preprocessor

INTERMEDIATE SOFTWARE DESIGN SPRING 2011 ACCESS SPECIFIER: SOURCE FILE


Variables Data types Variable I/O. C introduction. Variables. Variables 1 / 14

Chapter 11 Introduction to Programming in C

Transcription:

Conduite de Projet Cours 4 The C build process Stefano Zacchiroli zack@pps.univ-paris-diderot.fr Laboratoire IRIF, Université Paris Diderot 2016 2017 URL http://upsilon.cc/zack/teaching/1617/cproj/ Copyright 2012 2016 Stefano Zacchiroli License Creative Commons Attribution-ShareAlike 4.0 International License http://creativecommons.org/licenses/by-sa/4.0/deed.en_us Stefano Zacchiroli (Paris Diderot) Build 2016 2017 1 / 37

Outline 1 The build process 2 The C preprocessor 3 First steps with GCC Stefano Zacchiroli (Paris Diderot) Build 2016 2017 2 / 37

Outline 1 The build process 2 The C preprocessor 3 First steps with GCC Stefano Zacchiroli (Paris Diderot) Build 2016 2017 3 / 37

Compiler Definition (compiler) A compiler is a computer program that transforms source code (written in some source language) into another computer language called target language. usually, but not always, the source language is a programming language that humans (programmers) are able to understand e.g., C, Java, OCaml, Scala, Python, Ruby, F#, Matlab,... usually, but not always, the target language is object code that can be executed by a hardware platform e.g., x86-32, x86-64, ARM7, powerpc, etc. (native compilers) e.g., JVM bytecode, Python bytecode, etc. (bytecode compilers) Intuition A compiler is a translator from one language to another. Stefano Zacchiroli (Paris Diderot) Build 2016 2017 4 / 37

Interpreter (digression) Question What is an interpreter then? Stefano Zacchiroli (Paris Diderot) Build 2016 2017 5 / 37

Interpreter (digression) Question What is an interpreter then? An interpreter is an all-in-one computer program that compiles and execute source code on-the-fly. Pro/con: higher portability higher startup time source-code distribution Stefano Zacchiroli (Paris Diderot) Build 2016 2017 5 / 37

Compiler construction A compiler is not a magic object. It is a program like others: written in some programming language (the implementation language) by programmers, like you At least 3 languages are always involved in compiler construction: source, target, and implementation. How do we write a compiler without a compiler? This is the compiler bootstraping problem (see modules introduction à la compilation L3 and compilation avancée M2) luckily, we ve plenty of readily available compilers these days... Stefano Zacchiroli (Paris Diderot) Build 2016 2017 6 / 37

Essential anatomy of a compiler The architecture of a compiler consists of a few common macro-parts: 1 front end: check for program correctness wrt source language semantics and output an intermediate representation (IR) of the input program e.g., lexical checking, syntax checking, type checking, etc. 2 middle end: program optimization by rewriting the IR e.g., dead code removal, constant propagation, loop unrolling, etc. 3 back end: translate IR to the target language, doing further (platform-specific) optimization e.g., assembly language for the target platform Stefano Zacchiroli (Paris Diderot) Build 2016 2017 7 / 37

Before and after compilation In spite of being already complex enough, we often need two more steps to get from a source to a target program. Before compilation we might have to run the source program through a preprocessor that prepares the program for compilation e.g., the C preprocessor cpp takes care of all #directives e.g., the camlp4 preprocessor can perform arbitrary syntactic transformation on OCaml programs e.g., Lisp preprocessors, Domain Specific Languages (DSL), etc. After compilation we need to 1 combine several compiled objects (i.e., the result of compiling different source files) with the needed libraries into a single compiled program 2 assemble assembly language code to the actual sequence of bytes that the Operating system will be able to execute A linker (or link editor) is the program that takes care of these steps Stefano Zacchiroli (Paris Diderot) Build 2016 2017 8 / 37

The build process Putting it all together, the build process looks like this: general idea: each step embodies a translation from one language to another... but the number of phases varies; there might be more! e.g., DSL source code object code... Stefano Zacchiroli (Paris Diderot) Build 2016 2017 9 / 37

Terminology and slang compilation Strictly speaking, compilation is only the part of the build process in between preprocessing and linking, extremes excluded. However we (as in programmers ) often use the term compilation to refer to the build process as a whole, including preprocessing and linking. this slightly imprecise terminology is supported by the practice of using a single tool to drive the entire build process the tool is also usually distributed as part of compiler suites cc C compiler ocamlc OCaml compiler javac Java compiler scalac Scala compiler etc. Stefano Zacchiroli (Paris Diderot) Build 2016 2017 10 / 37

Build stages When do the various phases happen? usually, preprocessing and compilation happens together, on a file per file basis compilation and linking might happen together (in trivial projects) or be separate phases (in medium to complex projects) Stefano Zacchiroli (Paris Diderot) Build 2016 2017 11 / 37

Build dependencies preprocessing might act on several source files at a time e.g., inclusion of a header/interface file in an implementation file e.g., syntactic transformations implemented as compiled programs to compile source i we might need object j, with i j Those are just common examples of build dependencies. Stefano Zacchiroli (Paris Diderot) Build 2016 2017 12 / 37

Build dependencies (cont.) Typical effects of dependencies on the build process are: forcing a (partial) order on compilation steps e.g., the linking step must be performed after the compilation steps of all involved objects guiding the (re-)build process to (re-)build only what is needed after only some files get changed e.g., recompiling a C source file is needed only when either itself or its #include-s have been changed after the last compilation Stefano Zacchiroli (Paris Diderot) Build 2016 2017 12 / 37

The C build process We are going to focus on the build process for the C language. Its architecture maps 1-1 to the one we have presented. the C preprocessor (sometimes called cpp) transforms C programs with #directives to C programs where those directives have been executed (+ line no. annotations) the C linker is the ordinary system-level linker, usually provided by the operating system the C compiler (traditionally called cc) transforms C programs (w/o #directives) to object files supported by the system-level linker can also be used to drive the preprocessing and linking phase we can use the C compiler as driver of the whole C build process Stefano Zacchiroli (Paris Diderot) Build 2016 2017 13 / 37

Outline 1 The build process 2 The C preprocessor 3 First steps with GCC Stefano Zacchiroli (Paris Diderot) Build 2016 2017 14 / 37

The C preprocessor generalities The C language is defined by an international standard, whose most recent incarnation is ISO/IEC 9899:2011 (AKA C11 ) the standard supports a number of meta-language directives whose syntax is #directive the standard does not mandate the preprocessor be a separate program; it just defines the 4th phase of the C translation as macro expansion and directive handling many C compilers use a separate cpp program to implement that phase as the semantics of directives is language independent, that allows to use the C preprocessor in other contexts The main C language features implemented as directives are: 1 file inclusion #include 2 macros #define 3 conditional compilation #if, #ifdef, #ifndef,... Stefano Zacchiroli (Paris Diderot) Build 2016 2017 15 / 37

File inclusion File inclusion is a common feature of many text processing languages: an include directive references an external file by name the directive gets expanded to the content of the file as if it were included verbatim where the directive is located the main advantage of file inclusion is factorization: we can reuse the content of a file in different locations...... while we have to maintain only one copy of it Stefano Zacchiroli (Paris Diderot) Build 2016 2017 16 / 37

#include #include <stdio. h> int main ( void ) { p r i n t f ( " Hello, world! \n" ) ; } typedef unsigned char u_char ; typedef unsigned short int u_short ;... extern int p r i n t f ( const char * r e s t r i c t format,... ) ;... extern int scanf ( const char * r e s t r i c t format,... ) ;... int main ( void ) { p r i n t f ( " Hello, world! \n" ) ; } Stefano Zacchiroli (Paris Diderot) Build 2016 2017 17 / 37

#include Where are referenced files looked for? It depends on the used #include syntax: #include <file.ext> #include "file.ext" Stefano Zacchiroli (Paris Diderot) Build 2016 2017 18 / 37

#include Where are referenced files looked for? It depends on the used #include syntax: #include <file.ext> file.ext will be looked for in the standard compiler include path i.e., a list of pre-defined directories where to look for header files can be modified using compiler switches #include "file.ext" as above, but the compiler include path will be extended with the current source directory i.e., file.ext can be in the same directory of files that want to include it Either way, #include induces a build dependency from the including file to file.ext: if file.ext changes, you shall recompile all files that include it Stefano Zacchiroli (Paris Diderot) Build 2016 2017 18 / 37

#include troubles Consider the following utils.h: #include <stdio. h> void hello ( char *msg) { p r i n t f ( " Hello %s! \n", msg) ; } and hello.c: 1 #include " u t i l s. h" #include " u t i l s. h" int main ( void ) { hello ( " world " ) ; } What will happen when you compile hello.c?? 1. multiple #include only looks stupid; they easily (and often) happen due to transitive inclusion Stefano Zacchiroli (Paris Diderot) Build 2016 2017 19 / 37

#include troubles Consider the following utils.h: #include <stdio. h> void hello ( char *msg) { p r i n t f ( " Hello %s! \n", msg) ; } and hello.c: #include " u t i l s. h" #include " u t i l s. h" int main ( void ) { hello ( " world " ) ; } Error! In file included from hello.c:2:0: utils.h:3:6: error: redefinition of hello utils.h:3:6: note: previous definition of hello was here Stefano Zacchiroli (Paris Diderot) Build 2016 2017 19 / 37

Macros #define The general idea of macros is to define identifiers content associations (or bindings): wherever the identifier is used, it will get replaced by the associated content by the preprocessor. object-like macros: act like constants take no parameters; replacement content does not depend on the invocation Example (object-like macros) #define PI 3.14159 circ = 2 * PI * d; circ = 2 * 3.14159 * d; definition usage expansion Stefano Zacchiroli (Paris Diderot) Build 2016 2017 20 / 37

Macros #define (cont.) function-like macros: act like functions take parameters; replacement content depends on them Example (function-like macros) #define RADTODEG(x) ((x) * 57.29578) deg = RADTODEG(17 + 1.2); deg = ((17 + 1.2) * 57.29578); definition usage expansion Stefano Zacchiroli (Paris Diderot) Build 2016 2017 21 / 37

Macros #define (cont.) function-like macros: act like functions take parameters; replacement content depends on them Example (function-like macros) #define RADTODEG(x) ((x) * 57.29578) deg = RADTODEG(17 + 1.2); deg = ((17 + 1.2) * 57.29578); definition usage expansion Exercise (macros v. functions) What is the difference between the above and the following? float rad_to_deg ( float rad ) { return ( rad * 57.29578); } deg = rad_to_deg(17 + 1. 2 ) ; Stefano Zacchiroli (Paris Diderot) Build 2016 2017 21 / 37

Macros #undef An existing macro can be undefined using #undef. The macro will not be expanded any longer in the remainder of the file. #define P I 3.1415 circ1 = 2 * PI * d1; #undef PI circ2 = 2 * PI * d2; circ1 = 2 * 3.1415 * d1; circ2 = 2 * PI * d2; Stefano Zacchiroli (Paris Diderot) Build 2016 2017 22 / 37

Function-like macros pitfalls Function-like macros are powerful, but very tricky to use! for a macro definition to be interpreted as function like, no space should be given before the formal parameter list #define RADTODEG(x) ((x) * 57.29578) #define RADTODEG (x) ((x) * 57.29578) a function-like macro usage will be expanded only if it s given parameters deg = RADTODEG; will remain unchanged (and hence likely fail) Stefano Zacchiroli (Paris Diderot) Build 2016 2017 23 / 37

Function-like macros pitfalls (cont.) macro expansion is language agnostic pro: can be used with other syntaxes cons: you can cause syntax errors! #define strange ( f i l e ) f p r i n t f ( f i l e, "%s %d", strange ( stderr ) p, 35) expands to: f p r i n t f ( stderr, "%s %d", p, 35) Stefano Zacchiroli (Paris Diderot) Build 2016 2017 24 / 37

Function-like macros pitfalls (cont.) macro expansion is language agnostic pro: can be used with other syntaxes cons: you can cause syntax errors! #define strange ( f i l e ) f p r i n t f ( f i l e, "%s %d", strange ( stderr ) p, 35) expands to: f p r i n t f ( stderr, "%s %d", p, 35) #define c e i l _ d i v ( x, y ) ( x + y 1) / y a = c e i l _ d i v (b & c, sizeof ( int ) ) ; expands to: a = ( b & c + sizeof ( int ) 1) / sizeof ( int ) ; see http://tigcc.ticalc.org/doc/cpp.html#sec22 for more Stefano Zacchiroli (Paris Diderot) Build 2016 2017 24 / 37

Function-like macros pitfalls (cont.) macro expansion is language agnostic pro: can be used with other syntaxes cons: you can cause syntax errors! #define strange ( f i l e ) f p r i n t f ( f i l e, "%s %d", strange ( stderr ) p, 35) expands to: f p r i n t f ( stderr, "%s %d", p, 35) #define c e i l _ d i v ( x, y ) ( x + y 1) / y a = c e i l _ d i v (b & c, sizeof ( int ) ) ; expands to: a = ( b & c + sizeof ( int ) 1) / sizeof ( int ) ; see http://tigcc.ticalc.org/doc/cpp.html#sec22 for more Best practices: always balance parentheses in macro definitions always put parentheses around argument usage in macro definitions Stefano Zacchiroli (Paris Diderot) Build 2016 2017 24 / 37

Conditional compilation Conditional compilation is the ability to selectively compile or avoid to compile parts of the code. alternative code paths might exist in the code depending on the target platform (that is known a build-time); some of them might simply fail to compile on the wrong platform optional code paths might exist depending on the desired build-time configuration development build: with extensive debugging code, assertions, and logging production build: without any of it avoiding to compile unneeded optional code paths is beneficial reduced compile time reduced object / executable size reduced memory usage better performances (assert-s, if-s,... ) Stefano Zacchiroli (Paris Diderot) Build 2016 2017 25 / 37

Conditional compilation #ifdef & co. Various C preprocessor directives are used to support conditional compilation. #ifdef, #ifndef, #if start a conditional block #ifdef and #ifndef evaluates to true, enabling the corresponding conditional block, depending on whether a macro is defined or not #if can be used to test (a very restricted form) of boolean arithmetic expressions based on literal numbers and other macros #endif ends a conditional block (mandatory) #else, #elif start alternative branches of a conditional block #error can be used to fail at preprocessing time useful when no suitable alternative compilation branch exists Stefano Zacchiroli (Paris Diderot) Build 2016 2017 26 / 37

Conditional compilation examples #ifdef unix /* pre defined by compilers targeting Unix */ # include <unistd. h> # e l i f defined _WIN32 /* pre def. by compilers targeting Win */ # include <windows. h> #endif #ifdef DEBUG p r i n t f ( " entering magic_fun\n" ) ; # i f VERBOSE >= 2 p r i n t f ( " trace message\n" ) ; # endif /* VERBOSE >= 2 */ #endif /* DEBUG */ # i f RUBY_VERSION == 190 # error 1.9.0 not supported #endif Stefano Zacchiroli (Paris Diderot) Build 2016 2017 27 / 37

Avoiding multiple inclusion Best practice to avoid double inclusion issues. Sample header file hello.h: #ifndef HELLO_H #define HELLO_H void hello ( char *msg) ; #endif /* HELLO_H */ What would be the expansion of the following: #include " hello. h" #include " hello. h" #include " hello. h"? Stefano Zacchiroli (Paris Diderot) Build 2016 2017 28 / 37

The actual preprocessor output #include <stdio. h> int main ( void ) { p r i n t f ( " Hello, world! \n" ) ; } # 29 " / usr/ include /x86_64 linux gnu/ bits / types. h" 2 3 4 typedef unsigned char u_char ; typedef unsigned short int u_short ;... # 490 " /usr/ include / l i b i o. h" 3 4 extern int p r i n t f ( const char * r e s t r i c t format,... ) ;... # 414 " /usr/ include / stdio. h" 3 4 extern int scanf ( const char * r e s t r i c t format,... ) ;... # 2 " hello. c " 2 int main ( void ) { p r i n t f ( " Hello, world! \n" ) ; } Stefano Zacchiroli (Paris Diderot) Build 2016 2017 29 / 37

The actual preprocessor output (cont.) The output of the preprocessor is intermixed with line number annotations of the form # nnn "file"... that tells the compiler where a specific line of code really come from. Why is this needed? Stefano Zacchiroli (Paris Diderot) Build 2016 2017 30 / 37

The actual preprocessor output (cont.) The output of the preprocessor is intermixed with line number annotations of the form # nnn "file"... that tells the compiler where a specific line of code really come from. the compiler check for errors w.r.t. language semantics errors (& warnings) are reported to the user who should fix them to be meaningful to the user, error locations should match the files that the user is editing preprocessor output line and column numbers are affected by macro expansion Stefano Zacchiroli (Paris Diderot) Build 2016 2017 30 / 37

Outline 1 The build process 2 The C preprocessor 3 First steps with GCC Stefano Zacchiroli (Paris Diderot) Build 2016 2017 31 / 37

GCC GNU Compiler Collection formerly GNU C Compiler one of the most widespread and reputable C compiler Free Software, released under the GNU General Public License (GPL), version 3 or above actually, a large collection of compilers front-ends: C, C++, Java, Fortran, Objective-C, Ada, Go back-ends: 60+, ever growing list support: preprocessing, compilation, linking releases: 1987: 1.0 (by Richard Stallman et al.); 1992: 2.0; 2001: 3.0; 2005: 4.0; 2015: 5.1. man gcc Stefano Zacchiroli (Paris Diderot) Build 2016 2017 32 / 37

Building with gcc All in one build: $ gcc main.c preprocessing building linking deliver executable a.out (default, historical name) Stefano Zacchiroli (Paris Diderot) Build 2016 2017 33 / 37

Preprocessing with gcc Preprocessing can be executed as a stand-alone phase using cpp: $ cpp main.c $ # same, asking gcc to stop after preprocessing $ gcc -E main.c will dump preprocessor output to standard output The -o option can be used on all gcc (& friends) invocations to set output destination (overriding default names): $ cpp -o main.i main.c $ gcc -E -o main.i main.c will save preprocessor output to main.i Stefano Zacchiroli (Paris Diderot) Build 2016 2017 34 / 37

Compiling with gcc The -c option asks gcc to stop after compilation i.e., preprocessing + compilation, but no linking It is needed in all non trivial build processes, to compile objects separately and delay linking to the end. Stefano Zacchiroli (Paris Diderot) Build 2016 2017 35 / 37

Compiling with gcc (cont.) The default destination for the object corresponding to a source file source.c is source.o. It can be overridden with -o, as usual. It is recommended to always compile with -Wall that requires the compiler to enable all warnings about code correctness: uninitialized variables unused variables implicit function declaration missing parentheses etc. Stefano Zacchiroli (Paris Diderot) Build 2016 2017 35 / 37

Compiling with gcc examples $ gcc -Wall -c foo.c $ gcc -Wall -c bar.c $ gcc -Wall -c main.c build objects foo.o, bar.o, and main.o, ready to be linked Stefano Zacchiroli (Paris Diderot) Build 2016 2017 36 / 37

Linking with gcc Once all objects are available, we can use gcc to link them together by simply passing them as arguments as if they were source files. $ gcc -o my-program foo.o bar.o main.o will build the executable my-program linking together 3 objects default linking destination is a.out (if -o is omitted) To link a program that uses external libraries, you will need to reference them using -l at link-time. passing -lfoo will tell the linker to look for the libfoo library in the default library search path $ gcc -o my-program foo.o bar.o main.o -lm link with libm (math library) Stefano Zacchiroli (Paris Diderot) Build 2016 2017 37 / 37