Flutter Engine環境搭建

大逗大人發表於2020-02-22

對於深入學習Flutter來說,搭建一個Engine環境是很有必要的。EngineFlutter底層(C/C++)的實現,包含了Dart VM、Skia、vulkan等第三方庫。

1、環境準備

由於需要訪問谷歌去拉取原始碼,所以必須設定好代理,包括:

  • git的http/https代理
  • 終端的http/https代理

只有當代理設定成功後,後面的操作才會順利,否則有可能因為網路原因從而導致失敗。關於代理的具體設定可以去百度/谷歌搜一下。

在拉取程式碼前,需要先把依賴工具準備好。

  • Linux、macOS或Windows,最好macOS,因為MacOS同時支援Android和iOS的交叉編譯功能。
  • git,版本控制。
  • IDE,官方建議Android Studio。
  • ssh client,用於Github的身份認證,具體配置參考Connecting to GitHub with SSH
  • depot_tools,該工具包含gclient命令。
  • Python及Java環境。

2、Engine原始碼下載

環境準備好後,就可以來下載Engine原始碼。首先來建立一個空資料夾——engine,當然也可以使用其他名稱。然後在該資料夾中建立一個.gclient檔案,內容如下:

solutions = [
  {
    "managed": False,
    "name": "src/flutter",
    "url": "git@github.com:<your_name_here>/engine.git",
    "custom_deps": {},
    "deps_file": "DEPS",
    "safesync_url": "",
  },
]
複製程式碼

關於這裡的url,需要注意一下,如果自己的GitHub賬戶沒有forkhttps://github.com/flutter/engine,那麼就需要先fork,然後用自己的賬戶名稱替換<your_name_here>。如果不想fork,可以用flutter替換<your_name_here>。

注意: 建立的檔名稱是.gclient,而不是檔案的字尾為.gclient。建立成功後,不會在資料夾中顯示,但可以通過vim來檢視該檔案。

.gclient檔案建立成功後,進入engine這個空資料夾,然後執行gclient sync命令來下載Engine原始碼。這時候就需要拼網速或者訪問谷歌是否穩定,如果一切順利(可能幾個小時),目錄如下。

Flutter Engine環境搭建

3、Engine編譯

再看來Engine的編譯。進入src目錄,就可以通過一些命令來進行編譯Engine,如下:

./flutter/tools/gn --android --runtime-mode=debug
ninja -C out/android_debug -j 6
./flutter/tools/gn --runtime-mode=debug
ninja -C out/host_debug -j 6
複製程式碼

通過上面命令就可以編譯能在Android上執行且cpu型別為armeabi_v7a的產物。

再通過./flutter/tools/gn --help命令來看一下其他引數。

usage: gn [-h] [--unoptimized]
          [--runtime-mode {debug,profile,release,jit_release}] [--interpreter]
          [--dart-debug] [--full-dart-debug]
          [--target-os {android,ios,linux,fuchsia}] [--android]
          [--android-cpu {arm,x64,x86,arm64}] [--ios] [--ios-cpu {arm,arm64}]
          [--simulator] [--fuchsia] [--linux-cpu {x64,x86,arm64,arm}]
          [--fuchsia-cpu {x64,arm64}] [--arm-float-abi {hard,soft,softfp}]
          [--goma] [--no-goma] [--lto] [--no-lto] [--clang] [--no-clang]
          [--clang-static-analyzer] [--no-clang-static-analyzer]
          [--target-sysroot TARGET_SYSROOT]
          [--target-toolchain TARGET_TOOLCHAIN]
          [--target-triple TARGET_TRIPLE]
          [--operator-new-alignment OPERATOR_NEW_ALIGNMENT] [--enable-vulkan]
          [--enable-metal] [--enable-fontconfig] [--enable-skshaper]
          [--enable-vulkan-validation-layers] [--embedder-for-target]
          [--coverage] [--out-dir OUT_DIR] [--full-dart-sdk]
          [--no-full-dart-sdk] [--ide IDE] [--build-glfw-shell] [--bitcode]
          [--stripped] [--no-stripped] [--asan] [--lsan] [--msan] [--tsan]
          [--ubsan]
複製程式碼

