2017-05-03 3 views
0

Wir haben eine Visual Studio Android-Lösung mit (unter anderem) einem statischen Bibliotheksprojekt, das Funktionalität in Assembly implementiert enthält. Wie:Visual Studio Android Gebäude Assembly Dateien in App

Einige Reifen (unten) wurden bereits durchgesprungen, um es kompilieren zu lassen. Dann schlägt die Verknüpfung des Hauptprojekts der gemeinsam benutzten Bibliothek fehl (auf beiden Architekturen, die uns interessieren - x64 und arm64), mit undefinierten Verweisen auf die Funktionen, die in [der] Assembly [Datei] implementiert sind.

Es scheint, dass Visual Studio (oder sein Cross Platform Mobile Dev/Android-Plug-In) nicht richtig mit Assembly-Datei-Projektelementen umgehen kann - behandelt als C/C++ Compiler-Dateien, es wird auf den ersten Punkt Fehler ausgegeben Zeichen (zB in .text); und der Microsoft Macro Assembler wird "auf dieser Plattform nicht unterstützt". So in ich sah einen benutzerdefinierten Schritt, mit dem folgenden Befehl einrichten:

$(ClangToolExe) %(FullPath) --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o 

Dies wird vorverarbeitet, kompiliert und verknüpfen - aber mit dem falschen Linker: statt dem für den bestimmten Android-Toolchain, es würde Gehen Sie für den in meiner MinGW-Installation, der den Emulationsmodus nicht erkennt - das ist nicht der Speicherort meiner NDK-Toolchain.

Wir können die Verknüpfung des Objekts für jetzt überspringen (fügen Sie -c zum obigen Befehl hinzu). Zu unserer Bestürzung wird die resultierende Objektdatei immer noch nicht zur statischen Bibliothek hinzugefügt, wie von {Rest of the toolchain path}ar t libMine.a bestätigt. Und tatsächlich wird die Bibliothek nicht definierte Symbole für unsere Funktionen haben, wie {Rest of the toolchain path}objdump -t libMine.a zeigt.

Lassen Sie uns die Objektdatei ziemlich manuell hinzufügen, als Post-Build-Schritt. Befehl:

$(ToolChainPrebuiltPath){Rest of the toolchain path}ar.exe ru $(TargetPath) $(IntDir)my.o 

objdump -t libMine.a wird nun zeigen, dass wir die Symbole haben. Es gibt aber auch das * UND * efined-Paar.

Schneller Vorlauf:

  • Hinzufügen my.o mit ar rub otherObjectThatReferencesMyFunctions.o libMine.a, die guten Symbole vor den undefiniert denjenigen zeigen, bis zu keinem Unterschied machen.
  • Verknüpfen meiner kompilierten Assembly-Datei mit einem zweiten benutzerdefinierten Erstellungsschritt macht $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o keinen sinnvollen Unterschied.
  • Der Linker erneut auf der statischen Bibliothek ausgeführt, als ein zweiter Post-Build-Schritt $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath) macht keinen sinnvollen Unterschied.
  • Die letzten beiden Schritte führen zu einer Warnung vor einem fehlenden Symbol _start (Einstiegspunkt?). Ich schätze, das ist in Bezug auf die Verknüpfung eine ausführbare, die wir nicht wollen.

Was mache ich falsch? Wie kann ich diese undefinierten Referenzen auflösen?

Antwort

0

Was war zu haben scheint gearbeitet: sure

1, machen, dass die Verlängerung der Baugruppendatei .S, dh Kapital S. Dies ist einer der wenigen Fälle, die ich gefunden habe, wo der Fall Ein Dateiname ist wichtig für Windows.

2, Konfigurieren Sie das Projekt so, dass die Assemblydatei mit clang.exe {full/path/to/assembly.S, i.e. %(FullPath)} -c --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o erstellt wird. Im Fall von VS Android müssen wir die Build-Ausgabe separat angeben, was wiederum der $(IntDir)%(FileName).o-Teil ist.

3, Run ar als Post build-Befehl: {correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}, für jede Baugruppendatei.

Eine Sache, die diese Lösung fehlt, ist das Erkennen von [fehlenden] Änderungen, was bedeutet, dass die Assemblydatei bei jeder Kompilierung neu erstellt wird und alles, was davon abhängt.

+1

gcc/clang funktionieren unter Windows genauso wie unter Unix/Linux. 'clang -c foo.S' führt es durch den C-Präprozessor, bevor es dem Assembler zugeführt wird. '.s' nicht. Verwenden Sie '.S' für handgeschriebene Asm-Quellen und lassen Sie' .s' für Compiler-generierte Asms (wie von 'gcc -save-temps' oder' gcc -S foo.c'). –

Verwandte Themen