本文介紹了Flutter源碼的獲取與構建,後面會另有文章介紹Flutter源碼的版本管理、開發環境搭建等主題。java
Flutter源碼分爲兩個部分:python
相關依賴的安裝可參考官方文檔:Setting up the Engine development environment · flutter/flutter Wiki。以個人Mac爲例,如JDK等通常都已經安裝,無需擔憂。android
flutter/flutter
能夠直接經過git下載,可是flutter/engine
須要經過gclient
工具獲取,由於engine
有不少依賴,gclient
能夠很好地處理這些依賴,簡化源碼管理流程。ios
首先,新建一個目錄,下載flutter
框架代碼:git
$ mkdir flutter_source_code $ cd flutter_source_code $ git clone https://github.com/flutter/flutter.git Cloning into 'flutter'... remote: Enumerating objects: 12, done. remote: Counting objects: 100% (12/12), done. remote: Compressing objects: 100% (12/12), done. remote: Total 272396 (delta 0), reused 6 (delta 0), pack-reused 272384 Receiving objects: 100% (272396/272396), 116.98 MiB | 2.48 MiB/s, done. Resolving deltas: 100% (210440/210440), done.
獲取depot_tools
工具(這個一開始是用來管理chromium
源碼的):github
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git Cloning into 'depot_tools'... remote: Sending approximately 34.14 MiB ... remote: Total 40539 (delta 27803), reused 40539 (delta 27803) Receiving objects: 100% (40539/40539), 34.14 MiB | 5.04 MiB/s, done. Resolving deltas: 100% (27803/27803), done.
設置環境變量(每次構建以前都要設置,也能夠寫入系統配置):shell
export PATH=$PATH:`pwd`/depot_tools
開始拉取代碼(這一步比較耗時)json
$ gclient sync [18:04:43] ...... remote: Enumerating objects: 25, done. remote: Counting objects: 100% (25/25), done. remote: Compressing objects: 100% (22/22), done. remote: Total 209672 (delta 10), reused 13 (delta 3), pack-reused 209647 Receiving objects: 100% (209672/209672), 196.61 MiB | 3.74 MiB/s, done. Resolving deltas: 100% (153791/153791), done. Syncing projects: 31% (33/104) src/third_party/vulkan [0:03:59] Still working on: [0:03:59] src/ios_tools [0:03:59] src/third_party/angle [0:03:59] src/third_party/dart [0:03:59] src/third_party/icu ...... [0:12:48] Still working on: [0:12:48] src/third_party/dart Syncing projects: 100% (104/104), done. Running hooks: 100% ( 9/ 9) dart package config ________ running 'vpython src/flutter/tools/run_third_party_dart.py' in '/Users/vimerzhao/WorkProject/flutter_source_code' Resolving dependencies... (1.7s) + charcode 1.1.3 + collection 1.14.13 + meta 1.2.3 + package_config 1.9.3 + path 1.7.0 + pub_semver 1.4.4 + source_span 1.7.0 + string_scanner 1.0.5 + term_glyph 1.1.0 + yaml 2.2.1 Changed 10 dependencies!
須要注意的是,Syncing projects: 100% (104/104), done
以後,會繼續下載一些大文件,可能命令行沒有輸出,必定不能強制退出,能夠經過資源管理器查看網絡的流量,肯定cipd
是否在下載:vim
(由於git不是很擅長下載大文件,因此產生了cipd這個程序來作這些工做)xcode
此時的目錄結構:
$ tree -L 1 . ├── depot_tools # 源碼管理工具 ├── flutter # flutter framework目錄 └── src # flutter engine以及相關依賴所在目錄
framework的版本和engine的版本是一一對應的,framework的分支規則以下:
stable
是當前的穩定分支,無特殊狀況,推薦開發者使用該分支做爲flutter sdkmaster
包含最新的特性,可是不穩定截止到 2020-10-29 ,最新的較穩定版本是 1.22.0,因而咱們也先切到這個版本(不是必選的,可是我的認爲:基於一個明確的版本編譯和修改源代碼彷佛更合適)。
$ cd flutter $ git checkout 1.22.0 $ cat bin/internal/engine.version 5babba6c4d25fa237bbf755ab85c9a0c50b3c6ec
engine.version
這個文件指定了framework對應的engine版本,接下來,咱們進入engine目錄切換到此次commit。
$ cd ../src/flutter $ git reset --hard 5babba6c4d25fa237bbf755ab85c9a0c50b3c6ec HEAD is now at 5babba6c4 Flutter 1.22.0-12.3.pre engine cherrypicks (#21466)
此時,咱們須要執行如下命令:
$ gclient sync --with_branch_heads --with_tags Syncing projects: 100% (104/104), done. ...... Running hooks: 100% ( 8/ 8) dart package config ...... Running hooks: 100% (8/8), done.
後面這兩個參數的含義比較晦澀,參考Chromium的說明,其含義是:
Checkout all the submodules at their branch DEPS revisions
由於切換分支以後,某些依賴的版本可能有更改,因此須要再次sync一下,直接在src/flutter
目錄執行便可。
以上就完成了源碼環境的搭建,下面正式開始編譯。
首先咱們退回到src目錄,而後經過gn
生成ninja
須要的元數據:
$ cd .. $ pwd /Users/vimerzhao/WorkProject/flutter_source_code/src $ ./flutter/tools/gn --unoptimized --android --runtime-mode debug --android-cpu arm Generating GN files in: out/android_debug_unopt Generating Xcode projects took 75ms Done. Made 438 targets from 197 files in 1960ms
對於編譯參數,Compiling the engine · flutter/flutter Wiki有詳細介紹,在此不作贅述,這裏我構建的是一個未優化、Android平臺、debug版本、arm 32位的 engine。
此時,查看out目錄,能夠看到:
$ ls out/ android_debug_unopt compile_commands.json
compile_commands.json
能夠做爲IDE的索引文件,提供類/函數/變量的跳轉等能力,後面會說到。
而後就能夠開始正式的編譯了:
$ ninja -C out/android_debug_unopt ninja: Entering directory `out/android_debug_unopt' [38/3844] ACTION //flutter/shell/platform/android:flutter_shell_java(//build/toolchain/android:clang_arm) 警告: ../../third_party/android_tools/sdk/build-tools/30.0.1/core-lambda-stubs.jar(java/lang/invoke/LambdaMetafactory.class): 主版本 53 比 52 新, 此編譯器 支持最新的主版本。 建議升級此編譯器。 注: 某些輸入文件使用或覆蓋了已過期的 API。 注: 有關詳細信息, 請使用 -Xlint:deprecation 從新編譯。 1 個警告 [3844/3844] STAMP obj/default.stamp $ ls out/android_debug_unopt [19:35:15] all.xcodeproj flutter_embedding_debug-sources.jar.md5.stamp lib.stripped args.gn flutter_embedding_debug.jar libflutter.so armeabi_v7a_debug.jar flutter_embedding_debug.jar.md5.stamp libflutter.so.TOC armeabi_v7a_debug.pom flutter_embedding_debug.pom obj build.ninja flutter_icu toolchain.ninja build.ninja.d flutter_patched_sdk vm_outline_strong.dill clang_x64 gen vm_platform_strong.dill flutter.jar gyp-mac-tool vm_platform_strong.dill.d flutter_embedding_debug-sources.jar icudtl.dat zip_archives
其中,flutter_embedding_debug.jar
是Android嵌入層代碼,libflutter.so
是flutter的引擎層代碼,經過這兩個文件,能夠在Android工程混合接入Flutter代碼。
建立一個工程:
$ pwd /Users/vimerzhao/WorkProject/flutter_source_code $ ls depot_tools flutter src $ ./flutter/bin/flutter create flutter_demo Downloading Dart SDK from Flutter engine 5babba6c4d25fa237bbf755ab85c9a0c50b3c6ec... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 172M 100 172M 0 0 4381k 0 0:00:40 0:00:40 --:--:-- 4723k Building flutter tool... Downloading Material fonts... 0.5s Downloading Gradle Wrapper... 0.1s Downloading package sky_engine... 0.3s Downloading flutter_patched_sdk tools... 2.7s Downloading flutter_patched_sdk_product tools... 2.1s Downloading darwin-x64 tools... 8.2s Downloading libimobiledevice... 0.0s Downloading usbmuxd... 0.7s Downloading libplist... 0.0s Downloading openssl... 0.2s ...... Creating project flutter_demo... flutter_demo/ios/Runner.xcworkspace/contents.xcworkspacedata (created) flutter_demo/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (created) ...... flutter_demo/.idea/runConfigurations/main_dart.xml (created) flutter_demo/.idea/libraries/Dart_SDK.xml (created) flutter_demo/.idea/libraries/KotlinJavaRuntime.xml (created) flutter_demo/.idea/modules.xml (created) flutter_demo/.idea/workspace.xml (created) Running "flutter pub get" in flutter_demo... 2.3s Wrote 71 files. All done! ...... Run "flutter doctor" for information about installing additional components. In order to run your application, type: $ cd flutter_demo $ flutter run
使用flutter並指定本地engine運行(不指定則會拉遠程的、已經構建好的engine)。
$ ../flutter/bin/flutter run --local-engine-src-path ~/WorkProject/flutter_source_code/src --local-engine=android_debug_unopt No Flutter engine build found at /Users/vimerzhao/WorkProject/flutter_source_code/src/out/host_debug_unopt. $ ../flutter/bin/flutter run --local-engine-src-path ~/WorkProject/flutter_source_code/src --local-engine=host_debug_unopt Launching lib/main.dart on DUK AL20 in debug mode... Oops; flutter has exited unexpectedly: "Invalid argument(s): Cannot find executable for /Users/vimerzhao/WorkProject/flutter_source_code/src/out/host_debug_unopt/dart-sdk/bin/dart.". A crash report has been written to /Users/vimerzhao/WorkProject/flutter_source_code/flutter_demo/flutter_02.log. ... FAILURE: Build failed with an exception * Where: Script '/Users/vimerzhao/WorkProject/flutter_source_code/flutter/packages/flutter_tools/gradle/flutter.gradle' line: 904 * What went wrong: Execution failed for task ':app:compileFlutterBuildDebug'. > Process 'command '/Users/vimerzhao/WorkProject/flutter_source_code/flutter/bin/flutter'' finished with non-zero exit value 1 * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 1s Running Gradle task 'assembleDebug'... Running Gradle task 'assembleDebug'... Done 1.8s https://git.io/JTDf0 $../flutter/bin/flutter run --local-engine-src-path ~/WorkProject/flutter_source_code/src --local-engine=h ost_debug_unopt Launching lib/main.dart on DUK AL20 in debug mode... Error: Error when reading '../src/out/host_debug_unopt/gen/frontend_server.dart.snapshot': No such file or directory the Dart compiler exited unexpectedly. the Dart compiler exited unexpectedly. Running Gradle task 'assembleDebug'...
總的來講,遇到一些官方文檔上沒有提到的問題:
android_debug_unopt
卻提示找不到 host_debug_unopt
,這個莫名其妙,只能先改一下以前構建的文件夾名稱了。dart-sdk
,flutter會下載到bin/cache
目錄,只能本身手動copy一份到報錯的目錄。frontend_server.dart.snapshot
,在flutter目錄用find . -name "frontend_server.dart.snapshot"
找到,而後手動copy一份。解決這三個問題以後,終於能夠運行了。
$ ../flutter/bin/flutter run --local-engine-src-path ~/WorkProject/flutter_source_code/src --local-engine=host_debug_unopt Launching lib/main.dart on DUK AL20 in debug mode... Running Gradle task 'assembleDebug'... Running Gradle task 'assembleDebug'... Done 18.1s ✓ Built build/app/outputs/flutter-apk/app-debug.apk. Installing build/app/outputs/flutter-apk/app.apk... 3.5s Waiting for DUK AL20 to report its views... 8ms Syncing files to device DUK AL20... 210ms Flutter run key commands. r Hot reload. 🔥🔥🔥 R Hot restart. h Repeat this help message. d Detach (terminate "flutter run" but leave application running). c Clear the screen q Quit (terminate the application on the device). An Observatory debugger and profiler on DUK AL20 is available at: http://127.0.0.1:63146/LE7Uc6cshds=/ D/AwareBitmapCacher(24977): handleInit switch not opened pid=24977 Application finished.
以上完成源碼的獲取與構建,那麼:
等等。
其實問題還有不少,後面再一一講解。
更多相關內容可訪問個人博客:http://vimerzhao.top/
或
關注個人公衆號:
V大師在一號線