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

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.

  1. -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.
  2. -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.
  3. -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.
  4. -O0: Förkortar kompileringstiden och gör att felsökningen ger de förväntade resultaten. Detta är standardalternativet.
  5. -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.
  6. -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.
  7. -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).