chore: initial commit of OpenWRT

This commit is contained in:
sapient
2026-03-22 00:54:57 -07:00
commit 52a926b05e
3613 changed files with 1055180 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.env
.env.*
*.log
node_modules/
.venv/

64
docs/OPKG-REPO-README.md Executable file
View File

@@ -0,0 +1,64 @@
# opkg Repository - Quick Reference
## 📦 Repository Ready!
Your opkg-compatible repository is located at:
```
/home/user/Public/Projects/OpenWRT/opkg-repo/
```
## 🚀 Quick Upload
Upload to your HTTP server (`/srv/http`):
```bash
./upload-repo.sh SERVER_IP user /srv/http/opkg
```
Alternatively, manual upload:
```bash
scp -r opkg-repo/* user@SERVER_IP:/srv/http/opkg/
```
## 📋 Available Packages
- **btop-static** (1.4.3-1) - 1.0 MB - Resource monitor
- **mosh-static** (1.4.0-1) - 3.6 MB - Mobile Shell
## 🔧 On Your OpenWRT Device
```bash
# Add repository (replace SERVER_IP)
echo 'src/gz custom http://SERVER_IP/opkg/aarch64_cortex-a53/packages' > /etc/opkg/customfeeds.conf
# Update and install
opkg update
opkg install btop-static mosh-static
```
## Adding New Packages
```bash
# 1. Copy package to repository
cp new-package.ipk opkg-repo/aarch64_cortex-a53/packages/
# 2. Regenerate index
./generate-index.sh opkg-repo/aarch64_cortex-a53/packages/ > opkg-repo/aarch64_cortex-a53/packages/Packages
gzip -9 -k opkg-repo/aarch64_cortex-a53/packages/Packages
# 3. Upload to server
./upload-repo.sh SERVER_IP user /srv/http/opkg
```
## 📁 Files Created
- `opkg-repo/` - Local repository directory
- `generate-index.sh` - Package index generator
- `upload-repo.sh` - Server upload script
- Full documentation in the artifacts
## ⚠️ Notes
- Repository is for **aarch64_cortex-a53** architecture only
- All packages are statically linked
- Index must be regenerated after changes
- Two btop variants failed indexing (missing control files)

91
docs/PROJECT_README.md Executable file
View File

@@ -0,0 +1,91 @@
# OpenWRT Cross-Compilation Project
Cross-compilation environment for GL.iNet routers: **Flint1 (GL-AX1800)** and **Flint2 (GL-MT6000)**.
## Project Structure
### Router-Specific Directories
```
OpenWRT/
├── flint1-armv7/ # GL-AX1800 (ARMv7, 32-bit)
│ ├── sdk/ # ARMv7 cross-compilation toolchains
│ ├── src/ # Source code for compilation
│ └── build/ # Build scripts
├── flint2-aarch64/ # GL-MT6000 (ARMv8/aarch64, 64-bit)
│ ├── sdk/ # MediaTek OpenWrt SDKs
│ ├── src/ # Source code (symlinked)
│ └── build/ # Build scripts
├── binaries/ # Compiled binaries
│ ├── flint1/ # ARMv7 binaries
│ └── flint2/ # aarch64 binaries
├── packages/ # .ipk packages
│ ├── flint1/
│ ├── flint2/
│ └── common/
├── src/ # Shared source code
│ ├── btop/
│ └── mosh/
└── agent-notes/ # Research and documentation
```
### Shared Directories
- **`binaries/`** - Compiled binaries sorted by architecture
- **`packages/`** - OpenWrt `.ipk` packages
- **`src/`** - Original source code (shared reference)
- **`opkg-repo/`** - Package repository for deployment
- **`agent-notes/`** - Research, build results, SDK documentation
## Architecture Overview
| Router | Model | SoC | Architecture | Bits | OpenWrt Target |
|--------|-------|-----|--------------|------|----------------|
| **Flint1** | GL-AX1800 | Qualcomm IPQ6000 | ARMv7 rev 4 | 32-bit | ipq40xx |
| **Flint2** | GL-MT6000 | MediaTek MT7986A | ARMv8 rev 4 (aarch64) | 64-bit | mediatek-filogic |
**Note:** Different architectures require **separate binaries**.
## Quick Start
### Flint1 (ARMv7)
```bash
cd flint1-armv7/build
./download-armv7-toolchain.sh # First time only
./build-btop-armv7.sh
```
### Flint2 (aarch64)
Binaries already built and available in `binaries/flint2/`.
To rebuild:
```bash
cd flint2-aarch64/sdk/openwrt-sdk-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64/
./scripts/feeds update -a
make package/<name>/compile
```
## Documentation
- **Flint1 SDK Research:** `agent-notes/flint1-sdk-research.md`
- **Flint1 Build Results:** `agent-notes/glax1800-build-results.md`
- **Implementation Plan:** `.gemini/antigravity/brain/.../implementation_plan.md`
## Build Scripts
- `build-ipk.sh` - Create .ipk packages
- `build-verified-ipk.sh` - Build with verification
- `generate-index.sh` - Generate opkg repository index
- `upload-repo.sh` - Upload to repository server
## Active Toolchains
**Flint1:** musl.cc armv7l-linux-musleabihf (GCC 11.2.1)
**Flint2:** OpenWrt mediatek-filogic SDK (GCC 14.3.0)

121
docs/README-dummy-pkg.md Executable file
View File

@@ -0,0 +1,121 @@
# Dummy OPKG Package - hello-opkg
## Package Information
- **Name:** hello-opkg
- **Version:** 1.0.0-1
- **Architecture:** all (universal)
- **File:** `packages/hello-opkg_1.0.0-1_all.ipk`
- **Size:** ~812 bytes
## What It Does
This is a minimal test package that installs a simple shell script at `/usr/bin/hello-opkg`.
When executed, the script prints:
```
Hello from the opkg dummy package!
Package: hello-opkg v1.0.0
This package was installed successfully.
```
## Package Structure
The package follows standard IPK format:
```
hello-opkg_1.0.0-1_all.ipk
├── debian-binary (format version: 2.0)
├── control.tar.gz (package metadata)
│ └── control
└── data.tar.gz (installed files)
└── usr/bin/hello-opkg
```
## Installation
On an OpenWRT device:
```bash
opkg install hello-opkg_1.0.0-1_all.ipk
```
Or from your repository:
```bash
opkg update
opkg install hello-opkg
```
## Testing
```bash
# Run the installed script
hello-opkg
# Check package info
opkg status hello-opkg
# List installed files
opkg files hello-opkg
```
## Removal
```bash
opkg remove hello-opkg
```
## Troubleshooting "Malformed Package" Error
If you encounter a "malformed package" error, try:
1. **Check opkg version**: Some older opkg versions are picky about format
```bash
opkg --version
```
2. **Verify package structure**:
```bash
ar t hello-opkg_1.0.0-1_all.ipk
# Should show: debian-binary, control.tar.gz, data.tar.gz
```
3. **Check file permissions**: The script must be executable
```bash
tar tzf <(ar p hello-opkg_1.0.0-1_all.ipk data.tar.gz)
```
4. **Try verbose installation**:
```bash
opkg install -V3 hello-opkg_1.0.0-1_all.ipk
```
5. **Inspect control file**:
```bash
ar p hello-opkg_1.0.0-1_all.ipk control.tar.gz | tar xzO ./control
```
## Rebuilding the Package
Use the included `build-ipk.sh` script:
```bash
# Create package structure
mkdir -p my-package/CONTROL my-package/usr/bin
# Create control file
cat > my-package/CONTROL/control << 'EOF'
Package: my-package
Version: 1.0.0
Architecture: all
Maintainer: Your Name <you@example.com>
Description: My test package
EOF
# Add your files
echo '#!/bin/sh' > my-package/usr/bin/my-script
echo 'echo "Hello!"' >> my-package/usr/bin/my-script
chmod +x my-package/usr/bin/my-script
# Build it
./build-ipk.sh my-package packages/
```
## Use Cases
- Testing repository setup
- Verifying package index generation
- Testing upload scripts
- Debugging package installation issues
- CI/CD pipeline testing

View File

@@ -0,0 +1,53 @@
import os
import shutil
BASE_DIR = "/home/user/Public/Projects/OpenWRT"
STRUCTURE = {
"sdk": [
"openwrt-sdk-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64"
],
"sources": [
"btop"
],
"packages": [
"btop-flint2-package",
"btop-openwrt-package"
],
"bin": [
"btop-flint2"
]
}
def reorganize():
print(f"Reorganizing {BASE_DIR}...")
# Create new directories
for folder in STRUCTURE.keys():
path = os.path.join(BASE_DIR, folder)
if not os.path.exists(path):
print(f"Creating directory: {path}")
os.makedirs(path)
else:
print(f"Directory exists: {path}")
# Move items
for folder, items in STRUCTURE.items():
dest_dir = os.path.join(BASE_DIR, folder)
for item in items:
src_path = os.path.join(BASE_DIR, item)
dest_path = os.path.join(dest_dir, item)
if os.path.exists(src_path):
print(f"Moving {item} to {folder}/...")
try:
shutil.move(src_path, dest_path)
except Exception as e:
print(f"Error moving {item}: {e}")
else:
print(f"Warning: Source not found: {item}")
print("Reorganization complete.")
if __name__ == "__main__":
reorganize()

57
docs/ax1800-firmware-guide.md Executable file
View File

@@ -0,0 +1,57 @@
# GL-AX1800 (Flint) Firmware Research & Guide
This guide provides current (2024/2025) information on building and downloading firmware for the GL.iNet AX1800 (Flint).
## 🛠️ Hardware Specifications
- **SoC**: Qualcomm IPQ6000 (A7 is for ipq40xx, this is A53)
- **Architecture**: `aarch64_cortex-a53`
- **OpenWrt Target**: `qualcommax / ipq60xx` (Note: older models use `ipq40xx`, but the Flint requires `qualcommax`)
## 🧱 Building with `gl-infra-builder`
The official tool used by GL.iNet to build firmware is `gl-infra-builder`.
### ⚠️ Current Status (2024/2025)
- **Codeaurora Shutdown**: Many older SDKs depend on `source.codeaurora.org`, which is now offline. This causes build failures in the `qca-nss-client` and related packages.
- **Access**: GL.iNet has moved the repository to a more private or restricted access model in some cases, often returning 404s on previous public links.
### Build Steps (Updated)
1. **Setup**:
```bash
python3 setup.py -c configs/config-wlan-ap.yml
cd wlan-ap/openwrt
```
2. **Configure**:
Use the `barebones_ax1800` profile for a clean OpenWrt experience without the GL.iNet proprietary UI:
```bash
./scripts/gen_config.py target_wlan_ap-gl-ax1800 barebones_ax1800
```
3. **Compile**:
```bash
make V=s -j$(nproc)
```
## 📦 Firmware Inventory
The following firmwares are organized in the `firmware/flint1/` directory.
### Official GL.iNet (OpenWrt 21.02 based)
- **Latest Stable**: 4.6.8
- **Latest Beta**: 4.8.3
- **Primary Use**: Best for stability and proprietary features (VPN performance, specific hardware drivers).
### Vanilla OpenWrt (Mainline)
- **Status**: Currently only available via **Snapshots**. There is no official 22.03 or 23.05 stable release build for the GL-AX1800 on `downloads.openwrt.org` yet.
- **Snapshot Path**: `qualcommax/ipq60xx`
- **Pros**: Latest kernel (6.x), pure OpenWrt experience.
- **Cons**: No LuCI by default in many snapshots; potentially unstable.
### ImmortalWrt (Community Fork)
- **Status**: Stable builds exist for some models, but AX1800 is primarily in **Snapshots**.
- **Pros**: Often includes more "Chinese-friendly" packages and performance tweaks.
## 📂 Downloaded Files
Local copies are stored in:
- `firmware/flint1/official/`: 4.6.8 stable, 4.8.3 beta
- `firmware/flint1/vanilla/snapshots/`: Mainline OpenWrt
- `firmware/flint1/immortalwrt/`: ImmortalWrt snapshots

76
docs/backporting-research.md Executable file
View File

@@ -0,0 +1,76 @@
# OpenWRT Package Backporting Guide
## Overview
Backporting allows you to use a newer version of a package (from OpenWRT `master` or a newer release) on an older stable release (e.g., OpenWRT 21.02).
## The Process
1. **Prepare Build Environment**
- You need the **SDK** (Software Development Kit) for your **Target** version (the older version you are running).
- *Example:* If using OpenWRT 21.02 on x86/64, download the OpenWRT 21.02 SDK for x86/64.
2. **Locate Source Package**
- Find the package in the *newer* source tree (e.g., GitHub `openwrt/packages` repository, `master` branch).
- Package definition consists of:
- `Makefile`
- `patches/` (directory, if any)
- `files/` (directory, optional configuration files)
3. **Copy to SDK**
- Copy the package directory from the source to your SDK's `package/` directory.
- *Alternative:* Add the newer feed to `feeds.conf.default` but pin it to a specific commit (more complex due to dependencies). Manual copy is often easier for single packages.
4. **Adjust Dependencies**
- Check `DEPENDS` line in `Makefile`.
- Older SDKs might have older libraries.
- *If dependency is missing:* You must backport the dependency package too.
- *If dependency is tool old:* You might need to relax the requirement or backport the library (risky).
5. **Build**
- Run `make menuconfig` and select the package.
- Run `make package/refined-package/compile`.
## Example: Backporting `elinks`
**Scenario:** Backporting `elinks` from Master to OpenWRT 21.02.
**1. Get 21.02 SDK:**
```bash
wget https://downloads.openwrt.org/releases/21.02.7/targets/x86/64/openwrt-sdk-21.02.7-x86-64_gcc-8.4.0_musl.Linux-x86_64.tar.xz
tar xJsOf openwrt-sdk-*.tar.xz
cd openwrt-sdk-*
```
**2. Get `elinks` from Master:**
You don't need the whole master repo, just the folder.
```bash
svn export https://github.com/openwrt/packages/trunk/net/elinks package/elinks
# OR strictly from git
git clone https://github.com/openwrt/packages.git /tmp/packages
cp -r /tmp/packages/net/elinks package/
```
**3. Check Makefile (`package/elinks/Makefile`):**
```makefile
PKG_NAME:=elinks
PKG_VERSION:=0.16.1.1 # Newer version
...
DEPENDS:=+libopenssl +libexpat ...
```
*Verification:* Check if `libopenssl` and `libexpat` are functional in your SDK. Usually they are standard.
**4. Build:**
```bash
./scripts/feeds update -a
./scripts/feeds install -a
make menuconfig
# Select Network -> Web Servers/Browsers -> elinks
make package/elinks/compile V=s
```
**5. Result:**
The new IPK will be in `bin/packages/x86_64/base/elinks_*.ipk`.
## Common Pitfalls
- **Kernel Dependencies:** Kmods are hard to backport (require kernel version match). Avoid backporting kernel modules if possible.
- **Library ABIs:** If a package needs `libfoo.so.2` but your system has `libfoo.so.1`, you need to backport the library, which might break other things. Static linking can sometimes solve this.

