This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Manim Android APK (Complete Dependencies) | |
| on: | |
| push: | |
| branches: [ "main" ] | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Free Disk Space | |
| uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: false | |
| android: false | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| swap-storage: true | |
| - name: Set up Java JDK | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: '11' | |
| distribution: 'temurin' | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| # ============================================ | |
| # SYSTEM DEPENDENCIES - CORE RENDERING LIBS | |
| # ============================================ | |
| - name: Install System Build Dependencies | |
| run: | | |
| sudo apt-get update | |
| # Essential build tools | |
| sudo apt-get install -y \ | |
| build-essential \ | |
| git \ | |
| curl \ | |
| wget \ | |
| pkg-config \ | |
| autoconf \ | |
| automake \ | |
| libtool \ | |
| cmake \ | |
| ninja-build \ | |
| # Core graphics libraries | |
| sudo apt-get install -y \ | |
| libcairo2-dev \ | |
| libpango1.0-dev \ | |
| libpangocairo-1.0-0 \ | |
| libpango-1.0-0 \ | |
| # Font handling (CRITICAL for text rendering) | |
| sudo apt-get install -y \ | |
| libfreetype6-dev \ | |
| libfreetype-dev \ | |
| fonts-liberation \ | |
| fonts-dejavu-core \ | |
| # Text shaping engine | |
| sudo apt-get install -y \ | |
| libharfbuzz-dev \ | |
| libharfbuzz0b \ | |
| # Bidirectional text support | |
| sudo apt-get install -y \ | |
| libfribidi-dev \ | |
| libfribidi0 \ | |
| # Image and compression libraries | |
| sudo apt-get install -y \ | |
| libpng-dev \ | |
| zlib1g-dev \ | |
| libjpeg-dev \ | |
| # Video/FFmpeg libraries | |
| sudo apt-get install -y \ | |
| ffmpeg \ | |
| libavformat-dev \ | |
| libavcodec-dev \ | |
| libavdevice-dev \ | |
| libswscale-dev \ | |
| libswresample-dev \ | |
| libavutil-dev \ | |
| libavfilter-dev \ | |
| # SDL (Simple DirectMedia Layer) | |
| sudo apt-get install -y \ | |
| libsdl2-dev \ | |
| libsdl2-image-dev \ | |
| libsdl2-mixer-dev \ | |
| libsdl2-ttf-dev \ | |
| # GLib dependencies (needed for Pango) | |
| sudo apt-get install -y \ | |
| libglib2.0-dev \ | |
| libgobject-2.0-dev \ | |
| # XML libraries | |
| sudo apt-get install -y \ | |
| libxml2-dev \ | |
| libxslt1-dev \ | |
| # SSL/TLS | |
| sudo apt-get install -y \ | |
| libssl-dev \ | |
| # Other utilities | |
| sudo apt-get install -y \ | |
| libffi-dev \ | |
| libbz2-dev \ | |
| xz-utils \ | |
| unzip | |
| # ============================================ | |
| # LATEX INSTALLATION (For mathematical typesetting) | |
| # ============================================ | |
| - name: Install LaTeX Dependencies | |
| run: | | |
| sudo apt-get install -y \ | |
| texlive \ | |
| texlive-latex-base \ | |
| texlive-latex-extra \ | |
| texlive-fonts-extra \ | |
| texlive-fonts-recommended \ | |
| texlive-science \ | |
| texlive-latex-recommended \ | |
| cm-super \ | |
| dvipng \ | |
| dvisvgm | |
| # ============================================ | |
| # ANDROID SDK/NDK SETUP | |
| # ============================================ | |
| - name: Set up Android SDK | |
| uses: android-actions/setup-android@v3 | |
| with: | |
| packages: | | |
| platforms;android-31 | |
| ndk;25.2.9519653 | |
| cmake;3.22.1 | |
| build-tools;34.0.0 | |
| # ============================================ | |
| # PYTHON DEPENDENCIES | |
| # ============================================ | |
| - name: Install Python Build Dependencies | |
| run: | | |
| python -m pip install --upgrade pip setuptools wheel | |
| # Core build tools | |
| pip install \ | |
| Cython==0.29.33 \ | |
| setuptools-scm \ | |
| # Buildozer and dependencies | |
| pip install \ | |
| buildozer \ | |
| p4a \ | |
| # Manim and its dependencies | |
| pip install \ | |
| numpy \ | |
| scipy \ | |
| matplotlib \ | |
| pillow \ | |
| sympy \ | |
| pydub \ | |
| requests \ | |
| watchdog \ | |
| # Additional graphics processing | |
| pip install \ | |
| opencv-python \ | |
| scikit-image \ | |
| imageio \ | |
| imageio-ffmpeg | |
| - name: Verify Critical Dependencies | |
| run: | | |
| echo "=== Checking System Libraries ===" | |
| pkg-config --modversion cairo || echo "WARN: cairo not found" | |
| pkg-config --modversion pango || echo "WARN: pango not found" | |
| pkg-config --modversion pangocairo || echo "WARN: pangocairo not found" | |
| pkg-config --modversion freetype2 || echo "WARN: freetype2 not found" | |
| pkg-config --modversion harfbuzz || echo "WARN: harfbuzz not found" | |
| echo "=== Checking LaTeX Installation ===" | |
| latex --version || echo "WARN: LaTeX not found" | |
| echo "=== Checking FFmpeg ===" | |
| ffmpeg -version | head -3 | |
| echo "=== Checking Python Packages ===" | |
| python -c "import cairo; print(f'cairo: OK')" 2>/dev/null || echo "WARN: pycairo not installed yet" | |
| python -c "import numpy; print(f'numpy: {numpy.__version__}')" | |
| python -c "import PIL; print(f'pillow: OK')" | |
| # ============================================ | |
| # BUILDOZER CONFIGURATION | |
| # ============================================ | |
| - name: Create buildozer.spec | |
| run: | | |
| cat > buildozer.spec << 'EOF' | |
| [app] | |
| title = Manim Animation | |
| package.name = manimanim | |
| package.domain = org.manim | |
| source.dir = . | |
| source.include_exts = py,png,jpg,kv,atlas,ttf | |
| version = 0.1.0 | |
| requirements = python3,kivy,numpy,scipy,pydub,pillow,sympy,requests,watchdog,imageio,opencv,scikit-image | |
| orientation = portrait | |
| fullscreen = 0 | |
| android.permissions = INTERNET,ACCESS_NETWORK_STATE,WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE | |
| android.features = android.hardware.screen.landscape | |
| android.api = 31 | |
| android.minapi = 21 | |
| android.ndk = 25b | |
| android.accept_sdk_license = True | |
| android.arch = arm64-v8a | |
| android.allow_backup = True | |
| # Graphics and rendering | |
| android.gradle_dependencies = androidx.appcompat:appcompat:1.6.1 | |
| # Buildozer specific options | |
| p4a.source_dir = %(source.dir)s/.buildozer/android/platform/build-*_armeabi-v7a/build/other_builds | |
| p4a.local_recipes = ./ | |
| p4a.hook = %(source.dir)s/p4a_hook.py | |
| [buildozer] | |
| log_level = 2 | |
| warn_on_root = 1 | |
| EOF | |
| cat buildozer.spec | |
| # ============================================ | |
| # PREPARE MANIM APP FOR ANDROID | |
| # ============================================ | |
| - name: Create Minimal Manim Android App | |
| run: | | |
| cat > main.py << 'EOF' | |
| # Minimal Manim Android App | |
| import os | |
| os.environ['KIVY_WINDOW'] = 'pygame' | |
| from kivy.app import App | |
| from kivy.uix.boxlayout import BoxLayout | |
| from kivy.uix.label import Label | |
| from kivy.uix.button import Button | |
| class ManimApp(App): | |
| def build(self): | |
| layout = BoxLayout(orientation='vertical', padding=10, spacing=10) | |
| label = Label( | |
| text='Manim for Android\nInitialization successful!', | |
| size_hint_y=0.7, | |
| font_size='24sp' | |
| ) | |
| button = Button( | |
| text='Test Render', | |
| size_hint_y=0.3 | |
| ) | |
| button.bind(on_press=self.on_test) | |
| layout.add_widget(label) | |
| layout.add_widget(button) | |
| return layout | |
| def on_test(self, instance): | |
| print("Test render triggered") | |
| # Actual Manim rendering would go here | |
| if __name__ == '__main__': | |
| ManimApp().run() | |
| EOF | |
| cat > p4a_hook.py << 'EOF' | |
| # P4A Build Hook - Ensures all dependencies are included | |
| def postbuild_gradle(gradle_file): | |
| """Post-process gradle build to include Manim dependencies""" | |
| pass | |
| def install_python_package(ctx, package): | |
| """Install Python packages during build""" | |
| pass | |
| EOF | |
| # ============================================ | |
| # BUILD APK | |
| # ============================================ | |
| - name: Build with Buildozer (Debug APK) | |
| run: | | |
| # Accept Android SDK licenses | |
| yes | buildozer android debug 2>&1 | tee buildozer.log | |
| # Check build status | |
| if [ -f "bin/manimanim-0.1.0-debug.apk" ]; then | |
| echo "✓ APK build successful!" | |
| ls -lh bin/*.apk | |
| else | |
| echo "✗ APK build failed" | |
| tail -100 buildozer.log | |
| exit 1 | |
| fi | |
| # ============================================ | |
| # UPLOAD ARTIFACTS | |
| # ============================================ | |
| - name: Upload APK Artifact | |
| if: success() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: manim-android-apk | |
| path: bin/*.apk | |
| retention-days: 30 | |
| - name: Upload Build Log | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: buildozer-log | |
| path: buildozer.log | |
| retention-days: 7 | |
| # ============================================ | |
| # BUILD VERIFICATION | |
| # ============================================ | |
| - name: Verify APK Contents | |
| if: success() | |
| run: | | |
| echo "=== APK Details ===" | |
| for apk in bin/*.apk; do | |
| if [ -f "$apk" ]; then | |
| echo "File: $apk" | |
| unzip -l "$apk" | head -30 | |
| echo "..." | |
| echo "Total files in APK:" | |
| unzip -l "$apk" | tail -2 | |
| fi | |
| done | |