CS107 Kompilering av C-program med GCC
Skrivet av Chris Gregg, med ändringar av Nick Troccoli
Klicka här för en genomgångsvideo.
Den kompilator som vi kommer att använda i CS107 kallas ”GNU Compiler Collection” (gcc). Det är en av de mest använda kompilatorerna, och den är både fri programvara och tillgänglig på många olika datorplattformar.
gcc
utför kompileringssteget för att bygga upp ett program, och sedan anropar den andra program för att sätta ihop programmet och för att länka programmets beståndsdelar till ett körbart program som du kan köra. Vi kommer att lära oss lite om vart och ett av dessa steg under CS107, men det fina är att gcc
kan producera hela det körbara (körbara) programmet åt dig med ett enda kommando.
I CS107 kommer vi främst att använda Makefiles för att kompilera, sätta ihop och länka vår kod, men Makefilen kör gcc
för att göra arbetet. This is just a quick overview on how to compile and run your own programs should you decide to do so without a Makefile.
The simplest way to run gcc
is to provide gcc
a list of .c
files:
$ gcc hello.c$
Note that you do not put header files (.h
) into the gcc
command: it reads in the header files as it compiles, based on the #include
statements inside .c
files.
If the program compiled without errors or warnings, you don’t get any output from gcc
, and you will have a new file in your directory, called a.out
. To run this file, you need to tell the shell to run the file in the current directory, by using ./
before the name:
$ ./a.outHello, World!$
Vi vill i allmänhet inte att våra program ska heta a.out
, så du kan ge gcc
ett alternativ, -o programName
, för att tala om för den vad den ska kalla den körbara filen:
$ gcc hello.c -o hello$ ./helloHello, World!$
Notera: Var försiktig så att du inte av misstag anger ett namn på en körbar fil som är detsamma som din inmatningsfil – något i stil med:
$ gcc hello.c -o hello.c
På myth
har din profil ställts in för att fånga upp felet och inte kompilera det, vilket gör att din källfil förblir intakt. Detta är inte fallet på många andra Linuxsystem, så var försiktig! På andra system skulle GCC skriva över din källfil med den nya körbara filen.
gcc
tar många olika kommandoradsalternativ (flaggor) som ändrar dess beteende. En av de vanligaste flaggorna är flaggan ”optimeringsnivå”, -O
(stort ”o”). gcc
har möjlighet att optimera din kod för olika situationer.
- -O eller -O1: Optimera. Optimering av kompilering tar något mer tid och mycket mer minne för en stor funktion. Med
-O
försöker kompilatorn minska kodstorleken och exekveringstiden, utan att utföra några optimeringar som tar mycket kompileringstid i anspråk. - -O2: Optimera ännu mer. GCC utför nästan alla optimeringar som stöds och som inte innebär en kompromiss mellan utrymme och hastighet. Jämfört med
-O
ökar det här alternativet både kompileringstiden och prestandan hos den genererade koden. - -O3: Optimera ännu mer.
-O3
aktiverar alla optimeringar som anges av-O2
och aktiverar även andra optimeringar. Detta är ofta det bästa alternativet att använda. - -O0: Förkortar kompileringstiden och gör att felsökningen ger de förväntade resultaten. Detta är standardalternativet.
- -Os: Optimera för storlek.
-Os
aktiverar alla-O2
optimeringar som vanligtvis inte ökar kodstorleken. Den utför också ytterligare optimeringar som är utformade för att minska kodstorleken. - -Ofast: Strikt standardisering:: Strunta i att följa strikta standarder.
-Ofast
aktiverar alla-O3
optimeringar. Det aktiverar även optimeringar som inte är giltiga för alla program som följer standarden. - -Og: Optimerar felsökningsupplevelsen.
-Og
aktiverar optimeringar som inte stör felsökningen. Det bör vara den optimeringsnivå som väljs för standardcykeln edit-compile-debug, som erbjuder en rimlig optimeringsnivå med bibehållen snabb kompilering och en bra felsökningsupplevelse. Vi kommer att använda-Og
i CS107 när vi felsöker.
Se man
-sidan för gcc
för mer information om optimering (eller se här för mer information om optimeringar).
En annan vanlig flagga är alternativet -std=gnu99
, som talar om för gcc
att använda ”gnu c version of the 1999 c standard”. Standarden ger syntax som t.ex. att kunna definiera en variabel i en deklaration av en for-slinga (t.ex. for (int i = ...)
. Vi kommer att använda denna standard i CS107.
Vi kommer också att använda flaggan -g
, som gör det möjligt för oss att använda felsökaren, gdb, för att ge oss exakta radnummer i vår kod när vi kör den.
Exempel:
$ gcc -std=gnu99 -g -Og loop.c -o loop
Om du är intresserad av ännu mer information om gcc
kan du läsa avsnitt 1 i det här dokumentet om Stanford Unix Programming Tools, samt hela gcc-manualen(GNU).