Was ist eine * .o-Datei?

69

Ich kompiliere ein eigenes Projekt. Und es wurde durch diesen Fehler gestoppt:

LINK || Schwerwiegender Fehler LNK1181: Eingabedatei 'obj \ win \ release \ src \ lua \ bindings.o' | kann nicht geöffnet werden

Kompilieren mit Code :: Blocks mit dem VS 2005/2008 Compiler unter win7. Es gibt auch viele andere leere Verzeichnisse, in denen * .o-Dateien fehlen.

Was machen Sie?

Max Frai
quelle
3
Erstens ist eine '.o'-Datei eine Zwischenstufe zwischen Kompilieren und Verknüpfen. Wenn Kompilierungsfehler auftreten, generiert VS 2008 keine '.o'-Datei, versucht jedoch weiterhin, die Anwendung zu erstellen, was nach der Verknüpfungsphase fehlschlägt. Wenn Sie nervös sind, können Sie immer versuchen, "Alle neu zu erstellen". Ich empfehle jedoch, Fehlerprotokolle auf fehlende Objektdateien zu untersuchen.
Thomas Matthews

Antworten:

98

Eine Datei mit der Endung .o ist eine Objektdatei . Der Compiler erstellt für jede Quelldatei eine Objektdatei, bevor er sie mit der endgültigen ausführbaren Datei verknüpft.

Joseph Salisbury
quelle
1
Hm, welche Gründe können hier sein? Warum hat der Compiler nicht für alle benötigten Quellen Objektdateien erstellt?
Max Frai
1
Ein Compiler kann keine Objektdatei für die Quelle erstellen, die er nicht hat.
Liz Albin
Kann viele Gründe haben. Höchstwahrscheinlich haben Sie einige Einschlüsse oder eine Vorlage durcheinander gebracht. Es könnte auch eine Linker-Einstellung sein, die falsch ist, aber ich bezweifle das :)
cwap
für ocktonal: Bei Problemen ist es wahrscheinlich einfacher, kleinere Dateien anstelle einer großen Objektdatei zu verwalten.
Max
@Ockonal, überprüfen Sie das gesamte Ausgabeprotokoll des Compilers. Visual Studio 2008 hat die Angewohnheit, Dateien zu verknüpfen und zu versuchen, eine ausführbare Datei zu erstellen, wenn frühere Kompilierungsfehler auftreten, die dazu führen, dass Dateien nicht in ".o" -Dateien (Objektdateien) übersetzt werden.
Thomas Matthews
47

Sie haben einige Antworten erhalten, und die meisten davon sind richtig, aber verpassen Sie, was (glaube ich) hier wahrscheinlich der Punkt ist.

Ich vermute, Sie haben ein Makefile, mit dem Sie eine ausführbare Datei erstellen möchten. Falls Sie mit ihnen nicht vertraut sind, listen Makefiles Abhängigkeiten zwischen Dateien auf. Für einen wirklich einfachen Fall könnte es etwas haben wie:

myprogram.exe: myprogram.o
    $(CC) -o myprogram.exe myprogram.o

myprogram.o: myprogram.cpp
    $(CC) -c myprogram.cpp

