本文介绍了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大师在一号线