Cross-Compile ARM Architecture Browser on Deepin Linux

With the gradual development of domestic information technology systems, more and more devices are adopting non-x86 architecture CPUs, such as ARM, Loongson, Shenwei, and RISC-V. Among them, the ARM architecture has the highest market share, with major manufacturers including Phytium and Huawei Kirin. When developing software for these domestic systems, it is often necessary to support the aforementioned architectures.

In previous developments, we generally chose to compile and debug code directly on ARM machines. Although this method is simple, it faces many challenges for large applications, especially complex systems like browsers. Taking the Chromium browser as an example, its code is large and complex, requiring a significant amount of computational resources and memory during the build process. When compiling on ARM architecture devices, especially on machines with relatively weak processor performance and limited memory, issues such as prolonged compilation delays and insufficient memory may occur. For instance, many machines equipped with Phytium processors typically only have 8GB of memory, leading to slow compilation speeds and even potential compilation failures due to insufficient memory.

In embedded development, a common development model is cross-compilation, where the application is compiled on a more powerful machine and then ported to the target ARM device for testing and optimization. We can also adopt this approach to compile the ARM version of the Chromium browser on an x86 architecture development machine.

This article will introduce how to cross-compile an ARM architecture browser on the deepin Linux system.

System Requirements

  • A machine with x86-64 architecture, equipped with at least 8GB of memory (16GB or more is recommended). If using SSD, it is recommended to allocate ≥32GB/≥16GB of swap space for machines with 8GB/16GB of memory, respectively.
  • At least 100GB of available disk space is required, not necessarily on the same drive; it is recommended to allocate about 50-80GB on HDD for building.
  • Must have git and Python v3.8+ installed (and <span>python3</span> must point to the executable of that version). If the appropriate version is not available in the system, <span>depot_tools</span> will bundle a compatible version in <span>$depot_tools/python-bin</span>.
  • The only supported STL is <span>libc++</span>, and the officially recommended compiler is <span>clang</span>.

This article selects deepin V23 as the operating system, and other operating systems such as Open Kylin and Ubuntu 24.04 are also applicable.

Download depot_tools

Chromium uses a self-developed code management and build system called depot_tools, so we first need to download it:

  1. Clone the depot_tools repository:
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

Add depot_tools to the front of the PATH environment variable (it is recommended to write it in ~/.bashrc. Assuming depot_tools is cloned to /path/to/depot_tools):

$ export PATH="/path/to/depot_tools:$PATH"

Note: If depot_tools is cloned to the user home directory (e.g., /home/username/depot_tools), do not use the ~ symbol in the PATH (this will cause the gclient runhooks command to fail). Instead, use $HOME or the absolute path:

$ export PATH="$HOME/depot_tools:$PATH"

Download Specified Version of Chromium Source Code

Due to the extremely large size of Chromium’s git repository, if the entire git repository is cloned, it often encounters interruption issues. Moreover, git does not support resuming interrupted downloads. Downloading a large git repository that takes several hours only to be interrupted is frustrating. Typically, we will only develop based on a specific release version, so we only need to git clone the source code of the specified branch without the complete git history. If you need to browse the history of Chromium, you can look it up online at:

https://source.chromium.org/chromium/chromium/

Therefore, we will download the specified version (127.0.6533.100) of the Chromium source code without the history. This not only avoids interruptions but also significantly reduces the time required to download the code.

1. Download the source code for version 127.0.6533.100 (without git log)

$ git clone --depth 1 --branch 127.0.6533.100 https://chromium.googlesource.com/chromium/src.git

2. Create a branch

$ cd src
$ git branch branch-127

3. Create a .gclient file, note that it should be at the same directory level as src

solutions = [
  {
    "name": "src",
    "url": "https://chromium.googlesource.com/chromium/src.git",
    "managed": False,
    "custom_deps": {},
    "custom_vars": {},
  },
]

target_cpu="arm64"

4. Sync the modules and third-party library source code related to Chromium

$ gclient sync --nohooks --no-history

5. Sync related tools or binary files

$ gclient runhooks

Theoretically, this step will download the sysroot for the arm64 architecture. You can check if the build/linux/debian_bullseye_arm64-sysroot directory exists; if it does not, you can manually download it:

./build/linux/sysroot_scripts/install-sysroot.py --arch=arm64

Install Build Dependency System Libraries

Chromium provides a script ./build/install-build-deps.sh to download the required system libraries. However, executing it under deepin v23 will produce the following error:

WARNING: The following distributions are supported,
but distributions not in the list below can also try to install
dependencies by passing the `--unsupported` parameter.
EoS refers to end of standard support and does not include
extended security support.
        Ubuntu 20.04 LTS (focal with EoS April 2025)
        Ubuntu 22.04 LTS (jammy with EoS June 2027)
        Ubuntu 24.04 LTS (noble with EoS June 2029)
        Debian 10 (buster) or later

This is because the developers who wrote this script did not consider other Linux distributions; we can add the –unsupported parameter. After running with this parameter, the following error will also appear:

Running as non-root user.
You might have to enter your password one or more times for 'sudo'.