View File

@@ -0,0 +1,39 @@
# Barebones OpenWrt Image Research (GL-AX1800)
## Objectives
- Create a stripped-down image for GL-AX1800 (Flint 1).
- Accessible via SSH.
- No LuCI or GL.iNet UI.
- Use `gl-infra-builder` for hardware-specific optimizations.
- Ensure U-Boot compatible image output.
## Tool Selection
- **Builder:** `FUjr/gl-infra-builder`.
- **Base Config:** `config-wlan-ap.yml` (Qualcomm SDK based).
- **Target Profile:** `target_wlan_ap-gl-ax1800`.
## Findings
### 1. Reorganization
- Workspace reorganized into `firmware/`, `sdk/`, `docs/`, `scripts/`, `packages/`, `repo/`.
- Created `PROJECT_INDEX.md` as a master reference.
### 2. gl-infra-builder Logic
- The builder uses YAML profiles in the `profiles/` directory.
- `gen_config.py` merges multiple profiles.
- Standard GL.iNet profiles (`glinet_ax1800.yml`) include a heavy set of proprietary services.
- A "Barebones" profile can be created by overriding these with `-package` or `CONFIG_PACKAGE_xxx=n` in the `diffconfig` section.
### 3. OpenWrt Snapshots & Upgrade Path
- **V21.02 (GL 4.x):** Current base for most GL firmware.
- **V23.05:** Transitional, used `ipq40xx` target.
- **Master/V24/V25:** Native `qualcommax/ipq60xx` target (merged March 2025).
- **Upgrade Path:**
- From GL Stock -> Vanilla: Flash `factory.ubi` via U-Boot recovery (192.168.1.1).
- From Vanilla -> Newer Vanilla: Use `sysupgrade.bin`.
- **Note:** Partition layouts might change between 21.02 and 24.x. Using the `factory.ubi` is safest for major transitions.
### 4. Barebones Configuration Plan
- Include `dropbear` (SSH), `opkg` (Package management).
- Include essential HW drivers: `kmod-gl-sdk4-hw-info`, `gl-sdk4-led`.
- Explicitly disable `luci`, `nginx`, and all `gl-sdk4-ui-*` packages.
- Ensure `ath11k` drivers are included for Wi-Fi (if using OpenWrt master) or the proprietary QSDK drivers (if using the builder).

36
docs/cross_compilation_notes.md Executable file
View File

@@ -0,0 +1,36 @@
# Cross-Compilation Notes
## GL-iNet Flint 2 (GL-MT6000)
- **SoC**: MediaTek MT7986 (Filogic 830)
- **CPU**: Quad-core ARM Cortex-A53 @ 2.0GHz
- **Architecture**: `aarch64`
- **Target**: `mediatek/filogic`
- **SDK Path**: `../openwrt-sdk-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64`
- **Toolchain**: `gcc-14.3.0_musl`
### Compiling for Flint 2
1. Source the SDK environment (if using the full SDK wrapper) or add the staging_dir toolchain to PATH.
2. Export `STAGING_DIR`:
```bash
export STAGING_DIR=/home/sapient/Projects/OpenWRT/openwrt-sdk-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64/staging_dir
```
3. Add toolchain bin to PATH:
```bash
export PATH=$PATH:$STAGING_DIR/toolchain-aarch64_cortex-a53_gcc-14.3.0_musl/bin
```
4. Compile with `aarch64-openwrt-linux-gcc`.
## GL-iNet Flint 1 (GL-AX1800)
- **SoC**: Qualcomm IPQ6000
- **CPU**: Quad-core ARM Cortex-A53 @ 1.2GHz
- **Architecture**: `aarch64`
- **Target**: `ipq807x/generic` or `ipq807x/ipq60xx` (check OpenWRT target mapping)
### Compiling for Flint 1
- Similar to Flint 2, this is an `aarch64` architecture.
- CAUTION: while the architecture is the same (`aarch64`), kernel headers and libc versions might differ if using a different OpenWRT version.
- Ideally, obtain the SDK for `ipq807x` if the application relies on kernel interfaces or specific libraries. for generic userspace apps, the Flint 2 toolchain *might* work but is not guaranteed.
## General Notes
- Both devices are `aarch64`.
- Generic static binaries compiled for `aarch64-linux-musl` should likely work on both.

56
docs/firmware-inventory.md Executable file
View File

@@ -0,0 +1,56 @@
# GL-AX1800 (Flint) Firmware Inventory
This document catalogs all downloaded firmware images for the GL-AX1800 (Flint).
## 🎯 AX1800 (IPQ6000 / qualcommax/ipq60xx)
### GL.iNet Official Firmware
**Location**: `firmware/flint1/glinet-official/`
- **gl-ax1800-4.6.8-stable.tar** (8.6M) - Latest stable release (OpenWrt 21.02-based)
- **gl-ax1800-4.6.8-uboot.img** - U-Boot recovery image for 4.6.8
- **gl-ax1800-4.8.3-beta.tar** - Beta testing version
- **ax1800-4.8.3_beta1.img** - Beta U-Boot recovery
### OpenWrt Official (Snapshots)
**Location**: `firmware/flint1/openwrt-official/snapshots/`
- **openwrt-snapshot-factory.bin** (13M) - Latest mainline snapshot (factory install)
- **openwrt-snapshot-sysupgrade.bin** (12M) - Latest mainline snapshot (sysupgrade)
**Location**: `firmware/flint1/openwrt-official/`
- **openwrt-master-factory.bin** (13M) - Master branch build
- **openwrt-master-sysupgrade.bin** (12M)
- **openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.bin** (13M)
- **openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin** (12M)
### OpenWrt 25.12-rc2
**Location**: `firmware/flint1/openwrt-official/25.12-rc2/`
- **openwrt-25.12.0-rc2-factory.bin** - Release candidate 2 factory image
- **openwrt-25.12.0-rc2-sysupgrade.bin** - Release candidate 2 sysupgrade
- **openwrt-25.12.0-rc2-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.ubi** - UBI variant
### ImmortalWrt
**Location**: `firmware/flint1/immortalwrt/`
- **immortalwrt-snapshot-factory.bin** (13M) - ImmortalWrt snapshot build
- **immortalwrt-snapshot-sysupgrade.bin** (12M)
### Community Builds (KWRT)
**Location**: `firmware/flint1/community-kwrt/`
- **kwrt-01.10.2026-factory.bin** - KWRT community build
---
## Summary
| Source | Architecture | Device | Firmware Count |
|:-------|:-------------|:-------|:---------------|
| **qualcommax/ipq60xx** | aarch64_cortex-a53 | GL-AX1800 | 13 images |
### Recommended Images
- **Production**: `gl-ax1800-4.6.8-stable.tar` (GL.iNet official)
- **Latest Features**: `openwrt-snapshot-factory.bin` (OpenWrt mainline snapshot)
- **Release Candidate**: `openwrt-25.12.0-rc2-factory.bin` (near-stable)

319
docs/flint1-firmware-options.md Executable file
View File

@@ -0,0 +1,319 @@
# GL-AX1800 (Flint1) Firmware Options Research
**Date:** 2026-01-12
**Device:** GL-AX1800 (Flint 1)
**Current Firmware:** ApNos-3c11d1c4-devel, OpenWrt 23.05-SNAPSHOT
**Architecture:** ARMv7 rev 4 (v7l), IPQ6000 SoC
---
## Executive Summary
The GL-AX1800 has **three main firmware options** available in 2025-2026:
1. **GL.iNet Official Firmware** (v4.6-4.8) - Custom OpenWrt with proprietary features
2. **Vanilla OpenWrt** (23.05.x stable, master snapshots) - Official community builds
3. **Alternative Firmware** (DD-WRT potential, NO Tomato support)
**Key Finding:** GL-AX1800 was officially merged into OpenWrt master in March 2025, now under the `qualcommax/ipq60xx` target (NOT `ipq40xx` as in older 23.05 releases).
---
## Option 1: GL.iNet Official Firmware
### Latest Versions
| Version | Status | Release Date | Notes |
|---------|--------|--------------|-------|
| **4.8.x** | Beta/Upcoming | Q3 2025 (planned) | Major VPN & UI improvements |
| **4.7.0** | **Pulled/Problematic** | March 2025 | Wi-Fi instability reported |
| **4.6.11** | **Stable (Current)** | 2024-2025 | Most stable production version |
### Version 4.8.x Features (Upcoming)
**Major Improvements:**
- **Multiple VPN instances** - Run multiple VPN clients simultaneously in policy mode
- **OpenVPN DCO** (Data Plane Offload) - Hardware-accelerated OpenVPN on AX1800
- **Rebuilt cellular interface** - Better support for LTE/5G modems
- **Redesigned toggle switch** - Control Repeater, Wi-Fi, VPN, or LED
- **One-click log submission** - Improved troubleshooting
- **IPv6 VPN optimization**
- **Categorized log search**
**Status:** Beta testing started April 2025, stable Q3 2025
**AX1800 Support:** ✅ Confirmed
**Concerns:**
- Early 4.8.0 beta had VPN traffic leak issues (expected fix in 4.8.1)
- Beta firmware may have stability issues
---
### Version 4.7.0 (NOT RECOMMENDED)
**Features:**
- New device setup wizard
- Enhanced WireGuard + AzireVPN integration
- Control D DNS support
- Improved repeater privacy (random MAC)
**Problems:**
-**Wi-Fi instability** - Users reported connection drops
- ❌ Appears to have been **pulled/withdrawn** from download center
- ❌ Users downgraded to 4.6.8 for stability
- ❌ Missing package repositories (4.7.x)
**Status:** **Avoid** - Known issues, likely discontinued
---
### Version 4.6.x (STABLE - RECOMMENDED)
**Latest:** 4.6.11
**Features:**
- Stable repeater mode enhancements
- Proven reliability
- Full package repository support
**Security Note:**
- CVE-2025-67091 (moderate severity) in 4.6.4 and 4.6.8
- Vulnerability in custom opkg wrapper script
- Fixed in later versions
**Download:** https://dl.gl-inet.com/?model=ax1800
**Recommendation:** Use 4.6.11 until 4.8.x is proven stable
---
## Option 2: Vanilla OpenWrt
### Target Architecture Change
**IMPORTANT:** The GL-AX1800 target changed between OpenWrt versions:
| OpenWrt Version | Target | Architecture |
|-----------------|--------|--------------|
| **21.02** | `ipq40xx/generic` | ARMv7 (legacy support) |
| **23.05** | `ipq40xx/generic` | ARMv7 (transitional) |
| **Master/Snapshots** | **`qualcommax/ipq60xx`** | ARMv7 (proper IPQ6000 support) |
**Explanation:** Earlier versions used the `ipq40xx` target as a workaround. Official IPQ6000 support was merged into OpenWrt master in **March 2025** under the new `qualcommax/ipq60xx` target.
---
### 23.05.x Stable (What You're Running)
**Latest:** 23.05.5 (September 2024)
**Specs:**
- GCC 12.3.0
- Target: `ipq40xx/generic`
- SDK Downloaded: ✅ `/flint1-armv7/sdk/openwrt-23.05-sdk/`
**Download Paths:**
- Images: `https://downloads.openwrt.org/releases/23.05.5/targets/ipq40xx/generic/`
- SDK: ✅ Already downloaded
**Pros:**
- ✅ Stable, tested release
- ✅ SDK/toolchain available
- ✅ Matches your current firmware base
**Cons:**
- ⚠️ Uses legacy `ipq40xx` target (not native IPQ6000)
- ⚠️ Older kernel/packages vs snapshots
---
### Master Snapshots (Latest Development)
**Target:** `qualcommax/ipq60xx` (NEW as of March 2025)
**Specs:**
- **GCC:** 14.3.0 (latest)
- **Kernel:** Linux 6.x (newest)
- **Features:** Bleeding-edge OpenWrt
- **SDK:** Available with GCC 14.3.0
**Download Paths:**
- **Images:** `https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/`
- **SDK:** `https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/openwrt-sdk-qualcommax-ipq60xx_gcc-14.3.0_musl.Linux-x86_64.tar.zst`
**Available Images:**
```
openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.bin
openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin
```
**Firmware Selector:** https://firmware-selector.openwrt.org/
(Search: "GL-AX1800", select "SNAPSHOT")
**Pros:**
-**Native IPQ6000 support** (`qualcommax/ipq60xx`)
-**GCC 14.3.0** - Best C++23 support
- ✅ Latest kernel, drivers, features
- ✅ Active development, frequent updates
- ✅ Newer `ath11k` Wi-Fi driver
**Cons:**
- ⚠️ **No LuCI web interface** by default (install via SSH)
- ⚠️ Development builds - less stable than releases
- ⚠️ `ath11k` open-source driver uses more RAM (~380MB free vs 512MB total)
- ⚠️ Doesn't include all Qualcomm proprietary SDK components
- ⚠️ Daily builds - version changes constantly
**RAM Consideration:**
- GL.iNet firmware: Proprietary drivers, more free RAM
- Vanilla OpenWrt: Open-source `ath11k`, ~130MB used by driver firmware
---
### Installation Methods
**For Factory/Stock:**
```
openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.bin
```
**For OpenWrt→OpenWrt:**
```
openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin
```
**Via U-Boot:** Flash at router boot (advanced users)
---
## Option 3: Alternative Firmware
### DD-WRT
**Status:** **Potentially Supported** (unconfirmed)
**Evidence:**
- DD-WRT database lists: `glinet-gl-ax1800 build 61557 20250531`
- Build number suggests May 31, 2025 release
- **NOT verified** - check DD-WRT forums for actual availability
**Download (if available):** https://dd-wrt.com/support/router-database/
**Pros:**
- Different feature set than OpenWrt
- May have better QoS/VPN features
**Cons:**
- ⚠️ **Unverified support** - database may be outdated
- ⚠️ DD-WRT warns their database can have inaccurate entries
- ⚠️ Less community support for this device
- ⚠️ Risk of bricking if not officially supported
**Recommendation:** **Wait for confirmation** from DD-WRT community before attempting
---
### Tomato / Tomato64
**Status:****NO SUPPORT**
- Tomato64 lists support for ARM64 devices like GL-MT6000
- **GL-AX1800 is NOT listed**
- No indication of IPQ6000 support in Tomato ecosystem
**Recommendation:** Not an option for this device
---
### Other Firmware Options
- **ImmortalWrt** - OpenWrt fork with Chinese focus, likely has GL-AX1800 support
- **OpenWISP** - Network management platform (not firmware replacement)
- **LEDE** - Merged back into OpenWrt in 2018 (no longer separate)
---
## Comparison Matrix
| Feature | GL.iNet 4.6.11 | GL.iNet 4.8 (Beta) | OpenWrt 23.05.5 | OpenWrt Master | DD-WRT |
|---------|----------------|--------------------|-----------------|--------------------|--------|
| **Stability** | ⭐⭐⭐⭐⭐ | ⭐⭐⚠️ Beta | ⭐⭐⭐⭐ | ⭐⭐⭐ Snapshots | ❓ Unknown |
| **Features** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ❓ |
| **GCC Version** | ~8.x-12.x | ~12.x | 12.3.0 | **14.3.0** | N/A |
| **Target** | Custom | Custom | `ipq40xx` | **`qualcommax/ipq60xx`** | Custom |
| **RAM Usage** | Better (proprietary) | Better | Higher (ath11k) | Higher (ath11k) | ❓ |
| **Updates** | Quarterly | TBD | Periodic | **Daily** | Rare |
| **LuCI Web UI** | Custom | Custom | ✅ Included | ❌ Install manually | ✅ |
| **Support** | GL.iNet + Community | GL.iNet + Community | Official OpenWrt | Official OpenWrt | DD-WRT forums |
---
## Recommendations
### For Stability & Features
**Use GL.iNet 4.6.11**
- Most stable current option
- All GL.iNet features (VPN, AdGuard, etc.)
- Good for production use
### For Latest OpenWrt Features
**Use OpenWrt Master Snapshots**
- Native `qualcommax/ipq60xx` support
- GCC 14.3.0 for building packages
- Latest kernel & drivers
- **BUT:** Requires SSH comfort, less stable
### For SDK Development
**You Already Have:**
- ✅ OpenWrt 23.05.5 SDK (GCC 12.3.0) - Downloaded
- ✅ musl.cc ARMv7 toolchain (GCC 11.2.1) - Downloaded
**To Add:**
```bash
# Download latest snapshot SDK
cd flint1-armv7/sdk
wget https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/openwrt-sdk-qualcommax-ipq60xx_gcc-14.3.0_musl.Linux-x86_64.tar.zst
```
**GCC 14.3.0 = Best C++23 support for btop compilation**
---
## When to Upgrade
### Stick with Current (23.05-SNAPSHOT) If:
- ✅ Everything works
- ✅ You value stability
- ✅ You already have SDK for development
### Upgrade to GL.iNet 4.6.11 If:
- ✅ Want GL.iNet features (VPN, AdGuard, GUI)
- ✅ Need stable production firmware
- ✅ Want long-term support
### Upgrade to OpenWrt Master If:
- ✅ Want bleeding-edge features
- ✅ Comfortable with SSH/command line
- ✅ Don't mind installing LuCI manually
- ✅ Want native `qualcommax/ipq60xx` support
### Wait for GL.iNet 4.8.x If:
- ✅ Want multiple VPN instances
- ✅ Need OpenVPN DCO performance
- ✅ Can wait for stable release (Q3 2025)
---
## Summary
**You have excellent options:**
1. **Stay Current** - Your 23.05-SNAPSHOT works, SDK available
2. **GL.iNet 4.6.11** - Most stable GL.iNet firmware
3. **OpenWrt Snapshots** - Latest qualcommax/ipq60xx with GCC 14.3.0
4. **GL.iNet 4.8.x** - Wait for stable release (Q3 2025)
**For development:** You're well-equipped with 23.05.5 SDK (GCC 12.3.0). Consider adding snapshot SDK (GCC 14.3.0) for maximum C++23 compatibility.
**DD-WRT:** Unverified - wait for community confirmation
**Tomato:** Not supported for this device

