Visual Studio Android 将程序集文件构建到应用程序中
Visual Studio Android building assembly files into app
我们有一个 Visual Studio Android 解决方案,其中包含一个静态库项目,其中包含以汇编实现的功能。喜欢:
my.S -> libMine.a -> libMyApp.so
为了编译,已经跳过了一些环节(如下)。然后,主应用程序共享库项目的 linking 失败(在我们关心的两种体系结构上 - x64 和 arm64),未定义对 [the] 程序集 [文件] 中实现的函数的引用。
Visual Studio(或其跨平台移动开发/Android 插件)似乎无法正确处理程序集文件项目项 - 被视为 C/C++编译器文件,它会在第一个点字符处出错(即在 .text
中); Microsoft 宏汇编器是 "not supported on this platform"。所以我研究了设置自定义构建步骤,使用以下命令:
$(ClangToolExe) %(FullPath) --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o
这将预处理、编译和 link - 但是错误的 linker: 而不是针对特定 Android 工具链的那个,它将用于我的 MinGW 安装无法识别仿真模式 - 无论如何,那不是我的 NDK 工具链的位置。
我们现在可以跳过对象的 linking(将 -c
添加到上述命令)。令我们沮丧的是,生成的目标文件仍然没有添加到静态库中,正如 {Rest of the toolchain path}ar t libMine.a
所确认的那样。事实上,该库将为我们的函数提供未定义的符号,如 {Rest of the toolchain path}objdump -t libMine.a
.
所示
让我们手动将目标文件添加到生成的库中,作为 post 构建步骤。命令:
$(ToolChainPrebuiltPath){Rest of the toolchain path}ar.exe ru $(TargetPath) $(IntDir)my.o
objdump -t libMine.a
现在将显示我们已获得符号。然而,还有 *UND*efined 对。
快进:
- 将
my.o
与 ar rub otherObjectThatReferencesMyFunctions.o libMine.a
相加,让好的符号出现在未定义的符号之前并没有什么不同。
- 将我编译的程序集文件与第二个自定义构建步骤链接起来,
$(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o
没有产生有意义的差异。
- 运行 linker 再次 在静态库 上,作为第二个 post-构建步骤
$(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath)
带来有意义的改变。
- 最后两个步骤导致关于缺少符号 _start(入口点?)的警告。我猜这是参考 linking 可执行文件,我们不想要它。
我做错了什么?我该如何解决那些未定义的引用?
似乎奏效的是:
1,确保程序集文件的扩展名是 .S
,即大写 S。这是我发现的少数几个文件名大小写 [=28] 的例子之一=].
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
作为 post 构建命令:{correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}
、每个程序集文件.
此解决方案缺少的一件事是检测 [缺少] 更改,这意味着将在每次编译时重建程序集文件,以及依赖它的所有内容。
我们有一个 Visual Studio Android 解决方案,其中包含一个静态库项目,其中包含以汇编实现的功能。喜欢:
my.S -> libMine.a -> libMyApp.so
为了编译,已经跳过了一些环节(如下)。然后,主应用程序共享库项目的 linking 失败(在我们关心的两种体系结构上 - x64 和 arm64),未定义对 [the] 程序集 [文件] 中实现的函数的引用。
Visual Studio(或其跨平台移动开发/Android 插件)似乎无法正确处理程序集文件项目项 - 被视为 C/C++编译器文件,它会在第一个点字符处出错(即在 .text
中); Microsoft 宏汇编器是 "not supported on this platform"。所以我研究了设置自定义构建步骤,使用以下命令:
$(ClangToolExe) %(FullPath) --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o
这将预处理、编译和 link - 但是错误的 linker: 而不是针对特定 Android 工具链的那个,它将用于我的 MinGW 安装无法识别仿真模式 - 无论如何,那不是我的 NDK 工具链的位置。
我们现在可以跳过对象的 linking(将 -c
添加到上述命令)。令我们沮丧的是,生成的目标文件仍然没有添加到静态库中,正如 {Rest of the toolchain path}ar t libMine.a
所确认的那样。事实上,该库将为我们的函数提供未定义的符号,如 {Rest of the toolchain path}objdump -t libMine.a
.
让我们手动将目标文件添加到生成的库中,作为 post 构建步骤。命令:
$(ToolChainPrebuiltPath){Rest of the toolchain path}ar.exe ru $(TargetPath) $(IntDir)my.o
objdump -t libMine.a
现在将显示我们已获得符号。然而,还有 *UND*efined 对。
快进:
- 将
my.o
与ar rub otherObjectThatReferencesMyFunctions.o libMine.a
相加,让好的符号出现在未定义的符号之前并没有什么不同。 - 将我编译的程序集文件与第二个自定义构建步骤链接起来,
$(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o
没有产生有意义的差异。 - 运行 linker 再次 在静态库 上,作为第二个 post-构建步骤
$(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath)
带来有意义的改变。 - 最后两个步骤导致关于缺少符号 _start(入口点?)的警告。我猜这是参考 linking 可执行文件,我们不想要它。
我做错了什么?我该如何解决那些未定义的引用?
似乎奏效的是:
1,确保程序集文件的扩展名是 .S
,即大写 S。这是我发现的少数几个文件名大小写 [=28] 的例子之一=].
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
作为 post 构建命令:{correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}
、每个程序集文件.
此解决方案缺少的一件事是检测 [缺少] 更改,这意味着将在每次编译时重建程序集文件,以及依赖它的所有内容。