2017-05-03 73 views
0

我們已經有了一個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.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(入口點?)的警告。我猜這是關於鏈接可執行文件,這是我們不想要的。

我在做什麼錯?我怎樣才能解決那些未定義的參考?

回答

0

什麼似乎已經奏效是:

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}用於每個組件的文件

此解決方案缺乏的一件事是檢測[缺少]更改,這意味着彙編文件將在每個編譯中重建,並取決於它。

+1

gcc/clang在Windows上的工作方式與Unix/Linux上的相同。 'clang -c foo.S'通過C預處理器運行它,然後將它送入彙編器。 '.s'沒有。使用'.S'作爲手寫的asm源代碼,併爲編譯器生成的asm保留'.s'(例如'gcc -save-temps'或'gcc -S foo.c')。 –

相關問題