====== GCC ====== GCC - **GNU Compiler Collection** bei [[http://de.wikipedia.org/wiki/GNU_Compiler_Collection|Wikipedia]] * GCC-FAQ: [[https://gcc.gnu.org/faq.html]] * GCC-Wiki, FAQ: [[https://gcc.gnu.org/wiki/FAQ]] * man-pages: [[http://man7.org/linux/man-pages/man1/gcc.1.html]] * O'Reilly: [[http://www.oreilly.de/german/freebooks/rlinux3ger/ch132.html|Programmieren mit gcc]] * GCC - Kurzanleitung auf Ubuntuusers.de: [[https://wiki.ubuntuusers.de/GCC/]] C++ Standards Support in GCC: [[https://gcc.gnu.org/projects/cxx-status.html]] (Welche Funktionalität ab welcher GCC-Version unterstützt wird.) **MinGW** steht für "Minimalist GNU for Windows": [[http://www.mingw.org/]] * MS resource compiler: [[http://www.mingw.org/wiki/MS_resource_compiler]] * Building Windows **DLL**s with MinGW: [[http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/]] - Ein sehr guter Artikel! * Advanced MinGW DLL Topics: [[http://www.transmissionzero.co.uk/computing/advanced-mingw-dll-topics/]] Ein kleines Beispiel zeigt auf einfache Weise und sehr anschaulich die Unterschiede zwischen den **statischen** und **dynamischen** Libraries:\\ [[http://www.codeproject.com/Articles/84461/MinGW-Static-and-Dynamic-Libraries]] GCC and Make: [[https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html]] - Compiling, Linking and Building C/C++ Applications Bei Verwendung von den **MQ**-Libraries unter Windows (mqm.dll, mqic.dll) bitte Workaround beim [[edv:prg:mq-series:example:Kompilieren/Linken von mqic.dll/.lib mit GCC unter Windows]] beachten! Bei Verwendung auf **[[EDV:OS:UNIX:Derivate:AIX]]** unbedingt folgende Hinweise (IBM) beachten (insbesondere im Zusammenhang mit shared libraries): * Using the GNU C/C++ compiler on AIX: [[http://www.ibm.com/developerworks/aix/library/au-gnu.html]] ===== GCC kompilieren ===== * Anleitung: GCC kompilieren und installieren: [[http://www.floriankirsch.de/gcc/install.html]] * Building GCC on Ubuntu Linux: [[https://solarianprogrammer.com/2016/10/07/building-gcc-ubuntu-linux/]] (8 May 2018 - Article updated for GCC 8.1) * How to Manually Build and Install GNU Compiler Collection on Linux Mint: [[https://www.wikihow.com/Manually-Build-and-Install-GNU-Compiler-Collection-on-Linux-Mint]] * Building GCC: [[https://wiki.osdev.org/Building_GCC]] ===== Aufruf/Syntax ===== **Beispiele:** * Den Quelltext **hello.c** übersetzen und daraus ein ausführbares Programm namens **hello** generieren: gcc -o hello hello.c * Den Quelltext **hello.c** übersetzen, dabei nur die Objektdatei (hello.o) generieren: gcc -c hello.c Das funktioniert auch mit mehreren Quelltexten auf einmal: gcc -c funktion1.c funktion2.c funktion3.c Dabei werden in einem Gang funktion1.o funktion2.o funktion3.o generiert. Mit dem GCC-Parameter **-H** sieht man auch, welche Headerdateien beim Kompilieren eingeflossen sind (erleichtert Fehlersuche): gcc -H -c funktion1.c funktion2.c funktion3.c * Mehrere Quelltexte (foo.c und bar.c) übersetzen und daraus ein ausführbares Programm namens **abc** generieren: gcc -o abc foo.c bar.c Das gleiche kann man auch schrittweise erreichen: gcc -c foo.c gcc -c bar.c gcc -o abc foo.o bar.o * Debugger-Infos dem ausführbaren Programm anfügen (**-g**): gcc -g -o hello hello.c ===== Parameter/Compileroptionen ===== Option Index: [[https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Option-Index.html#Option-Index]] (gcc-4.8.5)\\ Keyword Index: [[https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Keyword-Index.html#Keyword-Index]] (gcc-4.8.5)\\ **Option Summary:** [[https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Option-Summary.html#Option-Summary]] (gcc-4.8.5) Das [[http://wiki.ubuntuusers.de/GCC|Ubuntuusers-Wiki]] empfiehlt Programme ausschließlich mit folgenden Parametern zu erstellen: gcc -g -Wall -Wextra -pedantic-errors foo.c -o foo Oft kommt noch __entweder__ **-O0 -ggdb3** für das Debugging __oder__ **-march=native -O3** für eine schnelle Ausführung hinzu. Die häufig verwendete (allgemeine) Optionen: ^Option ^Kommentar ^ |--help |Gibt die Hilfe aus. | |-c |Quelltexte übersetzen, aber nicht linken (z.B. bei **make**). | |-DCPU=586|weist den Compiler an, Pentium-CPU Code zu generieren. | |-fno-strength-reduce|keine Schleifenoptimierungen zulassen. | |-g |Symboltabelle für Debugger an den (binären) Code anfügen. | |-ggdb |Fügt weitere Debugging-Symbole für den **GDB** hinzu, mit **-ggdb3** wird alles mögliche unterstützt. | |**-g**Level|Level **1** beinhaltet die Beschreibung von Funktionen und externen Variablen, interne Variablen und Zeilennummern fehlen aber. Level **2** ist der eingestellte Defaultwert und bietet die notwendigen Informationen, um Code sinnvoll debuggen zu können. Level **3** enthält zusätzliche Informationen, wie zum Beispiel alle Makrodefinitionen, die im Programm vorhanden sind. | |**-I**//dir// |Zusätzlicher Pfad //dir// zu den Headerdateien (include). Alle mit -I angegebene Verzeichnisse werden von links nach rechts durchgegangen, und zwar vor den default-Verzeichnissen.\\ Das kann auch dafür verwendet werden, um die System-Headers mit eigener Version zu "überschreiben". | |**-H** |Zeigt alle verwendeten Headerdateien (mit Pfad). | |**-iquote**//dir// |Das gleiche wie -I, wirkt aber nur auf die Headers in der Form **#include "file"** (mit **"**-Zeichen), jedoch nicht auf die **#include ** (mit eckigen Klammern). | |-nostdinc |Der default INCLUDE-Pfad wird nicht genutzt. (Sinnvoll wenn man den Kernel kompiliert oder ein Programm, dass die Standard C Library nicht verwendet, oder wenn man die Standard C Library selbst übersetzt/baut.) | |-L |Pfad zu den Programmbibliotheken. | |**-l**xxx|Bindet zusätzliche Programm-Bibliotheken (Libraries) ein (z.B. **-l**ncurses für //libncurses//). | |-o |Der nachfolgende Name soll als Programmname verwendet werden (Standard: **a.out**). | |**-O**X|Optimiert den Quellcode, der Grad der Optimierung (Platzhalter X) kann: **0** (nichts), **1** (Größe und Geschwindigkeit), **2** (Geschwindigkeit), **3** (Geschwindigkeit, aggressiv) oder **s** (Größe) sein. | |-march=nativ|Optimiert speziell für den vorhandenen Prozessor und wird auf anderen Architekturen nicht laufen. | |-p |Profiling-Informationen für "prof" (Profiler) erzeugen. | |-pg |**Profiling-Informationen** für "gprof" (Profiler) erzeugen. (Mehr Infos unter [[http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/019_c_zeitroutinen_002.htm]]) | |-pipe |Linux-Pipes zum Datenaustausch zwischen Compilerstufen verwenden. | |**-W**all|Weist den Compiler an, alle auftretenden Warnungen anzuzeigen. | |**-W**extra|Aktiviert noch mehr Warnungen, die vom gcc-Compiler unterstützt werden. | |-S |Weist den Compiler an, den erzeugten Code als Assembler-Quelltext auszugeben. | |-ansi |Erlaubt nur ANSI C-konforme Konstrukte. | |-pedantic|Weist auf nicht ISO konforme Statements mit einer Warnung hin (**-pedantic-errors** erzwingt Fehler). | |**-W**no-deprecated|Keine Warnings, wenn im Quelltext [[https://gcc.gnu.org/onlinedocs/gcc/Deprecated-Features.html|deprecated features]] vorkommen. | |-fpermissive|Wenn einige Arten nicht konformes Codes festgestellt werden, werden diese von Errors zu Warnings heruntergestuft. Auf diese Weise wird es ermöglicht, dass ein nicht konformer Code kompiliert wird. | |-fpic¹ |Generiert positionsunabhängigen Code (**p**osition **i**ndependent **c**ode), falls die Zielmaschine das unterstützt. Solcher Code ist geeignet, um in shared Libraries eingesetzt zu werden. | |-fPIC¹ |Generiert positionsunabhängigen Code, falls die Zielmaschine das unterstützt, selbst wenn Verzweigungen großen Abstand benötigen. | |-fpie², -fPIE² |Generiert positionsunabhängigen Code (**p**osition **i**ndependent **e**xecutable). | |-static|Weist den Linker an, statische Libraries zu verwenden. | |-shared|Weist den Linker an, shared Libraries zu verwenden. | |-v |Gibt die Kommandos und Schritte aus, die der Compiler gerade ausführt (Präprozessor, Compiler, Assembler, Linker...). | :!: Hinweise:\\ ¹,² Weitere Infos zu den **PIC** und **PIE** sind hier: [[https://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Code-Gen-Options.html#Code-Gen-Options]]\\ ¹ Der Unterschied zwischen "-fpic" und "-fPIC" ist unter [[http://stackoverflow.com/questions/3544035/what-is-the-difference-between-fpic-and-fpic-gcc-parameters/3544211]] etwas genauer erklärt.\\ ² Unter [[http://stackoverflow.com/questions/28119365/what-are-the-differences-comparing-pie-pic-code-and-executable-on-64-bit-x86-pl]] ist der Unterschied zwischen "-fPIC" und "-fPIE" erläutert.\\ ² Code, der mit "-fpie" / "-fPIE" übersetzt wurde, soll mit "-pie" gelinkt werden (s. Options for Linking: [[https://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Link-Options.html#Link-Options]]). ==== Weitere Optionen ==== === Paranoid Flags === Satz von "Extra-Paranoid Flags": -g -O -Wall -Wextra -Werror -Weffc++ -pedantic -pedantic-errors -Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wconversion -Wdisabled-optimization -Wfloat-equal -Wformat -Wformat=2 -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimplicit -Wimport -Winit-self -Winline -Winvalid-pch -Wunsafe-loop-optimizations -Wlong-long -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstack-protector -Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch -Wswitch-default -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings === 32-/64-Bit und Memory-Model (bei Intel-Architektur) === Zwei Ausschnitte aus der GCC-Doku: **32-/64-Bit:** These '-m' switches are supported in addition to the above on x86-64 processors in 64-bit environments. -m32 -m64 -mx32 -m16 -miamcu Generate code for a 16-bit, 32-bit or 64-bit environment. The -m32 option sets int, long, and pointer types to 32 bits, and generates code that runs on any i386 system. The -m64 option sets int to 32 bits and long and pointer types to 64 bits, and generates code for the x86-64 architecture. For Darwin only the -m64 option also turns off the -fno-pic and -mdynamic-no-pic options. The -mx32 option sets int, long, and pointer types to 32 bits, and generates code for the x86-64 architecture. Example: 32-Bit: gcc -m32 -o exmaple32 example.c 64-Bit: gcc -m64 -o exmaple64 example.c (same with g++) **Memory-Model:** -mcmodel=small Generate code for the small code model: the program and its symbols must be linked in the lower 2 GB of the address space. Pointers are 64 bits. Programs can be statically or dynamically linked. This is the default code model. -mcmodel=kernel Generate code for the kernel code model. The kernel runs in the negative 2 GB of the address space. This model has to be used for Linux kernel code. -mcmodel=medium Generate code for the medium model: the program is linked in the lower 2 GB of the address space. Small symbols are also placed there. Symbols with sizes larger than -mlarge-data-threshold are put into large data or BSS sections and can be located above 2GB. Programs can be statically or dynamically linked. -mcmodel=large Generate code for the large model. This model makes no assumptions about addresses and sizes of sections. Quelle: [[https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/x86-Options.html]] ==== C/C++ Optionen ==== ^Option ^Kommentar ^ |-x c |Der Quelltext soll als C übersetzt werden. | |-x c++ |Der Quelltext soll als C++ übersetzt werden. | |-x c++-header |Der Quelltext soll als C++ übersetzt werden und zwar für die spätere Verwendung als **Precompiled Header** (**.gch**-File).\\ Bei Verwendung der Option "-x c++" (ohne "-header"-Zusatz) wird das gch-File zwar generiert, später aber nicht verwendet. | |-std=c++11\\ -std=c++14 |Beim Übersetzen der C++-Quelle den Sprach-Standard C++11 bzw. C++14 verwenden. | |-std=c11 |Beim Übersetzen der C-Quelle den Sprach-Standard C11 verwenden. | ===== Parameter/Linkeroptionen ===== ==== Option "-Wl,--subsystem,..." ==== Die Linker-Option **-Wl,--subsystem** hat Einfluss, wie bzw. für welche Zielplattform die Zieldatei gebaut wird. Ein interessanter Hinweis zum Schalter **-Wl,--subsystem,windows** findet man in der Anleitung **Building Windows DLLs with MinGW** auf folgender Seite (der 3. Treffer):\\ [[http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/]]\\ Dort steht:\\ //The "-Wl,--subsystem,windows" isn’t really necessary, but it’s just conventional that DLLs have the Windows GUI subsystem specified in their PE header. Also note the "-s" switch is used to strip symbols from the DLL—you’ll probably want to do this only for release builds.// ==== Mischen von statischen und dynamischen Libraries im Link-Vorgang ==== You need link flags **-Wl,-Bstatic** and **-Wl,-Bdynamic** because sometimes you want to force static linking, for example, when the dynamic library with the same name is also present in a search path: gcc object1.o object2.o -lMyLib2 -Wl,-Bstatic -lMyLib1 -Wl,-Bdynamic -o output The above snippet guarantees that the default linking priority of **-l** flag is overridden for **MyLib1**, i.e. even if **MyLib1.dll** is present in the search path, LD will choose **libMyLib1.a** to link against. Notice that for **MyLib2** LD will again prefer the dynamic version. :!: **NOTE:** If **MyLib2** depends on **MyLib1**, then **MyLib1** is dynamically linked too, regardless of **-Wl,-Bstatic** (i.e. it is ignored in this case). To prevent this you would have to link **MyLib2** statically too. Quelle: [[http://stackoverflow.com/questions/15852677/static-and-dynamic-shared-linking-with-mingw]] ===== Wichtige Hinweise ===== :!: Der Parameter **-fwritable-strings** wird ab GCC 4.* nicht mehr unterstützt (seit dem 3.4er als depprecated). Das heißt, in eine Variable, die wie folgt deklariert wurde: char * eineStringVariable = "TextTextText"; ...kann man nicht mehr schreiben. Früher war es durch die Anwendung der Compiler-Direktive "-fwritable-strings" möglich gewesen. Man ist also gezwungen, die beschreibbaren String-Variablen auf eine der beiden folgenden Weisen zu deklarieren: char eineStringVariable [] = "TextTextText"; // oder so: char eineStringVariable [] = {"TextTextText"}; :!: **ldd** zeigt Ihnen, welche Shared Libraries ein ausführbares Programm verwendet. Per Voreinstellung sucht der Loader nur in **/lib** und **/usr/lib**. Die Umgebungsvariable **LD_LIBRARY_PATH** ergänzt diese Suche um weitere (durch Doppelpunkte getrennte) Verzeichnisse. :!: GCC will **Libs nicht mit Pfaden**, man muss den Lib-Path als Parameter bzw. über LIBRARY_PATH setzen. :!: GCC will die Libs **ohne Erweiterung**, also nicht "-lodbc32**.lib** -lodbccp32**.lib**" sondern "-lodbc32 -lodbccp32". :!: GCC will die **Object-Files vor den Libs**, sonst bekommt er die Abhängigkeiten nicht aufgelöst. ===== Environment ===== **LD_LIBRARY_PATH** - Suchpfad für die dynamischen Libraries eines ausführbaren Programms (bzw. einer Library). :!: GCC ignoriert LIB und LIBPATH, er will **LIBRARY_PATH** gesetzt haben. ===== Vordefinierte Makros (Pre-defined Compiler Macros) ===== ^Type ^Macro ^Description ^ |Identification |%%__GNUC__%% | | |Version |%%__GNUC__%% |Version | |Version |%%__GNUC_MINOR__%% |Revision | |Version |%%__GNUC_PATCHLEVEL__%%|Patch (introduced in version 3.0) | Die durch den Compiler selbst gesetzte **Makros** auflisten: gcc -dM -E -x c nul ...oder: gcc -dM -E -x c++ nul Auf einigen Maschinen ist der Aufruf: gcc -dM -E - < /dev/null So sieht die Ausgabe aus (hier nur ein kleiner Ausschnitt): #define __GCC_ATOMIC_CHAR_LOCK_FREE 2 #define __FLT_EVAL_METHOD__ 0 #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 #define __x86_64 1 #define __UINT_FAST64_MAX__ 18446744073709551615ULL #define __SIG_ATOMIC_TYPE__ int #define __DBL_MIN_10_EXP__ (-307) #define __FINITE_MATH_ONLY__ 0 #define __GNUC_PATCHLEVEL__ 1 #define __UINT_FAST8_MAX__ 255 #define _stdcall __attribute__((__stdcall__)) #define __DEC64_MAX_EXP__ 385 #define __INT8_C(c) c #define __UINT_LEAST64_MAX__ 18446744073709551615ULL #define __SHRT_MAX__ 32767 Hier ist ein Beispiel auf SunOS auf der Sparc-Plattform: juergen@sunos_sparc:/home/juergen> gcc -dM -E - < /dev/null | grep -i sun #define __sun 1 #define sun 1 #define __sun__ 1 juergen@sunos_sparc:/home/juergen> gcc -dM -E - < /dev/null | grep -i sparc #define sparc 1 #define __sparc__ 1 #define __sparcv8 1 #define __sparc 1 juergen@sunos_sparc:/home/juergen> Weitere Infos auf: * Allgemein: [[https://sourceforge.net/p/predef/wiki/Compilers/]] * Speziell für GCC: [[https://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html]] * [[http://stackoverflow.com/questions/2224334/gcc-dump-preprocessor-defines]] ===== GCC Komponenten/Tools ===== ^Komponente ^Kommentar ^ |gcc | | |g++ | | FIXME Aus der GCC-Doku:\\ :!: //Also if you use g++ to link the object files it automatically links in the std C++ libraries (gcc does not do this).// ---- Stand: 08.06.2018 - **in Arbeit** EOF