Skip to content

Commit b77fe73

Browse files
authored
[BUILD] Restore Debian/RPM packaging (lost in history rewrite) + openEuler 24.03 support (#794)
Packaging from #607 (merged 2026-06-03, commit e56773e) is no longer on main after the branch history was rewritten; this restores it and brings it up to date with the current tree: - Recovered as-is: packaging/{debian,rpm,INSTALL.md,README.md,spike}, .github/workflows/build-{deb,rpm}.yml, .dockerignore. - Re-ported to the post-rewrite layout: setup.py / pyproject.toml / MANIFEST.in moved to the repo root — wheel-builder COPY lists and build WORKDIR updated in both Dockerfiles (narrow COPY kept so packaging-only edits don't invalidate the ~50 min wheel layer). - New FLAGTREE_DEFAULT_BACKENDS env knob (setup_tools/utils/tools.py): packaging builds pin nvidia,amd — the historical package contents. The new tileir default backend requires GCC >= 13 and the cuda-tile submodule, which distro toolchains (openEuler 24.03: GCC 12.3) cannot satisfy. - openEuler 24.03 support: RPM_BASE_IMAGE passthrough in the build script, fedora43 + openeuler2403 CI matrix (Fedora artifact name unchanged), %dist reconstruction on openEuler images, and %% escaping in spec preamble comments (openEuler's rpm expands macros inside comments; a bare %install there terminates the preamble). Verified locally: - fedora43: python3-flagtree-nvidia-0.5.0-1.fc43.x86_64.rpm (cp314) - openeuler2403: python3-flagtree-nvidia-0.5.0-1.oe2403.x86_64.rpm (cp311); installs on openeuler/openeuler:24.03-lts and 'import triton' succeeds (3.6.0).
1 parent c9f1046 commit b77fe73

17 files changed

Lines changed: 916 additions & 1 deletion

File tree

.dockerignore

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# VCS
2+
.git/
3+
.gitignore
4+
5+
# Python build artifacts
6+
*.egg-info/
7+
__pycache__/
8+
*.py[cod]
9+
*.so
10+
build/
11+
dist/
12+
.eggs/
13+
14+
# Packaging outputs (avoid re-bundling previous build products)
15+
dist-rpm/
16+
debian-packages/
17+
rpm-packages/
18+
19+
# Editor / OS
20+
.vscode/
21+
.idea/
22+
.DS_Store

.github/workflows/build-deb.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Build Debian Packages
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
pull_request:
8+
branches: [main]
9+
paths:
10+
- 'packaging/debian/**'
11+
- 'python/**'
12+
- 'include/**'
13+
- 'lib/**'
14+
- 'cmake/**'
15+
- 'bin/**'
16+
- 'CMakeLists.txt'
17+
- 'pyproject.toml'
18+
- '.github/workflows/build-deb.yml'
19+
workflow_dispatch:
20+
21+
jobs:
22+
build-deb:
23+
# WARNING: this builds the full FlagTree LLVM/MLIR wheel from source
24+
# (~36 min on a 4-core builder) and peaks well above 4 GB RAM. The
25+
# public `ubuntu-latest` runner (4 vCPU / ~16 GB RAM) is on the edge
26+
# of OOM; consider promoting to a self-hosted runner (FlagCX uses
27+
# `runs-on: h20`) once one is wired up.
28+
runs-on: ubuntu-latest
29+
timeout-minutes: 90
30+
steps:
31+
- name: Checkout repository
32+
uses: actions/checkout@v4
33+
with:
34+
submodules: recursive
35+
36+
- name: Set up Docker Buildx
37+
uses: docker/setup-buildx-action@v3
38+
39+
- name: Build .deb
40+
run: bash packaging/debian/build-helpers/build-flagtree.sh
41+
42+
- name: Upload artifacts
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: flagtree-nvidia-packages
46+
path: dist/output/*.deb
47+
retention-days: 7

.github/workflows/build-rpm.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Build RPM Packages
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
pull_request:
8+
branches: [main]
9+
paths:
10+
- 'packaging/rpm/**'
11+
- 'python/**'
12+
- 'include/**'
13+
- 'lib/**'
14+
- 'cmake/**'
15+
- 'bin/**'
16+
- 'CMakeLists.txt'
17+
- 'pyproject.toml'
18+
- '.github/workflows/build-rpm.yml'
19+
workflow_dispatch:
20+
21+
jobs:
22+
build-rpm:
23+
runs-on: ubuntu-latest
24+
strategy:
25+
fail-fast: false
26+
matrix:
27+
include:
28+
# Original Fedora target — artifact name unchanged so
29+
# downstream collectors keep working.
30+
- target: fedora43
31+
base_image: fedora:43
32+
artifact: flagtree-nvidia-rpm-packages
33+
- target: openeuler2403
34+
base_image: openeuler/openeuler:24.03-lts
35+
artifact: flagtree-nvidia-oe2403-rpm-packages
36+
steps:
37+
- name: Checkout repository
38+
uses: actions/checkout@v4
39+
with:
40+
submodules: recursive
41+
42+
- name: Set up Docker Buildx
43+
uses: docker/setup-buildx-action@v3
44+
45+
- name: Build .rpm (${{ matrix.target }})
46+
run: bash packaging/rpm/helpers/build-flagtree-rpm.sh
47+
env:
48+
RPM_BASE_IMAGE: ${{ matrix.base_image }}
49+
50+
- name: Upload artifacts
51+
uses: actions/upload-artifact@v4
52+
with:
53+
name: ${{ matrix.artifact }}
54+
path: dist-rpm/output/*.rpm
55+
retention-days: 7

packaging/INSTALL.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Installing python3-flagtree-nvidia
2+
3+
After `apt install python3-flagtree-nvidia` (Debian/Ubuntu) or `dnf install python3-flagtree-nvidia` (Fedora),
4+
install the ML runtime separately — it is intentionally **not** declared as a
5+
hard Depends/Requires because the distro versions are CPU-only (torch) or
6+
too old (triton) for GPU workloads.
7+
8+
This package itself *provides* `python3-triton`, so no separate triton install
9+
is needed. Torch is not a hard dependency, but most FlagTree consumers will
10+
want a matching GPU build:
11+
12+
```bash
13+
pip install --index-url https://download.pytorch.org/whl/cu128 torch==2.9.0+cu128
14+
```
15+
16+
A `venv` is recommended to isolate pip-installed packages from the system
17+
Python:
18+
19+
```bash
20+
python3 -m venv ~/.venv/flagos
21+
source ~/.venv/flagos/bin/activate
22+
# then the pip install lines above
23+
```
24+
25+
Note: the distro `python3-torch` package (CPU-only build) is intentionally
26+
not pulled in — FlagOS workloads need a GPU build, which PyTorch upstream
27+
distributes via PyPI (per-CUDA-version wheels), not as a `.deb` / `.rpm`.

packaging/README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# FlagTree Packaging
2+
3+
Debian (.deb) and RPM (.rpm) packaging for FlagTree.
4+
5+
## Status
6+
7+
- nvidia backend: scaffolded (DEB + RPM). Wheel build verified by spike
8+
(~36 min wall on 4-core, 205 MB wheel, 493 MB installed).
9+
- Other backends (mthreads, metax, amd, iluvatar, cambricon, hcu, xpu):
10+
not yet wired up. Each needs its own build container with the chip
11+
vendor toolchain.
12+
13+
## Layout
14+
15+
```
16+
packaging/
17+
├── debian/ # .deb packaging
18+
│ ├── control # python3-flagtree-<backend>
19+
│ ├── rules # installs pre-built wheel into staging
20+
│ ├── changelog, compat, source/format
21+
│ └── helpers/
22+
│ ├── Dockerfile.deb # 2 stages: wheel build → deb assemble
23+
│ └── build-flagtree.sh # entrypoint: ./build-flagtree.sh nvidia
24+
├── rpm/ # .rpm packaging
25+
│ ├── specs/flagtree.spec # uses pre-built wheel via wheel_dir define
26+
│ └── helpers/
27+
│ ├── Dockerfile.rpm # 2 stages: rpm-base wheel → rpm assemble
28+
│ └── build-flagtree-rpm.sh
29+
└── spike/
30+
└── Dockerfile-nvidia # original build-time spike for reference
31+
```
32+
33+
## Why pre-built wheels rather than dh-python source build
34+
35+
FlagTree's Python build invokes CMake/Ninja to compile a substantial C++/MLIR
36+
codebase (LLVM is downloaded at build time unless `LLVM_SYSPATH` is set).
37+
A 36-minute compile in `override_dh_auto_build` is slow, hard to debug, and
38+
collides with `dh-python`'s expectations for a pure-Python `pyproject` build.
39+
The two-stage Docker approach builds the wheel once, then wraps it cheaply
40+
into a `.deb`/`.rpm` — keeping the heavy lifting in a controlled container.
41+
42+
## Build locally
43+
44+
```sh
45+
# DEB
46+
./packaging/debian/build-helpers/build-flagtree.sh nvidia
47+
# Output: ./dist/output/python3-flagtree-nvidia_*.deb
48+
49+
# RPM
50+
./packaging/rpm/helpers/build-flagtree-rpm.sh nvidia
51+
# Output: ./dist-rpm/output/python3-flagtree-nvidia-*.rpm
52+
```
53+
54+
Both commands take 30–40 minutes wall on a typical 4-core machine.
55+
56+
## Namespace conflict
57+
58+
FlagTree installs into the `triton` Python namespace (it is a fork of
59+
`triton-lang/triton`). The package therefore declares:
60+
61+
- `Provides: python3-triton, python3-flagtree`
62+
- `Conflicts: python3-triton` (and other flagtree backend variants)
63+
- `Replaces: python3-triton`
64+
65+
Users with the upstream `python3-triton` installed must remove it first.
66+
67+
## Adding a new backend
68+
69+
1. Verify the backend builds in a Docker container (see
70+
`spike/Dockerfile-nvidia` as a template).
71+
2. Extend the relevant build helper (`build-flagtree.sh` /
72+
`build-flagtree-rpm.sh`) — add the backend to the case statement.
73+
3. If the backend needs a different base image (e.g. `mthreads` needs
74+
the MUSA toolkit), add a backend-specific Dockerfile or stage.
75+
4. Add the backend to the `Conflicts` lists in `debian/control` and
76+
`rpm/specs/flagtree.spec`.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Dockerfile to build the FlagTree wheel, then assemble a Debian package.
2+
#
3+
# Two-stage:
4+
# 1. wheel-builder: heavy stage with CMake/Ninja/LLVM that compiles the
5+
# flagtree wheel from source. Produces /wheels/flagtree-*.whl.
6+
# 2. deb-assembler: light stage that runs dpkg-buildpackage to wrap the
7+
# pre-built wheel into a .deb. The deb stage does NOT recompile.
8+
#
9+
# Build:
10+
# docker build -f packaging/debian/build-helpers/Dockerfile.deb \
11+
# --target deb-output \
12+
# -t flagtree-deb-nvidia .
13+
#
14+
# COPY-narrowing: the wheel-builder COPYs only the paths the build
15+
# needs (python/, third_party/, include/, lib/, cmake/, bin/,
16+
# CMakeLists.txt, *.toml, LICENSE, README*). It deliberately does NOT
17+
# copy packaging/, docs/, .github/, dockerfiles/, etc. — that way edits
18+
# to debian/control or rpm/specs/ don't invalidate the 36-min wheel
19+
# build cache. The deb-assembler stage gets packaging/debian via its
20+
# own narrow COPY.
21+
#
22+
# FLAGTREE_BACKEND notes: FlagTree's "default" backend IS nvidia (no
23+
# nvidia.py module exists in setup_tools/utils/). Setting
24+
# FLAGTREE_BACKEND=nvidia would make setup_helper.py try to import a
25+
# missing module and silently produce an empty stub. We unset the env
26+
# var explicitly in the wheel-build RUN.
27+
28+
ARG DEB_BASE_IMAGE=ubuntu:24.04
29+
30+
# ---------- Stage 1: build the wheel ----------
31+
FROM ${DEB_BASE_IMAGE} AS wheel-builder
32+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
33+
34+
ENV DEBIAN_FRONTEND=noninteractive
35+
ENV VIRTUAL_ENV=/opt/flagtree-build-venv
36+
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
37+
ENV PIP_ROOT_USER_ACTION=ignore
38+
39+
RUN apt-get update && apt-get install -y --no-install-recommends \
40+
python3 python3-pip python3-dev python3-venv \
41+
build-essential cmake ninja-build git \
42+
zlib1g zlib1g-dev libxml2 libxml2-dev \
43+
wget curl ca-certificates \
44+
&& apt-get clean && rm -rf /var/lib/apt/lists/*
45+
46+
# Ubuntu 24.04 marks /usr Python as externally managed (PEP 668). Keep all
47+
# wheel-builder pip installs inside a venv instead of mutating system Python.
48+
RUN python3 -m venv "${VIRTUAL_ENV}" && \
49+
python -m pip install --no-cache-dir --upgrade pip setuptools wheel build
50+
51+
WORKDIR /src
52+
# Dependency layer first so source edits don't invalidate it.
53+
COPY python/requirements.txt /src/python/requirements.txt
54+
RUN python -m pip install --no-cache-dir -r python/requirements.txt
55+
56+
# Narrow COPY: only the paths the wheel build needs, so packaging-only
57+
# edits (specs, debian/, helpers) do NOT invalidate the ~50 min wheel
58+
# layer. setup.py / pyproject.toml / MANIFEST.in live at the repo root
59+
# since the post-#607 restructure.
60+
COPY python /src/python
61+
COPY third_party /src/third_party
62+
COPY include /src/include
63+
COPY lib /src/lib
64+
COPY cmake /src/cmake
65+
COPY bin /src/bin
66+
COPY test /src/test
67+
COPY unittest /src/unittest
68+
COPY CMakeLists.txt pyproject.toml setup.py MANIFEST.in LICENSE README.md /src/
69+
70+
# Build wheel with MAX_JOBS capped to reduce peak RAM. Spike timing on a
71+
# 4-core builder: ~36 min wall.
72+
# FLAGTREE_DEFAULT_BACKENDS=nvidia,amd matches the historical package
73+
# contents and keeps the tileir backend (GCC >= 13 + cuda-tile
74+
# submodule) out of the distro build.
75+
RUN unset FLAGTREE_BACKEND && \
76+
FLAGTREE_DEFAULT_BACKENDS=nvidia,amd \
77+
MAX_JOBS=4 python -m pip wheel . --no-build-isolation --no-deps -w /wheels -v && \
78+
ls -lh /wheels/ && \
79+
test -n "$(ls /wheels/flagtree-*.whl 2>/dev/null)"
80+
81+
# ---------- Stage 2: assemble the .deb ----------
82+
FROM ${DEB_BASE_IMAGE} AS deb-assembler
83+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
84+
85+
ENV DEBIAN_FRONTEND=noninteractive
86+
ENV PIP_ROOT_USER_ACTION=ignore
87+
88+
RUN apt-get update && apt-get install -y --no-install-recommends \
89+
build-essential \
90+
debhelper dh-python python3-all python3-pip python3-setuptools \
91+
python3-wheel devscripts fakeroot lintian \
92+
&& apt-get clean && rm -rf /var/lib/apt/lists/*
93+
94+
WORKDIR /build
95+
COPY packaging/debian /build/debian
96+
COPY --from=wheel-builder /wheels /build/dist
97+
98+
# debian/source/format = "3.0 (native)" -> no orig.tar.gz needed.
99+
ENV WHEEL_DIR=/build/dist
100+
101+
RUN dpkg-buildpackage -us -uc -b && \
102+
ls -lh /python3-flagtree-*.deb
103+
104+
# Run lintian against the produced .deb — surface packaging warnings
105+
# (unused-license-paragraph, no-manual-page, missing-build-dependency, etc.)
106+
# in the build log without failing the build.
107+
RUN lintian --info --display-info /python3-flagtree-*.deb || true
108+
109+
# ---------- Stage 3: just the .deb output ----------
110+
FROM scratch AS deb-output
111+
COPY --from=deb-assembler /python3-flagtree-*.deb /output/
112+
COPY --from=deb-assembler /flagtree_*.changes /output/
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
# Build a FlagTree .deb for one backend.
3+
#
4+
# Usage:
5+
# ./packaging/debian/build-helpers/build-flagtree.sh [backend]
6+
#
7+
# Output: ./dist/output/python3-flagtree-<backend>_*.deb
8+
#
9+
# Run from the FlagTree repo root (the one containing python/setup.py).
10+
11+
set -euo pipefail
12+
13+
BACKEND="${1:-nvidia}"
14+
15+
case "$BACKEND" in
16+
nvidia)
17+
;;
18+
mthreads|metax|amd|iluvatar|cambricon|hcu|xpu)
19+
echo "ERROR: backend '$BACKEND' is not yet wired up in Dockerfile.deb"
20+
echo " (only 'nvidia' is supported in this revision)"
21+
exit 1
22+
;;
23+
*)
24+
echo "ERROR: unknown backend '$BACKEND'"
25+
exit 1
26+
;;
27+
esac
28+
29+
REPO_ROOT="$(git rev-parse --show-toplevel)"
30+
cd "$REPO_ROOT"
31+
32+
mkdir -p dist
33+
34+
echo ">>> Building wheel + .deb for backend=${BACKEND}"
35+
docker build \
36+
--network=host \
37+
-f packaging/debian/build-helpers/Dockerfile.deb \
38+
--target deb-output \
39+
--output "type=local,dest=${REPO_ROOT}/dist" \
40+
.
41+
42+
echo ""
43+
echo ">>> Output:"
44+
ls -lh dist/output/ 2>/dev/null || ls -lh dist/

packaging/debian/changelog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
flagtree (0.5.0-1) unstable; urgency=medium
2+
3+
* Initial Debian packaging.
4+
* Package the NVIDIA backend variant as python3-flagtree-nvidia.
5+
6+
-- FlagOS Contributors <contact@flagos.io> Sun, 26 Apr 2026 18:00:00 +0000

0 commit comments

Comments
 (0)