Skip to content

Instantly share code, notes, and snippets.

@jezell
Created January 15, 2025 08:01
Show Gist options
  • Save jezell/8d0a650cb6a6e2ccef8cbd5f1c27970e to your computer and use it in GitHub Desktop.
Save jezell/8d0a650cb6a6e2ccef8cbd5f1c27970e to your computer and use it in GitHub Desktop.
Monorepo engine buidls

Below is an example GitHub Actions workflow updated for the new monorepo structure, where the former Engine repository now resides inside an engine/ folder in the main Flutter repository. This assumes you still want to build the native engine artifacts (e.g., for Linux, Windows, macOS, iOS, Android, Web) using GN + Ninja (i.e., the Chromium-based build system).

Important: The monorepo is still in flux as of this writing. The steps below might require adjustments based on the latest official instructions from the Flutter repository. The general ideas—installing depot_tools, running gclient sync, running gn gen, and then ninja—remain the same, but you may need to tweak paths and GN args.


1. Workflow Overview

  1. Check out the main Flutter repo (which contains engine/ folder).
  2. Install dependencies needed for building the engine, including depot_tools.
  3. Navigate into the engine folder.
  4. Sync dependencies with gclient sync.
  5. Generate build files via gn gen.
  6. Build using ninja.
  7. Repeat for each combination of platform + build mode as needed.

Below is an example of a single YAML file that runs a matrix build for multiple platforms and build modes (debug, profile, release). Customize to your needs.


2. Example Workflow File

Create a file (for example, .github/workflows/build_engine.yml) with the following contents:

name: Build Flutter Engine (Monorepo)

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  # -------------------------------------------------------------------
  # 1) Build on Linux
  # -------------------------------------------------------------------
  build-linux:
    name: Build Engine on Linux
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build_mode: [debug, profile, release]
    steps:
      - name: Check out Flutter repo
        uses: actions/checkout@v3
        with:
          # If your repo still uses submodules, you may need this:
          # submodules: true
          # fetch-depth: 0 (if you need full history)
          fetch-depth: 0

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y curl python3 python3-pip python3-setuptools git clang cmake ninja-build pkg-config
          
          # Clone depot_tools to get gclient, gn, ninja, etc.
          git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $HOME/depot_tools
          echo "::add-path::$HOME/depot_tools"

      - name: Sync dependencies (gclient sync)
        working-directory: engine
        run: |
          # Run gclient sync from within the engine folder
          gclient sync

      - name: Generate GN build files
        working-directory: engine
        run: |
          # We'll name our build output directory based on mode + platform
          gn gen out/linux_${{ matrix.build_mode }} \
            --args="is_debug=${{ matrix.build_mode == 'debug' }} \
                    is_profile=${{ matrix.build_mode == 'profile' }} \
                    target_os=\"linux\""

      - name: Build flutter engine
        working-directory: engine
        run: |
          ninja -C out/linux_${{ matrix.build_mode }} flutter


  # -------------------------------------------------------------------
  # 2) Build on Windows
  # -------------------------------------------------------------------
  build-windows:
    name: Build Engine on Windows
    runs-on: windows-latest
    strategy:
      matrix:
        build_mode: [debug, profile, release]
    steps:
      - name: Check out Flutter repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Install dependencies
        run: |
          choco install python --version=3.9.0 -y
          choco install visualstudio2022buildtools -y
          choco install cmake ninja git -y
          
          # Set up depot_tools
          git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git C:\depot_tools
          echo "C:\\depot_tools" >> $env:GITHUB_PATH

      - name: Sync dependencies (gclient sync)
        run: |
          cd engine
          gclient sync

      - name: Generate GN build files
        run: |
          cd engine
          gn gen out\windows_${{ matrix.build_mode }} --args="is_debug=${{ matrix.build_mode == 'debug' }} is_profile=${{ matrix.build_mode == 'profile' }} target_os=\"win\""

      - name: Build flutter engine
        run: |
          cd engine
          ninja -C out\windows_${{ matrix.build_mode }} flutter


  # -------------------------------------------------------------------
  # 3) Build on macOS (and optionally iOS)
  # -------------------------------------------------------------------
  build-macos:
    name: Build Engine on macOS
    runs-on: macos-latest
    strategy:
      matrix:
        build_mode: [debug, profile, release]
    steps:
      - name: Check out Flutter repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Install dependencies
        run: |
          brew update
          brew install python git ninja cmake
          
          # depot_tools
          git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $HOME/depot_tools
          echo "::add-path::$HOME/depot_tools"

      - name: Sync dependencies (gclient sync)
        working-directory: engine
        run: |
          gclient sync

      - name: Generate GN build files
        working-directory: engine
        run: |
          gn gen out/mac_${{ matrix.build_mode }} \
            --args="is_debug=${{ matrix.build_mode == 'debug' }} \
                    is_profile=${{ matrix.build_mode == 'profile' }} \
                    target_os=\"mac\""

      - name: Build flutter engine
        working-directory: engine
        run: |
          ninja -C out/mac_${{ matrix.build_mode }} flutter


  # -------------------------------------------------------------------
  # (Optional) Build iOS
  # -------------------------------------------------------------------
  build-ios:
    name: Build Engine on iOS
    runs-on: macos-latest
    strategy:
      matrix:
        build_mode: [debug, profile, release]
    steps:
      - name: Check out Flutter repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Install dependencies
        run: |
          brew update
          brew install python git ninja cmake
          
          # depot_tools
          git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $HOME/depot_tools
          echo "::add-path::$HOME/depot_tools"

      - name: Sync dependencies (gclient sync)
        working-directory: engine
        run: |
          gclient sync

      - name: Generate GN build files
        working-directory: engine
        run: |
          # Customize for iOS device vs iOS simulator as needed
          gn gen out/ios_${{ matrix.build_mode }} \
            --args="is_debug=${{ matrix.build_mode == 'debug' }} \
                    is_profile=${{ matrix.build_mode == 'profile' }} \
                    target_os=\"ios\""

      - name: Build flutter engine
        working-directory: engine
        run: |
          ninja -C out/ios_${{ matrix.build_mode }} flutter


  # -------------------------------------------------------------------
  # (Optional) Build Android
  # -------------------------------------------------------------------
  build-android:
    name: Build Engine on Android
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build_mode: [debug, profile, release]
    steps:
      - name: Check out Flutter repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y curl python3 python3-pip python3-setuptools git clang cmake ninja-build pkg-config default-jdk
          
          # Android SDK/NDK setup if needed
          # e.g., install a specific NDK version, set environment variables, etc.
          
          # depot_tools
          git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $HOME/depot_tools
          echo "::add-path::$HOME/depot_tools"

      - name: Sync dependencies (gclient sync)
        working-directory: engine
        run: |
          gclient sync

      - name: Generate GN build files
        working-directory: engine
        run: |
          gn gen out/android_${{ matrix.build_mode }} \
            --args="is_debug=${{ matrix.build_mode == 'debug' }} \
                    is_profile=${{ matrix.build_mode == 'profile' }} \
                    target_os=\"android\""

      - name: Build flutter engine
        working-directory: engine
        run: |
          ninja -C out/android_${{ matrix.build_mode }} flutter


  # -------------------------------------------------------------------
  # (Optional) Build Web (WASM target)
  # -------------------------------------------------------------------
  build-web:
    name: Build Engine on Web
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build_mode: [debug, profile, release]
    steps:
      - name: Check out Flutter repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y curl python3 python3-pip python3-setuptools git clang cmake ninja-build pkg-config
          
          # depot_tools
          git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $HOME/depot_tools
          echo "::add-path::$HOME/depot_tools"

      - name: Sync dependencies (gclient sync)
        working-directory: engine
        run: |
          gclient sync

      - name: Generate GN build files
        working-directory: engine
        run: |
          gn gen out/web_${{ matrix.build_mode }} \
            --args="is_debug=${{ matrix.build_mode == 'debug' }} \
                    is_profile=${{ matrix.build_mode == 'profile' }} \
                    target_os=\"wasm\""

      - name: Build flutter engine
        working-directory: engine
        run: |
          ninja -C out/web_${{ matrix.build_mode }} flutter