Die erste Zeile sagt, dass das myprogram.exedavon abhängt myprogram.o. Die zweite Zeile zeigt , wie das Erstellen myprogram.exe von myprogram.o . Die dritte und vierte Zeile sagen, myprogram.ohängt davon ab myprogram.cpp, wie und wie myprogram.oaus myprogram.cpp` erstellt werden soll.

Ich vermute, dass Sie in Ihrem Fall ein Makefile wie das oben genannte haben, das für gcc erstellt wurde. Das Problem, auf das Sie stoßen, ist, dass Sie es mit MS VC anstelle von gcc verwenden. MS VC verwendet ".obj" als Erweiterung für seine Objektdateien anstelle von ".o".

Das heißt, wenn make (oder das in Ihrem Fall in die IDE integrierte Äquivalent) versucht, das Programm zu erstellen, werden diese Zeilen überprüft, um herauszufinden, wie es erstellt werden soll myprogram.exe. Um dies zu tun, sieht es, dass es erstellt werden muss myprogram.o, und sucht nach der Regel, die angibt, wie es erstellt werden soll myprogram.o. Das heißt, es sollte die CPP-Datei kompilieren, also macht es das.

Dann brechen die Dinge zusammen - der VC ++ - Compiler produziert myprogram.objstatt myprogram.oals Objektdatei. Wenn er also versucht, mit dem nächsten Schritt fortzufahren, myprogram.exeaus dem er produziert myprogram.o, stellt er fest, dass sein Versuch, etwas zu erstellen, myprogram.oeinfach fehlgeschlagen ist. Es hat getan, was die Regel vorschrieb, aber das hat nicht myprogram.owie versprochen produziert. Es weiß nicht, was es tun soll, daher wird es beendet und es wird eine Fehlermeldung angezeigt.

Die Lösung für dieses spezielle Problem ist wahrscheinlich ziemlich einfach: Bearbeiten Sie die make-Datei so, dass alle Objektdateien die Erweiterung .objanstelle von haben .o. Es gibt Raum für viele Fragen, ob dies alles beheben wird - das kann alles sein, was Sie brauchen, oder es kann einfach zu anderen (wahrscheinlich schwierigeren) Problemen führen.

Jerry Sarg
quelle
1
Also ist $ (CC) für den Compiler?
Zygimantus
1
@zygimantus: ja. Theoretisch ist es der C-Compiler, aber zumindest in den meisten Fällen sind die C- und C ++ - Compiler dieselbe Binärdatei (wodurch die Sprache basierend auf der Erweiterung der zu kompilierenden Datei sortiert wird).
Jerry Coffin
1
Ich habe alle meine .oErweiterungen durch ersetzt .obj, aber jetzt tritt der gleiche Fehler auf:make (e=2): The system cannot find the file specified. make: *** [src/haproxy.obj] Error 2
doubleOrt
6

Eine .o-Objektdatei (auch .obj unter Windows) enthält kompilierten Objektcode (dh Maschinencode, der von Ihrem C- oder C ++ - Compiler erstellt wurde) sowie die Namen der Funktionen und anderer Objekte, die die Datei enthält. Objektdateien werden vom Linker verarbeitet , um die endgültige ausführbare Datei zu erstellen. Wenn Ihr Erstellungsprozess diese Dateien nicht erstellt hat, stimmt wahrscheinlich etwas mit Ihren Makefile- / Projektdateien nicht.


quelle
1

Es ist wichtig zu beachten , dass Objektdateien zu Binär - Code in einem Format zusammengesetzt werden , das ist versetzbar . Dies ist ein Formular, mit dem der zusammengestellte Code an einer beliebigen Stelle in den Speicher geladen werden kann, um von einem Linker mit anderen Programmen verwendet zu werden .

Anweisungen, die sich auf Etiketten beziehen, ist in der O- Datei noch keine Adresse für diese Etiketten zugewiesen .

Diese Beschriftungen werden als '0' geschrieben und der Assembler erstellt einen Verschiebungsdatensatz für diese unbekannten Adressen. Wenn die Datei verknüpft und an eine ausführbare Datei ausgegeben wird, werden die unbekannten Adressen aufgelöst und das Programm kann ausgeführt werden.

Sie können das nm- Tool für eine Objektdatei verwenden, um die in einer .o-Datei definierten Symbole aufzulisten.

Cyrus Vahidi
quelle
0

Ink-Jet ist richtig. Insbesondere ist eine .o (.obj) - oder Objektdatei eine einzelne Quelldatei, die in Maschinencode kompiliert wurde ( ich bin nicht sicher, ob der "Maschinencode" mit einem ausführbaren Maschinencode identisch oder ähnlich ist ). Letztendlich ist es eine Zwischenstufe zwischen einem ausführbaren Programm und einer Nur-Text-Quelldatei.

Der Linker verwendet die o-Dateien, um die ausführbare Datei zusammenzustellen.

Wikipedia hat möglicherweise detailliertere Informationen. Ich bin mir nicht sicher, wie viele Informationen Sie möchten oder benötigen.

Frank V.
quelle