我们已经有了一个Visual Studio Android解决方案,其中包含一个静态库项目,其中包含在程序集中实现的功能。像:Visual Studio Android将构建程序集文件转换为应用程序
my.S -> libMine.a -> libMyApp.so
一些箍(下)已经跳过,让它编译。然后,主应用程序共享库项目的链接失败(在我们关心的两种体系结构 - x64和arm64上),以及未定义的对[assembly] [file]中实现的函数的引用。
似乎Visual Studio(或其跨平台移动开发/ 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(入口点?)的警告。我猜这是关于链接可执行文件,这是我们不想要的。
我在做什么错?我怎样才能解决那些未定义的参考?
gcc/clang在Windows上的工作方式与Unix/Linux上的相同。 'clang -c foo.S'通过C预处理器运行它,然后将它送入汇编器。 '.s'没有。使用'.S'作为手写的asm源代码,并为编译器生成的asm保留'.s'(例如'gcc -save-temps'或'gcc -S foo.c')。 –