引數眾多,來看幾個常用的。

  • --unoptimized,是否優化效能,預設優化。
  • --runtime-mode,flutter的執行模式,有debug,profile,release,jit_release四種選擇。
  • --target-os,目標系統,有android,ios,linux,fuchsia四種選擇。--target-os=android等同於--android命令,--target-os=ios等同於--ios命令,以此類推。
  • --android-cpu,Android所執行平臺,有arm,x64,x86,arm64四種選擇。如果要在Android模擬器上執行,則--android-cpu=x86。注意: 這裡的arm其實對應的是armeabi_v7a。但如果要編譯armeabi(Google目前已經不建議使用armeabi),可以參考Flutter Engine 編譯指北這篇文章。
  • --simulator,iOS所執行平臺為模擬器。
  • --ios-cpu,iOS所執行平臺,有arm,arm64兩種選擇。

通過對上面命令的組合,就可以編譯Android及iOS平臺上不同CPU型別的產物。

例如,Android平臺,cpu型別為arm64,執行模式為debug的產物。

./flutter/tools/gn --android --runtime-mode=debug --android-cpu=arm64 
ninja -C out/android_debug_arm64 -j 6
./flutter/tools/gn --runtime-mode=debug --android-cpu=arm64
ninja -C out/host_debug_arm64 -j 6
複製程式碼

例如,iOS平臺,cpu型別為arm64,執行模式為debug的產物。

./flutter/tools/gn --ios --runtime-mode=debug --ios-cpu=arm64 
ninja -C out/ios_debug_arm64 -j 6
./flutter/tools/gn --runtime-mode=debug --ios-cpu=arm64
ninja -C out/host_debug_arm64 -j 6
複製程式碼

4、執行及IDE支援

編譯成功後,就可以在執行flutter專案時使用編譯成功的本地Engine,通過一下命令執行專案即可。

flutter run --local-engine-src-path <FLUTTER_ENGINE_ROOT>/engine/src --local-engine=android_debug
複製程式碼

由於flutter專案的Android平臺預設支援x64armarm_64三種cpu型別,所有必須把這三種型別的Engine都編譯成功才能執行上面的命令。

但如果僅編譯了armx64arm_64中的任意一種或兩種,那麼這時候可以通過先打包APK,再安裝APK的方式來執行。

正式環境APK

 flutter build apk --release --local-engine-src-path /Users/limeihong/Desktop/engine/src --local-engine=android_release
複製程式碼

debug環境APK

 flutter build apk --debug --local-engine-src-path /Users/limeihong/Desktop/engine/src --local-engine=android_debug
複製程式碼

很不巧,上面打包APK也是需要x64armarm_64三種平臺都得支援。但如果僅編譯了armx64arm_64中的任意一種或兩種,就得在打包APK時顯示的指定某一型別。

flutter build apk --target-platform android-arm --split-per-abi --debug --local-engine-src-path /Users/limeihong/Desktop/engine/src --local-engine=android_debug
複製程式碼

上面是指定打包cpu型別為arm,如果要想其他型別的apk,則將android-arm替換即可,如替換成android-x64或android-arm_64。

打包成功後,apk預設在路徑build/app/outputs/apk/debugbuild/app/outputs/apk/release下,然後通過通過以下命令安裝即可。

flutter install build/app/outputs/apk/debug/xxxx.apk
複製程式碼

這樣就可以成功將編譯的Engine打包僅APK並執行。

注意: 正式環境下的apk需要簽名檔案,預設的正式包是沒有簽名的,而沒有簽名的正式包在手機上是無法執行的。

再來看如何通過VS Code來檢視原始碼,首先得配置VS Code的C/C++環境,然後再安裝cquery

在macOS上可以通過下面一句命令來安裝cquery

brew install --HEAD cquery
複製程式碼

cquery安裝成功後,VS Code還需要安裝cquery外掛支援,這很簡單,直接去商店搜尋cquery並安裝即可。

IDE配置完成後。再把src/out/compile_commands.json檔案移動到src/compile_commands.json

最後再用VS Code開啟src目錄就可以方便快捷的閱讀原始碼。當然如果要對Engine做一些修改,也可以通過上面的方式來重新編譯Engine並打包進安裝包中。

注意: 由於Engine的東西非常多,所以每次用VS Code開啟src都需要載入一段時間(好幾分鐘)。

【參考資料】

Setting up the Engine development environment

Compiling the engine

搭建Flutter Engine原始碼編譯環境

Flutter Engine 編譯指北

相關文章