请输入密码:
验证成功
命中:1 https://app-store-files.uniontech.com/250228174341123/appstorev23 beige InRelease        
忽略:2 https://community-packages.deepin.com/beige beige InRelease                               
命中:3 https://cdn-community-packages.deepin.com/driver-23 driver InRelease
命中:4 https://community-packages.deepin.com/beige beige Release
正在读取软件包列表... 完成
Finding missing packages...
Building apt package list.
Traceback (most recent call last):
  File "/work/browser/deepin-browser/branch-127/build/install-build-deps.py", line 939, in &lt;module&gt;
    sys.exit(main())
  File "/work/browser/deepin-browser/branch-127/build/install-build-deps.py", line 932, in main
    install_packages(options)
  File "/work/browser/deepin-browser/branch-127/build/install-build-deps.py", line 844, in install_packages
    packages = find_missing_packages(options)
  File "/work/browser/deepin-browser/branch-127/build/install-build-deps.py", line 818, in find_missing_packages
    packages = package_list(options)
  File "/work/browser/deepin-browser/branch-127/build/install-build-deps.py", line 757, in package_list
    packages = (dev_list() + lib_list() + dbg_list(options) +
  File "/work/browser/deepin-browser/branch-127/build/install-build-deps.py", line 272, in dev_list
    if package_exists("realpath"):
  File "/work/browser/deepin-browser/branch-127/build/install-build-deps.py", line 32, in package_exists
    return package_name in build_apt_package_list()
  File "/work/browser/deepin-browser/branch-127/build/install-deps.py", line 23, in build_apt_package_list
    output = subprocess.check_output(["apt-cache", "dumpavail"]).decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x92 in position 61529773: invalid start byte

This error is somewhat complicated to fix. A more straightforward method is to directly install the required dependency packages. Under deepin v23, you can execute the following command:

sudo apt install -y \
  debhelper \
  devscripts \
  lld-16 \
  clang-16 \
  clang-format-16 \
  libclang-rt-16-dev \
  libc++-16-dev \
  libc++abi-16-dev \
  rustc-web \
  bindgen \
  python3 \
  pkg-config \
  ninja-build \
  python3-jinja2 \
  python3-pkg-resources \
  ca-certificates \
  elfutils \
  wget \
  flex \
  yasm \
  xvfb \
  wdiff \
  gperf \
  bison \
  nodejs \
  rollup \
  valgrind \
  xz-utils \
  x11-apps \
  xcb-proto \
  xfonts-base \
  libdav1d-dev \
  libx11-xcb-dev \
  libxshmfence-dev \
  libgl-dev \
  libglu1-mesa-dev \
  libegl1-mesa-dev \
  libgles2-mesa-dev \
  libopenh264-dev \
  generate-ninja \
  mesa-common-dev \
  rapidjson-dev \
  libva-dev \
  libxt-dev \
  libgbm-dev \
  libpng-dev \
  libxss-dev \
  libelf-dev \
  libpci-dev \
  libcap-dev \
  libdrm-dev \
  libffi-dev \
  libhwy-dev \
  libkrb5-dev \
  libexif-dev \
  libflac-dev \
  libudev-dev \
  libpipewire-0.3-dev \
  libopus-dev \
  libxtst-dev \
  libjpeg-dev \
  libxml2-dev \
  libgtk-3-dev \
  libxslt1-dev \
  liblcms2-dev \
  libpulse-dev \
  libpam0g-dev \
  libdouble-conversion-dev \
  libxnvctrl-dev \
  libglib2.0-dev \
  libasound2-dev \
  libsecret-1-dev \
  libspeechd-dev \
  libminizip-dev \
  libhunspell-dev \
  libharfbuzz-dev \
  libxcb-dri3-dev \
  libusb-1.0-0-dev \
  libopenjp2-7-dev \
  libmodpbase64-dev \
  libnss3-dev \
  libnspr4-dev \
  libcups2-dev \
  libevent-dev \
  libevdev-dev \
  libgcrypt20-dev \
  libcurl4-openssl-dev \
  libzstd-dev \
  fonts-ipafont-gothic \
  fonts-ipafont-mincho

Build ARM64 Version of Chromium

To cross-compile Chromium for the ARM64 architecture, you need to pass the build parameters to gn:

gn gen out/Default-arm64 --args="target_cpu = \"arm64\""

Next, compile Chromium by executing the following command:

autoninja -C out/Default-arm64 chrome

This compilation will take some time, so grab a cup of tea, listen to some music, and wait patiently.

After the compilation is complete, an executable file named <span>chrome</span> will be generated in the <span>out/Default-arm64</span> directory, which is the ARM64 version of Chromium that we need.

Copy the <span>chrome</span> executable file and related resource files to the target device. You can use a script to complete the copying work:

cp -a ${build_dir}/chrome ${TARGET}
cp -a ${build_dir}/chrome_sandbox ${TARGET}
cp -a ${build_dir}/chrome_100_percent.pak ${TARGET}
cp -a ${build_dir}/chrome_200_percent.pak ${TARGET}
cp -a ${build_dir}/chrome_crashpad_handler ${TARGET}
cp -a ${build_dir}/icudtl.dat ${TARGET}
cp -a ${build_dir}/libEGL.so ${TARGET}
cp -a ${build_dir}/libGLESv2.so ${TARGET}
cp -a ${build_dir}/libvk_swiftshader.so ${TARGET}
cp -a ${build_dir}/libvulkan.so.1 ${TARGET}
cp -r ${build_dir}/locales/ ${TARGET}
cp -a ${build_dir}/resources.pak ${TARGET}
cp -a ${build_dir}/v8_context_snapshot.bin ${TARGET}
cp -a ${build_dir}/vk_swiftshader_icd.json ${TARGET}

Then you can run the ARM64 version of Chromium on the target device.

Conclusion

By following the steps in this article, you can successfully cross-compile an ARM architecture browser on the deepin system and deploy it to the target device for use.

Leave a Comment