Vor- und Nachteile verschiedener Transportarten. Transportlogistiktransport. Internationaler Straßenverkehr.

Um das GCC richtig zu verwenden, müssen Sie den Standard-Compiler mit Linux die Befehlszeilenoptionen untersuchen. Darüber hinaus erweitert das GCC die Sprache S. Auch wenn Sie den Quellcode schreiben möchten, um den Ansi-Standard dieser Sprache einzuhalten, müssen einige GCC-Erweiterungen einfach wissen, um die Linux-Header-Dateien zu verstehen.

Die meisten Befehlszeilenoptionen sind die gleichen wie die in C-Compilation verwendeten C-Compilation. Für einige Optionen werden keine Standards bereitgestellt. In diesem Kapitel decken wir die wichtigsten Optionen ab, die in der Alltagsprogrammierung verwendet werden.

Der Wunsch, dem ISO-Standard einzuhalten, ist sehr nützlich, aber aufgrund der Tatsache, dass mit einer geringen Sprache eine geringe Sprache ist, gibt es Situationen, in denen Standardfonds nicht ausdrücklich genug sind. Es gibt zwei Bereiche, in denen GCC-Erweiterungen weit verbreitet sind: Interaktion mit Assembler-Code (diese Probleme werden unter http://www.delorie.com/djgpp/doc/breennan/) und der Montage von freigegebenen Bibliotheken angegeben (siehe Kapitel 8) . Da die Header-Dateien Teil der freigegebenen Bibliotheken sind, manifestiert sich auch einige Erweiterungen in System-Header-Dateien.

Natürlich gibt es noch viele Erweiterungen, die in jedem anderen Programmierformular nützlich sind, die beim Codieren sogar helfen können. Weitere Informationen zu diesen Erweiterungen finden Sie in der GCC-Dokumentation im TEXINFO-Format.

5.1. GCC-Optionen

gCC akzeptiert mehrere Befehlsoptionen. Glücklicherweise ist eine Reihe von Optionen, die wirklich eine Präsentation haben müssen, nicht so toll, und in diesem Kapitel werden wir es ansehen.

Die meisten Optionen übereinstimmen oder ähnlich den Optionen anderer Compiler, GCC enthält eine große Dokumentation für seine Optionen, die über die info GCC verfügbar sind (Man GCC gibt auch diese Informationen aus, aber die MAN-Seiten werden jedoch nicht so oft wie Texinfo-Dokumentation aktualisiert).

-Voller Name Gibt den Namen der Ausgabedatei an. Normalerweise ist es nicht erforderlich, wenn in der Objektdatei kompiliert wird, dh der Standardeinstellung ist der Dateiname. Dateiname. Wenn Sie jedoch eine ausführbare Datei erstellen, standardmäßig (historische Gründe), wird sie unter dem Namen A.OUT erstellt. Es ist auch nützlich, wenn Sie die Ausgabedatei in ein anderes Verzeichnis aufgeben möchten.
-mit Kompiliert ohne Layout, die für die Befehlszeile angegebene Quelldatei. Infolgedessen wird für jede Quelldatei eine Objektdatei erstellt. Bei der Verwendung der Marke wird der GCC-Compiler normalerweise für jede Objektdatei aufgerufen. Somit ist es im Fehlerfall einfacher zu erkennen, welche Datei nicht kompiliert werden konnte. Wenn Sie jedoch den Befehl manuell eingeben, geben Sie häufig in einem GCC-Anruf eine Vielzahl von Dateien an. Wenn bei der Angabe eines Satzes von Dateien in der Eingabeaufforderung in der Eingabeaufforderung auftreten, ist es besser, es ist besser, nur eine Datei anzugeben. Zum Beispiel ist anstelle von GCC -C -O AO A. B. B. B.B Sinn, GCC-SO A.O.O B.C anzuwenden.
-D foo. Definiert den Vorprozessor-Makros auf der Befehlszeile. Vielleicht ist es notwendig, die von der Hülle verfolgten Zeichen als SPECIAL abzubrechen. Wenn Sie beispielsweise eine Zeichenfolge ermitteln, sollten Sie beispielsweise die Verwendung von Zeichenfolgen des Begrenzungszeichens vermeiden. "Hier sind die beiden am meisten verwendeten Methoden:" -dfoo \u003d "bar" "und -dfoo \u003d" bar "" und -dfoo \u003d \\ "bar \\". Der erste Weg funktioniert viel besser, wenn Es gibt Räume in der Linie, da die Hülle die Lücken auf besondere Weise untersucht.
-I Katalog Fügt ein Verzeichnis in der Verzeichnisliste hinzu, die die enthaltenen Dateien enthält.
-L Katalog Fügt ein Verzeichnis in der Verzeichnisliste hinzu, in dem die Bibliothekssuche durchsucht wird, ergibt das GCC den gemeinsam genutzten Bibliotheken und nicht statisch, es sei denn, das Gegenteil ist angegeben.
-L foo. Führt ein Layout mit Bibliothek lib Foo aus. Wenn nicht inverse inversen angegeben, bevorzugen GCC das Layout mit freigegebenen Bibliotheken (lib Foo .so) und nicht statisch (lib foo .a). Der Linker sucht nach Funktionen in allen aufgeführten Bibliotheken in der Reihenfolge, in der sie aufgelistet sind. Die Suche ist abgeschlossen, wenn alle gewünschten Funktionen gefunden werden.
-Statisch Führt ein Layout mit nur statischen Bibliotheken aus. Siehe Kapitel 8.
-g, -ggdb. Enthält Debug-Informationen. Option -g Bewirkt, dass GCC Standard-Debug-Informationen ermöglicht. Die Option -GGDB gibt an, dass die Notwendigkeit aufgenommen werden muss große Zahl Informationen, die nur den GDB-Debugger verstehen können.
Wenn der Speicherplatz begrenzt ist, oder Sie möchten einige Funktionalität für die Layoutgeschwindigkeit opfern, verwenden Sie -g. In diesem Fall kann es erforderlich sein, einen anderen Debugger, nicht mit GDB, zu verwenden. Für das vollständigste Debugging müssen Sie -GGDB angeben. In diesem Fall bereiten GCC so viel wie möglich vor. genaue Information Für GDB. Es ist zu beachten, dass GCC im Gegensatz zu den meisten Compilern einige Debug-Informationen in einen optimierten Code legt. Die Verfolgung des Debuggers des optimierten Codes kann jedoch mit den Schwierigkeiten verbunden sein, da während der Ausführung, Sprünge und Überspringen von Codierfragmenten auftreten können, die erwartet werden sollen. Sie können jedoch bekommen gute Aussicht Informationen, wie die Optimierung von Compilern die Methode der Ausführung des Codes ändern.
-O, -o n Zwingt GCC, den Code zu optimieren. Standardmäßig führt GCC ein kleines Optimierungsvolumen aus. Bei der Angabe der Nummer (n) wird die Optimierung auf einem bestimmten Niveau durchgeführt. Das häufigste Optimierungsgrad ist 2; Derzeit ist in der Standardversion von GCC das höchste Optimierungsgrad 3. Wir empfehlen die Verwendung von -O2 oder -O3; -O3 kann die Größe der Anwendung erhöhen, also probieren Sie beide Optionen aus, wenn es wichtig ist. Wenn Ihre Anwendung wichtig ist und Speicherplatz für Ihre Anwendung ist, können Sie auch die Option -OS verwenden, wodurch die Größe des Codes minimal ist, indem die Ausführungszeit erhöht wird. GCC enthält nur integrierte Funktionen, wenn zumindest minimale Optimierung (-O) verwendet wird.
-ansi. Unterstützung in Programmen in Sprachen mit allen ANSI-Standards (X3.159-1989) oder deren äquivalente ISO (ISO / IEC 9899: 1990) (das übliche namens C89 oder Weniger C90). Es sei darauf hingewiesen, dass dies nicht vollständig dem ANSI / ISO-Standard entspricht.
Die Option -ENSI-Option deaktiviert GCC-Erweiterungen, die normalerweise mit ANSI / ISO-Standards konfrontiert sind. (Infolgedessen werden diese Erweiterungen von vielen anderen Compilern unterstützt, mit der in der Praxis kein Problem darin ist.) Es definiert auch das Makro __Strict_ANSI__ (wie später in diesem Buch beschrieben), welche Header-Dateien zur Unterstützung der Umwelt verwendet werden ANSI / ISO.
-Pedantisch Zeigt alle Warnungen und Fehlermeldungen an, die für den ANSI / ISO-Standard S erforderlich sind. Dies entspricht nicht vollständig dem ANSI / ISO-Standard.
-Wand Enthält die Erzeugung aller GCC-Warnungen, die normalerweise nützlich ist. Daher sind daher keine Optionen, die in bestimmten Fällen nützlich sein können, nicht enthalten. Für das LINT-Syntaktische Steuerungsprogramm für Ihren Quellcode wird ein ähnliches Maß an Details installiert, das GCC ermöglicht Ihnen, jede Compiler-Warnung manuell zu aktivieren und zu deaktivieren. Das GCC-Handbuch beschreibt alle Warnungen ausführlich.
5.2. Header-Dateien
5.2.1. Lang Lang.

Der lang lange Typ zeigt an, dass der Speicherblock mindestens so groß ist wie lange. Auf Intel I86 und anderen 32-Bit-Long-Plattformen dauert es 32 Bit, und lang lang ist 64 Bits. Auf 64-Bit-Plattformen, Zeigern und langer langen BETRIEB 64 Bits und Long können je nach Plattform 32 oder 64 Bits dauern. Typ Long Long wird in Standard C99 (ISO / IEC 9899: 1999) unterstützt und ist eine langjährige Erweiterung mit GCC.

5.2.2. Eingebaute Funktionen

In einigen Teilen von Linux Header-Dateien (insbesondere solche, die für ein bestimmtes System spezifisch sind), werden integrierte Funktionen sehr weit verbreitet. Sie sind auch schnell wie Makros (keine Kostenaufrufe) und bieten alle Arten von Kontrollen, die während des normalen Funktionsaufrufs verfügbar sind. Der Code, der die eingebetteten Funktionen verursacht, muss mindestens mit der Mindestoptimierung (-O) zusammengestellt werden.

5.2.3. Alternative erweiterte Schlüsselwörter.

Im GCC haben jedes erweiterte Schlüsselwort (Schlüsselwörter, die nicht vom ANSI / ISO-Standard beschrieben wurden) zwei Versionen: stichwort Und das Schlüsselwort von beiden Seiten um zwei Unterstrichzeichen umgeben. Wenn der Compiler im Standardmodus angewendet wird (in der Regel, wenn die Option -ensi involviert ist), werden normale verbesserte Schlüsselwörter nicht erkannt. So muss beispielsweise das Attribut-Schlüsselwort in der Header-Datei als __Attribute__ aufgezeichnet werden.

5.2.4. Attribute

Das Schlüsselwort "Erweitertes Attribut" wird verwendet, um GCC mehr Informationen über die Funktion, den variablen oder deklarierten Typ zu übertragen, als der C-Code ermöglicht, der dem ANSI / ISO-Standard entspricht. Das ausgerichtete Attribut gibt beispielsweise einen Hinweis auf den GCC auf genau, wie Sie die Variable oder den Typ ausrichten. Das gepackte Attribut zeigt an, dass die Füllung nicht verwendet wird. Noreturn definiert die Tatsache, dass die Rendite von der Funktion niemals passieren wird, was den GCC ermöglicht, fiktive Warnungen besser zu optimieren und zu vermeiden.

Die Attribute der Funktionen werden deklariert, indem sie zur Anzeigenfunktion hinzugefügt werden, zum Beispiel:

void the_die_die (int, char *) __attribute__ ((__Noreturn__));

Eine Attribut-Anzeige befindet sich zwischen Klammern und einem Semikolon und enthält das Attribut-Schlüsselwort, gefolgt von Attributen in doppelten runden Klammern. Wenn die Attribute viele sind, sollten Sie eine durch Kommas getrennte Liste verwenden.

int printm (char *, ...)

Attribut __ ((const,

format (Printf, 1, 2)));

In diesem Beispiel ist ersichtlich, dass druckm keine Werte in Betracht zieht, außer dem angegebenen, und verfügt über keine Nebenwirkungen im Zusammenhang mit der Codeerzeugung (const), druckt druckm an, dass der GCC die Funktionsargumente sowie das Printf überprüfen muss () Argumente. Das erste Argument ist eine Formatierungszeichenfolge und der zweite - der erste Ersatzparameter (Format).

Einige Attribute werden als eine weitere Präsentation des Materials angesehen (zum Beispiel während der Beschreibung der Montage der gemeinsam genutzten Bibliotheken in Kapitel 8). In der GCC-Dokumentation im Texinfo-Format finden Sie in der GCC-Dokumentation in der GCC-Dokumentation.

Von Zeit zu Zeit können Sie sich beim Anzeigen von Linux Header-Dateien fangen. Am wahrscheinlichsten finden Sie gute Designs, die nicht mit dem ANSI / ISO-Standard kompatibel sind. Einige von ihnen sind, um mit ihnen umzugehen. Alle in diesem Buch berücksichtigten Designs werden in der GCC-Dokumentation näher beschrieben.

Von Zeit zu Zeit können Sie sich beim Anzeigen von Linux Header-Dateien fangen. Am wahrscheinlichsten finden Sie gute Designs, die nicht mit dem ANSI / ISO-Standard kompatibel sind. Einige von ihnen sind, um mit ihnen umzugehen. Alle in diesem Buch berücksichtigten Designs werden in der GCC-Dokumentation näher beschrieben.

Nun, da Sie etwas über den Standard-C gelernt haben, schauen wir uns die Optionen an, die dem GCC-Compiler anbieten, um die Einhaltung des Sprachstandards zu gewährleisten, von dem Sie schreiben. Es gibt drei Möglichkeiten, dafür zu sorgen, dass Ihr Code auf C Standards erfüllt und keine Fehler enthält: Optionen, die die Version des Standards steuern, die Sie beabsichtigen, Definitionen, Definitionen, die die Header-Dateien steuern, und Warnungen, die mehr initiieren möchten strenger Scan des Programmcodes.

GCC hat eine riesige Reihe von Optionen, und hier werden wir nur diejenigen von ihnen berücksichtigen, die das Wichtigste betrachten. Die vollständige Liste der Optionen finden Sie auf den GCC Interactive Referenzhandbuchseiten. Wir werden auch kurz einige Optionen für die #Define-Richtlinie diskutieren, die angewendet werden kann; Normalerweise sollten sie in Ihrem Quellcode vor allen Zeichenfolgen mit der Richtlinie #include angegeben oder auf der Eingabeaufforderung der GCC-Befehlsfunktion festgelegt werden. Sie können einen solchen Fülsen an Optionen überraschen, um den angewendeten Standard anstelle einer einfachen Flagge auszuwählen, und zwingt die Verwendung eines modernen Standards. Der Grund ist, dass viele ältere Programme auf das historisch etablierte Verhalten des Compilers angewiesen sind und erhebliche Arbeiten benötigen, um sie gemäß den neuesten Standards zu aktualisieren. Selten, wenn überhaupt, dass Sie den Compiler jemals aktualisieren möchten, damit er den Arbeitsprogrammcode unterbrechen kann. Da sich die Standards ändern, ist es wichtig, in der Lage zu sein, im Gegensatz zu einem bestimmten Standard arbeiten zu können, auch wenn dies nicht die neueste Version des Standards ist.

Selbst wenn Sie ein kleines Programm zum persönlichen Gebrauch schreiben, wenn die Einhaltung von Standards nicht so wichtig ist, ist es oft sinnvoll, zusätzliche GCC-Warnungen zu ermöglichen, um den Compiler zu zwingen, den Compiler vor der Ausführung des Programms nach Fehlern in Ihrem Code zu suchen. Es ist immer effektiver, als den Code in Debugger und Perplex über den möglichen Ort auszuführen, der aus dem Problem ergibt. Der Compiler verfügt über viele Optionen, die nicht auf eine einfache Compliance-Prüfung beschränkt sind, beispielsweise die Fähigkeit, den Code zu erkennen, der den Standard erfüllt, kann jedoch zweifelhafte Semantik haben. Beispielsweise kann das Programm eine solche Ausführungsreihenfolge aufweisen, mit der Sie auf die Variable auf die Initialisierung zugreifen können.

Wenn Sie ein Programm zum kollektiven Gebrauch schreiben müssen, mit dem ausgewählten Einhaltung der Einhaltung der Standards und Arten von Compiler-Warnungen, die Sie ausreichend halten, ist es sehr wichtig, ein wenig mehr Anstrengungen zu verbringen und Ihren Code ohne Warnungen überhaupt zu kompilieren . Wenn Sie einige Warnungen zulassen und sich daran gewöhnen, sie zu ignorieren, kann ein Tag eine ernstere Warnung erscheint, dass Sie überspringen können. Wenn Ihr Programmcode ohne Warnmeldungen immer kompiliert ist, wird eine neue Warnung unweigerlich Ihre Aufmerksamkeit auf sich ziehen. Die Zusammenstellung des Programmcodes ohne Warnungen ist eine nützliche Angewohnheit, die Sie in Ordnung bringen müssen.

Vollständige Optionen für Standards für Standards

ANSI ist die wichtigste Option in Bezug auf Normen und zwingt den Compiler, gemäß dem ISO C90-Sprachstandard zu handeln. Es deaktiviert einige GCC-Erweiterungen, die nicht mit dem Standard kompatibel sind, deaktiviert in den Programmen in der Sprache mit den Kommentaren in der C ++ - Style (//) und enthält die Verarbeitung von Trigraphen (Drei-Symbolsequenzen) ANSI. Darüber hinaus enthält es das Makro __ strict_ansi__, das einige Erweiterungen in den Header-Dateien deaktiviert, die nicht mit dem Standard kompatibel sind. In den nachfolgenden Versionen des Compilers kann sich der angenommene Standard ändern.

STD \u003d - Diese Option bietet eine subtile Steuerung des verwendeten Standards, der einen Parameter bereitstellt, der den gewünschten Standard definiert. Folgendes sind mögliche Optionen:

C89 - Support C89 Standard;

ISO9899: 1999 - Warten Sie die neueste Version von ISO, C90 Standard;

GNU89 ist, den C89-Standard zu unterstützen, aber einige GNU-Erweiterungen und eine Funktionalität C99 zu lösen. In Version 4.2 GCC wird diese Option standardmäßig angewendet.

Optionen, um den Standard in Definieren von Richtlinien zu verfolgen

Es gibt Konstanten (#definin), die mit Optionen in der Befehlszeile oder in der Form von Definitionen im Quelltext des Programms eingestellt werden können. Normalerweise glauben wir, dass die Befehlszeichenfolge des Compilers für sie verwendet wird.

Strict_ansi__ - wenden Sie den Standard mit ISO an. Es wird bestimmt, wenn die Option -ensi in der Commimand-Linie des Compilers angegeben ist.

POSIX_C_SOURCE \u003d 2 - Aktiviert die von IEEE STD 1003.1 und 1003.2-Standards definierten Funktionen. Wir werden in diesem Kapitel wieder zu diesen Standards zurückkehren.

BSD_Source - enthält BSD-Systemfunktionalität. Wenn sie mit POSIX-Definitionen inkl. BSD-Definitionen haben eine höhere Priorität.

GNU_Source - ermöglicht eine Vielzahl von Eigenschaften und Funktionen, einschließlich GNU-Erweiterungen. Wenn diese Definitionen mit POSIX-Definitionen konflikt, ist die neueste Priorität.

Vollständige Optionen für Warnleistung

Diese Optionen werden an den Compiler von der Befehlszeile übertragen. Und wieder werden wir nur das main auflisten, volle Liste Kann im Online-GCC-Referenzhandbuch gefunden werden.

Pedantic - Dies ist die leistungsstärkste Option zum Überprüfen der Reinheit, der Softwarecode in S. Zusätzlich zum Integrieren der Kontrolloption für die Einhaltung der Norm c, deaktiviert sie einige der traditionellen Konstruktionen der C-Sprache, die vom Standard verboten ist, und macht alle GNU-Erweiterungen in Bezug auf den Standard. Diese Option sollte verwendet werden, um eine maximale Toleranz Ihres Codes auf C zu erreichen. Das Mangel ist darin, dass der Compiler sich sehr besorgt um die Reinheit Ihres Programmcodes, und manchmal müssen Sie den Kopf brechen, um mit mehreren verbleibenden Warnungen aufzuteilen .

WFORFAT - Überprüft die Richtigkeit der Funktionen der Funktionen der Druckfamilienfunktionen.

Warenthess - überprüft das Vorhandensein von Klammern, auch wenn sie nicht benötigt werden. Diese Option ist sehr nützlich, um zu überprüfen, ob komplexe Strukturen wie beabsichtigt initialisiert werden.

Wswitch-default - Überprüft die Verfügbarkeit der Standardoption in den Switch-Operatoren, die normalerweise als guter Programmierstil angesehen wird.

Wunused - Überprüft verschiedene Fälle, beispielsweise statische Funktionen, die angekündigt, jedoch nicht beschrieben, nicht verwendete, nicht verwendete Parameter, verworfene Ergebnisse.

Wand - beinhaltet die meisten Arten von GCC-Warnungen, einschließlich aller vorherigen Optionen - W (nicht nur nicht abgedeckt - geedantisch). Damit ist es einfach, die Sauberkeit des Programmcodes zu erreichen.

Hinweis

Es gibt immer noch eine Vielzahl von zusätzlichen Warnungenoptionen, siehe alle Details auf GCC-Webseiten. Wir empfehlen hauptsächlich Wende -Wall; Dies ist ein guter Kompromiss zwischen dem Test, der einen hohen Qualitätssoftwarecode bereitstellt, und die Notwendigkeit, mit einer Compiler-Masse von trivialen Warnungen auszugeben, dass es schwierig ist, auf Null zu reduzieren.

GCC ist Teil einer Verteilung Linux Und in der Regel ist standardmäßig eingestellt. Die GCC-Schnittstelle ist die Standardschnittstelle des Compilers auf der UNIX-Plattform, die am Ende der 60er Jahre, der Beginn der 70er Jahre des letzten Jahrhunderts, der Befehlszeilenschnittstelle, verwurzelt ist. Sie sollten sich in der vergangenen Zeit nicht fürchten, der Benutzerinteraktionsmechanismus wurde in diesem Fall der Perfektion geschlagen, und arbeiten mit GCC (wenn es mehrere zusätzliche Dienstprogramme gibt texteditor) Es ist einfacher als mit einem der modernen visuellen IDes. Die Autoren des Sets versuchten, den Kompilitätsprozess- und Anwendungsmontageprozess zu maximieren. Der Benutzer ruft das Managementprogramm auf gCC., interpretiert es die übertragenen Befehlszeilenargumente (Optionen und Dateinamen), und für jede Eingabedatei, entsprechend der verwendeten Programmiersprache, beginnt der Compiler, falls erforderlich, falls erforderlich, gCC. Autmbler und Linker (Linker) ruft automatisch an.

Neugierig, Compiler sind einige der wenigen Unix-Anwendungen, für die die Dateierweiterung nicht gleichgültig ist. Die GCC-Erweiterung ermittelt, was die Datei vor ihm und damit, dass Sie damit umgehen müssen, bestimmt. Quellcode-Dateien in der Sprache C. muss die Erweiterung .c in der Sprache haben C ++.als Option, .cpp, Header-Dateien in der Sprache C. .h, Objektdateien .o und so weiter. Wenn Sie eine falsche Erweiterung verwenden, gCC. Es funktioniert nicht ordnungsgemäß (wenn Sie etwas zustimmen, etwas zu tun).

Wenden wir uns an die Praxis. Wir trinken und erfüllen ein unkompliziertes Programm. Wir entstehen nicht als Quelldatei des Programms in der Sprache C. Koordinieren Sie die Datei mit diesem Inhalt:

/ * Hallo c * /

#Einschließen.

Main ( leere. )
{

Printf ("Hallo World \\ n");

rückkehr. 0 ;

Jetzt wird im Katalog Chello.c das Team geben:

$ Gcc hello.c.

Nach einigen mehr als einer Sekunde im Katalog erscheint eine Datei: OUT:

$ Ls.
a.out hello.c.

Dies ist die bereitste ausführbare Datei unseres Programms. Default gCC. weist den Ausgang ausführbarer Dateiname A.OUT (einmal langer Zeit, den dieser Name schon lange ausführbar handelt assembler-Ausgang.).

$ Datei a.out.
a.OUT: ELF 64-Bit LSB-ausführbarer, X86-64, Version 1 (SYSV), dynamisch verknüpft (Nutzung mit gemeinsam genutzten Libs), für GNU / Linux 2.6.15, nicht abgeschlossen

Beginnen wir das entstandene software:

$ ./a.out.
Hallo Welt


Warum im Startup-Befehl, um eine Datei aus dem aktuellen Verzeichnis auszuführen, müssen Sie den Pfad explizit an die Datei angeben? Wenn der Pfad zur ausführbaren Datei nicht angegeben ist, sucht die Shell, das Interpretieren des Befehls nach einer Datei in Verzeichnissen, die auf der Liste der Pfadsystemvariablen eingestellt ist.

$ Echo $ Pfad
Usr / local / bin: / sbin: / bin: / sbin: / bin: / usr / spiele

Die Kataloge in der Liste werden durch ein Darmsymbol getrennt. Bei der Suche nach Dateien sehen die Shell-Verzeichnisse in der Reihenfolge, in der sie in der Liste aufgeführt sind. Standardmäßig aus Sicherheitsgründen das aktuelle Verzeichnis. Die Liste ist nicht eingereicht, jeweils die ausführbaren Dateien der Shell-Dateien, in der sie suchen, nicht.

Warum wird es nicht empfohlen, es zu machen. Im Pfad? Es wird angenommen, dass es in einem echten Multiplayer-System immer eine Art schlechter Person gibt, die ein schädliches Programm in dem öffentlich zugänglichen Verzeichnis mit dem Namen der ausführbaren Datei poste, die mit dem Namen einiger Befehl zusammenfällt, oft vom lokalen Administrator verursacht wird Mit den Rechten der Superuser ... ist die Verschwörung möglich, wenn. Es ist zu Beginn der Liste der Verzeichnisse.


Nützlichkeit datei Zeigt Informationen zum Typ (aus Sicht des Systems) an, die in der Befehlsleiste übertragen werden, für einige Dateitypen, zusätzliche Informationen zum Inhalt der Datei.

$ File hello.c.
hello.c: ASCII C-Programmtext
$ Datei Anmerkung.doc.
anmerkung Bürowort, Gesamtbearbeitungszeit: 09:37:00, Zuletzt gedruckt: THU 22 07:31:00 2009, Zeit / Datum erstellen: Mo Jan 12 07:36:00 2009, Zuletzt gespeichert Zeit / Datum: THU 22. Januar 07:34:00 2009, Anzahl der Seiten: 1, Anzahl der Wörter: 3094, Anzahl der Zeichen: 17637, Sicherheit: 0

Das ist eigentlich alles, was vom Benutzer zur erfolgreichen Verwendung erforderlich ist gCC. :)

Der Name der ausführbaren Ausgabedatei (sowie jede andere Datei, die gebildet werden gCC.) kann mit geändert werden optionen -o.:

$ Gcc -o hallo hallo.c
$ Ls.
hallo hallo.c.
$ ./Hello.
Hallo Welt


In unserem Beispiel kehrt die Haupt- () -Funktion zu jedem zurück, nicht den gewünschten Wert von 0. In unix-ähnlichen Systemen, nach Abschluss des Programms, ist es üblich, eine ganze Zahl an die Befehlsschale zurückzugeben - bei erfolgreicher Abschluss von Null, sonstiger anderer. Der Shell-Interpreter weist den Wert der Umgebungsvariablen automatisch zu. . Sie können den Inhalt mit dem Befehl Echo $ anzeigen? :

$ ./Hello.
Hallo Welt
$ ECHO $?
0

Darüber wurde das gesagt, dass gCC. Dies ist ein Managementprogramm, das den Compilationsprozess automatisieren soll. Mal sehen, was tatsächlich als Ergebnis der Ausführung des GCC HELLO.C-Befehls passiert.

Der Kompilierungsvorgang kann in 4 Hauptstufen unterteilt werden: Verarbeitungsprozessor, eigentlich Kompilierung, Montage, Verknüpfung (Bindung).

Optionen gCC. Erlauben Sie Ihnen, den Prozess auf einem dieser Stufen zu unterbrechen.

Der Präprozessor bereitet die Quelldatei auf Compile-Cuts-Kommentare vor, fügt den Inhalt der Header-Dateien (#include-Preprocessor-Richtlinie) hinzu, setzt die Offenbarung von Makro (symbolische Konstanten, der #Define-Präprozessorrichtlinie) um.

Benutzt option -e. Weitere Maßnahmen gCC. Sie können den Inhalt der Vorverarbeitungsdatei unterbrechen und anzeigen.

$ Gcc -e -o hello.i hallo.c
$ Ls.
hallo.c hallo.i.
$ Weniger hello.i.
. . .
# 1 "/usr/include/stdiO.h" 1 3 4
# 28 "/usr/include/stdiO.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
. . .
typedef unsigniert char __u_kar;
typedef unsigniert kurz int __u_short;
typedef unsigniert int __u_int;
. . .
externe int printf (__const char * __ einschränken __Format, ...);
. . .
# 4 "Hello.c" 2
main (leer)
{
Printf ("Hallo World \\ n");
Rückgabe 0;
}

Nach der Bearbeitung des Präprozessors ergibt sich der Quelltext unseres Programms und erwarb ein nicht lesbarer Erscheinungsbild. Der Code, den wir einmal persönlich persönlich mit einer Mehrfachlinie am Ende der Datei schwankten. Ursache - Anschließen der Standardbibliotheks-Header-Datei C.. Die Header-Datei stdio.h selbst enthält viele verschiedene Zeiten und erfordert die Einbeziehung anderer Header-Dateien.

Achten Sie auf die Erweiterung der Hello.i-Datei. Von Vereinbarungen. gCC. Erweiterung .i entspricht den Quelldateien in der Sprache C. Erfordert keine Verarbeitung von Vorprozessor. Solche Dateien werden durch Übergeben von Preprocessor zusammengestellt:

$ Gcc -o hallo hallo.i
$ Ls.
hallo hallo.c hallo.i.
$ ./Hello.
Hallo Welt

Nach der Vorverarbeitung kommt eine Kompilierungswarteschlange. Der Compiler wandelt den Quelltext des High-Level-Programms in den Code in der Assembler-Sprache um.

Der Wert der Wortkompilierung ist verschwommen. Wikipedistiken, zum Beispiel in Betracht ziehen internationale StandardsDiese Zusammenstellung ist "Transformation des Quelltext-Compilers durch ein beliebiges Programm, das in einer hochrangigen Programmiersprache in einer Zunge in der Nähe der Maschine oder an den Objektcode geschrieben wurde. Diese Definition ist grundsätzlich für uns geeignet, die Assembler-Sprache ist wirklich näher an der Maschine als C.. Im Alltag, aber im Alltag unter der Kompilierung, versteht man meistens eine beliebige Operation, die den Quellcode des Programms in jede Programmiersprache in den ausführbaren Code konvertiert. Das heißt, ein Prozess, der alle vier Noten enthält, kann die Bühne auch als Zusammenstellung bezeichnet werden. Ähnliche Zweideutigkeit ist in diesem Text vorhanden. Andererseits kann der Betrieb des Umwandelns des Quelltextes des Programms in den Code in der Assemblersprache mit der Wortrutsche - "Die Programmtransformation, die in einer der Programmiersprachen in das Programm in einer anderen Sprache dargestellt ist, und in gewissem Sinne entspricht dem ersten.

Stoppen Sie den Prozess zum Erstellen einer ausführbaren Datei nach Abschluss der Kompilierung erlaubt optionen.:

$ Gcc -s hello.c
$ Ls.
hallo.c hallo.s.
$ File hello.s.
hallo.s: ASCII Assembler-Programmtext
$ Weniger hallo.s.
.file "hello.c"
.Steile .Rodata.
.Lc0:
.string "Hallo Welt"
.Text.
.globl Main.
.Type Main, @function
main:
PUSHL% EBP.
MOVL% ESP,% EBP
ANDL $ -16,% ESP
SUBL $ 16,% ESP
MOVL $ .lc0 (% ESP)
Rufen Sie Puts an.
MOVL $ 0,% EAX
Leve.
Ret.
.Sische Main ,.- Haupt


Das Verzeichnis erschien die Hello.s-Datei mit der Implementierung des Assembler-Programms. HINWEIS, Setzen Sie den Namen der Ausgabedatei mit optionen -o. In diesem Fall brauchte es nicht gCC. Es wurde automatisch erzeugt, indem die .c-Erweiterung im Namen der Quelldatei ersetzt wurde. Für die meisten großen Operationen gCC. Der Name der Ausgabedatei wird durch einen ähnlichen Ersatz gebildet. Die Erweiterung. S-Standard für Quelldateien in der Assembler-Sprache.

Sie können den ausführbaren Code natürlich von der Hello.S-Datei abrufen:

$ Gcc -o hallo hallo.s
$ Ls.
hallo hallo.c hallo.s.
$ ./Hello.
Hallo Welt

Die nächste Phase des Annahmebetriebs ist der Übertragungscode in der Assembler-Sprache in den Maschinencode. Das Ergebnis der Operation ist die Objektdatei. Die Objektdatei enthält Blöcke des Maschinencodes, der Datenblöcke und eine Liste der in der Funktion und externen Variablen definierten Funktionen ( tabelle der Symbole. ), aber die absoluten Adressen von Verweisen auf Funktionen und Daten werden nicht darin angegeben. Die Objektdatei kann nicht direkt gestartet werden, später (während des Links) kann jedoch mit anderen Objektdateien kombiniert werden (gleichzeitig gemäß den Zeichentabellen werden die Adressen vorhandener Querverbindungen zwischen den Dateien) berechnet und ausgefüllt. Möglichkeit gCC. -c, stoppt den Prozess nach Abschluss der Montagephase:

$ Gcc -c hello.c
$ Ls.
hallo.c hallo.o.
$ File hello.o.
hallo.o: elf 64-bit lsb relokatable, x86-64, Version 1 (SYSV), nicht abgestreift

Für Objektdateien wird eine Standarderweiterung angenommen .O.

Wenn die erhaltene Objektdatei HELLO.O an den Link übertragen wird, berechnet Letztere die Linkadressen, fügen Sie den Startcode und den Fertigstellungscode hinzu, der Code der Aufruf von Bibliotheksfunktionen, und infolgedessen verfügen wir über eine einwandfreie ausführbare Programmdatei .

$ Gcc -o hallo hallo.o
$ Ls.
hallo hallo.c hallo.o.
$ ./Hello.
Hallo Welt

Was wir jetzt gemacht haben (oder eher gCC. Ich habe für uns getan) und es gibt den Inhalt der letzten Phase - Links (Bindung, Layouts).

Nun, wahrscheinlich um Kompilierung und das ist es. Nun berühren wir nun einige, meiner Meinung nach wichtig, Optionen gCC..

Option -I. pfad / K / Katalog / C / Header / Dateien - Fügt das angegebene Verzeichnis der Liste der Überschrift-Dateisuchpfade hinzu. Katalog nach Option hinzugefügt -ICH. Es wird zuerst angezeigt, dann wird die Suche in Standardverzeichnissen fortgesetzt. Wenn Optionen -ICH. Die von ihnen angegebenen Verzeichnisse werden links von rechts angezeigt, da Optionen angezeigt werden.

Option -wall. - Zeigt Warnungen an, die durch potenzielle Fehler in dem Code verursacht werden, der die Zusammenstellung des Programms nicht verhindert, sondern kann nach Ansicht des Compilers zu einem oder anderen Problemen in seiner Hinrichtung führen können. Wichtige und nützliche Option, Entwickler gCC. Empfohlen, um es immer zu verwenden. Zum Beispiel werden beim Versuch, diese Datei zu kompilieren, viele Warnungen ausgestellt:

1 / * Bemerkung.c * /
2
3 statisch. int. k \u003d 0;
4 statisch. int. L ( int. ein);
5
6 Haupt- ()
7 {
8
9 int. ein;
10
11 int. b, c;
12
13 B + 1;
14
15 b \u003d c;
16
17 int. * p;
18
19 b \u003d * p;
20
21 }


$ Gcc -o Bemerkung Bemerkung.c
$ Gcc -wall -o Bemerkung Bemerkung.c
bemerkung

bemerkung.c: 13: WARNUNG: Anweisung ohne Effekt
bemerkung.c: 9: Warnung: Nicht verwendete Variable 'A'
bemerkung.c: 21: WARNUNG: Die Steuerung erreicht das Ende der nicht-leeren Funktion
bemerkung.c: Auf der obersten Ebene:
bemerkung.c: 3: Warnung: 'k' definiert, aber nicht verwendet
bemerkung.c: 4: Warnung: 'l' erklärt 'statisch', aber nie definiert
bemerkung.c: In der Funktion 'Main':
bemerkung.c: 15: WARNUNG: 'C' wird in dieser Funktion unwichtig verwendet
bemerkung.c: 19: WARNUNG: 'P' wird in dieser Funktion unwichtig verwendet

Option -Werror. - Wechselt alle Warnungen in Fehlern. Wenn eine Warnung angezeigt wird, unterbricht er den Kompilierungsvorgang. Gemeinsam von S. verwendet wird option -wall..

$ gCC-WEHRROR -O BEMERKUNG BEMERK.C
$ gCC-WERRROR -WALL -O BEMERK BEMERK.C
cC1: Warnungen, die als Fehler behandelt werden
bemerkung.c: 7: Fehler: Return Type Standards to 'Int'
bemerkung.c: In der Funktion 'Main':
bemerkung.c: 13: Fehler: Anweisung ohne Effekt
bemerkung.c: 9: Fehler: Nicht verwendete Variable 'A'

Option -g. - Plätze in der Objekt- oder ausführbaren Datei Die Informationen, die für den Betrieb des Debuggers erforderlich sind gDB.. Beim Montieren eines Projekts zum Zwecke des anschließenden Debuggings option -g. Es ist notwendig, sowohl auf die Kompilierungsstufe und in die Layoutstufe aufzunehmen.

Optionen -O1, -O2, -O3 - Legen Sie das Optimierungsgrad des vom Compiler generierten Codes fest. Mit zunehmender Anzahl steigt der Optimierungsgrad an. Optionen sind in diesem Beispiel zu sehen.

Originaldatei:

/ * Circle.c * /

Main ( leere. )
{

int. ICH;

zum (i \u003d 0; ich< 10 ; ++i)
;

rückkehr. ICH;

Complploition mit Standardoptimierungsebene:

$ Gcc -s circle.c
$ Weniger Circle.S.
.file "circle.c"
.Text.
.globl Main.
.Type Main, @function
main:
PUSHL% EBP.
MOVL% ESP,% EBP
SUBL $ 16,% ESP
MOVL $ 0, -4 (% EBP)
Jmp .l2.
.L3:
Addl $ 1, -4 (% EBP)
.L2:
CMPL $ 9, -4 (% EBP)
Jle .l3.
MOVL -4 (% EBP),% EAX
Leve.
Ret.
.Sische Main ,.- Haupt
IdentIdent "GCC: (Ubuntu 4.4.3-4UBUNTU5) 4.4.3"
.section .note.gnu-stack, "", @ progbits

Kompilierung mit dem maximalen Optimierungsstufen:

$ Gcc -s -o3 circle.c
$ Weniger Circle.S.
.file "circle.c"
.Text.
.p2Arign 4,15.
.globl Main.
.Type Main, @function
main:
PUSHL% EBP.
MOVL $ 10,% EAX
MOVL% ESP,% EBP
POPL% EBP.
Ret.
.Sische Main ,.- Haupt
IdentIdent "GCC: (Ubuntu 4.4.3-4UBUNTU5) 4.4.3"
.section .note.gnu-stack, "", @ progbits

Im zweiten Fall gibt es sogar einen Hauch von jedem Zyklus im empfangenen Code. In der Tat kann der Wert, den ich an der Kompilierungsstufe berechnete, berechnet werden kann.

Alas, für echte Projekte, der Leistungsunterschied auf verschiedenen Optimierungsstufen ist praktisch nicht wahrnehmbar ...

Option -O0. - storniert jede Codeoptimierung. Die Option ist bei der Fixierungsphase der Anwendung erforderlich. Wie oben gezeigt, kann die Optimierung zu einer Änderung der Struktur des Programms über die Erkennung hinaus führen, wobei die Verbindung zwischen dem ausführbaren und dem Quellcode nicht explizit ist, jeweils nicht explizit ist, dass das STEP-by-Schritt-Debugging des Programms nicht möglich ist. Wenn Sie die Option aktivieren -G.Es wird empfohlen, einzuschließen und -O0..

Option -OS. - Gibt die Optimierung an, nicht durch die Effizienz des Codes, sondern mit der Größe der resultierenden Datei. Die Programmleistung sollte vergleichbar sein, mit der Leistung des Code, der beim Kompilieren mit dem standardmäßigen Optimierungsstufen ermittelt wird.

-March \u003d Architekturoption - Gibt die Zielprozessorarchitektur an. Die Liste der unterstützten Architekturen ist beispielsweise für Familienprozessoren umfangreich Intel / AMD. Du kannst Fragen i386., pentium., prescott., opteron-sse3. usw. Benutzer von binären Ausschüttungen müssen bedenken, dass für den korrekten Betrieb der Programme mit der angegebenen Option wünschenswert ist, dass alle angeschlossenen Bibliotheken mit derselben Option zusammengestellt werden.

Die Optionen der übertragenen Lincher werden unten gesagt.

Eine kleine Ergänzung:

Darüber wurde das gesagt, dass gCC. Bestimmt den Typ (Programmiersprache) der übertragenen Dateien nach der Erweiterung und führt entsprechend dem kräftigen Typ (Sprache) durch, um Aktionen auf ihnen auszuführen. Der Benutzer ist verpflichtet, die Erweiterungen der erstellten Dateien zu folgen, indem Sie sie auswählen, ob die Vereinbarung erfordert gCC.. In der Wirklichkeit gCC. Sie können Dateien mit beliebigen Namen rutschen. GCC -X Option. Ermöglicht das, dass Sie die Programmiersprache kompilierter Dateien explizit angeben. Die Optionen-Option gilt für alle nachfolgenden Dateien, die im Befehl aufgeführt sind (bis die folgende Option erscheint. -X.). Mögliche Argumente Optionen:

c C-Header C-CPP-Ausgang

c ++ C ++ - Header C ++ - CPP-Ausgang

objektive-C Objektive-C-Header Objektive-C-CPP-Ausgang

objektiv-C ++ Objektive-C ++ - Header-Objektive-C ++ - CPP-Ausgang

assembler Assembler-with-cpp

ada.

f77 F77-CPP-INPUT

f95 F95-CPP-INPUT

java.

Der Zweck der Argumente sollte von ihrem Schreiben klar sein (hier cpper hat keine Beziehung zu C ++.Dies ist die Quellcodedatei, die zuvor vom Präprozessor verarbeitet wurde). Prüfen:

$ Mv hello.c hello.txt
$ gCC -Wall -x C -O Hallo Hello.txt
$ ./Hello.
Hallo Welt

Separate Zusammenstellung

Die Stärke der Sprachen C / C ++ Ist die Möglichkeit, den Quellcode des Programms in mehreren Dateien freizugeben. Selbst Sie können mehr sagen - die Möglichkeit einer separaten Zusammenstellung ist die Grundlage der Sprache, ohne dass sie effektive Nutzung. C. Nicht denkbar Multifile-Programmierung ermöglicht das Implementieren von C. große Projekte, wie z Linux (hier unter dem Wort Linux Es wird als Kernel und das System als Ganzes verstanden). Was gibt ein separates Kompilieren des Programmierers?

1. Ermöglicht es Ihnen, den Programmcode (Projekt) lelesierender zu gestalten. Die Quelldatei für mehrere Dutzend-Bildschirme wird praktisch Awkhan von. Wenn, entsprechend einer bestimmten (vordurchlässigen) Logik, in eine Anzahl kleiner Fragmente (jeweils in einer separaten Datei) aufteilen, ist es viel einfacher, mit der Komplexität des Projekts fertig zu werden.

2. Ermöglicht das Reduzieren der Zeit des Re-Compility-Projekts. Wenn die Änderungen an einer Datei vorgenommen werden, ist es nicht sinnvoll, das gesamte Projekt neu zu kompilieren, es reicht aus, um nur diese geänderte Datei zusammenzustellen.

3. Ermöglicht das Verteilen von Arbeiten an einem Projekt zwischen mehreren Entwicklern. Jeder Programmierer erstellt und debuggt seinen Teil des Projekts, aber jederzeit ist es möglich, alle daraus resultierenden Entwicklungen im Endprodukt zu sammeln (wieder aufbauen).

4. Ohne eine separate Erstellung würden keine Bibliotheken vorhanden sein. Durch Bibliotheken, Wiederverwendung und Vertrieb von Code auf C / C ++Darüber hinaus ist der Binärcode, der es den Entwicklern ermöglicht, Entwicklern den Entwicklern einen einfachen Mechanismus zum Einarbeiten in ihre Programme zur Verfügung zu stellen, dagegen, bestimmte Verkaufsdetails von ihnen zu verbergen. Arbeiten an dem Projekt, immer einen Blick darauf wert, darüber nachzudenken, und brauche nichts von den bereits getanen in der Zukunft? Vielleicht ist es notwendig, im Voraus zu markieren und einen Teil des Codes als Bibliothek zu arrangieren? Meiner Meinung nach vereinfacht ein solcher Ansatz das Leben erheblich und rettet eine Masse der Zeit.

GCC.Natürlich behält es eine gesonderte Zusammenstellung und erfordert keine speziellen Anweisungen vom Benutzer. Im Allgemeinen ist alles sehr einfach.

Hier ist ein praktisches Beispiel (die Wahrheit ist sehr und sehr bedingt).

Satz von Quellcode-Dateien:

/ * Haupt c * /

#Einschließen.

#Include "First.h"
#Include "second.h"

int. Main ( leere. )
{

Zuerst ();
Zweite ();

Printf ("Hauptfunktion ... \\ n");

rückkehr. 0 ;


/ * First.h * /

leere. zuerst ( leere. );


/ * First.c * /

#Einschließen.

#Include "First.h"

leere. zuerst ( leere. )
{

Printf ("erste Funktion ... \\ n");


/ * Second.h * /

leere. Zweite ( leere. );


/ * Second.c * /

#Einschließen.

#Include "second.h"

leere. Zweite ( leere. )
{

Printf ("zweite Funktion ... \\ n");

Im Allgemeinen haben wir das:

$ Ls.
erster.c sed.h main.h zweiters.c zweiters

Diese gesamte Wirtschaft kann in einem Befehl kompiliert werden:

$ gCC -Wall -o Main Main.c First.c zweiter.c
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Nur dies gibt uns nicht praktisch keine Boni, nun, mit Ausnahme eines strukturierten und lesbaren Codes, der durch mehrere Dateien geteilt wird. Alle oben aufgeführten Vorteile werden bei einem solchen Kompilationsansatz angezeigt:

$ gcc -wall -c main.c
$ gcc -wall -c First.c
$ Gcc -wall -c second.c
$ Ls.
first.c First.h First.o Main.c Main.o zweiters.c zweiters.h zweiter.o
$ gCC -O Main Main.o First.o second.o
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Was haben wir getan? Aus jeder Quelldatei (kompilieren mit der Option -c.) Eine Objektdatei erhalten. Dann sind die Objektdateien mit der endgültigen ausführbaren Datei verknüpft. Na sicher gCC. Es wurde mehr, aber im Handbuch sammelt niemand die Projekte, denn es gibt Dienstprogramme für Sammler (am beliebtesten machen). Bei Verwendung der Sammler-Dienstprogramme und der gesamte Vorteil einer separaten Kompilierung wird gezeigt.

Frage Es gibt eine Frage: Wie kollet der Linker die Objektdateien zusammen, um zusammen zu sammeln, was die Adressierung von Anrufen korrekt berechnet? Wo er lernt, dass in der zweiten Datei den Codecode-Code () und im Hauptdateicode enthält, der seine Herausforderung darstellt? Es stellt sich heraus, dass alles einfach ist - das sogenannte Objekt ist in der Objektdatei vorhanden. symboltisch Dazu gehören die Namen einiger Codepositionen (Funktionen und externe Variablen). Der Linker bringt die Tabelle der Zeichen der einzelnen Objektdatei aus, sucht nach üblicher Position (mit übereinstimmenden Namen), basierend auf dem, was die Ausgänge zum tatsächlichen Speicherort des verwendeten Codes (oder Datenblöcke) herstellt, und dementsprechend die Anrufadressen in der neu berechnen ausführbare Datei.

Sie können die Symboltabelle mit dem Dienstprogramm anzeigen nm..

$ Nm main.o.
Du zuerst
00000000 t Main.
Du setzt.
U Zweiter
$ nm First.o.
00000000 t zuerst.
Du setzt.
$ Nm zweiter.o.
Du setzt.
00000000 T

Das Erscheinungsbild der Anrufnähte wird durch die Verwendung der Funktion der Standard-DRUMMING () -Bibliothek erläutert, die in der Kompilierungsstufe in Puts () umgewandelt wurde.

Die Charaktertabelle wird nicht nur im Objekt verschrieben, sondern auch in der ausführbaren Datei:

$ Nm Main.
08049F20 d _dynamic.
08049FF4 d _global_offset_table_
080484FC R _IO_STDIN_SEDEED.
W _jv_registerClasses.
08049f10 d __ctor_end__
08049f0c d __ctor_list__
08049F18 d __dtor_end__
08049F14 d __dtor_list__
08048538 R __Frame_end__
08049f1c d __jcr_end__
08049f1c d __jcr_list__
0804A014 A __BSS_START.
0804A00C D __DATA_START
080484B0 T __do_global_ctors_aux.
08048360 t __do_global_dtors_aux.
0804A010 d __dso_handle.
w __gmon_start__
080484AA t __i686.get_pc_thunk.bx.
08049f0c d __Init_array_end.
08049f0c d __Init_array_start.
08048440 t __LIBC_CSU_FINI.
08048450 t __libc_csu_init.
U. [E-Mail geschützt]@ Glibc_2.0.
0804A014 A _EDATA.
0804A01C A _end.
080484DC T _FINI.
080484f8 r _fp_hw.
080482B8 t _init.
08048330 t _start.
0804A014 B abgeschlossen.7021.
0804A00C W Data_start.
0804A018 B DTOR_IDX.7023.
0804840c t zuerst.
080483c0 t frame_dummy.
080483E4 t Main.
U. [E-Mail geschützt]@ Glibc_2.0.
08048420 T.

Um die Tabelle der Zeichen in der ausführbaren Datei zu ermöglichen, ist insbesondere erforderlich, um das Debugging zu vereinfachen. Grundsätzlich ist es nicht sehr notwendig, einen Antrag auszuführen. Für ausführbare Dateien von realen Programmen, mit vielen Definitionen von Funktionen und externen Variablen, mit einem Bündel unterschiedlicher Bibliotheken, wird die Charaktertabelle sehr umfangreich. Um die Größe der Ausgabedatei zu reduzieren, können Sie sie verwenden gCC-SO Option..

$ gCC-SO Main Main.o First.o zweitert.o
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...
$ Nm Main.
nm: Main: Keine Symbole

Es sei darauf hingewiesen, dass während der Anordnung die Linie keine Überprüfungen des Kontextes der Funktion der Funktion der Funktion vornimmt, es überwacht nicht den Typ des Rückgabewerts noch über den Typ und die Anzahl der empfangenen Parameter (ja er bekommt solche Informationen nicht). Alle Challenge-Checks müssen an der Kompilierungsstufe vorgenommen werden. Im Falle einer Multi-Fail-Programmierung müssen Sie den Header-Datei-Header-Mechanismus verwenden C..

Bibliotheken

Bibliothek - in der Sprache C.Die Datei, die den Objektcode enthält, der mit der Bibliothek mit der Bibliothek an der Verbindungsstufe an das Programm angehängt werden kann. In der Tat ist die Bibliothek ein Satz speziell konsultierter Objektdateien.

Bibliothekszuordnung - Stellen Sie einen Programmierer-Standardcode-Wiederverwendungsmechanismus bereit, und der Mechanismus ist einfach und zuverlässig.

Aus Sicht des Betriebssystems und der angewandten Software ist die Bibliothek vorhanden statisch und geteilt (dynamisch ).

Der statische Bibliothekscode ist während der letztgenannten Verbindung in der ausführbaren Datei enthalten. Die Bibliothek erweist sich als "genäht" in der Datei, der Bibliothekscode "Verschmelzt" mit dem Rest des Dateicodes. Das Programm, das statische Bibliotheken verwendet, wird autonom und kann mit einem geeigneten Architektur und einem Betriebssystem fast auf jedem Computer ausgeführt werden.

Der Code der freigegebenen Bibliothek wird vom Betriebssystem auf Anfrage des Programms während der Ausführung geladen und mit dem Programmcode verbunden und verbunden. Die ausführbare Datei des Programmcodes der dynamischen Bibliothek ist nicht inbegriffen, nur ein Link zur Bibliothek schaltet sich die ausführbare Datei ein. Das Programm, das die freigegebenen Bibliotheken mithilfe der freigegebenen Bibliotheken verwenden, ist nicht so konsequent und kann erfolgreich nur im System ausgeführt werden, in dem die beteiligten Bibliotheken installiert sind.

Das Paradigma der gemeinsam genutzten Bibliotheken bietet drei erhebliche Vorteile:

1. Die Größe der ausführbaren Datei reduziert wiederholt. In einem System, einschließlich einer Vielzahl von Binärdateien mit demselben Code, verschwindet es, dass eine Kopie dieses Codes für jede ausführbare Datei gespeichert werden muss.

2. Der Code der freigegebenen Bibliothek, die von mehreren Anwendungen verwendet wird, wird in einer Kopie in einem RAM gespeichert (in der Tat nicht alles ist so einfach ist ...) Infolgedessen wird das Bedürfnis des Systems im verfügbaren RAM reduziert.

3. Es ist nicht erforderlich, jede ausführbare Datei bei Änderungen an der Code der gemeinsamen Bibliothek für sie neu zusammenzubauen. Änderungen und Korrekturen des dynamischen Bibliothekscodes beeinflussen automatisch jedes der Programme, die sie verwenden.

Ohne Paradigma von freigegebenen Bibliotheken würde es keine vorkompollen (binären) Distributionen geben Linux (Ja, niemand gab es). Bereiten Sie die Verteilungsabmessungen in jeder Binärdatei vor, deren Standard-Bibliothekscode platziert wird. C. (und alle anderen verbundenen Bibliotheken). Stellen Sie sich auch vor, dass ich tun müsste, um das System zu aktualisieren, nachdem Sie die kritische Anfälligkeit in einem der weit verbreiteten Bibliotheken beseitigen ...

Jetzt eine kleine Praxis.

Um zu veranschaulichen, verwenden Sie den Satz von Quelldateien aus dem vorherigen Beispiel. In unserer hausgemachten Bibliothek werde ich den Code (Implementierung) der ersten () und zweiten () -Funktionen eingeben.

In Linux wird die folgende Bibliotheksdatei-Namensschema angenommen (obwohl es nicht immer eingehalten wird) - der Bibliotheksdateiname beginnt mit der Bibliothek der Bibliothek, folgt dem Namen der Bibliothek, an der Endverlängerung .a ( archiv. ) - Für eine statische Bibliothek, .so ( gemeinsames Objekt. ) - Für die gemeinsam genutzte (dynamische), nach der Erweiterung werden die Zahlennummern über den Punkt aufgeführt (nur für die dynamische Bibliothek). Der der Header-Dateibibliothek entspricht der Header-Datei (in der Regel) besteht aus dem Bibliotheksnamen (ohne Präfix und Version) und der Erweiterung .H. Zum Beispiel: libogg.a, libogg.so.0.7.0, ogg.h.

Am Anfang werden wir die statische Bibliothek erstellen und verwenden.

Die ersten () und zweiten () -Funktionen machen den Inhalt unserer Bibello-Bibliothek in Inhalte. Der Name der Bibliotheksdatei bzw. wird libello.a sein. Die Bibliothek ist vergleichbar mit der Header-Datei von Hello.h.

/ * Hallo h * /

leere. zuerst ( leere. );
leere. Zweite ( leere. );

Natürlich: Saiten:

#Include "First.h"


#Include "second.h"

in den Dateien von main.c müssen First.c und second.c ersetzt werden durch:

#Include "Hallo.h"

Stellen Sie nun die folgende Reihenfolge der Befehle ein:

$ gcc -wall -c First.c
$ Gcc -wall -c second.c
$ aR CRS LIBBELLO.A First.o zweitert.o
$ File lib bhello.a.
libbello.a: Aktuelles AR-Archiv

Wie bereits erwähnt, ist die Bibliothek ein Satz von Objektdateien. Die ersten beiden Befehle haben wir diese Objektdateien erstellt.

Als Nächstes werden Objektdateien benötigt, um das Set einzuhalten. Dies verwendet Archiver. ar. - Die Dienstprogramm "Klebstoffe" Mehrere Dateien zu einem, im resultierenden Archiv umfasst die zur Wiederherstellung (Extraktion) jeder einzelnen Datei erforderlichen Informationen (einschließlich der Attribute Zubehör, Zugriff, Time). Es wird keine "Komprimierung" des Inhalts des Archivs oder der anderen Konvertierung gespeicherter Daten nicht durchgeführt.

Option C Arname. - Erstellen Sie ein Archiv, wenn das Archiv namens Arname nicht vorhanden ist, erstellt er erstellt, andernfalls werden die Dateien dem vorhandenen Archiv hinzugefügt.

R. - Gibt den Archiv-Update-Modus an, wenn die Datei mit dem angegebenen Namen bereits im Archiv vorhanden ist, er wird gelöscht, und die neue Datei ist am Ende des Archivs abgeschlossen.

Optionen. - fügt den Archivindex hinzu (Updates). In diesem Fall ist der Archivindex eine Tabelle, in der für jeden symbolischen Namen, der in den archivierten Dateien definiert ist (Funktionsname oder Block), der dem entsprechenden Namen der Objektdatei zugeordnet ist. Der Archivindex ist notwendig, um die Arbeit mit der Bibliothek zu beschleunigen. Um die gewünschte Definition zu finden, müssen Sie die Zeichentabellen aller Archivdateien nicht anzeigen müssen, Sie können sofort in die Datei gehen, die den gewünschten Namen enthält. Sie können den Archivindex mit einem bekannten Dienstprogramm anzeigen nm. Davon nutzen optionen. (Symbole aller Archivobjektdateien werden ebenfalls angezeigt):

$ nm -s libbello.a
Archivindex:
zuerst in erster.o.
zweitens in zweiter Stelle.

erst.o:
00000000 t zuerst.
Du setzt.

zweiters.o:
Du setzt.
00000000 T

Um einen Archivindex zu erstellen, gibt es ein spezielles Dienstprogramm ranlib.. Libbello.a-Bibliothek könnte wie folgt erstellt werden:

$ aR CR LIBHELLO.A First.o zweitert.o
$ Ranlib Libbello.a.

Die Bibliothek funktioniert jedoch perfekt und ohne Archivindex.

Jetzt verwenden wir unsere Bibliothek:

$ gcc -wall -c main.c
$
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Arbeitet ...

Nun, jetzt Kommentare ... Es gibt zwei neue Optionen. gCC.:

Option -l Name. - Es wird ein Link übertragen, weist darauf hin, dass die Libname-Bibliothek an die ausführbare Datei angeschlossen werden muss. Verbindungsmittel, um anzugeben, dass solche Funktionen (externe Variablen) in einer solchen Bibliothek definiert sind. In unserem Beispiel beziehen sich die statische Bibliothek, alle Zeichennamen auf den Code, der sich direkt in der ausführbaren Datei befindet. Notizoptionen -L. Der Name der Bibliothek wird ohne die LIB-Konsole als Namen festgelegt.

Option -l.l. / Pfad / K / Katalog / mit / Bibliotheken - Die Linie wird übertragen, zeigt den Pfad in das Verzeichnis, das angeschlossene Bibliotheken enthält. In unserem Fall ist der Punkt eingestellt . Der Linker sucht zunächst nach den Bibliotheken im aktuellen Verzeichnis und dann in den im System definierten Verzeichnisse.

Hier müssen Sie eine kleine Bemerkung machen. Tatsache ist das für eine Reihe von Optionen gCC. Die Prozedur für den Anschluss an der Befehlszeile ist wichtig. Daher sucht der Linker nach einem Code, der dem in den Tabellennamen in den auf der Befehlszeile aufgeführten Bibliotheken angegeben ist nach dem Dieser Dateiname Der Inhalt der für den Dateiname-Linkgerät aufgeführten Bibliotheken ignoriert:

$ gcc -wall -c main.c
$ gCC -O Main -l. -Lhello main.o.
main.o: In der Funktion "Main":
main.c :(. text + 0xa): undefined Referenz auf `First"
main.c :(. text + 0xf): undefined referenz auf `second

$ gCC -O Main Main.o -l. -Lhello.
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Ein solches Merkmal des Verhaltens gCC. Entwickelt von dem Wunsch von Entwicklern, dem Benutzer die Möglichkeit zu geben, Dateien mit Bibliotheken auf unterschiedliche Weise zu kombinieren, verwenden Sie Kreuznamen ... Meiner Meinung nach, wenn möglich, ist es besser, nicht zu stören. Im Allgemeinen müssen die angeschlossenen Bibliotheken nach dem Namen der Datei auf sie aufgelistet werden.

Existieren alternativer Weg Standort der Bibliotheken im System. Je nach Verteilung kann die Umgebungsvariable LD_LIBRARY_PATH oder Library_Path eine Liste von Verzeichnissen speichern, die durch den Dickdarm geteilt werden, in dem der Linker nach Bibliotheken suchen muss. In der Regel wird diese Variable standardmäßig überhaupt nicht ermittelt, sondern nicht daran, ihn zu erstellen:

$ Echo $ ld_library_path

/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../../i686-pc-linux-gnu/bin/ld: find -lhello kann nicht gefunden werden
collect2: Ausführung LD mit Rückgabecode 1 abgeschlossen
$ Export library_path \u003d.
$ GCC -O Main Main.o -lhello
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Manipulationen mit Umgebungsvariablen sind nützlich, wenn Sie Ihre eigenen Bibliotheken erstellen und debuggen, sowie die Notwendigkeit, einige nicht-Standard-Anwendungen (veraltet, aktualisiert, modifiziert - im Allgemeinen außer in der Verteilung) -Bibliothek anzuschließen.

Lassen Sie uns nun die Bibliotheksdynamik erstellen und verwenden.

Der Satz von Quelldateien bleibt unverändert. Wir betreten in die Teams, schauen Sie sich an, was passiert ist, lesen Sie Kommentare:

$ Gcc -wall -fpic -c First.c
$ gcc -wall -fpic -c zweiters.c
$ gCC-hared -o libbello.so.2.4.0.5 -wl, -soname, libbello.so.2 erster.o zweiter.o

Was haben sie als Ergebnis bekommen?

$ Datei libbello.so.2.4.0.5.
libbello.so.2.4.0.5: ELF 64-Bit-LSB-freigegebenes Objekt, X86-64, Version 1 (SYSV), dynamisch verknüpft, nicht abgestreift

Datei libbello.so.2.4.0.5 ist unsere gemeinsame Bibliothek. Wie man es benutzt, ist etwas größer darunter.

Kommentare jetzt:

-FPIC-Option - Erfordert den Compiler, wenn Objektdateien erstellt werden, generieren Sie positionsunabhängiger Code (PIC - Position Unabhängiger Code ), der Hauptunterschied in der Methode der Präsentation von Adressen. Anstatt feste (statische) Positionen anzugeben, werden alle Adressen auf der Grundlage von in der angegebenen Verschiebungen berechnet globale Verdrängungstisch (globale Offset-Tabelle - erhalten ). Mit dem Format des positionsunabhängigen Codes können Sie die ausführbaren Module zum Zeitpunkt des Ladens an den Coda des Hauptprogramms anschließen. Dementsprechend besteht der Hauptzweck des positionsunabhängigen Codes darin, dynamische (freigegebene) Bibliotheken zu erstellen.

Option -Harded. - Zeigt an gCC.Infolgedessen muss eine nicht ausführbare Datei erhoben werden, aber das teilbare Objekt ist eine dynamische Bibliothek.

Option -wl, -soname, libbello.so.2 - Bestimmt soname. Bibliotheken. Über SONNAME Lassen Sie uns im nächsten Absatz detailliert sprechen. Nun diskutieren wir das Format der Option. Sagen ist seltsam, auf den ersten Blick ist das Design mit Kommas, um den Benutzer direkt mit einem Linker zu interagieren. Entlang der Kompilierung gCC. Bewirkt automatisch einen Linker, der automatisch nach eigenem Ermessen ist, gCC. Sendet es erforderlich, um die Option Task erfolgreich abzuschließen. Wenn der Benutzer auftritt, müssen Sie sich im Verknüpfungsprozess eingreifen, kann er eine spezielle Option verwenden. gCC. -Wl, -option, value1, value2 .... Was bedeutet, die Lincher zu übertragen ( -Wl.) Möglichkeit -Möglichkeit Mit Argumenten wert1., value2. usw. In unserem Fall wurde der Akku durch die Option übertragen -Sheiname. Mit Argument libbello.so.2..

Jetzt über SONNAME. Beim Erstellen und Verteilen von Bibliotheken, dem Problem der Kompatibilität und der Kontrolle von Versionen. Damit das System speziell der Downloader von dynamischen Bibliotheken, hatte eine Vorstellung von einer Bibliothek, deren Version beim Kompilieren eines Antrags verwendet wurde, und dementsprechend ist es für seinen erfolgreichen Betrieb erforderlich, ein spezielles Kennung erfolgt - soname. in der Bibliothek selbst und in der ausführbaren Antragsdatei platziert. Der SONNING-Kennung ist eine Zeichenfolge, die den Bibliotheksnamen mit dem Bibliothekspräfix, dem Punkt, der so-Erweiterung, wiederum, den Punkt und den ODU oder zwei (getrennt durch einen Punkt) der Version der Version des Namens der Bibliotheksversion - LIB. x. y. Das heißt, Soname fällt mit dem Namen der Bibliotheksdatei bis zur ersten oder zweiten Ziffern-Versionsnummer zusammen. Lassen Sie den Namen der ausführbaren Datei der Biblato.SO.4.4.0.5-Bibliothek von Libello.SO.2.4.0.5, dann kann die SONNAME-Bibliothek libello.so.2 sein. Wenn Sie die Bibliotheksschnittstelle ändern, muss seine SONNAME geändert werden! Jede Änderung des Kodex, der zur Inkompatibilität mit früheren Releases führt, muss von dem Aufkommen der neuen Soname begleitet werden.

Wie funktioniert das alles? Lassen Sie eine Bibliothek mit dem Namen HELLO eine Bibliothek für die erfolgreiche Ausführung einiger Anwendung benötigen, lass es im System sein, mit dem Bibliothek-Dateinamen libollelo.so.2.4.0.0.5, und die BiBhello.so2-Bibliothek von Libolle. es. An der Anwendungszusammenstellungsstufe, einem Linker, gemäß der Option -l Hallo.Wird in der Systemdatei mit dem Namen Libbello.SO suchen. In der Real Libollelo.so-System ist dies ein symbolischer Link mit der Datei libollelo.so.2.4.0.5. Zugriff auf die Bibliotheksdatei, der Linker glaubt, dass der darin vorgeschriebene SONNAME-Wert und zusammen mit dem anderen in die ausführbare Antragsdatei gestellt wird. Wenn die Anwendung läuft, erhält der dynamische Bibliotheksoader eine Anforderung zum Anschließen der Sonynyn-Bibliothek, die aus der ausführbaren Datei gelesen wird, und versuchen, die Bibliothek im System zu finden, der Dateiname ist derselbe wie Soname. Das heißt, der Bootloader wird versuchen, die libbello.so-Datei zu finden. Wenn das System korrekt konfiguriert ist, sollte der symbolische Link libello.so.2 an der Datei libello.so.s.2.4.0.5 vorhanden sein. Der Bootloader wird auf die gewünschte Bibliothek zugreifen, und dann ohne Denken (und nichts mehr überprüfend) es an die Anwendung. Stellen Sie sich vor, wir haben die auf diese Weise zusammengestellte Anwendung in ein anderes System übertragen, wobei nur die vorherige Version der Bibliothek mit SONNE LIBHELLO.SO.1 bereitgestellt wird. Das Versuch, das Programm zu starten, führt zu einem Fehler, da in diesem Dateisystem namens libbello.so.2 Nein.

Während der Kompilierungsstufe müssen Sie somit eine Bibliotheksdatei (oder einen symbolischen Link zur Bibliotheksdatei) mit dem Namen LIB-Namen bereitstellen. .damit. x. y. Wie heißt der LIB-Name. x. Y muss mit der SONNE-Zeichenfolge der verwendeten Bibliothek übereinstimmen.

In der Binary-Distribution wird in der Regel die BiBhello.so.2.4.0.5-Bibliotheksdatei und der Link zu IT libello.o.2 in das Libolle-Paket und das Libbello.SO, das nur zum Kompilieren der Link Libello-Pakete erforderlich ist, in das Libello-Paket gelegt. Zusammen mit der Header-Datei der Hello-Bibliothek. Im Libbello-Devel-Paket verpackt (im Devel-Paket, der statischen Version der BiBhello.a-Bibliothek, kann auch die statische Bibliothek auch nur bei der Kompilierungsstufe verwendet werden). Beim Auspacken des Pakets befinden sich alle aufgelisteten Dateien und Links (außer Hello.h) im selben Verzeichnis.

Stellen Sie sicher, dass die angegebene SONNE-Zeichenfolge in der Datei unserer Bibliothek wirklich ausgeführt wird. Wir verwenden Mega Utility objdump. Mit Option -p. :

$ objdump -p libello.so.2.4.0.5 | Greprontoname.
Soname libbello.so.2.


Nützlichkeit objdump. - Ein leistungsstarkes Werkzeug, mit dem Sie umfassende Informationen zum internen Inhalt (und dem Gerät) des Objekts oder der ausführbaren Datei erhalten können. In einem Mann sagt der Dienstprogrammsseite das objdump. Zunächst ist es nützlich, Programmierer zu schaffen, um ein Debugging- und Compilation-Tools zu erstellen, und nicht nur Anwendungsprogramme schreiben :) Insbesondere mit der Option -d. Dies ist ein Disassembler. Wir haben die Option genutzt -p. - Um eine andere META-Information über die Objektdatei zurückzuziehen.

Im obigen Beispiel, die Bibliothek zu erstellen, haben wir unermüdlich den Prinzipien der separaten Zusammenstellung gefolgt. Natürlich wäre es möglich, die Bibliothek und so mit einem Anruf zusammenzustellen gCC.:

$ gCC -Hared -Wall -FPIC -O Libbello.SO.2.4.0.5 -wl, -Sheiname, libello.so.2 First.c zweiter.c

Versuchen Sie nun, die resultierende Bibliothek zu nutzen:

$ gcc -wall -c main.c
$
Usr / bin / ld: kann nicht gefunden -lhello
collect2: LD kehrte 1 Exit-Status zurück

Der Linker schwört. Wir erinnern uns, was oben über symbolische Links erwähnt wurde. Erstellen Sie libbello.so und wiederholen Sie einen Versuch:

$ ln -s libbhello.so.2.4.0.5 libbello.so
$ gCC -O Main Main.o -l. -Lhello -wl, -rath ,.

Jetzt ist jeder zufrieden. Wir starten die erstellte binäre:

Fehler ... Der Bootloader schwört, kann die BiBhello.SO.2-Bibliothek nicht finden. Stellen Sie sicher, dass der Link zu Libbello.so.2 in der ausführbaren Datei wirklich ausgeführt wird.

$ Objdump -p Main | Grep benötigt
Brauchte libollelo.so.2.
Brauchte libc.so.6.

$ ln -s libbello.so.2.4.0.5 libbello.so.2
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Verdient ... jetzt Kommentare zu neuen Optionen gCC..

Option -wl, -Rpath ,. - Bereits vertrautes Design, übertragen Sie die Zeile an den Linker -Rpath. Mit Argument . . Mit der Hilfe -Rpath. In der ausführbaren Programmdatei können Sie zusätzliche Pfade registrieren, für die der Lader von freigegebenen Bibliotheken nach Bibliotheksdateien suchen. In unserem Fall ist der Pfad registriert . - Suche nach Bibliotheksdateien starten im aktuellen Verzeichnis.

$ Objdump -p Main | Grep RPath.
Rpath.

Dank der angegebenen Option, wenn das Programm beginnt, müssen Sie die Umgebungsvariablen ändern. Wenn Sie das Programm in ein anderes Verzeichnis übertragen und versuchen, auszuführen, wird die Bibliotheksdatei nicht gefunden und der Bootloader zeigt eine Fehlermeldung an:

$ MV Main ..
$ ../main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Finden Sie heraus, welche geteilten Bibliotheken von der Anwendung benötigt werden und das Dienstprogramm verwendet werden ldd.:

$ Ldd Main.
Linux-VDSO.SO.1 \u003d\u003e (0x00007FFFADDFF000)
libbello.so.2 \u003d\u003e ./Libhello.SO.2 (0x00007F9689001000)
libc.so.6 \u003d\u003e /lib/libc.so.6 (0x00007f9688c62000)
/lib64/ld-linux-x86-64.so.2 (0x00007F9689205000)

Im Ergebnis ldd. Für jede erforderliche Bibliothek wird seine SONNAME angegeben und der vollständige Pfad in die in Übereinstimmung mit den Systemeinstellungen definierten Bibliotheksdatei.

Jetzt ist es an der Zeit, darüber zu sprechen, wo in dem System Bibliotheksdateien erforderlich ist, in der der Bootloader versucht, sie zu finden und wie sie sie kontrollieren sollen.

In Übereinstimmung mit Vereinbarungen FHS (Dateisystemhierarchie-Standard) Das System muss zwei (zumindest) Verzeichnis zum Speichern von Bibliotheksdateien haben:

/ lib - Hier werden die Hauptverteilungsbibliotheken, die für den Betrieb von Programmen aus / bin und / SBIN erforderlich sind, gesammelt werden;

/ Usr / lib - Bibliotheken werden hier für die erforderlichen Anwendungen von / usr / bin und / usr / sbin gespeichert.

Relevante Bibliotheken-Header-Dateien müssen sich im Verzeichnis / usR befinden.

Der Standardlader wird in diesen Verzeichnissen nach Bibliotheksdateien suchen.

Zusätzlich zu den oben aufgeführten, dem Verzeichnis / usR / local / lib-Verzeichnis muss das Verzeichnis / usr / local / libary in den vom Benutzer bereitgestellten Systembibliotheken unabhängig voneinander vorhanden sein, um das Paketverwaltungssystem zu umgehen (nicht in der Verteilung enthalten). Beispielsweise werden in diesem Verzeichnis standardmäßig die Bibliotheken aus Quellen zusammengestellt (Programme, die aus den Quellen installiert sind, in / usR / local / bin und / usr / local / sbin, natürlich sprechen wir über binäre Distributionen). Bibliotheksheader-Dateien werden in diesem Fall in / usr / local / incluce platziert.

In einer Reihe von Distributionen (in Ubuntu.) Der Bootloader ist nicht so konfiguriert, dass das Verzeichnis / usR / local / lib-Verzeichnis angezeigt wird, wenn der Benutzer die Bibliothek von der Quelle einstellt, das System nicht sucht. Syo Die Autoren der Verteilung ergab sich speziell, um den Benutzer umzugehen, um die Software nur über das Paketverwaltungssystem zu installieren. Was in diesem Fall zu tun ist, wird nachstehend beschrieben.

Um den Bibliotheksdateisuchprozess zu vereinfachen und zu beschleunigen, zeigt der Bootloader nicht jedes Mal, wenn die angegebenen Verzeichnisse nicht angezeigt wird, und verwenden Sie die in der Datei /etc/ld.so.cache-Datei (Library Cache) gespeicherte Datenbank nicht. Hier werden Informationen darüber erfasst, wo das System der Bibliotheksdatei dieser SONNAME entspricht. Lader, der eine Liste der erforderlichen spezifischen Bibliotheken erhalten hat (die Liste der in der Programm ausführbaren Dateien der Programms angegebenen Bibliotheken), ermittelt über /etc/ld.so.cache den Pfad in die Datei jeder erforderlichen Bibliothek und lädt sie in den Speicher. Darüber hinaus kann der Bootloader die in den LD_LIBRARY_PATH-Systemvariablen, Library_Path und im Feld REPP-Feld der ausführbaren Datei (siehe oben) anzeigen.

Um den ultimativen Status des Bibliotheks-Cache zu steuern und aufrechtzuerhalten, verwendet ein Dienstprogramm ldconfig.. Wenn laufen ldconfig. Ohne Optionen prüft das Programm die auf der Eingabeaufforderung, vertrauenswürdigen Verzeichnisse / lib und / usr / lib, die in der Datei /etc/ld.so.conf aufgeführten Kataloge. Für jede Bibliotheksdatei, die in den angegebenen Verzeichnissen erstellt wurde, wird Soname gelesen, ein symbolischer Link basierend auf Soname erstellt, aktualisiert in /etc/ld.so.cache aktualisiert.

Clead in was gesagt wurde:

$ Ls.
hallo.h libbello.so libbello.so.2.4.0.5 main.c
$
$ sudo ldconfig / voll / path / k / katalog / c / z.
$ Ls.
hello.h libbello.so libbello.so.2 libello.so.2.4.0.5 main main.c
$ ./main.
Erste Funktion ...
Zweite Funktion ...
Hauptfunktion ...

Erste Herausforderung ldconfig. Wir haben zu unserer Bibliothek zum Cache beigetragen, die zweite Herausforderung wurde ausgeschlossen. Bitte beachten Sie, dass beim Kompilieren von Main die Option ausgelassen wurde -Wl, -runpath ,.Infolgedessen führte der Bootloader die Suche nach den erforderlichen Bibliotheken nur im Cache durch.

Jetzt sollte es klar sein, wie Sie tun, wenn Sie nach der Installation der Bibliothek aus dem Quellsystem nicht sehen. Zunächst müssen Sie den vollständigen Pfad /etc/ld.so.conf-Datei in die Bibliotheksdateien hinzufügen (Standard / USR / LOCAL / LIB). Format /etc/ld.so.conf - Die Datei enthält eine Liste von getrennt von einem Dickdarm, einem Speicherplatz, Registerkarten oder einem Symbol einer neuen Zeile, in der die Bibliothekssuche ausgewählt ist. Nach dem Anrufen ldconfig. Ohne Optionen, aber mit Superuser-Rechten. Alles sollte verdienen.

Nun, am Ende sprechen wir darüber, wie statische und dynamische Version von Bibliotheken miteinander zusammenkommen. Was ist die Frage? Wenn oben die empfangenen Namen und der Speicherort der Bibliotheksdateien erörtert wurden, werden die statischen und dynamischen Versionen der Bibliothek in demselben Verzeichnis gespeichert. Wie denn gCC. Erlernen Welche Art von Bibliothek möchten wir verwenden? Standardmäßig ist die dynamische Bibliothek bevorzugt. Wenn die Linie eine dynamische Bibliotheksdatei findet, dachte er nicht darüber nach, dass es an der ausführbaren Programmdatei klins wird:

$ Ls.
hallo.h labello.a libbello.so libbello.so.2 libollelo.so.2.4.0.5 main.c
$ gcc -wall -c main.c
$ gCC -O Main Main.o -l. -Lhello -wl, -rath ,.
$ Ldd Main.
Linux-Vdso.so.1 \u003d\u003e (0x00007FFE1BB0000)
libbello.so.2 \u003d\u003e ./Libhello.SO.2 (0x00007FD50370B000)
libc.so.6 \u003d\u003e /lib/libc.so.6 (0x00007fd50336c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd50390f000)
$ du -h Main
12k Main.

Achten Sie auf die Größe der ausführbaren Programmdatei. Es ist das Minimum möglich. Alle verwendeten Bibliotheken werden dynamisch verknüpft.

Existieren gCC -Tatic Option. - Angabe der Zeile, um nur statische Versionen aller erforderlichen Bibliotheksanwendungen zu verwenden:

$ gCC -Tatic -o Main Main.o -l. -Lhello.
$ Datei-Main.
haupt: ELF 64-Bit LSB-ausführbar, X86-64, Version 1 (GNU / Linux), statisch verknüpft, für GNU / Linux 2.6.15, nicht abgestreift
$ Ldd Main.
ist keine dynamische ausführbare Datei
$ du -h Main
728k Main.

Die Größe der ausführbaren Datei ist 60-mal mehr als im vorherigen Beispiel - die Standardsprachenbibliotheken sind in der Datei enthalten. C.. Jetzt kann unsere Anwendung sicher vom Verzeichnis in das Verzeichnis übertragen werden, und selbst auf andere Maschinen, der Hello-Bibliothekcode in der Datei, ist das Programm vollständig autonom.

Wie ist es, wenn Sie sein, wenn es notwendig ist, eine statische Verknüpfung von nur Teilen der verwendeten Bibliotheken auszuführen? Mögliche Variante Lösungen - Nennen Sie den Namen der statischen Version der Bibliothek, die im Namen der geteilten, und beim Kompilieren von Anwendungen unterschiedlich ist, angeben, welche Version wir diese Zeit verwenden möchten:

$ Mv libbello.a libbello_s.a
$ gCC -O Main Main.o -l. -lhello_s.
$ Ldd Main.
Linux-Vdso.so.1 \u003d\u003e (0x00007FFF021F5000)
libc.so.6 \u003d\u003e /lib/libc.so.6 (0x00007fd0D0803000)
/lib64/ld-linux-x86-64.so.2 (0x00007FD0D0BA4000)
$ du -h Main
12k Main.

Da Libbello Library Code-Größe vernachlässigbar ist,

$ du -h libbello_s.a
4,0 kbbhello.a.

die Größe der empfangenen ausführbaren Datei ist fast nicht von der Größe der mit dynamischen Verknüpfung erstellten Datei unterschiedlich.

Nun, wahrscheinlich alle. Vielen Dank an alle, die an diesem Ort lesen.

Es ist üblich, dass GCC hinter der Leistung von anderen Compilern zurückbleibt. In diesem Artikel werden wir versuchen, herauszufinden, welche Grundoptimierung des Compiler-GCC auf eine akzeptable Leistung angewendet werden sollte.

Welche Optionen in der Standard-GCC?

(1) Standardmäßig verwendet GCC-Optimierungsniveau "-O0". Es ist eindeutig nicht optimal aus der Sicht der Leistung und wird nicht empfohlen, das Endprodukt zusammenzustellen.
GCC erkennt nicht die Architektur, auf der die Kompilierung gestartet wird, bis die Option "-March \u003d Native" übertragen wird. Standardmäßig verwendet GCC die während seiner Konfiguration angegebene Option. Um die GCC-Konfiguration herauszufinden, reicht es aus, um zu beginnen:

Dies bedeutet, dass GCC auf Ihre Optionen "-March \u003d Corei7" hinzufügen (wenn keine andere Architektur angibt).
Die meisten GCC-Compiler für X86 (Basic für 64 Bit Linux) fügen hinzu: "-mtune \u003d generic -march \u003d x86-64" zu spezifizierten Optionen, da die Konfigurationen die Architektur nicht bestimmende Optionen angeben. Sie können immer alle Optionen erfahren, die beim Start von GCC übertragen werden, sowie die internen Optionen mit dem Befehl:

Infolgedessen wird häufig verwendet:

Eine Angabe der verwendeten Architektur ist für die Leistung wichtig. Die einzige Ausnahme kann als Programme angesehen werden, bei denen der Anruf der Bibliotheksfunktionen fast die ganze Zeit des Starts dauert. Glibc kann die Funktion für diese Architektur während der Ausführung optimal wählen. Es ist wichtig zu beachten, dass mit statischen Verknüpfungen einige Glibc-Funktionen keine Versionen für verschiedene Architekturen haben. Das heißt, die dynamische Anordnung ist besser, wenn die Geschwindigkeit der Glibc-Funktionen wichtig ist..
(2) Standardmäßig verwenden die meisten GCC-Compiler für X86 im 32-Bit-Modus X87-Modell der Fließkomma-Berechnungen, da sie ohne "-MFPMATH \u003d SSE" konfiguriert wurden. Nur wenn die GCC-Konfiguration "--with-mfpmath \u003d sse" enthält:

Der Compiler verwendet standardmäßig das SSE-Modell. In allen anderen Fällen ist es besser, die Option "-mfPMATH \u003d SSE" an die Montage im 32-Bit-Modus hinzuzufügen.
Also oft verwendet:

Hinzufügen der Option "-MFPMATH \u003d SSE" ist wichtig im 32-Bit-Modus! Die Ausnahme ist der Compiler, in dem die Konfiguration "--with-mfpmath \u003d sse" ist.

32 Bit-Modus oder 64 Bit?

Der 32-Bit-Modus wird üblicherweise verwendet, um den verwendeten Speichermengen zu reduzieren, und infolge der Beschleunigung der Arbeit mit IT (mehr Daten werden im Cache platziert).
Im 64-Bit-Modus (im Vergleich zu 32 Bit) erhöht sich die Anzahl der öffentlich verfügbaren Register von 6 bis 14, XMM-Registern von 8 bis 16. Auch alle 64-Bit-Architekturen unterstützen SSE2-Erweiterung, daher müssen Sie im 64-Bit-Modus nicht benötigen "-mfpmath \u003d sse" hinzuzufügen.
Es wird empfohlen, den 64-Bit-Modus zum Zählen von Aufgaben und einen 32-Bit-Modus für mobile Anwendungen zu verwenden.

Wie bekomme ich maximale Leistung?

Es gibt keine eindeutigen Optionen, um die maximale Projektion zu erhalten, jedoch gibt es viele Optionen in der GCC, die Sie verwenden sollten. Nachfolgend finden Sie eine Tabelle mit empfohlenen Optionen und Ausgabeprognosen für Intel Atom- und 2. Generation Intel Core i7-Prozessoren relativ zur Option "-O2". Die Prognosen basieren auf den durchschnittlichen geometrischen Ergebnissen eines bestimmten Satzes von Aufgaben, die von GCC Version 4.7 zusammengestellt wurden. Es wird auch angenommen, dass die Compiler-Konfiguration für X86-64 generisch durchgeführt wurde.
Prognose für die Erhöhung der Produktivität auf mobile Anwendungen relativ zu "-o2" (nur im 32-Bit-Modus, da es sich um das Mobile-Segment ist):

Prognose für die Erhöhung der Produktivität bei Berechtigungsaufgaben relativ zu "-O2" (im 64-Bit-Modus):
-M64 -Fast -flto. ~17%
-M64 -Fast -flto -March \u003d nativ ~21%
-M64 -Fast -flto -March \u003d Native -Funroll-Loops ~22%

Der Vorteil des 64-Bit-Modus über 32 Bit zum Berechnen von Aufgaben mit Optionen "-O2 -MFPMATH \u003d SSE" beträgt ungefähr ~ 5%
Alle Daten in dem Artikel sind eine Prognose, die auf den Ergebnissen eines bestimmten Benchmarks basieren.
Nachfolgend finden Sie eine Beschreibung der in dem Artikel verwendeten Optionen. Ausführliche Beschreibung (in Englisch): http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/optimize-options.html "
  • "-Ofafast-Mathe" "-O3 -FFFAST-MATH" umfasst ein höheres Maß an Optimierung und aggressivere Optimierung für arithmetische Berechnungen (z. B. echte Neusicherungsbildung)
  • "-flut" Intermodulische Optimierung
  • 32-Bit-Modus "-M32"
  • "-MFPMATH \u003d SSE" umfasst die Verwendung von XMM-Registern in echter Arithmetik (anstelle eines echten Stapels im X87-Modus)
  • "-Funroll-Loops" beinhaltet den Einsatz von Zyklen

Transportlogistik (Analyse verschiedener Transportarten: Vorteile, Nachteile)

Der Transport ist ein Zweig der Materialproduktion, der den Transport von Menschen und Ladung durchführt. In der Struktur der sozialen Produktion gehört der Transport zum Bereich der Materialdienste.

Es wird angemerkt, dass ein erheblicher Teil der Logistikvorgänge auf der Bewegung des Materialstroms von der primären Rohstoffquelle bis zum endgültigen Verbrauch unter Verwendung verschiedener fahrzeug. Die Kosten für die Durchführung dieser Vorgänge betragen 50% der gesamten Logistikkosten.

Für seine Ernennung werden zwei Haupttransportgruppen zugeteilt: öffentliche Verkehrsmittel - die öffentliche Wirtschaftswirtschaft, die den Bedürfnissen aller Sektoren der Volkswirtschaft und der Öffentlichkeit im Transport von Waren und Passagieren erfüllt. Der Gemeinsame Verkehr dient der Behandlung von Behandlungen und Bevölkerung. Es wird häufig als Hauptstraße (Highway - Haupt-, Hauptlinie in einem System in diesem Fall in diesem Fall in dem Kommunikationssystem) bezeichnet. Allgemeine Nutzung von öffentlichen Verkehrsmitteln bahnverkehr., Wassertransport (Meer und Fluss), Automobil-, Luftverkehrs- und Pipeline-Transport).

Der Transport ist nicht öffentlich - intrawandativer Transport sowie Fahrzeuge aller Arten, die nicht zu Transportorganisationen gehören.

Die Organisation der Bewegung von Gütern durch Transport ist nicht allgemein, sondern ist Gegenstand des Studiums der Produktionslogistik. Die Aufgabe der Auswahl von Kanalkanälen wird im Bereich der Vertriebslogistik gelöst.

Also gibt es folgende Haupttypen des Transports:

eisenbahn

innerer Wasserfluss

automotive

luft

pipeline

Jeder der Transportarten hat spezifische Merkmale aus der Sicht von Logistikmanagement, Würde und Nachteilen, die die Möglichkeiten für den Einsatz im Logistiksystem bestimmen. Verschiedene Transportarten sind ein Transportkomplex. Der russische Transportkomplex bildet juristische Personen und Einzelpersonen, die auf seinem Territorium registriert sind - Unternehmer, die auf allen Arten von Verkehrsmitteln und Transport- und Expeditionstätigkeiten, Design, Bau, Reparatur und Wartung von Eisenbahngleisen, Straßen und Strukturen, Pipelines, arbeiten zur Wartung der Schifffahrt hydraulischen Strukturen, Wasser und atemweg Nachrichten, Halten wissenschaftliche Forschung und Schulung in den Fertigungsfahrzeugen der Unternehmensransportsysteme sowie Organisationen, die ansonsten mit dem Transportprozess verbunden sind. TK Russlands ist über 160.000 km Hauptbahn- und Zufahrtsstraßen, 750 Tausend km Automotive teuer mit einer soliden Abdeckung, 1,0 Millionen km maritimen Versandlinien, 101.000 km Binnenwasserstraßen, 800.000 km Fluggesellschaften. Für diese Mitteilungen werden derzeit nur etwa 4,7 Millionen Tonnen Fracht (nach 2000) und der Transportanteil im Bruttoinlandsprodukt täglich transportiert, und der Transportanteil im flachen inländischen Produkt des Landes ist etwa 9%. So stellt der Transport den wichtigsten Teil der Infrastruktur der Wirtschaft und das gesamte Sozio-Produktionspotenzial unseres Landes dar.

Auf der Registerkarte. 1 (4, 295) sind mit einem relativ logistischen Merkmal verschiedener Transportarten dargestellt.

Tabelle 1 charakteristisch für den Transportmodi

Art des Transports.

Würde

Nachteile

eisenbahn

High Resort und Bandbreite. Unabhängigkeit von den klimatischen Bedingungen, Saison und Tag.

Hohe Verkehrsmittel. Relativ geringe Tarife; Signifikante Rabatte für Transit sendet. High-Speed-Versandgeschwindigkeit über lange Entfernungen.

Begrenzte Anzahl von Trägern. Große Investitionen in der Produktion und technischen Basis. Hoher Materialverbrauch und Energieverbrauch. Geringe Zugänglichkeit an Endpunkte des Umsatzes (Verbrauch).

Nicht genug Frachtsicherheit.

Die Möglichkeit des Interverbessertransports. Kostengünstige Sendungen für lange Entfernungen. High Resort und Bandbreite. Niedrige Kapitalpflege.

Begrenzbarkeit.

Niedrige Liefergeschwindigkeit (hoher Transport von Frachtübergang).

Abhängigkeit von geografischen, Navigations- und Wetterbedingungen.

Die Notwendigkeit, eine komplexe Anschlussinfrastruktur zu erstellen.

Inneres Wasser (Fluss)

Hohe transluzente Fähigkeiten auf Flüssen der Tiefsee und -reservoirs.

Niedrige Versandkosten. Niedriges Kapitalgewicht.

Begrenzbarkeit. Niedrige Liefergeschwindigkeit.

Abhängigkeit von Ungleichmäßigkeit der Tiefen von Flüssen und Gewässern, Navigationsbedingungen. Saisonalität. Unzureichende Zuverlässigkeit des Transports und der Wartung von Fracht.

automotive

Hohe Verfügbarkeit.

Die Möglichkeit des Versands "von Tür zu Tür"

Hohe Manövrierfähigkeit, Flexibilität, Dynamik. Hohe Liefergeschwindigkeit. Fähigkeit, verschiedene Routen und Lieferungsschemata zu verwenden.

Hohe Frachtsicherheit. Die Möglichkeit des Versands durch kleine Parteien.

Schlechte Leistung. Abhängigkeit von Wetter- und Straßenbedingungen. Relativ hohe Transportkosten über langen Entfernungen.

Unzureichende Umweltreinheit.

Luft

Die höchste Versandrate. Hohe Zuverlässigkeit.

Die höchste Wartung der Fracht.

Die kürzesten Transportrouten.

Hohe Transportkosten, höchste Tarife unter anderen Transportmitteln. Hohe Kapitalintensität, Material- und Energieintensität des Transports. Abhängigkeit von den Wetterbedingungen. Unzureichende geografische Zugänglichkeit.

pipeline

Kostengünstig. Hohe Leistung (Bandbreite). Hohe Frachtsicherheit. Niedriges Kapitalgewicht.

Grenze der Frachtarten (Gas, Erdölprodukte, Warenemulsionen). Unzureichende Zugänglichkeit von kleinen Mengen von Transportgütern.

Zunächst muss der Logistikmanager das Problem lösen, um seine Flotte von Fahrzeugen zu erstellen oder den gemieteten Transport (allgemeiner Gebrauch oder privat) zu verwenden. Bei der Auswahl einer Alternative basiert er normalerweise auf einem bestimmten System von Kriterien, das Folgendes umfasst: die Kosten für das Erstellen und Betrieb ihrer eigenen Fahrzeugflotte. Die Kosten für den Zahlen für Transport, Transport-Extensivgesellschaften und andere Logistikintermediäre im Transport

Transportqualität (Liefersicherheit, Frachtsicherheit usw.)

In den meisten Fällen erreichten die Hersteller auf spezialisierte Transportunternehmen.