262
docs/flint1-sdk-research.md Executable file
View File

@@ -0,0 +1,262 @@
# GL-AX1800 (Flint1) SDK Research and Cross-Compilation Strategy
**Date:** 2026-01-11
**Device:** GL-AX1800 (Flint 1)
**SoC:** Qualcomm IPQ6000 (Quad-core ARM @ 1.2GHz)
## Architecture Confirmation (CORRECTED)
> [!IMPORTANT]
> **Confirmed from actual hardware:**
> - **Flint1 (GL-AX1800)**: ARMv7 rev 4 (v7l) - **32-bit ARM**
> - **Flint2 (GL-MT6000)**: ARMv8 rev 4 (v8l) - **64-bit ARM (aarch64)**
>
> These are **different architectures** and require **separate binaries**.
### Architecture Details
**GL-AX1800 (Flint1):**
- CPU: ARMv7 Processor rev 4 (v7l)
- Instruction set: 32-bit ARM
- Typical target triplet: `arm-linux-musleabihf` or `armv7l-linux-musleabihf`
**GL-MT6000 (Flint2):**
- CPU: ARMv8 Processor rev 4 (v8l)
- Instruction set: 64-bit ARM (aarch64)
- Typical target triplet: `aarch64-linux-musl`
---
## SDK Options for GL-AX1800 (ARMv7)
### Option 1: Pre-built musl.cc Toolchain (RECOMMENDED for Quick Start)
**Source:** https://musl.cc/
#### Relevant Toolchains
- `armv7l-linux-musleabihf-cross.tgz` (ARMv7, hard-float)
- `arm-linux-musleabihf-cross.tgz` (Generic ARM, hard-float)
**Download:**
```bash
wget https://musl.cc/armv7l-linux-musleabihf-cross.tgz
tar -xzf armv7l-linux-musleabihf-cross.tgz
export PATH=$PWD/armv7l-linux-musleabihf-cross/bin:$PATH
```
#### Advantages
- Quick setup (download and extract)
- Modern GCC (13.2+) with C++23 support
- Proven for static binary compilation
- Small download (~40-50MB compressed)
#### Disadvantages
- Not optimized for IPQ6000 specifically
- Generic ARMv7 (not Cortex-A7 specific)
---
### Option 2: musl-cross-make (Build Your Own)
**Source:** https://github.com/richfelker/musl-cross-make
#### Configuration for ARMv7
```makefile
TARGET = armv7l-linux-musleabihf
# or: arm-linux-musleabihf
GCC_VER = 14.2.0
MUSL_VER = 1.2.5
LINUX_VER = 6.6.y
GCC_CONFIG += --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard
```
#### Advantages
- Full control over toolchain versions
- Can build latest GCC 14+ for C++23
- Optimize for Cortex-A7 specifically
- Creates musl-based static-friendly toolchain
#### Disadvantages
- Time-consuming build (30-60 minutes)
- Requires build dependencies
- More complex setup
---
### Option 3: GL.iNet SDK (NOT RECOMMENDED)
**SDK:** `ipq807x-2102`
**GCC:** 5.5.0 (Too old)
**Architecture:** arm_cortex-a7 (32-bit)
#### Why Not Use This?
- ❌ GCC 5.5.0 cannot compile C++23 (btop)
- ❌ Outdated toolchain from ~2017
- ❌ Build failures documented in `agent-notes/glax1800-build-results.md`
- ✅ Correct architecture (ARMv7), but toolchain too old
---
## Compilation Requirements
### btop Requirements
**Language:** C++23
**Minimum GCC:** 11 (experimental), **14+ recommended** (full support)
**Dependencies:** None (headers only)
**Build System:** Make or CMake
**Static Linking:** Fully supported with musl
#### Build Strategy
```bash
# With OpenWrt SDK
make STATIC=true VERBOSE=true CXX=aarch64-openwrt-linux-musl-g++ \
CXXFLAGS="-static -std=c++23 -O3" LDFLAGS="-static"
```
---
### mosh Requirements
**Language:** C++14
**Build System:** Autotools (./configure)
**Dependencies (must be cross-compiled):**
- **protobuf** 3.x (C++ library, requires host protoc)
- **ncurses** 6.x (terminfo)
- **OpenSSL** 1.1.x (or omit with `--without-crypto`)
- **zlib** (compression)
#### Build Strategy (Multi-Stage)
1. **Build host protoc** (x86_64)
```bash
cd protobuf-3.17.3
./configure --prefix=/usr/local
make && sudo make install
```
2. **Cross-compile protobuf libraries**
```bash
./configure --host=aarch64-linux-musl --prefix=$PWD/sysroot \
--with-protoc=/usr/local/bin/protoc \
CXXFLAGS="-static" LDFLAGS="-static"
make && make install
```
3. **Cross-compile ncurses**
```bash
./configure --host=aarch64-linux-musl --prefix=$PWD/sysroot \
--without-shared --with-normal --without-debug
make && make install
```
4. **Build mosh** (static)
```bash
./configure --host=aarch64-linux-musl \
PKG_CONFIG_PATH=$PWD/sysroot/lib/pkgconfig \
CXXFLAGS="-static" LDFLAGS="-static -pthread" \
--without-crypto # Optional: skip OpenSSL
make
```
#### Existing Build Environment
The `src/mosh/` directory already has:
- `env.sh` - Cross-compilation environment
- `sysroot/` - Custom libraries
- `host_protoc/` - Host protobuf compiler
- Built static binaries (for aarch64)
✅ **This can likely be reused or adapted!**
---
## Recommended Approach (CORRECTED)
### Phase 1: Toolchain Setup
**Use musl.cc pre-built ARMv7 toolchain for fastest results:**
```bash
cd /home/user/Public/Projects/OpenWRT/sdk/
# Download ARMv7 hard-float toolchain
wget https://musl.cc/armv7l-linux-musleabihf-cross.tgz
tar -xzf armv7l-linux-musleabihf-cross.tgz
# Add to PATH
export PATH=$PWD/armv7l-linux-musleabihf-cross/bin:$PATH
# Verify
armv7l-linux-musleabihf-gcc --version
```
---
### Phase 2: Build btop for ARMv7
```bash
cd /home/user/Public/Projects/OpenWRT/src/btop
# Clean previous builds
make clean
# Build static for ARMv7
make STATIC=true \
CXX=armv7l-linux-musleabihf-g++ \
CXXFLAGS="-static -std=c++23 -O3 -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard" \
LDFLAGS="-static"
# Verify architecture
file bin/btop
# Should show: ELF 32-bit LSB executable, ARM, EABI5
# Copy to flint1 binaries
cp bin/btop /home/user/Public/Projects/OpenWRT/binaries/flint1/btop/
```
---
### Phase 3: Build mosh for ARMv7
Mosh requires cross-compiling dependencies. Two options:
#### Option A: Adapt Existing Environment
The `src/mosh/` directory has a working setup for aarch64. Update it for ARMv7:
```bash
cd /home/user/Public/Projects/OpenWRT/src/mosh
# Update environment
export PATH=/path/to/armv7l-linux-musleabihf-cross/bin:$PATH
export CC=armv7l-linux-musleabihf-gcc
export CXX=armv7l-linux-musleabihf-g++
export AR=armv7l-linux-musleabihf-ar
export RANLIB=armv7l-linux-musleabihf-ranlib
# Rebuild protobuf for ARMv7
# (Host protoc already built)
# Configure mosh
./configure --host=armv7l-linux-musleabihf \
CXXFLAGS="-static" \
LDFLAGS="-static -pthread" \
--without-crypto
make clean && make
```
#### Option B: Fresh Build
Follow multi-stage process from research document (protobuf → ncurses → mosh).
---
## Next Steps
1.**Verify architecture** - Confirmed ARMv7 (32-bit ARM) vs ARMv8 (aarch64)
2. ⏭️ **Download ARMv7 toolchain** - Use musl.cc armv7l-linux-musleabihf
3. ⏭️ **Build btop** - Static ARMv7 binary with modern GCC
4. ⏭️ **Build mosh** - Cross-compile dependencies + static linking
5. ⏭️ **Create .ipk packages** - Package for opkg installation
6. ⏭️ **Test on hardware** - Verify on actual GL-AX1800

View File

@@ -0,0 +1,25 @@
# Future Improvements for AX1800 Barebones Firmware
After the initial successful build, several areas can be optimized to make the "Barebones" experience even better.
## 1. Performance & Resource Management
- **Zram Integration**: Enable `zram-swap` by default to better handle memory-intensive tasks like package updates or heavy VPN usage.
- **Kernel Slimming**: Review the default `ipq60xx` kernel configuration and disable unused filesystem drivers or legacy protocols to reduce the kernel footprint.
- **SQM (Smart Queue Management)**: Add `luci-app-sqm` and `cake` for better bufferbloat management.
## 2. Security Enhancements
- **SSH Hardening**: Provide a profile that disables password authentication by default and injects a provided SSH key.
- **WireGuard Optimization**: Ensure `kmod-wireguard` is optimized for the IPQ6000's SIMD instructions if available.
- **DNS-over-HTTPS/TLS**: Include `https-dns-proxy` or `unbound` for encrypted DNS.
## 3. Storage & Partitioning
- **U-Boot Custom Layout**: Research if a larger overlay partition can be achieved by resizing the factory GL.iNet layout (requires careful U-Boot interaction).
- **External Overlay**: Create a script or guide for using a USB drive as `overlayfs` (ExtRoot).
## 4. Build Automation
- **CI/CD Integration**: Move the build process to a GitHub Action to ensure images are always up-to-date with the latest OpenWrt security patches.
- **Local Repo**: Host a local Opkg repository for custom packages like `btop` or `mosh` to avoid manual transfers.
## 5. UI/UX
- **Modern Themes**: Swap the default LuCI theme for something more modern like `luci-theme-argon`.
- **Dashboard Utilities**: Add `luci-app-statistics` for better monitoring.

