Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 0 additions & 68 deletions .github/workflows/build_and_publish.yml

This file was deleted.

56 changes: 56 additions & 0 deletions .github/workflows/nanvix-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright(c) The Maintainers of Nanvix.
# Licensed under the MIT License.

name: Nanvix CI

on:
schedule:
- cron: "0 13 * * *"
push:
branches: ["nanvix/**"]
pull_request:
branches: ["nanvix/**"]
workflow_dispatch:

permissions:
contents: write
actions: write
issues: write
pull-requests: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref_name || github.ref || 'default' }}
cancel-in-progress: true

jobs:
ci:
if: github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
uses: nanvix/workflows/.github/workflows/nanvix-ci.yml@v2.0.0
with:
zutil-version: "v0.8.2"
docker-image: "ghcr.io/nanvix/toolchain-python:latest"
platforms: '["microvm"]'
memory-sizes: '["256mb"]'
windows-matrix-exclude: '[]'
skip-full-test-modes: '[]'
caller-event-name: ${{ github.event_name }}
windows-test: false
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }}
DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}

ci-scheduled:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
uses: nanvix/workflows/.github/workflows/nanvix-ci.yml@v2.0.0
with:
zutil-version: "v0.8.2"
docker-image: "ghcr.io/nanvix/toolchain-python:latest"
platforms: '["microvm"]'
memory-sizes: '["256mb"]'
windows-matrix-exclude: '[]'
skip-full-test-modes: '[]'
caller-event-name: 'schedule'
windows-test: false
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }}
DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}
35 changes: 0 additions & 35 deletions .github/workflows/test.yml

This file was deleted.

10 changes: 10 additions & 0 deletions .nanvix/nanvix.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "wordcloud"
version = "1.9.6"
nanvix-version = "0.12.552"

[builds]
[builds.matrix]
platforms = ["microvm"]
modes = ["standalone"]
memory = ["256mb"]
86 changes: 86 additions & 0 deletions .nanvix/z.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright(c) The Maintainers of Nanvix.
# Licensed under the MIT License.

"""Nanvix build script for wordcloud C extension.

Usage:
./z setup # Download Nanvix sysroot and CPython headers
./z build # Cross-compile wordcloud C extension
./z test # (no-op — tested via nanvix-python)
./z release # Package libwordcloud.a release tarball
./z clean # Remove build artifacts
./z distclean # Deep clean
"""

import os
import shutil
import sys
from pathlib import Path

from nanvix_zutil import ZScript, log


class WordcloudBuild(ZScript):
"""Build script for nanvix/word_cloud."""

SYSROOT_REQUIRED_FILES: tuple[str, ...] = (
"lib/libposix.a",
"lib/user.ld",
)

@property
def _nanvix_port_dir(self) -> Path:
return self.repo_root / "nanvix-port"

@property
def _dist_dir(self) -> Path:
return self._nanvix_port_dir / "dist"

def setup(self) -> bool:
ok = super().setup()
if not ok:
return False
log.info("setup complete")
return True

def build(self) -> None:
log.info("cross-compiling wordcloud C extension...")
script = self._nanvix_port_dir / "build-nanvix.sh"
if not script.is_file():
log.error(f"build script not found: {script}")
sys.exit(1)

self.run("bash", "nanvix-port/build-nanvix.sh")

lib = self._dist_dir / "libwordcloud.a"
if lib.is_file():
log.info(f"build complete: {lib} ({lib.stat().st_size // 1024} KB)")
else:
log.error("build failed: libwordcloud.a not found")
sys.exit(1)

def test(self) -> None:
log.info("wordcloud extension is tested via nanvix-python — skipping")

def release(self) -> None:
import tarfile

lib = self._dist_dir / "libwordcloud.a"
if not lib.is_file():
log.error("libwordcloud.a not found — run ./z build first")
sys.exit(1)

platform = os.environ.get("NANVIX_MACHINE", "microvm")
memory = os.environ.get("NANVIX_MEMORY_SIZE", "256mb")
tag = f"wordcloud-{platform}-standalone-{memory}"
tarball = self._dist_dir / f"{tag}.tar.gz"

with tarfile.open(tarball, "w:gz") as tf:
tf.add(lib, arcname=f"{tag}/lib/libwordcloud.a")

log.info(f"release: {tarball} ({tarball.stat().st_size // 1024} KB)")

def clean(self) -> None:
if self._dist_dir.is_dir():
shutil.rmtree(self._dist_dir)
log.info("cleaned dist/")
43 changes: 43 additions & 0 deletions nanvix-port/build-nanvix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Copyright(c) The Maintainers of Nanvix.
# Licensed under the MIT License.
#
# Cross-compile wordcloud C extension for Nanvix (i686).
# wordcloud has a single C file (query_integral_image.c) generated by Cython.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
DIST_DIR="$SCRIPT_DIR/dist"

TOOLCHAIN="${NANVIX_TOOLCHAIN:-/opt/nanvix}"
CC="${TOOLCHAIN}/bin/i686-nanvix-gcc"
AR="${TOOLCHAIN}/bin/i686-nanvix-ar"

CPYTHON_HEADERS="$SCRIPT_DIR/cpython-headers/python3.12"

CFLAGS="-O2 -fPIC -DNDEBUG"
CFLAGS="$CFLAGS -I${CPYTHON_HEADERS}"
CFLAGS="$CFLAGS -I${REPO_ROOT}/wordcloud"

mkdir -p "$DIST_DIR/obj"

echo "[wordcloud] Cross-compiling C extension for i686-nanvix..."

SRC="$REPO_ROOT/wordcloud/query_integral_image.c"
if [ ! -f "$SRC" ]; then
echo "[wordcloud] Generating Cython source..."
cd "$REPO_ROOT"
cython wordcloud/query_integral_image.pyx || {
echo "ERROR: cython not found and .c file missing"; exit 1
}
fi

$CC $CFLAGS -c "$SRC" -o "$DIST_DIR/obj/query_integral_image.o"

echo "[wordcloud] Creating static archive..."
$AR rcs "$DIST_DIR/libwordcloud.a" "$DIST_DIR/obj/query_integral_image.o"

echo "[wordcloud] Done: $DIST_DIR/libwordcloud.a"
ls -la "$DIST_DIR/libwordcloud.a"
Loading
Loading