2017-05-03 4 views
0

Nous avons une solution Visual Studio Android avec (entre autres) un projet de bibliothèque statique qui contient des fonctionnalités implémentées dans l'assemblage. Comme:Fichiers de l'assemblage Visual Studio Android dans l'application

my.S -> libMine.a -> libMyApp.so 

Certains cercles (ci-dessous) ont déjà été sautés, pour le compiler. Ensuite, la liaison du projet de bibliothèque partagée de l'application principale échoue (sur les deux architectures qui nous intéressent - x64 et arm64), avec des références non définies aux fonctions implémentées dans [l'assemblage] [fichier]. Il semble que Visual Studio (ou son plug-in Cross Platform Mobile/Android) ne gère pas correctement les éléments de projet de fichier d'assemblage - traités comme des fichiers du compilateur C/C++, il va erreur sur le premier point caractère (c'est-à-dire .text); et Microsoft Macro Assembler n'est "pas pris en charge sur cette plate-forme". Alors j'ai regardé dans la mise en place d'une étape de génération personnalisée, avec la commande suivante:

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

Cette volonté prétraiter, compilez et lien - mais avec l'éditeur de liens mal: au lieu de celui de la chaîne d'outils Android particulier, il va optez pour celui de mon installation MinGW, qui ne reconnaît pas le mode d'émulation - de toute façon, ce n'est pas l'emplacement de ma chaîne d'outils NDK.

Nous pouvons ignorer la liaison de l'objet pour l'instant (ajoutez -c à la commande ci-dessus). À notre grande consternation, le fichier objet résultant n'est toujours pas ajouté à la bibliothèque statique, comme confirmé par {Rest of the toolchain path}ar t libMine.a. Et en effet, la bibliothèque aura des symboles indéfinis pour nos fonctions, comme indiqué par {Rest of the toolchain path}objdump -t libMine.a.

Ajoutons le fichier objet à la bibliothèque résultante tout à fait manuellement, en tant qu'étape de post-construction. Commande:

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

objdump -t libMine.a indique maintenant que nous avons les symboles. Il y a cependant aussi la paire * UND * définie.

Avance rapide:

  • Ajout my.o avec ar rub otherObjectThatReferencesMyFunctions.o libMine.a, d'avoir les bons symboles apparaissent avant ceux non définis ne fait pas de différence.
  • Lier mon fichier assemblé compilé avec une deuxième étape de génération personnalisée, $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o ne fait pas de différence significative.
  • L'exécution de l'éditeur de liens à nouveau sur la bibliothèque statique, comme une deuxième étape de post-construction $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath) ne fait pas une différence significative.
  • Les deux dernières étapes entraînent un avertissement concernant un symbole manquant _start (point d'entrée?). Je suppose que c'est en référence à la liaison un exécutable, que nous ne voulons pas.

Qu'est-ce que je fais mal? Comment puis-je résoudre ces références non définies?

Répondre

0

Ce qui semble avoir travaillé était de:

1, Assurez-vous que l'extension du fichier d'assemblage est .S, à savoir le capital S. Ceci est l'un des rares cas que j'ai trouvé, où le cas de un nom de fichier est important sur Windows.

2, configurer le projet afin que le fichier d'assemblage est construit avec clang.exe {full/path/to/assembly.S, i.e. %(FullPath)} -c --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o. Dans le cas de VS Android, nous avons besoin de spécifier la sortie de construction séparément, ce qui est la partie $(IntDir)%(FileName).o tout recommencer.

3, Run ar en tant que poste de commandement de construction: {correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}, pour chaque fichier d'assemblage.

Une chose cette solution manque détecte [manque] de changements, ce qui signifie que le fichier d'assemblage sera reconstruit sur chaque compilation, et tout ce qui en dépend.

+1

travail gcc/clang même sous Windows comme sous Unix/Linux. 'Clang -c foo.S' il traverse le préprocesseur C avant de l'introduire dans l'assembleur. '.s' ne le fait pas. Utilisez '.S' pour la source asm écrite à la main, et lui laisser' .s' pour asm généré par le compilateur (comme de gcc -save-temps' ou gcc -S foo.c'). –