推出Android原生開發工具包r16

谷歌開發者_發表於2017-09-22

0?wx_fmt=gif&wxfrom=5&wx_lazy=1


文 / Google Android NDK 技術負責人 Dan Albert

最新版本的 Android 原生開發工具包 (NDK) Android NDK r16 Beta 1 現在可以下載了:

https://developer.android.google.cn/ndk/downloads/index.html


也可以通過 Android Studio 在 SDK 管理器中獲取此版本。

NDK r16 對我們來說是一個重大的里程碑,因為它是我們準備建議使用者開始遷移到 libc++ 的第一個版本!我們會在後面提供更多資訊。

我們還更新了 libc++ 及其相關專案,因此,這個版本提升了對 C++1z 的支援。請注意,在 C++1z 成為 C++17 之前,包含的任何內容都有可能發生變化。

您可以在此處檢視該版本的版本說明:

https://android.googlesource.com/platform/ndk/+/ndk-release-r16/CHANGELOG.md



libc++ 和 libandroid_support

NDK 有一個名為 libandroid_support 的庫,這個庫可以向後移植 libc++ 依賴、但舊版本不支援的 libc API。我們至今無法認可 libc++(在 NDK 中實現)的原因仍然是對這個庫缺乏信心。r16 的焦點是重新編寫了這個庫,以獲得更高的穩定性。

由於 libandroid_support 現在是一個比較小的庫,您的應用的行為應當更接近系統的行為。例如,libandroid_support 之前包含對部分 stdio 的替代實現。儘管一些功能向後移植到 ICS,不過,這也意味著替代實現中的任何錯誤都會出現在自從您的應用引入錯誤以來發布的 所有 OS 版本中。


在新版本的 libandroid_support 中,我們已將替代實現移除,因此您在較舊的裝置上將無法使用某些功能(幾乎是一些沒人使用的功能,例如格式字串中的 %a 支援),不過由於沒有這些功能,您使用 libc++ 的應用將變得更小、更可靠。



轉到 libc++

所以,為什麼您應轉到 libc++ 呢?首先,其他 STL 今後將不再受支援。我們一直將 libc++ 用於自 Lollipop 以來的 Android 平臺,有一項變化讓我們的工程師感到非常興奮。我們在平臺中比在 NDK 中更早地完成了這種過渡,因為我們不需要 libandroid_support,並且可以僅更新 libc。

與 NDK 中當前可用的其他 STL 相比,libc++ 完全支援 C++11、C++14 和大多數的 C++1z!Stlport 自從 2008 年以來就沒有更新過了,gnustl(我們對 GNU 的 libstdc++ 的叫法,這是為了避免與 Bionic 的 libstdc++ 混淆,後者不是一種 STL)一直以來都不是很適合 Clang,尤其是在與 和 之類的編譯器內建函式緊密關聯的標頭中,更是如此。

我們很有可能讓 libc++ 成為下一個 NDK 版本的預設選擇,但是現在,如果您還沒用過,可以按照下面的說明操作,選擇啟用這種庫。

像其他 STL 一樣,libc++ 同時提供靜態庫和共享庫。使用哪一個取決於您的具體情況,但是如果您的應用中有且僅有一個共享庫,tl;dr 將使用靜態版本,並在所有其他情況下使用共享版本。


ndk-build

將以下內容新增至您的 Application.mk 檔案中:

APP_STL := c++_shared

CMake

呼叫 CMake 時請貼上以下內容:

-DANDROID_STL=c++_shared


如果您正在通過 Gradle 使用 CMake,請將以下內容新增至您的 build.gradle 中:

externalNativeBuild {
    cmake {
        arguments "-DANDROID_STL=c++_shared"
    }
}

獨立工具鏈
在建立獨立工具鏈時,請傳遞 --stl=libc++。



libandroid_support 的未來

如果您已經閱讀我們的路線圖:

https://android.googlesource.com/platform/ndk/+/master/docs/Roadmap.md


想必瞭解我們計劃擴充套件 libandroid_support 以向後移植儘可能多的 libc/libm。每次跟大家說到這個問題,我們最多隻是收到冷淡的迴應。考慮到大家看起來不感興趣,而且這樣做也會讓庫增大(進而導致 APK 增大,這是每個人都非常感興趣的話題),我們不再打算擴充套件。

如果我們誤解了您的迴應,或者您還沒有迴應我們,並且希望我們擴充套件,請告訴我們:

https://github.com/android-ndk/ndk/issues/456



_FILE_OFFSET_BITS=64

tl;dr:如果您想要保留舊 NDK 中的行為,請不要設定 _FILE_OFFSET_BITS=64。

在 NDK 中設定 _FILE_OFFSET_BITS=64 一直都沒什麼用。此功能在棄用的標頭中已經移除。對於統一標頭,NDK 現在具有支援此功能的最新標頭。

您可以在您的應用中定義 _FILE_OFFSET_BITS=64 巨集,以便在 32 位程式碼中獲取對 64 位 off_t 的支援。將 off_t 設為 64 位(預設情況下,它在 32 位程式碼中為 32 位)和使用 lseek64 呼叫隱式替換對 lseek 之類 API 的呼叫可以實現這種支援。

之前版本的 Android 沒有新增對 _FILE_OFFSET_BITS=64 的支援。lseek64 這個 API 一直在 bionic 中。大多數 API 在 Lollipop 中新增,其他的一些 API 則到後期版本才新增。

如果您針對的版本不支援正在使用的某個函式的 64 位 off_t 變體,並且已設定 _FILE_OFFSET_BITS=64,該函式將不可用。這與 r15 和 r15b 的行為不同(但與 r15c 的行為一致),在這兩個版本中,函式使用 32 位 off_t 錯誤公開,將被靜默截斷。

請注意,即使沒有不同名稱的 _FILE_OFFSET_BITS=64,64 位 off_t API 仍然可用。例如,請呼叫 lseek64,而不是 lseek。使用 off64_t,而不是 off_t。

最後,由於此功能對具有統一標頭的 NDK 來說是一項新功能,如果您只想返回到統一前的標頭行為,您要做的只是停止設定 _FILE_OFFSET_BITS=64。

如需瞭解有關 bionic 中 off_t ABI 詳細資訊的更多資訊,請參閱 Bionic 32 位 ABI 錯誤文件:

https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md


推薦閱讀:

AMP Roadshow技術分享路演中國專場報名開始了!

Android 8.0 Oreo 國內可用測試平臺上線

Android Vitals 讓您的應用擁有卓越效能

解析ConstraintLayout的效能優勢


檢視全文及文中連結,請點選文末“閱讀原文”。


0?wx_fmt=gif

相關文章