flutter_engine 交叉编译【自定义编译器(最新)】

1. 前言

flutter的下载参考前一篇文章,flutter源码下载
源码下载结束后,最好使用gclient切换stable版本,比较稳定,这样使用自定义编译器修改的缺陷最少。

2. 准备编译环境

2.1 确定sysroot

sysroot是指你的编译器的sysroot,编译器的sysroot可以通过命令打印出来:

arm-linux-gnueabihf-gcc --print-sysroot

到时候编译不过,可能需要在sysroot路径的下的lib中新增内容,这里不建议直接修改sysroot,影响原生编译器运行,所以拷贝一份sysroot进行备份。

cp `arm-linux-gnueabihf-gcc --print-sysroot` ~/sysroot/arm-linux-gnueabihf

如果你的编译器运行 使用参数--print-sysroot没有打印,可以使用 -v找找--sysroot=dir对应的dir,如果还是没有,可以直接找到编译器的安装目录,去查找类似linux根目录(路径下包含bin, lib, usr等目录)的路径。如编译器gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabihf.tar.gz,我安装在toolchains(相对路径)目录,那么他的sysroot就是:toolchains/gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc.

2.2 创建clang软连接

直接修改 src/build/toolchain/custom/BUILD.gn最终还是编译不过,使用软连接方式即可
直接修改 src/build/toolchain/custom/BUILD.gn最终还是编译不过,使用软连接方式即可
直接修改 src/build/toolchain/custom/BUILD.gn最终还是编译不过,使用软连接方式即可
要么直接创建clang/clang++的软连接

ln -sf \
toolchains/gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabih/bin/arm-linux-gnueabihf-gcc \
toolchains/gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabih/bin/clang

ln -sf \
toolchains/gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabih/bin/arm-linux-gnueabihf-g++ \
toolchains/gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabih/bin/clang++

3. 编译

3.1 生成ninja编译脚本

进入到flutter引擎目录下的src目录,执行如下命令:

./flutter/tools/gn --target-os linux --linux-cpu arm \
--target-toolchain toolchains/gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabihf \
--target-sysroot sysroot/gcc-linaro-12.0.1-2022.02-x86_64_arm-linux-gnueabihf \
--target-triple arm-linux-gnueabihf --runtime-mode release --arm-float-abi hard \
--embedder-for-target --disable-desktop-embeddings --no-build-embedder-examples \
--no-goma --no-clang --no-prebuilt-dart-sdk  --no-build-glfw-shell \
--disable-desktop-embeddings

--target-os linux 表示目标系统是Linux
--target-cpu arm 表示目标板子的cpu是arm,如果是64位系统,则使用--target-cpu arm64
--target-toolchain表示工具链的安装路径
--target-sysroot 表示编译器的sysroot,不同编译器的sysroot相对于编译器的相对路径不一样,所以需要额外指定
--target-tripple 表示编译器命令的前缀,编译结束后会使用 arm-linux-gnueabihf-strip命令去掉libflutter_engine.so的符号表
--runtime-mode 表示运行模式,调试或者发布
--arm-float-abi hard 表示浮点运算使用硬浮点方式,性能比较高
--embedder-for-target 表示支持embedder嵌入式模式
--disable-desktop-emddings 表示不存在桌面系统,如果是移植到树莓派这种自带X11,wayland桌面图形的系统,开启该选项(个人猜测)
--no-build-embedder-examples 表示不编译相关的用例,如果没有--disable-desktop-emddings选项,则可以删除该选项。(个人猜测)
--no-goma 表示google内部使用的分布式编译,我们没有,不需要
--no-clang 表示不用clang
--no-prebild-dart-sdk 表示没有预编译dart-sdk,所以本次编译会编译dartsdk
--no-build-glfw-shell 表示不编译glfw,因为没有用到

3.2 ninja编译

ninja -j16 -C out/linux_release_arm

3.3 编译报错处理

3.3.1 找不到freetype2和zlib依赖

具体报错信息忘了,看见类似的可以参考如下内容。
该错误需要在sysroot的/usr/lib/pkgconfig目录中创建对应的freetype2.pczlib.pc。这是因为flutter用到了pkg-config这个工具,pkg-config工具能够直接生成编译依赖参数。比如pkg-config --cflag --libs freetype2 会直接生成 -I${freetype头文件路径} -L${libfreetype2.so所在路径} -L${依赖libz.so所在路径} -lz -lfreetype2这样的cflags参数。至于pkg-config为什么知道freetype2依赖于zlib,则是因为pkg-cofnig会到/usr/lib/pkgconfig/目录下解析freetype2.pc文件,文件中会声明freetype2依赖的库以及其头文件安装路径和库安装路径。
如果没有${sysroot}/usr/lib/pkgconfig目录,则手动创建一个。

freetype2.pc内容如下,复制自flutter源码中的freetype2.pc并做修改:

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=/usr/include

Name: FreeType 2
URL: https://freetype.org
Description: A free, high-quality, and portable font engine.
Version: 23.1.17
Requires:
Requires.private: zlib, libpng
Libs: -L${libdir} -lfreetype
Libs.private: 
Cflags: -I${includedir}/freetype2

zlib.pc如下,复制自flutter源码中的freetype2.pc并做修改:

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
sharedlibdir=${libdir}
includedir=${prefix}/include

Name: zlib
Description: zlib compression library
Version: 1.2.11

Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz
Cflags: -I${includedir}
3.3.2 不识别编译参数

如:
-Wno-c99-designator
-Wno-implicit-int-float-conversion
-Wno-deprecated-copy
-Wno-non-c-typedef-for-linkage
-Wno-range-loop-construct参数不识别导致编译报错,
修改flutter/src/build/config/compiler/BUILD.gn文件, 注释不支持的编译参数

  if (!use_xcode) {
    default_warning_flags += [
      "-Wno-unused-but-set-parameter",
      "-Wno-unused-but-set-variable",
      #"-Wno-implicit-int-float-conversion",
      #"-Wno-c99-designator",
      #"-Wno-deprecated-copy",
      # Needed for compiling Skia with clang-12
      "-Wno-psabi",
    ]
    if (!is_fuchsia) {
      default_warning_flags += [
        #"-Wno-non-c-typedef-for-linkage",
        #"-Wno-range-loop-construct",
      ]
    }
  }
3.3.3 编译警告导致编译报错

如果设置了-Werror选项,所有编译警告都会报错,因此直接关了该选项,并设置-Wno-error,同样修改flutter/src/build/config/compiler/BUILD.gn文件,修改如下:

  default_warning_flags += [
    # Enables.
    "-Wendif-labels",  # Weird old-style text after an #endif.
    #"-Werror",  # Warnings as errors.
    "-Wno-error",

    # Disables.
    "-Wno-missing-field-initializers",  # "struct foo f = {0};"
    "-Wno-unused-parameter",  # Unused function parameters.
  ]
3.3.4 不支持-stdlib=libstdc++参数

修改flutter/src/build/config/compiler/BUILD.gn文件,修改如下:

  if (is_linux) {
    if (!use_flutter_cxx) {
      #cflags_cc += [ "-stdlib=libstdc++" ]
      #ldflags += [ "-stdlib=libstdc++" ]
      libs += [ "gcc" ]
    }
  }
其他编译错误:
  1. unqualified call to std::move [-Wunqualified-std-cast-call]
    解决:修改代码,将move替换为std:move
  2. 一些未知未定义
    解决:包含对应的头文件#include <memory>, #include <cstring>等等,都比较简单。
  3. constexpr造成的错误
    解决:直接删除constexpr的错误

4. 编译结束

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值