2010-03-01 6 views
37

Ich habe eine gemeinsam genutzte Bibliothek, die mit einer anderen (dritten) freigegebenen Bibliothek verknüpft ist. Meine gemeinsam genutzte Bibliothek wird dann mit dlopen in meiner Anwendung geladen. All dies funktioniert einwandfrei (vorausgesetzt, die Dateien befinden sich im richtigen Pfad usw.).Force GCC, um über nicht definierte Verweise in gemeinsam genutzten Bibliotheken zu benachrichtigen

Jetzt ist das Problem, dass ich nicht einmal angeben muss, um mit der gemeinsam genutzten Bibliothek von Drittanbietern zu verknüpfen, wenn ich meine Bibliothek verlinke. GCC akzeptiert dies, ohne Fehler über undefinierte Referenzen zu melden. Also, die Frage; Wie kann ich GCC zwingen, mich über nicht definierte Referenzen zu benachrichtigen?

Wenn ich meine Bibliothek ändern, um (vorübergehend) eine ausführbare Datei zu sein, bekomme ich undefinierte Referenzen (wenn die Bibliothek nicht an den Linker geliefert wird). (Funktioniert gut, wenn ich es angeben.)

Das heißt, wird die folgende getan:

g++ -fPIC -shared -o libb.so b.o 
g++ -fPIC -shared -o liba.so a.o 
g++ -o a.exe a.cpp 

Wo die zweite Zeile geben keinen Fehler und die dritte Zeile beschwert sich über einen nicht definierten Referenz.

Beispielcode:

A. h:

class a 
{ 
public: 
    void foobar(); 
}; 

a.cpp:

#include "a.h" 
#include "b.h" 

void a::foobar() 
{ 
    b myB; 
    myB.foobar(); 
} 

int main() 
{ 
    a myA; myA.foobar(); 
} 

b.h:

b.cpp:

#include "b.h" 

void b::foobar() 
{ 
} 

Antwort

33

-Wl, - no-undefined Die Linker-Option kann beim Erstellen einer gemeinsamen Bibliothek verwendet werden, undefinierte Symbole werden als Linker-Fehler angezeigt.

g ++ -shared -Wl, -soname, libmylib.so.5 -Wl, - no-undefined -o libmylib.so.1.1 mylib.o -lthirdpartylib

+0

Nein, überhaupt kein Fehler. –

+0

Können Sie die Linker-Ausgabe bereitstellen? –

+0

Hm, ich hätte schwören können, dass ich das vorher gemacht habe und nichts als Ausgabe bekommen habe. Dies wieder zu tun schien dies gut zu machen (dh ich bekomme einen Fehler!) –

1

Sie können nicht machen ld (was gcc gerade läuft) achten Sie auf eine Bibliothek, die nicht dort in der Verbindung ist. Sie können RTLD_LAZY deaktivieren, um aggressive Berichte zu erhalten, und Sie können einen Komponententest hinzufügen, der unmittelbar nach dem Link ausgeführt wird, um diese Probleme zu beheben.

+0

Was Sie * tun können * und was der Fragesteller wollte, ist '' ld'', um Ihnen zu sagen: "Ich habe keine Ahnung, woher diese Symbole kommen werden, aber sie sind nicht in der Bibliotheken, von denen du mir erzählt hast. " –

13

Nach mehr Forschung, Ich habe erkannt, wie das Zeug funktioniert. Es gibt zwei Linker-Optionen, um undefinierte Symbole von gemeinsam genutzten Bibliotheken zu manipulieren:

Die erste ist --no-undefined. Es meldet die nicht aufgelösten Symbole, die nicht sofort bei der Verknüpfung aufgelöst werden. Wenn das Symbol nicht in einer gemeinsam genutzten Bibliothek gefunden wird, die entweder manuell (mit -l Switch) oder automatisch (libgcc_s, C++ runtime; libc, C runtime; ld-linux-**.so, dynamische Linker utils) ausgewählt wurde, meldet --no-undefined dies als Fehler. Das ist der Schlüssel, den der Fragesteller benötigt.

Es gibt einen weiteren Schlüssel, --no-allow-shlib-undefined (dessen Beschreibung auch --no-undefined vorschlägt). Es prüft, ob die Definitionen in den gemeinsamen Bibliotheken , mit denen Sie Ihre gemeinsam genutzte Bibliothek mit verknüpfen, erfüllt sind. Dieser Schlüssel ist in diesem Fall wenig hilfreich, kann aber nützlich sein.Es hat jedoch seine eigenen Hindernisse.

Die Manpage liefert einige Gründe, warum es nicht Standard ist:

--allow-shlib-undefined 
    --no-allow-shlib-undefined 
     Allows (the default) or disallows undefined symbols in shared 
     libraries (It is meant, in shared libraries _linked_against_, not the 
     one we're creating!--Pavel Shved). This switch is similar to --no-un- 
     defined except that it determines the behaviour when the undefined 
     symbols are in a shared library rather than a regular object file. It 
     does not affect how undefined symbols in regular object files are 
     handled. 

     The reason that --allow-shlib-undefined is the default is that the 
     shared library being specified at link time may not be the same as 
     the one that is available at load time, so the symbols might actually 
     be resolvable at load time. Plus there are some systems, (eg BeOS) 
     where undefined symbols in shared libraries is normal. (The kernel 
     patches them at load time to select which function is most appropri- 
     ate for the current architecture. This is used for example to dynam- 
     ically select an appropriate memset function). Apparently it is also 
     normal for HPPA shared libraries to have undefined symbols. 

Die Sache ist, dass das, was oben gesagt wird, auch wahr ist, beispielsweise für Linux-Systeme, in denen einige der internen Routinen des gemeinsamen Bibliothek ist in ld-linux.so implementiert, der dynamische Loader (es ist sowohl ausführbare als auch freigegebene Bibliothek).

/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 
/usr/lib64/gcc/x86_64-suse-linux/4.3/libstdc++.so: undefined reference to `[email protected]_2.3' 
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 

Dies sind undefinierte Referenzen aus dem Lader, ld-linux.so: Wenn Sie es irgendwie miteinander verknüpfen, werden Sie so etwas wie dieses. Es ist plattformspezifisch (zum Beispiel ist auf meinem System der richtige Loader /lib64/ld-linux-x86-64.so). Sie können den Lader mit Ihrer Bibliothek verknüpfen und überprüfen auch die heikelen Referenzen oben gezeigt:

g++ -fPIC -shared -o liba.so a.o -Wl,--no-allow-shlib-undefined /lib64/ld-linux-x86-64.so.2 
+0

Nein, überhaupt kein Fehler, egal ob ich --no-allow-shlib-undefined oder --no-undefined verwende. –

+0

@Fredrik, ich nehme an, du hast vergessen, "-Wl" hinzuzufügen. Es * zeigt * Fehler, obwohl * nicht * der, den Sie wollten. Aber das ist das Meiste, was du haben kannst. –

+0

Es scheint --no-undefined funktioniert wie erwartet, aber --no-allow-shlib-undefined nicht. (Arbeiten wie du sagst.) –