我們已經有了一個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')。 –