【发布时间】: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.o与ar 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