Frage

Ich habe ein kleines Stück Code, das auf vielen statischen Bibliotheken abhängt (a 1-a_n). Ich mag, dass Code in einer statischen Bibliothek verpacken und zu anderen Menschen zur Verfügung zu stellen.

Meine statische Bibliothek, nennen wir es X kompiliert in Ordnung.

Ich habe ein einfaches Beispielprogramm erstellt, das eine Funktion von X verwendet, aber wenn ich versuche, es zu X zu verbinden, erhalte ich über viele Fehler Symbole aus Bibliotheken A_1 fehlt -. A_n

Gibt es eine Möglichkeit, dass ich eine neue statische Bibliothek erstellen kann, Y, die X und alle Funktionen von X (ausgewählten Bits von a 1 - a_n) benötigt enthält, so dass ich nur Y verteilen kann für Menschen, ihre Programme verlinken auf ?


UPDATE:

Ich habe bei nur Dumping alles sah mit ar und machen ein Mega-lib jedoch, dass endet eine Menge von Symbolen enthält, die nicht benötigt werden (alle die .o-Dateien sind über 700 MB jedoch ein statisch gelinkte ausführbar sind 7 MB). Gibt es eine schöne Möglichkeit, nur zu schließen, was notwendig ist eigentlich?


Das sieht eng verwandt mit Wie mehrere C / C ++ Bibliotheken in einem? kombinieren.

War es hilfreich?

Lösung

Statische Bibliotheken verknüpfe nicht mit anderen statischen Bibliotheken. Der einzige Weg, dies zu tun ist Ihren Bibliothekar / Archivierungs-Tool verwenden (zum Beispiel ar auf Linux) eine einzige neue statische Bibliothek zu erstellen, indem die mehrere Bibliotheken verketten.

Edit: Als Reaktion auf das Update, der einzige Weg, ich kenne nur die Symbole auszuwählen, die erforderlich sind, um die Bibliothek manuell aus der Teilmenge der .o-Dateien zu erstellen, die sie enthalten. Dies ist schwierig, zeitaufwendig und fehleranfällig. Ich bin mir nicht bewusst, werkzeuglos zu helfen tut dies (nicht zu sagen, dass sie nicht existieren), aber es wäre durchaus ein interessantes Projekt zu produzieren machen.

Andere Tipps

Wenn Sie Visual Studio verwenden, dann ja, Sie können dies tun.

Die Bibliothek Builder-Tool, das kommt mit Visual Studio ermöglicht es Ihnen, Bibliotheken zusammen auf der Kommandozeile zu verbinden. Ich weiß nicht von irgendeiner Weise obwohl dies im visuellen Editor zu tun.

lib.exe /OUT:compositelib.lib  lib1.lib lib2.lib

Unter Linux oder MingW mit GNU-Toolchain:

ar -M <<EOM
    CREATE libab.a
    ADDLIB liba.a
    ADDLIB libb.a
    SAVE
    END
EOM
ranlib libab.a

Wenn Sie nicht löschen liba.a und libb.a, können Sie einen „thin-Archiv“ machen:

ar crsT libab.a liba.a libb.a

Unter Windows mit MSVC Toolchain:

lib.exe /OUT:libab.lib liba.lib libb.lib

Eine statische Bibliothek ist nur ein Archiv von .o Objektdateien. Extrahieren Sie sie mit ar (vorausgesetzt, Unix) und packen sie wieder in eine große Bibliothek.

Als Alternative zu Link Library Dependencies in Projekteigenschaften gibt es eine andere Art und Weise zu Link Libraries in Visual Studio.

  1. Öffnen Sie das Projekt der Bibliothek (X), dass Sie mit anderen Bibliotheken kombiniert werden sollen.
  2. Fügen Sie die anderen Bibliotheken, die Sie mit X kombiniert werden sollen (Rechtsklick, Add Existing Item...).
  3. Gehen Sie auf ihre Eigenschaften und stellen Sie sicher, Item Type ist Library

Damit werden die anderen Bibliotheken in X enthalten, als ob Sie lief

lib /out:X.lib X.lib other1.lib other2.lib

Beachten Sie, bevor Sie lesen den Rest: Das Shell-Skript hier gezeigt ist sicherlich nicht sicher zu bedienen und gut getestet. Benutzung auf eigene Gefahr!

Ich schrieb einen Bash-Skript, diese Aufgabe zu erfüllen. Angenommen, Ihre Bibliothek ist lib1 und die, die Sie brauchen, um einige Symbole sind von lib2 ist. Das Skript läuft nun in einer Schleife, wo es zuerst überprüft, welche Symbole von lib1 undefined in lib2 finden. Es extrahiert dann die entsprechenden Objektdateien aus lib2 mit ar, benennt sie ein wenig, und setzt sie in lib1. Nun kann es mehr Symbole fehlen, weil das Material, das Sie von lib2 enthalten andere Sachen aus lib2 braucht, die wir noch nicht aufgenommen haben, so dass die Schleife erneut ausgeführt werden muss. Wenn nach einigen Durchläufen der Schleife mehr da keine Änderungen sind, das heißt keine Objektdateien von lib2 zu lib1 hinzugefügt, kann die Schleife stoppen.

Beachten Sie, dass die darin enthaltenen Symbole weiterhin als nicht definiert durch nm berichtet, so dass ich den Überblick über die Objektdateien zu halten bin, das zu lib1 hinzugefügt wurde, selbst, um zu bestimmen, ob die Schleife gestoppt werden kann.

#! /bin/bash

lib1="$1"
lib2="$2"

if [ ! -e $lib1.backup ]; then
    echo backing up
    cp $lib1 $lib1.backup
fi

remove_later=""

new_tmp_file() {
    file=$(mktemp)
    remove_later="$remove_later $file"
    eval $1=$file
}
remove_tmp_files() {
    rm $remove_later
}
trap remove_tmp_files EXIT

find_symbols() {
    nm $1 $2 | cut -c20- | sort | uniq 
}

new_tmp_file lib2symbols
new_tmp_file currsymbols

nm $lib2 -s --defined-only > $lib2symbols

prefix="xyz_import_"
pass=0
while true; do
    ((pass++))
    echo "Starting pass #$pass"
    curr=$lib1
    find_symbols $curr "--undefined-only" > $currsymbols
    changed=0
    for sym in $(cat $currsymbols); do
        for obj in $(egrep "^$sym in .*\.o" $lib2symbols | cut -d" " -f3); do
            echo "  Found $sym in $obj."
            if [ -e "$prefix$obj" ]; then continue; fi
            echo "    -> Adding $obj to $lib1"
            ar x $lib2 $obj
            mv $obj "$prefix$obj"
            ar -r -s $lib1 "$prefix$obj"
            remove_later="$remove_later $prefix$obj"
            ((changed=changed+1))
        done
    done
    echo "Found $changed changes in pass #$pass"

    if [[ $changed == 0 ]]; then break; fi
done

ich das Skript libcomp benannt, so dass man es so nennen kann z.B. mit

./libcomp libmylib.a libwhatever.a

wo libwhatever ist, wo Sie aufnehmen möchten Symbole aus. Aber ich denke, es ist am sichersten zuerst alles in ein separates Verzeichnis zu kopieren. Ich würde meinem Skript nicht so viel Vertrauen (aber es funktionierte für mich, ich libgsl.a in meine Numerik-Bibliothek mit, dass beinhalten könnte und auslassen, dass -lgsl Compiler-Schalter).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top