【问题标题】:Visual Studio Android building assembly files into appVisual Studio Android 将程序集文件构建到应用程序中
【发布时间】:2017-05-03 15:16:00
【问题描述】:

我们有一个 Visual Studio Android 解决方案,其中包含一个静态库项目,其中包含在程序集中实现的功能。喜欢:

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

一些箍(下)已经被跳过,让它编译。然后,主应用程序共享库项目的链接失败(在我们关心的两种架构 - x64 和 arm64 上),对 [the] 程序集 [file] 中实现的函数的未定义引用。

Visual Studio(或其 Cross Platform Mobile Dev / Android 插件)似乎不能完全正确地处理程序集文件项目项 - 被视为 C/C++ 编译器文件,它会在第一个点字符上出错(即在.text);并且“此平台不支持 Microsoft 宏汇编程序”。因此,我研究了使用以下命令设置自定义构建步骤:

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

这将预处理、编译和链接——但使用了错误的链接器:而不是用于特定 Android 工具链的链接器,而是用于我的 MinGW 安装中的那个,它无法识别仿真模式——无论如何,那不是我的 NDK 工具链的位置。

我们现在可以跳过对象的链接(在上面的命令中添加-c)。令我们沮丧的是,生成的目标文件仍然没有添加到静态库中,正如{Rest of the toolchain path}ar t libMine.a 所证实的那样。实际上,该库将包含我们函数的未定义符号,如{Rest of the toolchain path}objdump -t libMine.a 所示。

让我们手动将目标文件添加到生成的库中,作为后期构建步骤。命令:

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

objdump -t libMine.a 现在将显示我们已经获得了符号。然而,还有 *UND* 定义的对。

快进:

  • my.oar rub otherObjectThatReferencesMyFunctions.o libMine.a 添加在一起,以便在未定义的符号没有影响之前显示好的符号。
  • 将我已编译的程序集文件与第二个自定义构建步骤 $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o 链接起来没有任何意义。
  • 再次在静态库上运行链接器,作为构建后的第二个步骤$(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath) 并没有什么意义。
  • 最后两个步骤会导致关于缺少符号 _start(入口点?)的警告。我猜这是指链接可执行文件,这是我们不想要的。

我做错了什么?如何解决那些未定义的引用?

【问题讨论】:

    标签: android visual-studio assembly ld unix-ar


    【解决方案1】:

    似乎有效的是:

    1,确保程序集文件的扩展名是 .S,即大写 S。这是我发现的少数情况之一,文件名的大小写在 Windows 上很重要。

    2、配置项目,使程序集文件使用clang.exe {full/path/to/assembly.S, i.e. %(FullPath)} -c --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o构建。在 VS Android 的情况下,我们需要单独指定构建输出,也就是 $(IntDir)%(FileName).o 部分。

    3,运行 ar 作为构建后命令:{correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}对于每个程序集文件

    此解决方案缺少的一件事是检测 [缺少] 更改,这意味着将在每次编译时重新构建程序集文件,以及依赖于它的所有内容。

    【讨论】:

    • gcc/clang 在 Windows 上的工作方式与在 Unix/Linux 上的工作方式相同。 clang -c foo.S 在将其提供给汇编程序之前通过 C 预处理器运行它。 .s 没有。将.S 用于手写asm 源,将.s 用于编译器生成的asm(例如来自gcc -save-tempsgcc -S foo.c。)
    猜你喜欢
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多