對於深入學習Flutter
來說,搭建一個Engine
環境是很有必要的。Engine
是Flutter
底層(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
原始碼。這時候就需要拼網速或者訪問谷歌是否穩定,如果一切順利(可能幾個小時),目錄如下。
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平臺預設支援x64
、arm
及arm_64
三種cpu型別,所有必須把這三種型別的Engine
都編譯成功才能執行上面的命令。
但如果僅編譯了arm
、x64
及arm_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也是需要x64
、arm
及arm_64
三種平臺都得支援。但如果僅編譯了arm
、x64
及arm_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/debug
或build/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
都需要載入一段時間(好幾分鐘)。
【參考資料】