View File

@@ -0,0 +1,57 @@
# GL-AX1800 (Flint) Firmware History & Comparison
## 🕰️ Firmware Evolution Timeline
The GL-AX1800 (Flint) has undergone several major architectural shifts since its release:
| Era | Base OpenWrt Version | Kernel Version | Notes |
|:---|:---|:---|:---|
| **Early (2021)** | **15.05 (Chaos Calmer)** | 4.4.x | Initial release used a legacy Qualcomm SDK (QSDK) base. |
| **Mid (2022-2024)** | **21.02 (Esmond)** | 4.4.x | The foundation for the "4.x" GL.iNet firmware series. Most 4.6.x builds are here. |
| **Official (March 2025)** | **Mainline / Master** | 6.x | Officially merged into OpenWrt mainline under `qualcommax/ipq60xx`. |
| **Current (2025-2026)** | **23.05+ / GL.iNet 4.8+** | 5.x / 6.x | GL.iNet is transitioning their proprietary UI over newer OpenWrt bases. |
> [!NOTE]
> **Fork Point**: GL.iNet traditionally forks from OpenWrt stable releases (like 21.02) and replaces the standard network core with **Qualcomm's QSDK** to support proprietary Wi-Fi blobs and performance optimizations.
---
## 🏗️ GL.iNet Additions vs. Official OpenWrt
GL.iNet's firmware is "OpenWrt-based" but contains significant deviations and proprietary layers.
### 1. Proprietary UI & Middleware
- **Proprietary Dashboard**: A custom, user-friendly frontend (React/JS) that sits on top of OpenWrt.
- **Middleware API**: A custom C/Go backend (`gl-sdk`) that manages settings, bridging the UI to system files.
### 2. Networking & Drivers
- **Qualcomm QSDK Drivers**: Unlike official OpenWrt's `ath11k` (open source), GL.iNet uses proprietary Qualcomm blobs.
- **Benefit**: Better stability, higher throughput, and lower CPU usage for Wi-Fi.
- **Trade-off**: Harder to update the kernel independently.
- **Hardware NPS (Network Processing Unit) Offload**: Specialized code to utilize Qualcomm's hardware acceleration for faster routing.
### 3. Integrated Features (Not in Vanilla)
- **Advanced VPN Policies**: Easy-to-use UI for routing specific devices, IPs, or domains through VPN (WireGuard/OpenVPN).
- **AdGuard Home**: First-class integration with dedicated UI buttons and lifecycle management.
- **Multi-WAN / Failover**: Enhanced "Repeater" logic that handles Captive Portals and multi-interface failover more gracefully than standard OpenWrt.
- **GLDDNS**: Proprietary dynamic DNS service integrated with their cloud.
- **GoodCloud**: Remote management system for controlling the router over the internet.
### 4. Hardware Customization
- **Flip-Switch Support**: Logic for the physical toggle switch (can be mapped to VPN, Wi-Fi, etc. via UI).
- **LED Patterns**: Proprietary logic for LED indication of system status.
---
## ⚖️ Summary Comparison
| Feature | GL.iNet Firmware | Vanilla OpenWrt |
|:---|:---|:---|
| **Ease of Use** | ⭐⭐⭐⭐⭐ (Very Easy) | ⭐⭐ (Technical/LuCI) |
| **Wi-Fi Performance** | ⭐⭐⭐⭐⭐ (Highly Optimized) | ⭐⭐⭐ (Open Source `ath11k`) |
| **RAM Usage** | ~180MB Free | ~200MB+ Free (Less Bloat) |
| **Customizability** | Limited (Locked by UI/Plugins) | Infinite (Full Linux Control) |
| **Security Updates** | Vendor Dependent (Slow) | Community Driven (Fast) |
> [!IMPORTANT]
> Official OpenWrt support for the AX1800 arrived late (March 2025) because the **Qualcomm IPQ6000** platform required significant upstream work for its Wi-Fi (ath11k) and interrupt handling before it was stable enough for mainline.

45
docs/glax1800-build-results.md Executable file
View File

@@ -0,0 +1,45 @@
# GL-AX1800 Package Build Results
> [!IMPORTANT]
> **Architecture Confirmed (2026-01-11):** The GL-AX1800 uses **ARMv7 rev 4 (v7l)** - 32-bit ARM architecture. The GL.iNet SDK `ipq807x-2102` correctly targets 32-bit ARM, but uses an outdated GCC 5.5.0 toolchain that cannot compile modern C++23 code.
**Date:** 2026-01-11
**Target:** GL-AX1800 (Flint 1) - IPQ6000 SoC
**Architecture:** ARMv7 Processor rev 4 (v7l) - 32-bit ARM
**SDK Tested:** `ipq807x-2102` (GCC 5.5.0, ARM Cortex-A7, 32-bit) - **Correct arch, outdated compiler**
## Summary
Attempted to build `btop` and `mosh` packages using the GL.iNet SDK. Both failed due to the SDK's outdated GCC 5.5.0 toolchain.
## Findings
### SDK Architecture
The `ipq807x-2102` SDK targets **32-bit ARM** (`arm_cortex-a7`), which matches the actual hardware architecture (ARMv7). However, the toolchain is outdated (GCC 5.5.0 from ~2017) and cannot compile modern C++ standards.
### btop (v1.4.6)
- **Error:** `error: unrecognized command line option '-std=c++23'`
- **Cause:** btop requires C++23, GCC 5.5.0 only supports up to C++14
- **Resolution:** Would need GCC 11+ minimum (GCC 14 recommended)
### mosh (protobuf dependency)
- **Error:** `constexpr constructor calls non-constexpr function`
- **Cause:** protobuf 3.17.3 uses C++14 constexpr features that GCC 5.5.0 doesn't fully implement
- **Resolution:** Would need GCC 7+ for full C++14 constexpr support
### Successfully Built
- ncurses 6.2
- OpenSSL 1.1.1v
- terminfo
- cryptodev-linux 1.12
- Hundreds of kernel modules for ipq807x
## Recommendations (Updated 2026-01-11)
> [!NOTE]
> The GL-AX1800 uses ARMv7 (32-bit ARM), requiring modern ARMv7 toolchains:
1. **Use musl.cc ARMv7 toolchain** - Pre-built `armv7l-linux-musleabihf` with modern GCC
2. **Alternative: musl-cross-make** - Build your own ARM v7 toolchain with GCC 14+
3. **Not recommended: GL.iNet SDK** - Correct architecture but GCC too old (5.5.0)
4. **See detailed options in:** `agent-notes/flint1-sdk-research.md`

472
docs/kwrt-vs-immortalwrt-guide.md Executable file
View File