Notes and Adjustments

  1. Working Directory

    • We’re specifying working-directory: engine (or cd engine) before calling gclient sync, gn gen, or ninja. This is crucial now that the Engine code lives in engine/.
    • If your local layout or build instructions differ, you may need to adjust paths accordingly.
  2. gclient sync and DEPS

    • In the monorepo, the DEPS file may have changed. You still need to run gclient sync from within the engine/ folder to download any additional third-party dependencies.
    • You might also need to run gclient config if your local environment is not set up with .gclient or if the config is missing.
  3. GN Args

    • The --args shown here are simplified. You may need additional flags like enable_fontconfig, use_dart_zip, or something else based on your needs. Check the monorepo’s updated build docs for the latest recommended flags.
  4. Caching

    • Consider adding GitHub Actions caching for ~/.pub-cache, ~/.gradle, ~/.dartServer, or even the out/ directory to speed up builds. Be careful with caching built artifacts though, as partial/incompatible caches can cause sporadic failures.
  5. Artifacts

    • If you want to distribute or test your built engine artifacts, you might want to upload artifacts or push them to a custom storage location. For example:
      - name: Upload built artifacts
        uses: actions/upload-artifact@v3
        with:
          name: flutter-engine-${{ matrix.build_mode }}-linux
          path: engine/out/linux_${{ matrix.build_mode }}
  6. Android & iOS

    • For iOS, you need Xcode installed (which macos-latest generally provides).
    • For Android, you typically need the SDK + NDK. This example does not fully demonstrate setting up the correct NDK versions or environment variables. Adapt as needed.

3. Wrapping Up

With the above workflow:

  • You build multiple platforms (Linux, Windows, macOS, iOS, Android, Web) in parallel via GitHub Actions.
  • You build multiple modes (debug, profile, release) via the matrix.
  • You run gclient sync in the engine/ subdirectory to pull in dependencies.
  • You use gn gen and ninja to compile the engine targets.

You’ll almost certainly need to tweak the commands for your own environment, but this provides a template to get started building the Flutter Engine code in the new monorepo structure. Good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment