GCC Compiler je velmi výkonný a oblíbený kompilátor jazyka C pro různé distribuce Linuxu. Tento článek vysvětluje některé oblíbené možnosti kompilátoru GCC.
Příklad kódu C
V tomto článku bude použit následující základní kód C (main.c):
#include<stdio.h> int main(void) { printf("\n The Geek Stuff\n"); return 0; }
Možnosti kompilátoru GCC
1. Zadejte název výstupního spustitelného souboru
Ve své nejzákladnější formě lze kompilátor gcc použít jako :
gcc main.c
Výše uvedený příkaz provede celý proces kompilace a vydá spustitelný soubor s názvem a.out.
Použijte volbu -o, jak je uvedeno níže, k zadání názvu výstupního souboru pro spustitelný soubor.
gcc main.c -o main
Výše uvedený příkaz vytvoří výstupní soubor s názvem ‚main‘.
Chcete-li porozumět úplnému procesu kompilace kompilátoru GCC, přečtěte si náš článek Cesta programu C do spustitelného souboru Linux ve 4 fázích.
2. Povolit všechna varování nastavená pomocí volby -Wall
Tato možnost povolí všechna varování v GCC.
#include<stdio.h> int main(void) { int i; printf("\n The Geek Stuff [%d]\n", i); return 0; }
Pokud je výše uvedený kód zkompilován, zobrazí se následující varování související s neinicializovanou proměnnou i:
$ gcc -Wall main.c -o main main.c: In function ‘main’: main.c:6:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
3. Vytvořte pouze výstup preprocesoru s volbou -E
Výstup fáze předběžného zpracování lze vytvořit pomocí volby -E.
$ gcc -E main.c > main.i
Příkaz gcc vytváří výstup na stdout, takže můžete přesměrovat výstup v libovolném souboru. V našem případě (výše) by soubor main.i obsahoval předzpracovaný výstup.
4. Vytvořte pouze kód sestavení pomocí volby -S
Výstup na úrovni sestavy lze vytvořit pomocí volby -S.
gcc -S main.c > main.s
V tomto případě by soubor main.s obsahoval výstup sestavení.
5. Vytvořte pouze zkompilovaný kód pomocí volby -C
Chcete-li vytvořit pouze zkompilovaný kód (bez jakéhokoli propojení), použijte volbu -C.
gcc -C main.c
Výše uvedený příkaz by vytvořil soubor main.o, který by obsahoval kód na úrovni stroje nebo zkompilovaný kód.
6. Vytvořte všechny přechodné soubory pomocí funkce -save-temps
Volba -save-temps může provést veškerou práci provedenou v příkladech 4, 5 a 6 výše. Prostřednictvím této volby je výstup ve všech fázích kompilace uložen do aktuálního adresáře. Vezměte prosím na vědomí, že tato volba vytvoří také spustitelný soubor.
Například:
$ gcc -save-temps main.c $ ls a.out main.c main.i main.o main.s
Vidíme tedy, že na výstupu byly vytvořeny všechny přechodné soubory i konečný spustitelný soubor.
7. Propojit se sdílenými knihovnami pomocí volby -l
Volbu -l lze použít k propojení se sdílenými knihovnami. Například:
gcc -Wall main.c -o main -lCPPfile
Výše zmíněný příkaz gcc propojí kód main.c se sdílenou knihovnou libCPPfile.so, aby vytvořil konečný spustitelný soubor ‚main‘.
8. Vytvořte kód nezávislý na pozici pomocí volby -fPIC
Při vytváření sdílených knihoven by měl být vytvořen kód nezávislý na pozici. To pomáhá sdílené knihovně načíst jako libovolnou adresu místo nějaké pevné adresy. K tomu se používá volba -fPIC.
Například následující příkazy vytvoří sdílenou knihovnu libCfile.so ze zdrojového souboru Cfile.c:
$ gcc -c -Wall -Werror -fPIC Cfile.c $ gcc -shared -o libCfile.so Cfile.o
Vidíme tedy, že při vytváření sdílené knihovny byla použita volba -fPIC.
9. Vytiskněte všechny provedené příkazy pomocí volby -V
Volbu -v lze použít k poskytnutí podrobných informací o všech krocích, které gcc provádí při kompilaci zdrojového souboru.
Například:
$ gcc -Wall -v main.c -o main Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ... ... ...
Vidíme tedy, že ve výstupu byly vytvořeny podrobné informace.
10. Povolte podporu programů ISO C89 pomocí volby -ansi
Prostřednictvím volby -ansi je povolena podpora stylu ISO C89.
Zvažte následující kód:
#include<stdio.h> int main(void) { // Print the string printf("\n The Geek Stuff\n"); return 0; }
Pokud je výše uvedený kód zkompilován s volbou -ansi, pak by gcc způsobilo chybu, protože komentáře C++ nejsou povoleny ve stylu ISO C89.
Zde je výstup:
$ gcc -Wall -ansi main.c -o main main.c: In function ‘main’: main.c:5:3: error: expected expression before ‘/’ token
Vidíme tedy, že gcc vyvolalo chybu související se stylem komentáře.
11. Interpretujte znak jako znak bez znaménka pomocí volby -funsigned-char
Prostřednictvím této volby je typ znaku považován za typ bez znaménka.
Zde je příklad:
#include<stdio.h> int main(void) { char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
Když je výše uvedený kód zkompilován s možností funsigned-char, zde je výstup:
$ gcc -Wall -funsigned-char main.c -o main $ ./main The Geek Stuff [246]
Vidíme tedy, že znak byl skutečně považován za nepodepsaný.
12. Interpretujte znak jako podepsaný znak pomocí volby -fsigned-char
To je opak toho, co jsme diskutovali v (12) výše. Pomocí tohoto příznaku jsou proměnné char považovány za podepsané.
Zde je příklad:
$ gcc -Wall -fsigned-char main.c -o main $ ./main The Geek Stuff [-10]
Výstup potvrzuje, že znak byl považován za podepsaný.
13. Použijte makra doby kompilace pomocí volby -D
Možnost kompilátoru D lze použít k definování maker pro čas kompilace v kódu.
Zde je příklad:
#include<stdio.h> int main(void) { #ifdef MY_MACRO printf("\n Macro defined \n"); #endif char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
Volbu kompilátoru -D lze použít k definování makra MY_MACRO z příkazového řádku.
$ gcc -Wall -DMY_MACRO main.c -o main $ ./main Macro defined The Geek Stuff [-10]
Tisk související s makrem ve výstupu potvrzuje, že makro bylo definováno.
14. Převeďte varování na chyby pomocí volby -Werror
Prostřednictvím této možnosti se všechna varování, která by mohla nahlásit gcc, převedou na chybu.
Zde je příklad:
#include<stdio.h> int main(void) { char c; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
Kompilace výše uvedeného kódu by měla generovat varování související s nedefinovanou proměnnou c a to by mělo být převedeno na chybu pomocí volby -Werror.
$ gcc -Wall -Werror main.c -o main main.c: In function ‘main’: main.c:7:10: error: ‘c’ is used uninitialized in this function [-Werror=uninitialized] cc1: all warnings being treated as errors
15. Poskytněte možnosti gcc prostřednictvím souboru pomocí možnosti @
Možnosti pro gcc lze také poskytnout prostřednictvím souboru. To lze provést pomocí volby @ následované názvem souboru obsahujícího volby. Více než jedna možnost je oddělena mezerou.
Zde je příklad:
$ cat opt_file -Wall -omain
Soubor opt_file obsahuje možnosti.
Nyní zkompilujte kód poskytnutím opt_file spolu s volbou @.
$ gcc main.c @opt_file main.c: In function ‘main’: main.c:6:11: warning: ‘i’ is used uninitialized in this function [-Wuninitialized] $ ls main main
Výstup potvrzuje, že soubor opt_file byl analyzován za účelem získání možností a kompilace byla provedena odpovídajícím způsobem.