@@ -0,0 +1,472 @@
# KWRT vs ImmortalWrt - Comprehensive Comparison
**Created:** 2026-01-12
**Purpose:** Deep dive into the two main community OpenWrt forks available for GL-AX1800
---
## 🌟 Executive Summary
Both **KWRT** and **ImmortalWrt** are enhanced forks of OpenWrt that add features, packages, and optimizations beyond vanilla OpenWrt. However, they target different audiences and have distinct philosophies:
- **KWRT (Koolshare OpenWrt by Kiddin9):** Chinese-focused, online firmware customization, bleeding-edge packages
- **ImmortalWrt:** International fork with performance optimizations, broader device support, more conservative approach
---
## 1⃣ KWRT (Koolshare OpenWrt / Kiddin9 OpenWrt)
### What Is KWRT?
**Full Name:** Koolshare OpenWrt (also known as Kiddin9's OpenWrt or just "Kwrt")
**Developer:** Kiddin9
**Website:** https://openwrt.ai
**GitHub:** https://github.com/kiddin9/OpenWrt_x86-r2s-r4s
### Philosophy
KWRT aims to provide **maximum customization** through an online build platform while maintaining the latest OpenWrt code with extensive plugin/package support. It's particularly popular in the Chinese OpenWrt community but supports international users.
### Key Features
#### 🔧 Online Firmware Customization
- **Web-based Builder:** Visit openwrt.ai to customize firmware before download
- **Kernel Selection:** Choose from multiple kernel versions (5.15.x, 6.1.x, 6.6.x, 6.12.x)
- **Package Pre-selection:** Select packages to include before compilation
- **Theme Options:** Choose default LuCI theme
- **File System:** Ext4 support for sponsored users
#### 📦 Extensive Package Repository
- Maintains comprehensive GitHub repos for OpenWrt packages
- **Vast collection** of open-source plugins
- Many packages commonly needed by Chinese users
- Third-party packages and tools not in official OpenWrt
**Common Default Packages:**
- `autocore` - System auto-configuration
- `base-files` - Core system files
- `bash` - Full bash shell (not just busybox ash)
- `dnsmasq-full` - Enhanced DNS/DHCP server
- `firewall4` - NFTables firewall
- `luci-app-firewall` - Firewall web interface
- `openssh-sftp-server` - SFTP support
**Optional Packages** (examples):
- `luci-app-accesscontrol-plus` - Access control
- `luci-app-adbyby-plus` / `luci-app-adguardhome` - Ad blocking
- `luci-app-aliyundrive-webdav` - Cloud drive integration
- `luci-app-aria2` - Download management
- Network proxy tools: `koolss` (SS/SSR), `v2ray`, `wireguard`, `brook`
#### 🏗️ Architecture Support
Unlike Koolshare's original X64-only focus, Kiddin9's KWRT supports:
- **X86_64** - Desktop/server platforms
- **i386_pentium4** - Older Intel platforms
- **aarch64** - Generic, Cortex-A72, Cortex-A53 (← **GL-AX1800 uses this**)
- **ARM** - Cortex-A9, Cortex-A7, ARM1176JZF-S
- **MIPS** - mipsel_24kc, mips_24kc
- Devices: Raspberry Pi, N1, various routers
#### 🚀 Build Frequency
- **Monthly snapshots** (typically around the 10th of each month)
- Based on latest OpenWrt master
- Dated builds (MM.DD.YYYY format)
#### 🖥️ Web Server
- Uses **Nginx** instead of Uhttpd
- Better performance for web services
- Enhanced HTTP server capabilities
### For GL-AX1800 Specifically
**Target:** `qualcommax/ipq60xx`
**Architecture:** aarch64_cortex-a53
**Build Example:** `kwrt-01.10.2026-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.bin`
**Installation:**
1. Enter U-Boot mode (hold reset, power on, 10 sec)
2. Browse to http://192.168.1.1
3. Flash `.bin` or `.ubi` factory image
4. For upgrades: use `sysupgrade.bin`
**Available Files:**
- **Factory.bin** - Standard factory image
- **Factory.ubi** - UBI format for NAND flash
- **Sysupgrade.bin** - For OpenWrt→OpenWrt upgrades
### Pros
**Online customization** - Build exactly what you need
**Latest packages** - Bleeding-edge versions
**LuCI included** - Web interface by default
**Nginx** - Better web server
**More pre-installed** - Many useful packages out-of-box
**Regular builds** - Monthly updates
**Wide hardware support** - Many architectures
**Active development** - Frequent commits
### Cons
⚠️ **Chinese-focused** - Documentation/UI primarily Chinese
⚠️ **Less stable** - Monthly builds, less testing than releases
⚠️ **Non-upstreamable** - Custom patches not in official OpenWrt
⚠️ **Larger images** - More packages = bigger firmware
⚠️ **Slow download** - openwrt.ai server can be very slow
⚠️ **Less support** - Smaller international community
### When to Choose KWRT
**Choose KWRT if you:**
- Want maximum customization before download
- Need specific Chinese-region packages/tools
- Want the latest packages immediately
- Prefer pre-configured systems
- Are comfortable with monthly snapshot builds
- Like having many options/plugins available
- Can read/navigate Chinese interfaces
---
## 2⃣ ImmortalWrt
### What Is ImmortalWrt?
**Full Name:** ImmortalWrt
**Type:** OpenWrt fork
**Developer:** Chinese developer community
**Website:** https://immortalwrt.org
**GitHub:** https://github.com/immortalwrt/immortalwrt
### Philosophy
ImmortalWrt aims to **enhance OpenWrt** with better performance, more device support, and additional packages while maintaining a more traditional approach than KWRT. Focus on performance optimization and "non-upstreamable" improvements.
### Key Features
#### ⚡ Performance Optimization
- **Wireless driver optimization** - Enhanced Wi-Fi performance
- **Kernel optimization** - Tuned for better speed/stability
- **MediaTek focus** - Particularly good for MTK chips
- Users report better performance vs vanilla OpenWrt in many cases
- **High network speed** - Optimized for throughput
#### 🔧 Out-of-the-Box Functionality
- More features **pre-enabled** vs official OpenWrt
- Less manual configuration needed
- Better defaults for common use cases
#### 📱 Device Support
- **Wider range of devices** than official OpenWrt
- Particularly: Chinese-branded routers
- Single-board computers (SBCs)
- Devices not officially supported by mainstream OpenWrt
- **Faster adoption** of new hardware
#### 🌍 Localization
- Default optimized profiles for mainland China
- Includes Chinese-specific optimizations
- More international than KWRT
- English documentation available
#### 📦 Package Differences
- Uses `opkg` package manager (same as OpenWrt)
- **More packages ported** than vanilla
- Includes packages commonly needed by Chinese users
- Third-party packages addressing local internet requirements
- Approximately **8000+ packages** available
#### 🔄 Release Model
- **Stable releases** - e.g., 23.05.7
- **Snapshot builds** - Daily/regular updates
- More conservative than KWRT's monthly approach
### For GL-AX1800 Specifically
**Target:** `qualcommax/ipq60xx`
**Architecture:** aarch64_cortex-a53
**GCC:** 12.3.0 (stable), 14.3.0 (snapshots)
**Stable Release:** 23.05.7
- **URL:** https://downloads.immortalwrt.org/releases/23.05.7/targets/qualcommax/ipq60xx/
- **Note:** GL-AX1800 support may not be in stable yet (404 errors observed)
**Snapshots:**
- **URL:** https://downloads.immortalwrt.org/snapshots/targets/qualcommax/ipq60xx/
- Regular builds available
**File Pattern:**
```
immortalwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.bin
immortalwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin
```
### Pros
**Performance** - Optimized for speed/stability
**Device support** - More hardware than vanilla
**Stable releases** - Not just snapshots
**LuCI included** - Web interface by default
**More international** - Better English support than KWRT
**Frequent updates** - Bug fixes come quickly
**Better drivers** - Enhanced wireless drivers
**Proven track record** - Established fork
**Less bloated** - More focused than KWRT
### Cons
⚠️ **Non-upstreamable** - Custom patches not in official OpenWrt
⚠️ **Less mainstream** - Smaller than vanilla OpenWrt community
⚠️ **Custom tweaks** - May conflict with official packages
⚠️ **Documentation** - Less comprehensive than vanilla
⚠️ **Update lag** - Sometimes behind vanilla on security updates
⚠️ **Regional focus** - Still Chinese-oriented
### When to Choose ImmortalWrt
**Choose ImmortalWrt if you:**
- Want **better performance** than vanilla OpenWrt
- Need support for Chinese/Asian hardware
- Prefer **stable releases** over snapshots
- Want more packages but not KWRT's full collection
- Like the balance between vanilla and heavily customized
- Need MediaTek optimization
- Want frequent bug fixes
- Prefer a more traditional OpenWrt experience
---
## 📊 Detailed Comparison Matrix
| Feature | Vanilla OpenWrt | KWRT (Kiddin9) | ImmortalWrt |
|---------|----------------|----------------|-------------|
| **Philosophy** | Upstream-first, stability | Maximum customization | Performance + support |
| **Release Model** | Stable + snapshots | Monthly builds | Stable + snapshots |
| **Stability** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| **Performance** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| **Device Support** | Wide | Very Wide | Widest |
| **Package Count** | ~8000 | ~10000+ | ~8000+ |
| **Pre-installed** | Minimal | Many | More than vanilla |
| **Customization** | Manual | **Online builder** | Manual |
| **LuCI Included** | Yes | Yes | Yes |
| **Web Server** | Uhttpd | **Nginx** | Uhttpd |
| **Chinese Focus** | No | Strong | Moderate |
| **International** | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| **Documentation** | Excellent | Limited | Good |
| **Community Size** | Huge | Small | Medium |
| **Update Speed** | Moderate | Fast (monthly) | Fast |
| **Build Frequency** | Daily snapshots | Monthly dated | Regular |
| **Security Updates** | Fastest | Moderate | Fast |
| **Upstream Compat.** | Perfect | Modified | Modified |
| **File Size** | Smallest | Largest | Medium |
| **Learning Curve** | Medium | Medium | Easy-Medium |
---
## 🎯 Which Should You Choose for GL-AX1800?
### Choose **Vanilla OpenWrt 25.12.0-rc2** If:
- Want official, well-supported firmware
- Value **stability** and security above all
- Need reliable security updates
- Want largest community support
- Comfortable with SSH/manual package installation
-**RECOMMENDED for most users**
### Choose **KWRT** If:
- Want **online firmware customization**
- Need specific Chinese-region tools
- Want bleeding-edge packages immediately
- Like pre-configured systems with many options
- Don't mind monthly snapshot builds
- Can navigate Chinese interfaces
- Want Nginx web server
- Enjoy tinkering with latest features
### Choose **ImmortalWrt** If:
- Want **best performance** optimization
- Need stable releases with extra features
- Want balance between vanilla and KWRT
- Prefer traditional OpenWrt feel with enhancements
- Like more international focus than KWRT
- Want enhanced wireless drivers
- Need quick bug fixes
- Want more packages than vanilla but not KWRT's full selection
---
## 🔍 Technical Differences
### Package Management
**All three use `opkg`** but with different repositories:
```bash
# Vanilla OpenWrt
opkg update
opkg install <package>
# KWRT
# Pre-configured with Kiddin9's repos
# Nginx instead of Uhttpd
# More packages available by default
# ImmortalWrt
# Own package repos
# More packages ported
# Chinese-specific tools included
```
### Kernel Versions
| Firmware | Kernel | Notes |
|----------|--------|-------|
| OpenWrt 25.12-rc2 | 6.6.x | LTS kernel |
| OpenWrt Master | 6.6.x+ | Latest stable |
| KWRT | 5.15.x -6.12.x | **User selectable!** |
| ImmortalWrt Stable | 5.15.x | Conservative |
| ImmortalWrt Snapshot | 6.6.x | Latest |
### GCC Toolchain
| Firmware | GCC Version | C++ Support |
|----------|-------------|-------------|
| OpenWrt 25.12-rc2 | 14.3.0 | C++23 |
| OpenWrt Master | 14.3.0 | C++23 |
| KWRT | 14.3.0 | C++23 |
| ImmortalWrt 23.05 | 12.3.0 | C++20 |
| ImmortalWrt Snapshot | 14.3.0 | C++23 |
---
## 📥 Download Links for GL-AX1800
### KWRT
```
https://dl.openwrt.ai/firmware/qualcommax-ipq60xx/glinet_gl-ax1800/
Latest: kwrt-01.10.2026-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.bin
```
### ImmortalWrt Snapshots
```
https://downloads.immortalwrt.org/snapshots/targets/qualcommax/ipq60xx/
Latest: immortalwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-factory.bin
```
### ImmortalWrt Stable (if available)
```
https://downloads.immortalwrt.org/releases/23.05.7/targets/qualcommax/ipq60xx/
```
---
## 💡 Real-World Use Cases
### Home Lab / Development
**Recommendation:** KWRT or OpenWrt Master
- Online customization for dev tools
- Latest GCC for compiling
- Many packages available
### Production Router / Reliability
**Recommendation:** ImmortalWrt Stable or OpenWrt 25.12-rc2
- Stable releases
- Performance optimized
- LuCI included
### Chinese Internet / Region-Specific
**Recommendation:** KWRT
- Best Chinese tool support
- Optimized for region
- Custom packages included
### Performance Testing / Benchmarking
**Recommendation:** ImmortalWrt
- Best wireless performance
- Kernel optimizations
- Proven speed improvements
### Learning OpenWrt / First Time
**Recommendation:** OpenWrt 25.12-rc2
- Official documentation
- Largest community
- Best learning resources
---
## 🚀 My Recommendation for Your GL-AX1800
Based on having downloaded multiple firmware variants:
**1st Choice: OpenWrt 25.12.0-rc2**
- Stable release candidate
- Native IPQ6000 support
- LuCI included
- GCC 14.3.0
- Will become official stable soon
**2nd Choice: ImmortalWrt Snapshot**
- If you need better performance
- Stable enough for daily use
- More packages than vanilla
**3rd Choice: KWRT**
- If you want to experiment
- Try the online customization
- Test bleeding-edge packages
**Avoid for Production: OpenWrt Master Snapshots**
- Too unstable (daily builds)
- Use 25.12-rc2 instead
---
## 🛠️ Installation Tips
Both KWRT and ImmortalWrt install the same way as vanilla OpenWrt:
### U-Boot Method (Recommended)
1. Power off router
2. Hold reset button while powering on
3. Hold 10 seconds until LED blinks
4. Set PC IP: 192.168.1.100
5. Browse: http://192.168.1.1
6. Upload factory.bin file
7. Wait 3-5 minutes
### Via SSH (if already running OpenWrt)
```bash
scp firmware.bin root@192.168.x.1:/tmp/
ssh root@192.168.x.1
sysupgrade -n /tmp/firmware.bin
```
---
## 📚 Additional Resources
### KWRT
- Website: https://openwrt.ai
- GitHub: https://github.com/kiddin9/OpenWrt_x86-r2s-r4s
- Packages: https://github.com/kiddin9/openwrt-packages
### ImmortalWrt
- Website: https://immortalwrt.org
- GitHub: https://github.com/immortalwrt/immortalwrt
- Forum: Various Chinese and international forums
### Community
- OpenWrt Forum: https://forum.openwrt.org
- Reddit: r/openwrt
- GL.iNet Forum: https://forum.gl-inet.com
---
## 📝 Summary
- **KWRT = Customization King** 👑 (online builder, many packages, Chinese-focused)
- **ImmortalWrt = Performance Beast** ⚡ (optimized, stable, balanced)
- **Vanilla OpenWrt = Rock Solid** 🗿 (official, supported, stable)
All three work great on GL-AX1800 with the `qualcommax/ipq60xx` target!

30
docs/mawk_vs_gawk_report.md Executable file
View File

@@ -0,0 +1,30 @@
# Report: mawk vs gawk in OpenWRT SDK Context
## Introduction
This report details the technical differences between `mawk` and `gawk` that led to the build failure of the Mosh package within the OpenWRT SDK environment.
## The failure
The OpenWRT SDK build process failed with the following error:
```
awk: include/scan.awk: line 21: function asort never defined
```
This error occurred during the package scanning phase (`include/scan.mk`), which uses `awk` scripts to parse package definitions.
## mawk (Mike's AWK)
- **Design Philosophy**: Built for speed and strict POSIX compliance. It is significantly faster than `gawk` for simple text processing tasks, which is why it is the default `awk` provider on many Debian-based minimal installations.
- **Limitation**: It generally implements only the features defined in the POSIX standard for AWK. It lacks many GNU-specific extensions.
- **Missing Feature**: complex sorting functions like `asort` and `asorti` are NOT part of the POSIX standard, and thus are absent in `mawk`.
## gawk (GNU AWK)
- **design Philosophy**: The GNU implementation of AWK. It includes all POSIX features plus a vast array of extensions.
- **Key Features**:
- `asort()` / `asorti()`: Built-in functions for sorting arrays.
- Network capabilities (`/inet/tcp/...`).
- Bitwise operations (`and`, `or`, `xor`).
- Time functions (`mktime`, `strftime`).
- **OpenWRT Requirement**: The OpenWRT build system (scripts in `include/` and `scripts/`) relies heavily on these GNU extensions for dependency resolution and menu construction. Specifically, `asort` is used to deterministically order package lists.
## Conclusion
The task was blocked because the system's `/usr/bin/awk` pointed to `mawk`. The OpenWRT SDK assumes a full-featured `gawk` environment. Although `mawk` is faster, it is functionally insufficient for the complex logic contained in OpenWRT's build scripts.
Now that `gawk` is installed, the SDK scripts will be able to execute the `asort` function and proceed with the build.

51
docs/organizational_checkup.md Executable file
View File

@@ -0,0 +1,51 @@
# Organizational Checkup Report
**Date:** 2025-12-12
**Workspace:** `/home/user/Public/Projects/OpenWRT`
## Executive Summary
An organizational checkup was performed to ensure the workspace has a structured layout for binaries, packages, source code, and SDKs. Missing directories were identified and created. Existing directories were audited, and legacy directories were consolidated. Mosh and Btop assets were organized into the standard structure.
## Directory Status
### 1. Binaries
- **Goal:** Dedicated folder for binaries.
- **Status:** `binaries/` verified.
- **Contents:**
- `binaries/btop-flint2/`
- `binaries/mosh/` (Added)
### 2. Packages
- **Goal:** Dedicated folder for packages.
- **Status:** `packages/` verified.
- **Contents:**
- `btop-flint2-package/`
- `btop-openwrt-package/`
- `btop-package-build/` (Moved)
- `mosh-package-build/` (Moved)
- `*.ipk` files (Moved)
### 3. Source Code
- **Goal:** Dedicated folder for source code (`src`).
- **Status:** `src/` verified.
- **Contents:**
- `src/btop/`
- `src/mosh/` (Moved from `mosh-static-build`)
### 4. SDK
- **Goal:** Dedicated folder for SDKs.
- **Status:** `sdk/` verified.
- **Contents:**
- `openwrt-sdk-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64/`
## Summary of Actions Taken
- Created new directory: `/home/user/Public/Projects/OpenWRT/binaries`
- Created new directory: `/home/user/Public/Projects/OpenWRT/src`
- Consolidated `sources/` contents to `src/`.
- Consolidated `bin/` contents to `binaries/`.
- Moved `mosh-static-build` to `src/mosh`.
- Copied `mosh-server` and `mosh-client` to `binaries/mosh`.
- Moved package build directories and artifact `.ipk` files to `packages/`.
- Removed legacy directories: `sources/`, `bin/`.
## Next Steps
- Ensure all future build scripts point to these standard directories.

View File

@@ -0,0 +1,17 @@
# Package Creation Procedure
## New Standard Workflow (as of 2025-12-13)
1. **Build Format**: Always build packages as `.tar.gz` first.
- Do NOT build directly as `.ipk`.
- The `.tar.gz` must contain: `debian-binary`, `control.tar.gz`, `data.tar.gz`.
2. **Verification**:
- Verify the `.tar.gz` can be extracted using standard `tar -xzf`.
- Check contents of extracted archive.
3. **Finalize**:
- Only AFTER verification is successful, rename the `.tar.gz` file to `.ipk`.
## Why?
This ensures the package structure is valid and compatible with standard archive tools before being deployed, preventing "malformed package" errors on some systems.

33
docs/project_log.md Executable file
View File

@@ -0,0 +1,33 @@
# Project Log - OpenWRT Agent
## 2025-12-12
- Initiated project tracking.
- Reviewed project directory `OpenWRT`.
- Created `agent-notes` directory.
- Started research on GL-iNet Flint2 and Flint1 hardware.
- **Flint 2 (GL-MT6000)** status:
- Confirmed CPU: Quad-core ARM Cortex-A53.
- Architecture: `aarch64`.
- SDK identified: `openwrt-sdk-mediatek-filogic`.
- **Flint 1 (GL-AX1800)** status:
- Likely CPU: Quad-core ARM Cortex-A53 (Qualcomm IPQ6000).
- Requires verification of specific SDK if different from generic aarch64.
## 2026-01-14
- **Flint 1 (GL-AX1800) Research Update:**
- Confirmed CPU: Qualcomm IPQ6000 (ARMv7).
- Best Build Tool: `FUjr/gl-infra-builder` (supports hardware patches).
- OpenWrt Path: Target changed from `ipq40xx/generic` (v23.05) to `qualcommax/ipq60xx` (Master/v24/v25).
- Barebones Image: Defined profile for SSH-only, no-UI firmware.
- **Project Reorganization:**
- Reorganized workspace into `firmware/`, `sdk/`, `docs/`, `scripts/`, `packages/`, `repo/`.
- Created `PROJECT_INDEX.md`.
- Consolidated research notes into `docs/`.
## Tasks
- [x] Research GL-iNet Flint2 (GL-MT6000) CPU <!-- id: 2 -->
- [x] Research GL-iNet Flint1 (GL-AX1800) CPU <!-- id: 3 -->
- [x] Research gl-infra-builder forks and up-to-date options <!-- id: 5 -->
- [x] Document upgrade paths to v24/v25 <!-- id: 6 -->
- [/] Attempt barebones firmware creation for AX1800 <!-- id: 7 -->
- [x] Reorganize project directory and create index <!-- id: 8 -->

View File

@@ -0,0 +1,31 @@
# Python 3.13 Compatibility Fix for OpenWrt
## Problem
The `gl-infra-builder` and OpenWrt build system encountered Python 3.13 compatibility issues:
1. OpenWrt's `prereq-build.mk` only checked for Python 3.5-3.10
2. Python 3.13 removed the `distutils` module (deprecated since 3.10)
## Solution Applied
### 1. Updated Python Version Detection
Modified `/src/glbuilder/wlan-ap/openwrt/include/prereq-build.mk`:
- Changed regex from `Python 3\.([5-9]|10)\.?` to `Python 3\.([5-9]|1[0-9])\.?`
- This now accepts Python 3.5 through 3.19
### 2. Disabled Distutils Check
Commented out the distutils prerequisite check (lines 173-175):
```makefile
#$(eval $(call TestHostCommand,python3-distutils, \
# Please install the Python3 distutils module, \
# $(STAGING_DIR_HOST)/bin/python3 -c 'import setuptools'))
```
## Rationale
- Python 3.13 is fully functional and more advanced than the minimum required 3.5
- `setuptools` provides the necessary functionality previously offered by `distutils`
- The build system doesn't actually require distutils features - it's a legacy check
## Result
- Python prereqs now pass: `Checking 'python'... ok.` and `Checking 'python3'... ok.`
- Configuration generated successfully via `make defconfig`
- Build can proceed on Debian Trixie with Python 3.13

235
docs/upgrade-to-openwrt-master.md Executable file
View File

@@ -0,0 +1,235 @@
# Upgrade to OpenWrt Master (GCC 14.3.0) - GL-AX1800
## Your Upgrade File
**SYSUPGRADE Image (Use this one):**
```
https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin
```
**SHA256 Checksums:**
```
https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/sha256sums
```
**Size:** ~23 MB
---
## What This Gives You
- **Target:** `qualcommax/ipq60xx` (native IPQ6000 support)
- **GCC:** 14.3.0 (best C++23 support)
- **Kernel:** Latest Linux 6.x
- **Architecture:** ARMv7 (proper IPQ6000)
- **Updates:** Daily snapshots
---
## Before You Upgrade
### ⚠️ IMPORTANT WARNINGS
1. **No LuCI by default** - Web interface NOT included
- You'll need SSH access to install it
- Command: `opkg update && opkg install luci`
2. **Snapshot = development build**
- Less stable than release versions
- Daily updates (version changes constantly)
3. **Different target** - Migration from `ipq40xx``qualcommax/ipq60xx`
- Settings may not transfer cleanly
- Backup your configuration!
4. **RAM usage** - Open-source ath11k driver
- ~130MB used by Wi-Fi firmware
- ~380MB free (vs 512MB total)
---
## Upgrade Methods
### Method 1: Web Interface (GL.iNet firmware)
1. **Download the sysupgrade file:**
```bash
wget https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin
```
2. **Verify checksum:**
```bash
wget https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/sha256sums
sha256sum -c sha256sums 2>&1 | grep glinet_gl-ax1800-squashfs-sysupgrade.bin
```
3. **Upload via web interface:**
- Go to GL.iNet web panel (http://192.168.8.1)
- Navigate to: System → Firmware Upgrade
- Upload: `openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin`
- **Do NOT keep settings** (recommended for target change)
---
### Method 2: SSH/SCP (Advanced)
1. **Copy file to router:**
```bash
scp openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin root@192.168.8.1:/tmp/
```
2. **SSH into router:**
```bash
ssh root@192.168.8.1
```
3. **Flash firmware:**
```bash
cd /tmp
sysupgrade -n openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin
```
**Options:**
- `-n` = Do NOT save settings (recommended for target change)
- `-F` = Force upgrade (if sysupgrade complains)
---
### Method 3: OpenWrt Firmware Selector
**URL:** https://firmware-selector.openwrt.org/
1. Search: "GL-AX1800"
2. Select version: "SNAPSHOT"
3. Download: "SYSUPGRADE"
4. Use web interface or SSH method above
---
## After Upgrade
### First Boot
1. **Connect via Ethernet** (Wi-Fi disabled by default)
2. **Default IP:** `192.168.1.1`
3. **Set root password:**
```bash
ssh root@192.168.1.1
passwd
```
4. **Install LuCI (Web Interface):**
```bash
opkg update
opkg install luci luci-ssl
/etc/init.d/uhttpd start
/etc/init.d/uhttpd enable
```
5. **Access web interface:**
- URL: https://192.168.1.1
- Username: `root`
- Password: (what you set above)
---
## Configure Wi-Fi
Via SSH:
```bash
# Edit wireless config
vi /etc/config/wireless
# Remove disabled lines for wifi devices
# Set your SSID and password
# Enable Wi-Fi
uci set wireless.radio0.disabled=0
uci set wireless.radio1.disabled=0
uci commit wireless
wifi reload
```
Or use LuCI web interface: Network → Wireless
---
## Download Commands
```bash
# Download sysupgrade image
wget https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/openwrt-qualcommax-ipq60xx-glinet_gl-ax1800-squashfs-sysupgrade.bin
# Download checksums
wget https://downloads.openwrt.org/snapshots/targets/qualcommax/ipq60xx/sha256sums
# Verify
sha256sum -c sha256sums 2>&1 | grep glinet_gl-ax1800-squashfs-sysupgrade.bin
# Should show: OK
```
---
## Backup Your Current System
**Before upgrading, backup:**
```bash
# Via SSH
ssh root@192.168.8.1
sysupgrade -b /tmp/backup-$(date +%F).tar.gz
exit
# Copy backup to your computer
scp root@192.168.8.1:/tmp/backup-*.tar.gz ./
```
---
## Rollback Plan
If you need to go back to GL.iNet firmware:
1. Download GL.iNet 4.6.11 from: https://dl.gl-inet.com/?model=ax1800
2. Use U-Boot recovery or sysupgrade back to GL.iNet firmware
---
## Comparison: Current vs Master
| Feature | Current (23.05-SNAPSHOT) | OpenWrt Master |
|---------|--------------------------|----------------|
| Target | `ipq40xx` | **`qualcommax/ipq60xx`** ✅ |
| GCC | 12.3.0 | **14.3.0** ✅ |
| Kernel | 5.15.x | **6.x** ✅ |
| LuCI | Included | **Manual install** ⚠️ |
| Stability | Good | **Snapshot** ⚠️ |
| Updates | Periodic | **Daily** |
---
## Recommendation
**Think twice before upgrading if:**
- ❌ You need stable firmware for production
- ❌ You're not comfortable with SSH/command line
- ❌ You rely on GL.iNet-specific features (VPN, AdGuard GUI, etc.)
**Upgrade if:**
- ✅ You want latest OpenWrt features
- ✅ You need GCC 14.3.0 for development
- ✅ You want native `qualcommax/ipq60xx` support
- ✅ You're comfortable troubleshooting via SSH
**Alternative:** Stay on your current firmware and use the OpenWrt 23.05.5 SDK (already downloaded) for development. It has GCC 12.3.0 which is good enough for most C++20 code.
---
## Support
- **OpenWrt Forum:** https://forum.openwrt.org/
- **GL.iNet Forum:** https://forum.gl-inet.com/
- **Wiki:** https://openwrt.org/toh/gl.inet/gl-ax1800

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -e
CROSS=arm-linux-gnueabihf
CFLAGS_CROSS="-O2 -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard"
CFLAGS_CROSS="-O2 -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard"
# Debian armhf packages use these paths
ARM_INCLUDE="-I/usr/include/arm-linux-gnueabihf -I/usr/include"
ARM_LIBDIR="/usr/lib/arm-linux-gnueabihf"
SYSROOT=/home/user/Public/Projects/OpenWRT/flint1-armv7/src/mosh-sysroot
BUILDDIR=/tmp/mosh-arm-build
SRCDIR=/home/user/Public/Projects/OpenWRT/flint1-armv7/src/mosh
BINDIR=/home/user/Public/Projects/OpenWRT/flint1-armv7/binaries
mkdir -p "$SYSROOT" "$BUILDDIR" "$BINDIR"
echo "=== [1/3] Building protobuf host tools + ARM library ==="
PROTO_VER=3.21.12
cd "$BUILDDIR"
rm -rf protobuf-"${PROTO_VER}"
tar -xzf /tmp/protobuf-"${PROTO_VER}".tar.gz
cd protobuf-"${PROTO_VER}"
# Build host protoc
./configure --prefix=/tmp/host-protoc
make -j$(nproc)
make install
HOST_PROTOC=/tmp/host-protoc/bin/protoc
echo " host protoc: $($HOST_PROTOC --version)"
# Cross-compile protobuf library
make distclean
./configure \
--host=${CROSS} \
--prefix="$SYSROOT" \
--with-protoc="$HOST_PROTOC" \
CC=${CROSS}-gcc \
CXX=${CROSS}-g++ \
CFLAGS="-static ${CFLAGS_CROSS}" \
CXXFLAGS="-static ${CFLAGS_CROSS} -std=c++14" \
LDFLAGS="-static"
make -j$(nproc)
make install
echo " protobuf ARM OK: $SYSROOT/lib/libprotobuf.a"
echo "=== [2/3] Configuring mosh ==="
cd "$SRCDIR"
[ -f configure ] || ./autogen.sh
./configure \
--host=${CROSS} \
--prefix="$SYSROOT" \
CC=${CROSS}-gcc \
CXX=${CROSS}-g++ \
CFLAGS="-static ${CFLAGS_CROSS}" \
CXXFLAGS="-static ${CFLAGS_CROSS}" \
LDFLAGS="-static -L${SYSROOT}/lib -L${ARM_LIBDIR}" \
LIBS="-lz -lzstd -ldl" \
CPPFLAGS="-I${SYSROOT}/include ${ARM_INCLUDE}" \
PKG_CONFIG="pkg-config" \
PKG_CONFIG_PATH="${SYSROOT}/lib/pkgconfig:${ARM_LIBDIR}/pkgconfig" \
PKG_CONFIG_LIBDIR="${SYSROOT}/lib/pkgconfig:${ARM_LIBDIR}/pkgconfig"
echo "=== [3/3] Compiling mosh ==="
make -j$(nproc)
cp src/frontend/mosh-server "$BINDIR/mosh-server-static-armv7" 2>/dev/null || \
cp src/frontend/mosh-server "$BINDIR/mosh-server-static-armv7"
cp src/frontend/mosh-client "$BINDIR/mosh-client-static-armv7" 2>/dev/null || \
cp src/frontend/mosh-client "$BINDIR/mosh-client-static-armv7"
echo ""
echo "=== Build Complete ==="
file "$BINDIR/mosh-server-static-armv7"
file "$BINDIR/mosh-client-static-armv7"
ls -lh "$BINDIR/"

Binary file not shown.

View File

@@ -0,0 +1 @@
.

Binary file not shown.

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
import multiprocessing
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.analyze import analyze_build
if __name__ == '__main__':
multiprocessing.freeze_support()
sys.exit(analyze_build())

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-21.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-check.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-extdef-mapping.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-format.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-installapi.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-linker-wrapper.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-nvlink-wrapper.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-offload-bundler.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-offload-packager.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-refactor.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-repl.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-scan-deps.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.clang-sycl-linker.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.diagtool.bin" "$@"

View File

@@ -0,0 +1,858 @@
#!/usr/bin/env python3
#
# ===- git-clang-format - ClangFormat Git Integration -------*- python -*--=== #
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===----------------------------------------------------------------------=== #
r"""
clang-format git integration
============================
This file provides a clang-format integration for git. Put it somewhere in your
path and ensure that it is executable. Then, "git clang-format" will invoke
clang-format on the changes in current files or a specific commit.
For further details, run:
git clang-format -h
Requires Python version >=3.8
"""
from __future__ import absolute_import, division, print_function
import argparse
import collections
import contextlib
import errno
import os
import re
import subprocess
import sys
usage = "git clang-format [OPTIONS] [<commit>] [<commit>|--staged] [--] [<file>...]"
desc = """
If zero or one commits are given, run clang-format on all lines that differ
between the working directory and <commit>, which defaults to HEAD. Changes are
only applied to the working directory, or in the stage/index.
Examples:
To format staged changes, i.e everything that's been `git add`ed:
git clang-format
To also format everything touched in the most recent commit:
git clang-format HEAD~1
If you're on a branch off main, to format everything touched on your branch:
git clang-format main
If two commits are given (requires --diff), run clang-format on all lines in the
second <commit> that differ from the first <commit>.
The following git-config settings set the default of the corresponding option:
clangFormat.binary
clangFormat.commit
clangFormat.extensions
clangFormat.style
"""
# Name of the temporary index file in which save the output of clang-format.
# This file is created within the .git directory.
temp_index_basename = "clang-format-index"
Range = collections.namedtuple("Range", "start, count")
def main():
config = load_git_config()
# In order to keep '--' yet allow options after positionals, we need to
# check for '--' ourselves. (Setting nargs='*' throws away the '--', while
# nargs=argparse.REMAINDER disallows options after positionals.)
argv = sys.argv[1:]
try:
idx = argv.index("--")
except ValueError:
dash_dash = []
else:
dash_dash = argv[idx:]
argv = argv[:idx]
default_extensions = ",".join(
[
# From clang/lib/Frontend/FrontendOptions.cpp, all lower case
"c",
"h", # C
"m", # ObjC
"mm", # ObjC++
"cc",
"cp",
"cpp",
"c++",
"cxx",
"hh",
"hpp",
"hxx",
"inc", # C++
"ccm",
"cppm",
"cxxm",
"c++m", # C++ Modules
"cu",
"cuh", # CUDA
"cl", # OpenCL
# Other languages that clang-format supports
"proto",
"protodevel", # Protocol Buffers
"java", # Java
"js",
"mjs",
"cjs", # JavaScript
"ts", # TypeScript
"cs", # C Sharp
"json",
"ipynb", # Json
"sv",
"svh",
"v",
"vh", # Verilog
"td", # TableGen
"txtpb",
"textpb",
"pb.txt",
"textproto",
"asciipb", # TextProto
]
)
p = argparse.ArgumentParser(
usage=usage,
formatter_class=argparse.RawDescriptionHelpFormatter,
description=desc,
)
p.add_argument(
"--binary",
default=config.get("clangformat.binary", "clang-format"),
help="path to clang-format",
),
p.add_argument(
"--commit",
default=config.get("clangformat.commit", "HEAD"),
help="default commit to use if none is specified",
),
p.add_argument(
"--diff",
action="store_true",
help="print a diff instead of applying the changes",
)
p.add_argument(
"--diffstat",
action="store_true",
help="print a diffstat instead of applying the changes",
)
p.add_argument(
"--extensions",
default=config.get("clangformat.extensions", default_extensions),
help=(
"comma-separated list of file extensions to format, "
"excluding the period and case-insensitive"
),
),
p.add_argument(
"-f",
"--force",
action="store_true",
help="allow changes to unstaged files",
)
p.add_argument(
"-p", "--patch", action="store_true", help="select hunks interactively"
)
p.add_argument(
"-q",
"--quiet",
action="count",
default=0,
help="print less information",
)
p.add_argument(
"--staged",
"--cached",
action="store_true",
help="format lines in the stage instead of the working dir",
)
p.add_argument(
"--style",
default=config.get("clangformat.style", None),
help="passed to clang-format",
),
p.add_argument(
"-v",
"--verbose",
action="count",
default=0,
help="print extra information",
)
p.add_argument(
"--diff_from_common_commit",
action="store_true",
help=(
"diff from the last common commit for commits in "
"separate branches rather than the exact point of the "
"commits"
),
)
# We gather all the remaining positional arguments into 'args' since we need
# to use some heuristics to determine whether or not <commit> was present.
# However, to print pretty messages, we make use of metavar and help.
p.add_argument(
"args",
nargs="*",
metavar="<commit>",
help="revision from which to compute the diff",
)
p.add_argument(
"ignored",
nargs="*",
metavar="<file>...",
help="if specified, only consider differences in these files",
)
opts = p.parse_args(argv)
opts.verbose -= opts.quiet
del opts.quiet
commits, files = interpret_args(opts.args, dash_dash, opts.commit)
if len(commits) > 2:
die("at most two commits allowed; %d given" % len(commits))
if len(commits) == 2:
if opts.staged:
die("--staged is not allowed when two commits are given")
if not opts.diff:
die("--diff is required when two commits are given")
elif opts.diff_from_common_commit:
die("--diff_from_common_commit is only allowed when two commits are given")
if os.path.dirname(opts.binary):
opts.binary = os.path.abspath(opts.binary)
changed_lines = compute_diff_and_extract_lines(
commits, files, opts.staged, opts.diff_from_common_commit
)
if opts.verbose >= 1:
ignored_files = set(changed_lines)
filter_by_extension(changed_lines, opts.extensions.lower().split(","))
# The computed diff outputs absolute paths, so we must cd before accessing
# those files.
cd_to_toplevel()
filter_symlinks(changed_lines)
filter_ignored_files(changed_lines, binary=opts.binary)
if opts.verbose >= 1:
ignored_files.difference_update(changed_lines)
if ignored_files:
print(
"Ignoring the following files (wrong extension, symlink, or "
"ignored by clang-format):"
)
for filename in ignored_files:
print(" %s" % filename)
if changed_lines:
print("Running clang-format on the following files:")
for filename in changed_lines:
print(" %s" % filename)
if not changed_lines:
if opts.verbose >= 0:
print("no modified files to format")
return 0
if len(commits) > 1:
old_tree = commits[1]
revision = old_tree
elif opts.staged:
old_tree = create_tree_from_index(changed_lines)
revision = ""
else:
old_tree = create_tree_from_workdir(changed_lines)
revision = None
new_tree = run_clang_format_and_save_to_tree(
changed_lines, revision, binary=opts.binary, style=opts.style
)
if opts.verbose >= 1:
print("old tree: %s" % old_tree)
print("new tree: %s" % new_tree)
if old_tree == new_tree:
if opts.verbose >= 0:
print("clang-format did not modify any files")
return 0
if opts.diff:
return print_diff(old_tree, new_tree)
if opts.diffstat:
return print_diffstat(old_tree, new_tree)
changed_files = apply_changes(
old_tree, new_tree, force=opts.force, patch_mode=opts.patch
)
if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1:
print("changed files:")
for filename in changed_files:
print(" %s" % filename)
return 1
def load_git_config(non_string_options=None):
"""Return the git configuration as a dictionary.
All options are assumed to be strings unless in `non_string_options`, in
which is a dictionary mapping option name (in lower case) to either "--bool"
or "--int"."""
if non_string_options is None:
non_string_options = {}
out = {}
for entry in run("git", "config", "--list", "--null").split("\0"):
if entry:
if "\n" in entry:
name, value = entry.split("\n", 1)
else:
# A setting with no '=' ('\n' with --null) is implicitly 'true'
name = entry
value = "true"
if name in non_string_options:
value = run("git", "config", non_string_options[name], name)
out[name] = value
return out
def interpret_args(args, dash_dash, default_commit):
"""Interpret `args` as "[commits] [--] [files]" and return (commits, files).
It is assumed that "--" and everything that follows has been removed from
args and placed in `dash_dash`.
If "--" is present (i.e., `dash_dash` is non-empty), the arguments to its
left (if present) are taken as commits. Otherwise, the arguments are
checked from left to right if they are commits or files. If commits are not
given, a list with `default_commit` is used."""
if dash_dash:
if len(args) == 0:
commits = [default_commit]
else:
commits = args
for commit in commits:
object_type = get_object_type(commit)
if object_type not in ("commit", "tag"):
if object_type is None:
die("'%s' is not a commit" % commit)
else:
die(
"'%s' is a %s, but a commit was expected"
% (commit, object_type)
)
files = dash_dash[1:]
elif args:
commits = []
while args:
if not disambiguate_revision(args[0]):
break
commits.append(args.pop(0))
if not commits:
commits = [default_commit]
files = args
else:
commits = [default_commit]
files = []
return commits, files
def disambiguate_revision(value):
"""Returns True if `value` is a revision, False if it is a file, or dies."""
# If `value` is ambiguous (neither a commit nor a file), the following
# command will die with an appropriate error message.
run("git", "rev-parse", value, verbose=False)
object_type = get_object_type(value)
if object_type is None:
return False
if object_type in ("commit", "tag"):
return True
die("`%s` is a %s, but a commit or filename was expected" % (value, object_type))
def get_object_type(value):
"""Returns a string description of an object's type, or None if it is not
a valid git object."""
cmd = ["git", "cat-file", "-t", value]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
return None
return convert_string(stdout.strip())
def compute_diff_and_extract_lines(commits, files, staged, diff_common_commit):
"""Calls compute_diff() followed by extract_lines()."""
diff_process = compute_diff(commits, files, staged, diff_common_commit)
changed_lines = extract_lines(diff_process.stdout)
diff_process.stdout.close()
diff_process.wait()
if diff_process.returncode != 0:
# Assume error was already printed to stderr.
sys.exit(2)
return changed_lines
def compute_diff(commits, files, staged, diff_common_commit):
"""Return a subprocess object producing the diff from `commits`.
The return value's `stdin` file object will produce a patch with the
differences between the working directory (or stage if --staged is used) and
the first commit if a single one was specified, or the difference between
both specified commits, filtered on `files` (if non-empty).
Zero context lines are used in the patch."""
git_tool = "diff-index"
extra_args = []
if len(commits) == 2:
git_tool = "diff-tree"
if diff_common_commit:
extra_args += ["--merge-base"]
elif staged:
extra_args += ["--cached"]
cmd = ["git", git_tool, "-p", "-U0"] + extra_args + commits + ["--"]
cmd.extend(files)
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.close()
return p
def extract_lines(patch_file):
"""Extract the changed lines in `patch_file`.
The return value is a dictionary mapping filename to a list of (start_line,
line_count) pairs.
The input must have been produced with ``-U0``, meaning unidiff format with
zero lines of context. The return value is a dict mapping filename to a
list of line `Range`s."""
matches = {}
for line in patch_file:
line = convert_string(line)
match = re.search(r"^\+\+\+\ [^/]+/(.*)", line)
if match:
filename = match.group(1).rstrip("\r\n\t")
match = re.search(r"^@@ -[0-9,]+ \+(\d+)(,(\d+))?", line)
if match:
start_line = int(match.group(1))
line_count = 1
if match.group(3):
line_count = int(match.group(3))
if line_count == 0:
line_count = 1
if start_line == 0:
continue
matches.setdefault(filename, []).append(Range(start_line, line_count))
return matches
def filter_by_extension(dictionary, allowed_extensions):
"""Delete every key in `dictionary` that doesn't have an allowed extension.
`allowed_extensions` must be a collection of lowercase file extensions,
excluding the period."""
allowed_extensions = frozenset(allowed_extensions)
for filename in list(dictionary.keys()):
base_ext = filename.rsplit(".", 1)
if len(base_ext) == 1 and "" in allowed_extensions:
continue
if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
del dictionary[filename]
def filter_symlinks(dictionary):
"""Delete every key in `dictionary` that is a symlink."""
for filename in list(dictionary.keys()):
if os.path.islink(filename):
del dictionary[filename]
def filter_ignored_files(dictionary, binary):
"""Delete every key in `dictionary` that is ignored by clang-format."""
ignored_files = run(binary, "-list-ignored", *dictionary.keys())
if not ignored_files:
return
ignored_files = ignored_files.split("\n")
for filename in ignored_files:
del dictionary[filename]
def cd_to_toplevel():
"""Change to the top level of the git repository."""
toplevel = run("git", "rev-parse", "--show-toplevel")
os.chdir(toplevel)
def create_tree_from_workdir(filenames):
"""Create a new git tree with the given files from the working directory.
Returns the object ID (SHA-1) of the created tree."""
return create_tree(filenames, "--stdin")
def create_tree_from_index(filenames):
# Copy the environment, because the files have to be read from the original
# index.
env = os.environ.copy()
def index_contents_generator():
for filename in filenames:
git_ls_files_cmd = [
"git",
"ls-files",
"--stage",
"-z",
"--",
filename,
]
git_ls_files = subprocess.Popen(
git_ls_files_cmd,
env=env,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
stdout = git_ls_files.communicate()[0]
yield convert_string(stdout.split(b"\0")[0])
return create_tree(index_contents_generator(), "--index-info")
def run_clang_format_and_save_to_tree(
changed_lines, revision=None, binary="clang-format", style=None
):
"""Run clang-format on each file and save the result to a git tree.
Returns the object ID (SHA-1) of the created tree."""
# Copy the environment when formatting the files in the index, because the
# files have to be read from the original index.
env = os.environ.copy() if revision == "" else None
def iteritems(container):
try:
return container.iteritems() # Python 2
except AttributeError:
return container.items() # Python 3
def index_info_generator():
for filename, line_ranges in iteritems(changed_lines):
if revision is not None:
if len(revision) > 0:
git_metadata_cmd = [
"git",
"ls-tree",
"%s:%s" % (revision, os.path.dirname(filename)),
os.path.basename(filename),
]
else:
git_metadata_cmd = [
"git",
"ls-files",
"--stage",
"--",
filename,
]
git_metadata = subprocess.Popen(
git_metadata_cmd,
env=env,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
stdout = git_metadata.communicate()[0]
mode = oct(int(stdout.split()[0], 8))
else:
mode = oct(os.stat(filename).st_mode)
# Adjust python3 octal format so that it matches what git expects
if mode.startswith("0o"):
mode = "0" + mode[2:]
blob_id = clang_format_to_blob(
filename,
line_ranges,
revision=revision,
binary=binary,
style=style,
env=env,
)
yield "%s %s\t%s" % (mode, blob_id, filename)
return create_tree(index_info_generator(), "--index-info")
def create_tree(input_lines, mode):
"""Create a tree object from the given input.
If mode is '--stdin', it must be a list of filenames. If mode is
'--index-info' is must be a list of values suitable for "git update-index
--index-info", such as "<mode> <SP> <sha1> <TAB> <filename>". Any other
mode is invalid."""
assert mode in ("--stdin", "--index-info")
cmd = ["git", "update-index", "--add", "-z", mode]
with temporary_index_file():
p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
for line in input_lines:
p.stdin.write(to_bytes("%s\0" % line))
p.stdin.close()
if p.wait() != 0:
die("`%s` failed" % " ".join(cmd))
tree_id = run("git", "write-tree")
return tree_id
def clang_format_to_blob(
filename,
line_ranges,
revision=None,
binary="clang-format",
style=None,
env=None,
):
"""Run clang-format on the given file and save the result to a git blob.
Runs on the file in `revision` if not None, or on the file in the working
directory if `revision` is None. Revision can be set to an empty string to
run clang-format on the file in the index.
Returns the object ID (SHA-1) of the created blob."""
clang_format_cmd = [binary]
if style:
clang_format_cmd.extend(["--style=" + style])
clang_format_cmd.extend(
[
"--lines=%s:%s" % (start_line, start_line + line_count - 1)
for start_line, line_count in line_ranges
]
)
if revision is not None:
clang_format_cmd.extend(["--assume-filename=" + filename])
git_show_cmd = [
"git",
"cat-file",
"blob",
"%s:%s" % (revision, filename),
]
git_show = subprocess.Popen(
git_show_cmd, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE
)
git_show.stdin.close()
clang_format_stdin = git_show.stdout
else:
clang_format_cmd.extend([filename])
git_show = None
clang_format_stdin = subprocess.PIPE
try:
clang_format = subprocess.Popen(
clang_format_cmd, stdin=clang_format_stdin, stdout=subprocess.PIPE
)
if clang_format_stdin == subprocess.PIPE:
clang_format_stdin = clang_format.stdin
except OSError as e:
if e.errno == errno.ENOENT:
die('cannot find executable "%s"' % binary)
else:
raise
clang_format_stdin.close()
hash_object_cmd = [
"git",
"hash-object",
"-w",
"--path=" + filename,
"--stdin",
]
hash_object = subprocess.Popen(
hash_object_cmd, stdin=clang_format.stdout, stdout=subprocess.PIPE
)
clang_format.stdout.close()
stdout = hash_object.communicate()[0]
if hash_object.returncode != 0:
die("`%s` failed" % " ".join(hash_object_cmd))
if clang_format.wait() != 0:
die("`%s` failed" % " ".join(clang_format_cmd))
if git_show and git_show.wait() != 0:
die("`%s` failed" % " ".join(git_show_cmd))
return convert_string(stdout).rstrip("\r\n")
@contextlib.contextmanager
def temporary_index_file(tree=None):
"""Context manager for setting GIT_INDEX_FILE to a temporary file and
deleting the file afterward."""
index_path = create_temporary_index(tree)
old_index_path = os.environ.get("GIT_INDEX_FILE")
os.environ["GIT_INDEX_FILE"] = index_path
try:
yield
finally:
if old_index_path is None:
del os.environ["GIT_INDEX_FILE"]
else:
os.environ["GIT_INDEX_FILE"] = old_index_path
os.remove(index_path)
def create_temporary_index(tree=None):
"""Create a temporary index file and return the created file's path.
If `tree` is not None, use that as the tree to read in. Otherwise, an
empty index is created."""
gitdir = run("git", "rev-parse", "--git-dir")
path = os.path.join(gitdir, temp_index_basename)
if tree is None:
tree = "--empty"
run("git", "read-tree", "--index-output=" + path, tree)
return path
def print_diff(old_tree, new_tree):
"""Print the diff between the two trees to stdout."""
# We use the porcelain 'diff' and not plumbing 'diff-tree' because the
# output is expected to be viewed by the user, and only the former does nice
# things like color and pagination.
#
# We also only print modified files since `new_tree` only contains the files
# that were modified, so unmodified files would show as deleted without the
# filter.
return subprocess.run(
["git", "diff", "--diff-filter=M", "--exit-code", old_tree, new_tree]
).returncode
def print_diffstat(old_tree, new_tree):
"""Print the diffstat between the two trees to stdout."""
# We use the porcelain 'diff' and not plumbing 'diff-tree' because the
# output is expected to be viewed by the user, and only the former does nice
# things like color and pagination.
#
# We also only print modified files since `new_tree` only contains the files
# that were modified, so unmodified files would show as deleted without the
# filter.
return subprocess.run(
[
"git",
"diff",
"--diff-filter=M",
"--exit-code",
"--stat",
old_tree,
new_tree,
]
).returncode
def apply_changes(old_tree, new_tree, force=False, patch_mode=False):
"""Apply the changes in `new_tree` to the working directory.
Bails if there are local changes in those files and not `force`. If
`patch_mode`, runs `git checkout --patch` to select hunks interactively."""
changed_files = (
run(
"git",
"diff-tree",
"--diff-filter=M",
"-r",
"-z",
"--name-only",
old_tree,
new_tree,
)
.rstrip("\0")
.split("\0")
)
if not force:
unstaged_files = run("git", "diff-files", "--name-status", *changed_files)
if unstaged_files:
print(
"The following files would be modified but have unstaged changes:",
file=sys.stderr,
)
print(unstaged_files, file=sys.stderr)
print("Please commit, stage, or stash them first.", file=sys.stderr)
sys.exit(2)
if patch_mode:
# In patch mode, we could just as well create an index from the new tree
# and checkout from that, but then the user will be presented with a
# message saying "Discard ... from worktree". Instead, we use the old
# tree as the index and checkout from new_tree, which gives the slightly
# better message, "Apply ... to index and worktree". This is not quite
# right, since it won't be applied to the user's index, but oh well.
with temporary_index_file(old_tree):
subprocess.run(["git", "checkout", "--patch", new_tree], check=True)
index_tree = old_tree
else:
with temporary_index_file(new_tree):
run("git", "checkout-index", "-f", "--", *changed_files)
return changed_files
def run(*args, **kwargs):
stdin = kwargs.pop("stdin", "")
verbose = kwargs.pop("verbose", True)
strip = kwargs.pop("strip", True)
for name in kwargs:
raise TypeError("run() got an unexpected keyword argument '%s'" % name)
p = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
)
stdout, stderr = p.communicate(input=stdin)
stdout = convert_string(stdout)
stderr = convert_string(stderr)
if p.returncode == 0:
if stderr:
if verbose:
print("`%s` printed to stderr:" % " ".join(args), file=sys.stderr)
print(stderr.rstrip(), file=sys.stderr)
if strip:
stdout = stdout.rstrip("\r\n")
return stdout
if verbose:
print("`%s` returned %s" % (" ".join(args), p.returncode), file=sys.stderr)
if stderr:
print(stderr.rstrip(), file=sys.stderr)
sys.exit(2)
def die(message):
print("error:", message, file=sys.stderr)
sys.exit(2)
def to_bytes(str_input):
# Encode to UTF-8 to get binary data.
if isinstance(str_input, bytes):
return str_input
return str_input.encode("utf-8")
def to_string(bytes_input):
if isinstance(bytes_input, str):
return bytes_input
return bytes_input.encode("utf-8")
def convert_string(bytes_input):
try:
return to_string(bytes_input.decode("utf-8"))
except AttributeError: # 'str' object has no attribute 'decode'.
return str(bytes_input)
except UnicodeError:
return str(bytes_input)
if __name__ == "__main__":
sys.exit(main())

View File

@@ -0,0 +1,297 @@
#!/usr/bin/env python3
from __future__ import absolute_import, division, print_function
from ctypes import ArgumentError
import json
import optparse
import os
import struct
import sys
###
k_header_magic_LE = b'pamh'
k_header_magic_BE = b'hmap'
def hmap_hash(str):
"""hash(str) -> int
Apply the "well-known" headermap hash function.
"""
return sum((ord(c.lower()) * 13
for c in str), 0)
class HeaderMap(object):
@staticmethod
def frompath(path):
with open(path, 'rb') as f:
magic = f.read(4)
if magic == k_header_magic_LE:
endian_code = '<'
elif magic == k_header_magic_BE:
endian_code = '>'
else:
raise SystemExit("error: %s: not a headermap" % (
path,))
# Read the header information.
header_fmt = endian_code + 'HHIIII'
header_size = struct.calcsize(header_fmt)
data = f.read(header_size)
if len(data) != header_size:
raise SystemExit("error: %s: truncated headermap header" % (
path,))
(version, reserved, strtable_offset, num_entries,
num_buckets, _) = struct.unpack(header_fmt, data)
if version != 1:
raise SystemExit("error: %s: unknown headermap version: %r" % (
path, version))
if reserved != 0:
raise SystemExit("error: %s: invalid reserved value in header" % (
path,))
# The number of buckets must be a power of two.
if num_buckets == 0 or (num_buckets & num_buckets - 1) != 0:
raise SystemExit("error: %s: invalid number of buckets" % (
path,))
# Read all of the buckets.
bucket_fmt = endian_code + 'III'
bucket_size = struct.calcsize(bucket_fmt)
buckets_data = f.read(num_buckets * bucket_size)
if len(buckets_data) != num_buckets * bucket_size:
raise SystemExit("error: %s: truncated headermap buckets" % (
path,))
buckets = [struct.unpack(bucket_fmt,
buckets_data[i*bucket_size:(i+1)*bucket_size])
for i in range(num_buckets)]
# Read the string table; the format doesn't explicitly communicate the
# size of the string table (which is dumb), so assume it is the rest of
# the file.
f.seek(0, 2)
strtable_size = f.tell() - strtable_offset
f.seek(strtable_offset)
if strtable_size == 0:
raise SystemExit("error: %s: unable to read zero-sized string table"%(
path,))
strtable = f.read(strtable_size)
if len(strtable) != strtable_size:
raise SystemExit("error: %s: unable to read complete string table"%(
path,))
if strtable[-1] != 0:
raise SystemExit("error: %s: invalid string table in headermap" % (
path,))
return HeaderMap(num_entries, buckets, strtable)
def __init__(self, num_entries, buckets, strtable):
self.num_entries = num_entries
self.buckets = buckets
self.strtable = strtable
def get_string(self, idx):
if idx >= len(self.strtable):
raise SystemExit("error: %s: invalid string index" % (
idx,))
end_idx = self.strtable.index(0, idx)
return self.strtable[idx:end_idx].decode()
@property
def mappings(self):
for key_idx,prefix_idx,suffix_idx in self.buckets:
if key_idx == 0:
continue
yield (self.get_string(key_idx),
self.get_string(prefix_idx) + self.get_string(suffix_idx))
###
def action_dump(name, args):
"dump a headermap file"
parser = optparse.OptionParser("%%prog %s [options] <headermap path>" % (
name,))
parser.add_option("-v", "--verbose", dest="verbose",
help="show more verbose output [%default]",
action="store_true", default=False)
(opts, args) = parser.parse_args(args)
if len(args) != 1:
parser.error("invalid number of arguments")
path, = args
hmap = HeaderMap.frompath(path)
# Dump all of the buckets.
print ('Header Map: %s' % (path,))
if opts.verbose:
print ('headermap: %r' % (path,))
print (' num entries: %d' % (hmap.num_entries,))
print (' num buckets: %d' % (len(hmap.buckets),))
print (' string table size: %d' % (len(hmap.strtable),))
for i,bucket in enumerate(hmap.buckets):
key_idx,prefix_idx,suffix_idx = bucket
if key_idx == 0:
continue
# Get the strings.
key = hmap.get_string(key_idx)
prefix = hmap.get_string(prefix_idx)
suffix = hmap.get_string(suffix_idx)
print (" bucket[%d]: %r -> (%r, %r) -- %d" % (
i, key, prefix, suffix, (hmap_hash(key) & (len(hmap.buckets) - 1))))
else:
mappings = sorted(hmap.mappings)
for key,value in mappings:
print ("%s -> %s" % (key, value))
print ()
def next_power_of_two(value):
if value < 0:
raise ArgumentError
return 1 if value == 0 else 2**(value - 1).bit_length()
def action_write(name, args):
"write a headermap file from a JSON definition"
parser = optparse.OptionParser("%%prog %s [options] <input path> <output path>" % (
name,))
(opts, args) = parser.parse_args(args)
if len(args) != 2:
parser.error("invalid number of arguments")
input_path,output_path = args
with open(input_path, "r") as f:
input_data = json.load(f)
# Compute the headermap contents, we make a table that is 1/3 full.
mappings = input_data['mappings']
num_buckets = next_power_of_two(len(mappings) * 3)
table = [(0, 0, 0)
for i in range(num_buckets)]
max_value_len = 0
strtable = "\0"
for key,value in mappings.items():
if not isinstance(key, str):
key = key.decode('utf-8')
if not isinstance(value, str):
value = value.decode('utf-8')
max_value_len = max(max_value_len, len(value))
key_idx = len(strtable)
strtable += key + '\0'
prefix = os.path.dirname(value) + '/'
suffix = os.path.basename(value)
prefix_idx = len(strtable)
strtable += prefix + '\0'
suffix_idx = len(strtable)
strtable += suffix + '\0'
hash = hmap_hash(key)
for i in range(num_buckets):
idx = (hash + i) % num_buckets
if table[idx][0] == 0:
table[idx] = (key_idx, prefix_idx, suffix_idx)
break
else:
raise RuntimeError
endian_code = '<'
magic = k_header_magic_LE
magic_size = 4
header_fmt = endian_code + 'HHIIII'
header_size = struct.calcsize(header_fmt)
bucket_fmt = endian_code + 'III'
bucket_size = struct.calcsize(bucket_fmt)
strtable_offset = magic_size + header_size + num_buckets * bucket_size
header = (1, 0, strtable_offset, len(mappings),
num_buckets, max_value_len)
# Write out the headermap.
with open(output_path, 'wb') as f:
f.write(magic)
f.write(struct.pack(header_fmt, *header))
for bucket in table:
f.write(struct.pack(bucket_fmt, *bucket))
f.write(strtable.encode())
def action_tovfs(name, args):
"convert a headermap to a VFS layout"
parser = optparse.OptionParser("%%prog %s [options] <headermap path>" % (
name,))
parser.add_option("", "--build-path", dest="build_path",
help="build path prefix",
action="store", type=str)
(opts, args) = parser.parse_args(args)
if len(args) != 2:
parser.error("invalid number of arguments")
if opts.build_path is None:
parser.error("--build-path is required")
input_path,output_path = args
hmap = HeaderMap.frompath(input_path)
# Create the table for all the objects.
vfs = {}
vfs['version'] = 0
build_dir_contents = []
vfs['roots'] = [{
'name' : opts.build_path,
'type' : 'directory',
'contents' : build_dir_contents }]
# We assume we are mapping framework paths, so a key of "Foo/Bar.h" maps to
# "<build path>/Foo.framework/Headers/Bar.h".
for key,value in hmap.mappings:
# If this isn't a framework style mapping, ignore it.
components = key.split('/')
if len(components) != 2:
continue
framework_name,header_name = components
build_dir_contents.append({
'name' : '%s.framework/Headers/%s' % (framework_name,
header_name),
'type' : 'file',
'external-contents' : value })
with open(output_path, 'w') as f:
json.dump(vfs, f, indent=2)
commands = dict((name[7:].replace("_","-"), f)
for name,f in locals().items()
if name.startswith('action_'))
def usage():
print ("Usage: %s command [options]" % (
os.path.basename(sys.argv[0])), file=sys.stderr)
print (file=sys.stderr)
print ("Available commands:", file=sys.stderr)
cmds_width = max(map(len, commands))
for name,func in sorted(commands.items()):
print (" %-*s - %s" % (cmds_width, name, func.__doc__), file=sys.stderr)
sys.exit(1)
def main():
if len(sys.argv) < 2 or sys.argv[1] not in commands:
usage()
cmd = sys.argv[1]
commands[cmd](cmd, sys.argv[2:])
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
import multiprocessing
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.intercept import intercept_build
if __name__ == '__main__':
multiprocessing.freeze_support()
sys.exit(intercept_build())

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.llc.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.lld.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.llvm-ar.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.llvm-as.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.llvm-dis.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.llvm-link.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.llvm-nm.bin" "$@"

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
dir="$(dirname "$0")"
export RUNAS_ARG0="$0"
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dir/../../lib/runas.so"
exec "$dir/../../lib/ld-linux-x86-64.so.2" --library-path "$dir/../../lib/" "$dir/.llvm-objcopy.bin" "$@"

Some files were not shown because too many files have changed in this diff Show More