Das Problem, wie ich es verstehe, ist wie folgt. Sie haben mehrere Bibliotheken, einige statische, einige dynamische und einige sowohl statische als auch dynamische. Das Standardverhalten von gcc besteht darin, "meist dynamisch" zu verknüpfen. Das heißt, gcc verlinkt nach Möglichkeit auf dynamische Bibliotheken , greift aber ansonsten auf statische Bibliotheken zurück. Wenn Sie die Option -static für gcc verwenden, besteht das Verhalten darin, nur statische Bibliotheken zu verknüpfen und mit einem Fehler zu beenden , wenn keine statische Bibliothek gefunden werden kann, selbst wenn eine geeignete dynamische Bibliothek vorhanden ist.
Eine weitere Option, die ich bei verschiedenen Gelegenheiten haben wollte gcc hatte, nenne ich -meist statisch und ist im Wesentlichen das Gegenteil von -Dynamic (Standardeinstellung). -mostly-static würde, falls vorhanden, lieber eine Verknüpfung mit statischen Bibliotheken herstellen, würde jedoch auf dynamische Bibliotheken zurückgreifen.
Diese Option existiert nicht, kann jedoch mit dem folgenden Algorithmus emuliert werden:
Erstellen der Link-Befehlszeile ohne Einbeziehung von -static .
Durchlaufen Sie die dynamischen Verknüpfungsoptionen.
Akkumulieren Sie Bibliothekspfade, dh diese Optionen der Form -L <Lib_Dir> in einer Variablen <Lib_Pfad>
Führen Sie für jede Option für dynamische Verknüpfungen, dh für die Form -l <Lib -Name > , den Befehl gcc <Lib_Pfad> -print-Dateiname = lib <Lib_name> .a aus und erfassen Sie die Ausgabe.
Wenn der Befehl etwas anderes als das ausgibt, was Sie übergeben haben, ist dies der vollständige Pfad zur statischen Bibliothek. Ersetzen Sie die Option für die dynamische Bibliothek durch den vollständigen Pfad zur statischen Bibliothek.
Spülen und wiederholen, bis Sie die gesamte Link-Befehlszeile verarbeitet haben. Optional kann das Skript auch eine Liste von Bibliotheksnamen verwenden, um diese von der statischen Verknüpfung auszuschließen.
Das folgende Bash-Skript scheint den Trick zu tun:
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: $0 [--exclude <lib_name>]. . . <link_command>"
fi
exclude=()
lib_path=()
while [ $# -ne 0 ]; do
case "$1" in
-L*)
if [ "$1" == -L ]; then
shift
LPATH="-L$1"
else
LPATH="$1"
fi
lib_path+=("$LPATH")
echo -n "\"$LPATH\" "
;;
-l*)
NAME="$(echo $1 | sed 's/-l\(.*\)/\1/')"
if echo "${exclude[@]}" | grep " $NAME " >/dev/null; then
echo -n "$1 "
else
LIB="$(gcc $lib_path -print-file-name=lib"$NAME".a)"
if [ "$LIB" == lib"$NAME".a ]; then
echo -n "$1 "
else
echo -n "\"$LIB\" "
fi
fi
;;
--exclude)
shift
exclude+=(" $1 ")
;;
*) echo -n "$1 "
esac
shift
done
echo
Beispielsweise:
mostlyStatic gcc -o test test.c -ldl -lpthread
auf meinem System gibt zurück:
gcc -o test test.c "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libdl.a" "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libpthread.a"
oder mit einem Ausschluss:
mostlyStatic --exclude dl gcc -o test test.c -ldl -lpthread
Ich bekomme dann:
gcc -o test test.c -ldl "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libpthread.a"