From 4c01520cd33a1ad6058776e618117593db14d3a8 Mon Sep 17 00:00:00 2001 From: bernard Date: Tue, 14 Jul 2026 08:53:35 +0800 Subject: [PATCH 1/4] rtthread-env: add Env and EBuild workflow Document current Env installation, upgrade, activation, and validation flows. Add cross-platform network helpers and maintainable EBuild templates. --- rtthread-env/SKILL.md | 118 ++++++ rtthread-env/references/ebuild.md | 417 +++++++++++++++++++++ rtthread-env/references/install-upgrade.md | 194 ++++++++++ rtthread-env/scripts/env-network.ps1 | 41 ++ rtthread-env/scripts/env-network.sh | 40 ++ 5 files changed, 810 insertions(+) create mode 100644 rtthread-env/SKILL.md create mode 100644 rtthread-env/references/ebuild.md create mode 100644 rtthread-env/references/install-upgrade.md create mode 100755 rtthread-env/scripts/env-network.ps1 create mode 100755 rtthread-env/scripts/env-network.sh diff --git a/rtthread-env/SKILL.md b/rtthread-env/SKILL.md new file mode 100644 index 0000000..04f3721 --- /dev/null +++ b/rtthread-env/SKILL.md @@ -0,0 +1,118 @@ +--- +name: rtthread-env +description: Use when installing, upgrading, activating, or troubleshooting RT-Thread Env, Env scripts, packages index, Python venv, or EBuild/SCons project and component scripts for RT-Thread projects. +--- + +# RT-Thread Env + +## Role + +你是一位熟悉 RT-Thread Env、packages 索引、SCons 与 EBuild 的嵌入式工程师, +能根据主机平台选择合适的 Env 版本,正确激活环境,并为 RT-Thread 工程创建 +可维护的 EBuild 构建脚本。 + +## Env Version Policy + +- 安装 Env 默认使用最新版本:取 `RT-Thread/env` git 仓库当前默认分支, + 中国大陆网络取 Gitee mirror 当前默认分支。 +- 默认使用 Env v2.0 风格流程:Python 3、`kconfiglib` 和 Env scripts。 +- 只有用户明确要求维护旧 RT-Thread 工程或旧 Env 环境时,才选择 Env + v1.5.x;此时不要安装或保留 `kconfiglib`,因为 v1.5.x 与 + `kconfiglib` 冲突。 +- 无法确认用户是否需要旧 Env 时,按最新 Env 安装,并把旧工程兼容性作为 + 风险提示列出。 + +## Inputs + +执行本 skill 前先确认: + +- 主机平台:Linux、Windows PowerShell、WSL、macOS 或容器。 +- 网络位置:安装 Env 前先检测公网 IP;中国大陆使用 `--gitee` 和清华 + PyPI 源,其他地区使用默认 GitHub/PyPI。 +- RT-Thread 版本和目标工程路径。 +- 工具链类型与路径,如 `arm-none-eabi-gcc` 的 `bin` 目录。 +- 是否允许修改 shell profile、PowerShell profile 或 `~/.env`。 + +## File Map + +- 安装、升级、激活 Env:读取 + [references/install-upgrade.md](references/install-upgrade.md)。 +- Linux / WSL / macOS 网络检测和 pip 包装:按需使用 + [scripts/env-network.sh](scripts/env-network.sh)。 +- Windows PowerShell 网络检测和 pip 包装:按需使用 + [scripts/env-network.ps1](scripts/env-network.ps1)。 +- EBuild 工程、组件脚本、级联 `SConscript` 模板:读取 + [references/ebuild.md](references/ebuild.md)。 + +## Workflow + +1. 默认安装最新 Env git 仓库版本;仅在用户明确要求旧 Env 时切到 v1.5.x。 +2. 安装或升级 Env 前,先运行对应平台的网络脚本;中国大陆机器必须使用 + `--gitee` 和清华 PyPI 源。 +3. 安装 Env 时优先使用官方安装脚本;无官方脚本的平台按手动目录结构安装。 +4. 升级 Env 时同时更新 `~/.env/tools/scripts`、`~/.env/packages/packages` + 和 `~/.env/packages/sdk`,并用 `git pull --ff-only` 避免覆盖本地修改。 +5. 激活 Env 后检查 `scons`、`pkgs`、Python 依赖和 packages index。 +6. 创建 EBuild 工程或脚本时,先读取 `references/ebuild.md`,再生成文件。 + +## Env Directory + +最新 Env 默认目录结构: + +```text +~/.env/ +├── env.sh / env.ps1 +├── local_pkgs/ +├── packages/ +│ ├── Kconfig +│ ├── packages/ +│ └── sdk/ +└── tools/ + └── scripts/ +``` + +## Validation + +安装或升级后至少执行: + +```sh +source ~/.env/env.sh +scons --menuconfig +scons --pyconfig-silent +scons +``` + +Windows 使用 `~\.env\env.ps1` 替换 `source ~/.env/env.sh`。如需导出工程, +再运行 `scons --target=vscode`、`scons --target=cmake` 或 +`scons --target=mdk5`。 + +## Done Checklist + +- [ ] 已默认选择最新 Env git 仓库版本,或按用户要求切到旧 Env。 +- [ ] 安装或升级前已运行网络检测;中国大陆使用 `--gitee` 和清华 PyPI 源。 +- [ ] Env scripts 位于 `~/.env/tools/scripts` 并可执行。 +- [ ] packages index 位于 `~/.env/packages/packages`,SDK 位于 + `~/.env/packages/sdk`。 +- [ ] Env 已激活,`scons`、`pkgs`、Python 依赖可用。 +- [ ] 升级流程已更新 Env scripts、packages index 和 SDK。 +- [ ] EBuild 工程包含 `SConstruct`、`SConscript`、`Kconfig`、 + `proj_config.py` 和 hello 程序。 +- [ ] 组件脚本使用 `DefineGroup` 或 `BuildPackage`,依赖宏明确。 +- [ ] 源码列表优先使用 `Glob` 或 `Split`;增量文件使用 `src += [...]`, + 移除文件使用 `SrcRemove` 或 EBuild 的 `env.SrcRemove`。 +- [ ] 每个源码文件仅由一个叶子 `SConscript` 和一个 group 编译;存在 + `package.json` 时使用 `env.BuildPackage`,不重复使用 `env.DefineGroup`。 +- [ ] `CPPPATH` 以 `cwd + '/include'` 和 `+=` 维护,不为普通相对路径引入 + `os.path.join`。 +- [ ] 条件源码、私有 include 和私有宏位于相同的 `GetDepend` 分支; + `depend` 列表按 AND 处理,OR 条件显式表达。 +- [ ] 公共属性使用 `CPPPATH`/`CPPDEFINES`,组件私有属性使用 + `LOCAL_CPPPATH`/`LOCAL_CPPDEFINES`/`LOCAL_CFLAGS`,不修改共享环境。 +- [ ] RT-Thread 原生 `SConscript` 通过 `building` 直接调用构建辅助函数; + EBuild 保留其注入的 `env.DefineGroup`、`env.BuildPackage`、 + `env.Bridge`、`env.GetCurrentDir` 和 `env.SrcRemove` 接口。 +- [ ] 级联子目录使用 `env.Bridge()`,叶子目录返回 group;有顺序或筛选需求时 + 显式调用 `SConscript`。 +- [ ] `scons --menuconfig`、`scons --pyconfig-silent`、`scons -c`、`scons` + 通过;切换会影响条件源码的 Kconfig 选项后重复构建,必要时使用 + `scons --verbose` 核对编译命令。 diff --git a/rtthread-env/references/ebuild.md b/rtthread-env/references/ebuild.md new file mode 100644 index 0000000..48c2f2d --- /dev/null +++ b/rtthread-env/references/ebuild.md @@ -0,0 +1,417 @@ +# EBuild Templates + +## Basic Project + +Use this template for an EBuild-style `stm32f407-rt-spark` hello project. + +```text +stm32f407-rt-spark-hello/ +├── .config +├── Kconfig +├── SConstruct +├── SConscript +├── proj_config.py +├── applications/ +│ ├── SConscript +│ └── main.c +└── board/ + ├── SConscript + └── linker_scripts/ + └── link.lds +``` + +`SConstruct`: + +```python +from SCons.Script import Environment, Export, SConscript +from ebuild import PrepareBuilding, DoBuilding +import proj_config + +env = Environment() +PrepareBuilding(env, proj_config=proj_config) +Export('env') + +objs = SConscript('SConscript') +DoBuilding(env, 'rtthread.elf', objs) +``` + +`proj_config.py`: + +```python +import os + +PROJECT_NAME = 'stm32f407-rt-spark-hello' +TARGET_NAME = 'rtthread.elf' +CONFIG_HEADER = 'proj_config.h' + +TOOLCHAIN_CONFIG = { + 'CC_PREFIX': 'arm-none-eabi-', + 'EXEC_PATH': os.getenv('RTT_EXEC_PATH', ''), + 'MCU_SERIES': { + 'CONFIG_SOC_STM32F407': { + 'cpu': 'cortex-m4', + 'fpu': 'fpv4-sp-d16', + 'float_abi': 'hard', + 'link_script': 'board/linker_scripts/link.lds', + }, + }, + 'BUILD': 'debug', +} + +POST_ACTION = '$OBJCOPY -O binary $TARGET build/rtthread.bin' +``` + +`Kconfig`: + +```text +mainmenu "RT-Thread stm32f407-rt-spark hello" + +config SOC_STM32F407 + bool + default y + +config APP_HELLO + bool "Enable hello application" + default y + +source "$PKGS_DIR/Kconfig" +``` + +Root `SConscript` using bridge: + +```python +from SCons.Script import Import + +Import('env') + +groups = env.Bridge() +Return('groups') +``` + +`env.Bridge()` scans immediate child directories such as `applications/` and +`board/`, executes their `SConscript` files, and merges returned groups. Use +explicit `SConscript('path/SConscript')` calls only when the root must include a +fixed subset or a specific order. + +`applications/main.c`: + +```c +#include + +int main(void) +{ + rt_kprintf("hello rt-thread env ebuild\n"); + return 0; +} +``` + +`applications/SConscript`: + +```python +from SCons.Script import Import, Split + +Import('env') + +cwd = env.GetCurrentDir() + +src = Split(""" +main.c +""") + +CPPPATH = [cwd + '/include'] + +group = env.DefineGroup( + 'applications', + src, + depend=['APP_HELLO'], + CPPPATH=CPPPATH, +) + +Return('group') +``` + +`board/SConscript`: + +```python +from SCons.Script import Glob, Import + +Import('env') + +cwd = env.GetCurrentDir() + +src = Glob('*.c') + +CPPPATH = [cwd + '/include'] + +group = env.DefineGroup( + 'board', + src, + depend=['SOC_STM32F407'], + CPPPATH=CPPPATH, +) + +Return('group') +``` + +Reuse startup files, board init, drivers, and linker script from the existing +`stm32f407-rt-spark` BSP before adapting the build entry points. + +Build: + +```sh +scons --menuconfig +scons --pyconfig-silent +scons -c +scons +scons --target=vscode +``` + +## SConscript Style + +When a `SConscript` selects source files, use `Glob` for a pattern and `Split` +for an explicit, multiline list. Select exactly one initial form for a source +list. Add individual files incrementally with `src += [...]`; do not replace +an existing source list merely to add a file. + +```python +from SCons.Script import Glob, Import, Split + +Import('env') + +cwd = env.GetCurrentDir() + +# Use this form when the component compiles every matching file. +src = Glob('*.c') +src += Glob('*.cpp') +src += Glob('*.S') +``` + +```python +from SCons.Script import Import, Split + +Import('env') + +cwd = env.GetCurrentDir() + +# Use this form when the source set must be a deliberate whitelist. +src = Split(""" +xx.c +nn/mm.c +""") + +src += ['yy.c'] +env.SrcRemove(src, 'xx.c') + +CPPPATH = [cwd + '/include'] +CPPPATH += [cwd + '/xx/include'] +``` + +Use `Glob` for an ordinary directory whose matching files all belong to the +component. Use `Split` for startup files, protocol stacks, generated vendor +sources, or any component where the file set and order must be explicit. Do +not add a file explicitly when it is already selected by the same `Glob`. + +Use `/` in `SConscript` relative paths on both Linux and Windows. Prefer the +simple `cwd + '/subdir'` form above for include directories and source paths; +do not introduce `os.path.join` solely to build these paths. Keep `os.path` +only where filesystem inspection or other path operations actually require it. + +EBuild injects `DefineGroup`, `BuildPackage`, `Bridge`, `GetCurrentDir`, and +`SrcRemove` onto `env`, so EBuild scripts call them as `env.DefineGroup(...)`, +`env.BuildPackage(...)`, `env.Bridge()`, `env.GetCurrentDir()`, and +`env.SrcRemove(...)`. `Glob` and `Split` are SCons functions imported directly +as shown above. + +### Configuration, Scope, and Ownership + +Keep a feature's source files, private include directories, and private defines +in the same configuration branch. A `depend` list is an AND condition in both +RT-Thread and EBuild: `depend=['CONFIG_A', 'CONFIG_B']` requires both options. +For an OR condition, use an explicit `if` expression. + +```python +from SCons.Script import Glob, Import + +Import('env') + +cwd = env.GetCurrentDir() +src = Glob('src/common/*.c') + +CPPPATH = [cwd + '/include'] +LOCAL_CPPPATH = [cwd + '/src/include'] +LOCAL_CPPDEFINES = ['COMPONENT_INTERNAL'] + +if env.GetDepend('CONFIG_TLS'): + src += ['src/tls.c'] + LOCAL_CPPPATH += [cwd + '/src/tls/include'] + LOCAL_CPPDEFINES += ['COMPONENT_USING_TLS'] + +if env.GetDepend('CONFIG_IPV6'): + src += ['src/ipv6.c'] + LOCAL_CPPPATH += [cwd + '/src/ipv6/include'] + LOCAL_CPPDEFINES += ['COMPONENT_USING_IPV6'] + +group = env.DefineGroup( + 'component', + src, + depend=['CONFIG_COMPONENT'], + CPPPATH=CPPPATH, + LOCAL_CPPPATH=LOCAL_CPPPATH, + LOCAL_CPPDEFINES=LOCAL_CPPDEFINES, +) +Return('group') +``` + +Use `CPPPATH` and `CPPDEFINES` for public interfaces required outside the +component. Use `LOCAL_CPPPATH`, `LOCAL_CPPDEFINES`, and `LOCAL_CFLAGS` for +private headers, defines, and compiler options so they stay on the component's +cloned build environment. Do not mutate the shared SCons environment from a +component script. + +Each source file has exactly one owning leaf `SConscript` and one group. A +directory with `package.json` uses `env.BuildPackage(...)`; do not also register +the same sources with `env.DefineGroup(...)`. + +For the RT-Thread source tree and conventional BSP `SConscript` files, import +the build helpers with `from building import *` and call the helpers directly: + +```python +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +src += ['yy.c'] +SrcRemove(src, 'xx.c') + +CPPPATH = [cwd + '/include'] +CPPPATH += [cwd + '/xx/include'] + +group = DefineGroup('component', src, depend=['RT_USING_COMPONENT'], + CPPPATH=CPPPATH) +Return('group') +``` + +Do not change these RT-Thread direct calls to `env.Method(...)`; the standard +RT-Thread `building` interface exports them as module-level functions. + +## Component Script + +Prefer `DefineGroup` for local components. + +```text +components/foo/ +├── Kconfig +├── SConscript +├── include/ +│ └── foo.h +└── src/ + └── foo.c +``` + +`components/foo/Kconfig`: + +```text +config COMPONENT_USING_FOO + bool "Enable foo component" + default n +``` + +`components/foo/SConscript`: + +```python +from SCons.Script import Glob, Import + +Import('env') + +cwd = env.GetCurrentDir() + +src = Glob('src/*.c') + +CPPPATH = [cwd + '/include'] + +group = env.DefineGroup( + 'foo', + src, + depend=['COMPONENT_USING_FOO'], + CPPPATH=CPPPATH, + CPPDEFINES=['FOO_USING_EBUILD'], +) + +Return('group') +``` + +Use `BuildPackage` when the component owns a `package.json`: + +```python +from SCons.Script import Import + +Import('env') + +group = env.BuildPackage('.') +Return('group') +``` + +`package.json`: + +```json +{ + "type": "rt-thread-component", + "name": "foo", + "dependencies": ["COMPONENT_USING_FOO"], + "defines": ["FOO_USING_EBUILD"], + "sources": [ + { + "dependencies": [], + "includes": ["include"], + "files": ["src/*.c"] + } + ] +} +``` + +## Cascaded SConscript + +Use `env.Bridge()` for cascaded subdirectories. It scans only immediate child +directories that contain `SConscript`, in sorted directory-name order, and +merges their returned groups. + +```text +components/ +├── SConscript +├── drivers/ +│ ├── SConscript +│ └── uart_ext/ +│ └── SConscript +└── middleware/ + ├── SConscript + └── foo/ + └── SConscript +``` + +`components/SConscript` and intermediate directory `SConscript` files: + +```python +from SCons.Script import Import + +Import('env') + +groups = env.Bridge() +Return('groups') +``` + +Leaf directories use `DefineGroup` or `BuildPackage` and return `group`. +The project root `SConscript` can also use bridge to connect all immediate +subdirectory `SConscript` files. When the parent needs a fixed order, must +exclude a child directory, or needs to make the selected children obvious, use +explicit `SConscript('path/SConscript')` calls instead of `env.Bridge()`: + +```python +from SCons.Script import Import, SConscript + +Import('env') + +groups = [] +groups += SConscript('drivers/SConscript') +groups += SConscript('middleware/SConscript') +Return('groups') +``` diff --git a/rtthread-env/references/install-upgrade.md b/rtthread-env/references/install-upgrade.md new file mode 100644 index 0000000..f90cf80 --- /dev/null +++ b/rtthread-env/references/install-upgrade.md @@ -0,0 +1,194 @@ +# Env Install and Upgrade + +## Network Setup + +Before installing or upgrading Env, use the bundled network script: + +```sh +source rtthread-env/scripts/env-network.sh +``` + +```powershell +. .\rtthread-env\scripts\env-network.ps1 +``` + +The script sets: + +- `RTT_ENV_MIRROR="--gitee"` when public IP is in China mainland. +- `PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple` in China mainland. +- `PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn` in China mainland. + +If the user already knows the machine is in China mainland, set +`RTT_ENV_REGION=CN` before loading the script. + +## Linux / WSL Install + +Default install means latest Env: download the installer from the current +`RT-Thread/env` default install entry, or its Gitee mirror. Do not pin an old +Env branch unless the user explicitly asks for legacy Env. + +```sh +source rtthread-env/scripts/env-network.sh +if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then + url="https://gitee.com/RT-Thread-Mirror/env/raw/master/install_ubuntu.sh" +else + url="https://raw.githubusercontent.com/RT-Thread/env/master/install_ubuntu.sh" +fi +wget "$url" -O install_ubuntu.sh +chmod 755 install_ubuntu.sh +./install_ubuntu.sh $RTT_ENV_MIRROR +rm install_ubuntu.sh +``` + +The official script installs Python3, pip, gcc, git, ncurses dependencies, +`scons`, `requests`, `tqdm`, `kconfiglib`, `pyyaml`, and creates: + +```text +~/.env/ +├── env.sh +├── local_pkgs/ +├── packages/ +│ ├── Kconfig +│ ├── packages/ +│ └── sdk/ +└── tools/ + └── scripts/ +``` + +## Windows PowerShell Install + +Run PowerShell as administrator for `set-executionpolicy remotesigned`. +Afterward, normal PowerShell is enough. +Default install uses the installer from the current default branch. + +```powershell +. .\rtthread-env\scripts\env-network.ps1 +if ($script:RTT_ENV_MIRROR -eq "--gitee") { + $url = "https://gitee.com/RT-Thread-Mirror/env/raw/master/install_windows.ps1" +} else { + $url = "https://raw.githubusercontent.com/RT-Thread/env/master/install_windows.ps1" +} +wget $url -O install_windows.ps1 +if ($script:RTT_ENV_MIRROR -eq "--gitee") { + $content = Get-Content install_windows.ps1 + $content = $content -replace "http://mirrors.aliyun.com/pypi/simple", ` + "https://pypi.tuna.tsinghua.edu.cn/simple" + $content = $content -replace "mirrors.aliyun.com", ` + "pypi.tuna.tsinghua.edu.cn" + $content | Set-Content install_windows.ps1 +} +set-executionpolicy remotesigned +.\install_windows.ps1 $script:RTT_ENV_MIRROR +``` + +## macOS / Other Linux Manual Install + +Manual install clones the current default branch with `--depth=1`, so Env, +packages index, and SDK are installed at their latest default-branch versions. + +```sh +source rtthread-env/scripts/env-network.sh +pip_install --user -U pip scons requests tqdm kconfiglib pyyaml +mkdir -p ~/.env/local_pkgs ~/.env/packages ~/.env/tools +if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then + pkg_url="https://gitee.com/RT-Thread-Mirror/packages.git" + sdk_url="https://gitee.com/RT-Thread-Mirror/sdk.git" + env_url="https://gitee.com/RT-Thread-Mirror/env.git" +else + pkg_url="https://github.com/RT-Thread/packages.git" + sdk_url="https://github.com/RT-Thread/sdk.git" + env_url="https://github.com/RT-Thread/env.git" +fi +git clone "$pkg_url" ~/.env/packages/packages --depth=1 +git clone "$sdk_url" ~/.env/packages/sdk --depth=1 +git clone "$env_url" ~/.env/tools/scripts --depth=1 +printf '%s\n' 'source "$PKGS_DIR/packages/Kconfig"' > ~/.env/packages/Kconfig +user_base="$(python3 -m site --user-base)" +printf '%s\n' \ + "export PATH=$user_base/bin:\$HOME/.env/tools/scripts:\$PATH" \ + 'export RTT_EXEC_PATH=/usr/bin' > ~/.env/env.sh +``` + +## Upgrade Env + +Update Env scripts, packages index, and SDK. Stop and report if a repo has local +changes. + +```sh +source rtthread-env/scripts/env-network.sh +for repo in "$HOME/.env/tools/scripts" \ + "$HOME/.env/packages/packages" \ + "$HOME/.env/packages/sdk"; do + test -d "$repo/.git" || continue + git -C "$repo" status --short + git -C "$repo" pull --ff-only +done +pip_install --user -U scons requests tqdm kconfiglib pyyaml +``` + +```powershell +. .\rtthread-env\scripts\env-network.ps1 +$repos = @( + "$HOME\.env\tools\scripts", + "$HOME\.env\packages\packages", + "$HOME\.env\packages\sdk" +) +foreach ($repo in $repos) { + if (Test-Path "$repo\.git") { + git -C $repo status --short + git -C $repo pull --ff-only + } +} +Invoke-PipInstall -U scons requests tqdm kconfiglib pyyaml +``` + +After upgrading, reactivate Env and run `scons --menuconfig` or +`scons --pyconfig-silent` in the RT-Thread project. + +## Activate Env + +Linux / WSL / macOS: + +```sh +source ~/.env/env.sh +``` + +Persistent shell activation: + +```sh +printf '%s\n' 'source ~/.env/env.sh' >> ~/.bashrc +``` + +Python venv activation when Env scripts need it: + +```sh +source rtthread-env/scripts/env-network.sh +python3 -m venv ~/.env/.venv +. ~/.env/.venv/bin/activate +pip_install -U pip +pip_install ~/.env/tools/scripts +source ~/.env/env.sh +``` + +Windows: + +```powershell +~\.env\env.ps1 +``` + +Persistent PowerShell activation: + +```powershell +mkdir -Force "$HOME\Documents\WindowsPowerShell" +$profile = "$HOME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1" +Add-Content $profile "~\.env\env.ps1" +``` + +## Activation Checks + +```sh +which scons || where scons +scons --version +python -c "import kconfiglib; print('kconfiglib ok')" +pkgs --help +``` diff --git a/rtthread-env/scripts/env-network.ps1 b/rtthread-env/scripts/env-network.ps1 new file mode 100755 index 0000000..670d094 --- /dev/null +++ b/rtthread-env/scripts/env-network.ps1 @@ -0,0 +1,41 @@ +function Set-EnvNetwork { + $country = $env:RTT_ENV_REGION + if (-not $country) { + try { + $country = (Invoke-RestMethod -Uri "https://ipinfo.io/json" ` + -UseBasicParsing -TimeoutSec 5).country + } catch { + $country = "" + } + } + + if ($country -eq "CN") { + $script:RTT_ENV_MIRROR = "--gitee" + $script:PIP_INDEX_URL = "https://pypi.tuna.tsinghua.edu.cn/simple" + $script:PIP_TRUSTED_HOST = "pypi.tuna.tsinghua.edu.cn" + } else { + $script:RTT_ENV_MIRROR = "" + $script:PIP_INDEX_URL = "" + $script:PIP_TRUSTED_HOST = "" + } + + $env:PIP_INDEX_URL = $script:PIP_INDEX_URL + $env:PIP_TRUSTED_HOST = $script:PIP_TRUSTED_HOST + + if (-not $country) { + $country = "unknown" + } + Write-Host "RT-Thread Env region: $country" +} + +function Invoke-PipInstall { + param([Parameter(ValueFromRemainingArguments = $true)][string[]]$Args) + if ($script:PIP_INDEX_URL) { + python -m pip install -i $script:PIP_INDEX_URL ` + --trusted-host $script:PIP_TRUSTED_HOST @Args + } else { + python -m pip install @Args + } +} + +Set-EnvNetwork diff --git a/rtthread-env/scripts/env-network.sh b/rtthread-env/scripts/env-network.sh new file mode 100755 index 0000000..4382399 --- /dev/null +++ b/rtthread-env/scripts/env-network.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +detect_env_region() { + RTT_ENV_REGION="${RTT_ENV_REGION:-}" + country="${RTT_ENV_REGION:-$(python3 - <<'PY' +import json +import urllib.request + +try: + with urllib.request.urlopen("https://ipinfo.io/json", timeout=5) as res: + print(json.load(res).get("country", "")) +except Exception: + print("") +PY +)}" + + if [ "$country" = "CN" ]; then + RTT_ENV_MIRROR="--gitee" + PIP_INDEX_URL="https://pypi.tuna.tsinghua.edu.cn/simple" + PIP_TRUSTED_HOST="pypi.tuna.tsinghua.edu.cn" + else + RTT_ENV_MIRROR="" + PIP_INDEX_URL="" + PIP_TRUSTED_HOST="" + fi + + echo "RT-Thread Env region: ${country:-unknown}" + export RTT_ENV_MIRROR PIP_INDEX_URL PIP_TRUSTED_HOST +} + +pip_install() { + if [ -n "$PIP_INDEX_URL" ]; then + python3 -m pip install -i "$PIP_INDEX_URL" \ + --trusted-host "$PIP_TRUSTED_HOST" "$@" + else + python3 -m pip install "$@" + fi +} + +detect_env_region From 2ca81c2c07cde3bb7c9622ca250a813d8f805c51 Mon Sep 17 00:00:00 2001 From: bernard Date: Sat, 18 Jul 2026 06:57:53 +0800 Subject: [PATCH 2/4] rtthread-env: update Env installation workflow Sync platform installers and Windows first-activation behavior with the latest Env scripts. Document mirror selection, venv initialization, and safe handling of existing installations. --- rtthread-env/SKILL.md | 18 ++-- rtthread-env/references/install-upgrade.md | 115 ++++++++++++++++++--- 2 files changed, 111 insertions(+), 22 deletions(-) diff --git a/rtthread-env/SKILL.md b/rtthread-env/SKILL.md index 04f3721..d135ebb 100644 --- a/rtthread-env/SKILL.md +++ b/rtthread-env/SKILL.md @@ -27,8 +27,8 @@ description: Use when installing, upgrading, activating, or troubleshooting RT-T 执行本 skill 前先确认: - 主机平台:Linux、Windows PowerShell、WSL、macOS 或容器。 -- 网络位置:安装 Env 前先检测公网 IP;中国大陆使用 `--gitee` 和清华 - PyPI 源,其他地区使用默认 GitHub/PyPI。 +- 网络位置:安装 Env 前先检测公网 IP;中国大陆下载 Env 时使用 `--gitee`。 + Windows 首次激活会再次检测公网 IP,并自动选择清华或默认 PyPI 源。 - RT-Thread 版本和目标工程路径。 - 工具链类型与路径,如 `arm-none-eabi-gcc` 的 `bin` 目录。 - 是否允许修改 shell profile、PowerShell profile 或 `~/.env`。 @@ -47,9 +47,10 @@ description: Use when installing, upgrading, activating, or troubleshooting RT-T ## Workflow 1. 默认安装最新 Env git 仓库版本;仅在用户明确要求旧 Env 时切到 v1.5.x。 -2. 安装或升级 Env 前,先运行对应平台的网络脚本;中国大陆机器必须使用 - `--gitee` 和清华 PyPI 源。 -3. 安装 Env 时优先使用官方安装脚本;无官方脚本的平台按手动目录结构安装。 +2. 安装或升级 Env 前,先运行对应平台的网络脚本;中国大陆机器下载 Env + 时必须使用 `--gitee`,不要现场改写下载的官方安装脚本。 +3. Ubuntu / WSL、Windows、macOS、Arch Linux 和 openSUSE 优先使用对应的 + 官方安装脚本;无官方脚本的平台按手动目录结构安装。 4. 升级 Env 时同时更新 `~/.env/tools/scripts`、`~/.env/packages/packages` 和 `~/.env/packages/sdk`,并用 `git pull --ff-only` 避免覆盖本地修改。 5. 激活 Env 后检查 `scons`、`pkgs`、Python 依赖和 packages index。 @@ -82,18 +83,21 @@ scons --pyconfig-silent scons ``` -Windows 使用 `~\.env\env.ps1` 替换 `source ~/.env/env.sh`。如需导出工程, +Windows 首次运行 `~\.env\env.ps1` 时会创建 `~\.env\.venv`、升级 pip +并安装本地 Env scripts;必须等待该过程成功后再执行构建检查。如需导出工程, 再运行 `scons --target=vscode`、`scons --target=cmake` 或 `scons --target=mdk5`。 ## Done Checklist - [ ] 已默认选择最新 Env git 仓库版本,或按用户要求切到旧 Env。 -- [ ] 安装或升级前已运行网络检测;中国大陆使用 `--gitee` 和清华 PyPI 源。 +- [ ] 安装或升级前已运行网络检测;中国大陆下载 Env 时使用 `--gitee`。 +- [ ] 未改写下载的官方安装脚本;需要更换 PyPI 源时修改用户侧激活配置。 - [ ] Env scripts 位于 `~/.env/tools/scripts` 并可执行。 - [ ] packages index 位于 `~/.env/packages/packages`,SDK 位于 `~/.env/packages/sdk`。 - [ ] Env 已激活,`scons`、`pkgs`、Python 依赖可用。 +- [ ] Windows 的 `~/.env/.venv` 已在首次激活时成功创建并安装 Env scripts。 - [ ] 升级流程已更新 Env scripts、packages index 和 SDK。 - [ ] EBuild 工程包含 `SConstruct`、`SConscript`、`Kconfig`、 `proj_config.py` 和 hello 程序。 diff --git a/rtthread-env/references/install-upgrade.md b/rtthread-env/references/install-upgrade.md index f90cf80..808cb6a 100644 --- a/rtthread-env/references/install-upgrade.md +++ b/rtthread-env/references/install-upgrade.md @@ -2,7 +2,8 @@ ## Network Setup -Before installing or upgrading Env, use the bundled network script: +Before downloading, installing, or upgrading Env, use the bundled network +script: ```sh source rtthread-env/scripts/env-network.sh @@ -19,9 +20,18 @@ The script sets: - `PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn` in China mainland. If the user already knows the machine is in China mainland, set -`RTT_ENV_REGION=CN` before loading the script. +`RTT_ENV_REGION=CN` before loading the script. Use `RTT_ENV_MIRROR` to select +the Git hosting mirror. The Windows installer and first-activation script may +select their own pip index; do not rewrite a downloaded official installer to +change it. -## Linux / WSL Install +All official installers eventually run `touch_env.sh` or `touch_env.ps1`. If +`~/.env` already exists, that script asks whether to delete and recreate the +whole directory. Do not answer yes automatically. Treat an existing Env as an +upgrade unless the user explicitly approves recreation after preserving local +packages and local changes. + +## Ubuntu / WSL Install Default install means latest Env: download the installer from the current `RT-Thread/env` default install entry, or its Gitee mirror. Do not pin an old @@ -55,6 +65,55 @@ The official script installs Python3, pip, gcc, git, ncurses dependencies, └── scripts/ ``` +Use this installer only for Ubuntu or an Ubuntu-based WSL distribution. Select +the matching official installer for other supported hosts. + +## macOS / Arch Linux / openSUSE Install + +Select the installer that matches the host: + +| Host | Installer | Behavior | +| --- | --- | --- | +| macOS | `install_macos.sh` | Updates Homebrew and installs build tools. | +| Arch Linux | `install_arch.sh` | Offers AUR or manual package setup. | +| openSUSE | `install_suse.sh` | Uses `zypper` for dependencies. | + +For Arch Linux or openSUSE: + +```sh +source rtthread-env/scripts/env-network.sh +installer=install_arch.sh # Use install_suse.sh on openSUSE. +if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then + url="https://gitee.com/RT-Thread-Mirror/env/raw/master/$installer" +else + url="https://raw.githubusercontent.com/RT-Thread/env/master/$installer" +fi +wget "$url" -O "$installer" +chmod 755 "$installer" +./"$installer" $RTT_ENV_MIRROR +rm "$installer" +``` + +For macOS, use `curl` because it is available by default: + +```sh +source rtthread-env/scripts/env-network.sh +installer=install_macos.sh +if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then + url="https://gitee.com/RT-Thread-Mirror/env/raw/master/$installer" +else + url="https://raw.githubusercontent.com/RT-Thread/env/master/$installer" +fi +curl -fL "$url" -o "$installer" +chmod 755 "$installer" +./"$installer" $RTT_ENV_MIRROR +rm "$installer" +``` + +Before running the macOS installer, tell the user that it executes +`brew update` and `brew upgrade` and may install a toolchain. Do not run the +Arch installer unattended because it contains installation prompts. + ## Windows PowerShell Install Run PowerShell as administrator for `set-executionpolicy remotesigned`. @@ -69,22 +128,32 @@ if ($script:RTT_ENV_MIRROR -eq "--gitee") { $url = "https://raw.githubusercontent.com/RT-Thread/env/master/install_windows.ps1" } wget $url -O install_windows.ps1 +set-executionpolicy remotesigned if ($script:RTT_ENV_MIRROR -eq "--gitee") { - $content = Get-Content install_windows.ps1 - $content = $content -replace "http://mirrors.aliyun.com/pypi/simple", ` - "https://pypi.tuna.tsinghua.edu.cn/simple" - $content = $content -replace "mirrors.aliyun.com", ` - "pypi.tuna.tsinghua.edu.cn" - $content | Set-Content install_windows.ps1 + .\install_windows.ps1 --gitee +} else { + .\install_windows.ps1 } -set-executionpolicy remotesigned -.\install_windows.ps1 $script:RTT_ENV_MIRROR ``` -## macOS / Other Linux Manual Install +The installer may install Python or Git and ask the user to close PowerShell +and rerun it. Follow that instruction before continuing. It also supports an +optional second positional argument, `-y`, which skips only the final +completion pause: + +```powershell +.\install_windows.ps1 --gitee -y # China mainland +.\install_windows.ps1 "" -y # Other regions +``` -Manual install clones the current default branch with `--depth=1`, so Env, -packages index, and SDK are installed at their latest default-branch versions. +The `-y` option does not answer the prompt for an existing `~/.env`; never use +it as permission to replace an existing installation. + +## Other Linux Manual Install + +Use manual installation only when the host has no matching official installer. +It clones the current default branch with `--depth=1`, so Env, packages index, +and SDK are installed at their latest default-branch versions. ```sh source rtthread-env/scripts/env-network.sh @@ -173,9 +242,25 @@ source ~/.env/env.sh Windows: ```powershell -~\.env\env.ps1 +& "$HOME\.env\env.ps1" ``` +On first activation, the current `env.ps1` performs these steps: + +1. Create `~/.env/.venv` and activate it. +2. Query `https://ipinfo.io/json` with a short timeout. +3. Use the Tsinghua PyPI mirror for a China mainland IP, otherwise use the + default PyPI index. +4. Upgrade pip, then install `~/.env/tools/scripts` and its dependencies into + the venv. + +Do not create `~/.env/.venv` before first activation: its presence causes +`env.ps1` to skip package installation. If first activation fails while +installing packages, verify that the venv contains no user data, remove only +the incomplete `~/.env/.venv`, change both pip index URLs in +`~/.env/env.ps1` to a reachable trusted mirror if necessary, and activate +again. Do not delete the whole `~/.env` directory just to retry venv setup. + Persistent PowerShell activation: ```powershell From 1022b39761354589cbf8f0205391b02164a18dcc Mon Sep 17 00:00:00 2001 From: bernard Date: Sat, 18 Jul 2026 10:35:08 +0800 Subject: [PATCH 3/4] rtthread-env: clarify --gitee mirror semantics Align installation guidance and mirror helpers with the current Env scripts. Keep --gitee scoped to installer and Git clone selection without overriding pip configuration. --- rtthread-env/SKILL.md | 36 ++++--- rtthread-env/references/install-upgrade.md | 110 ++++++++++++++++----- rtthread-env/scripts/env-network.ps1 | 22 +---- rtthread-env/scripts/env-network.sh | 20 +--- 4 files changed, 117 insertions(+), 71 deletions(-) diff --git a/rtthread-env/SKILL.md b/rtthread-env/SKILL.md index d135ebb..066cb0a 100644 --- a/rtthread-env/SKILL.md +++ b/rtthread-env/SKILL.md @@ -13,8 +13,9 @@ description: Use when installing, upgrading, activating, or troubleshooting RT-T ## Env Version Policy -- 安装 Env 默认使用最新版本:取 `RT-Thread/env` git 仓库当前默认分支, - 中国大陆网络取 Gitee mirror 当前默认分支。 +- 安装 Env 默认使用最新版本:取 `RT-Thread/env` git 仓库当前默认分支。 + 中国大陆按当前官方 README 下载 Gitee installer,并把 `--gitee` 作为安装 + 脚本的第一个参数。 - 默认使用 Env v2.0 风格流程:Python 3、`kconfiglib` 和 Env scripts。 - 只有用户明确要求维护旧 RT-Thread 工程或旧 Env 环境时,才选择 Env v1.5.x;此时不要安装或保留 `kconfiglib`,因为 v1.5.x 与 @@ -27,34 +28,38 @@ description: Use when installing, upgrading, activating, or troubleshooting RT-T 执行本 skill 前先确认: - 主机平台:Linux、Windows PowerShell、WSL、macOS 或容器。 -- 网络位置:安装 Env 前先检测公网 IP;中国大陆下载 Env 时使用 `--gitee`。 - Windows 首次激活会再次检测公网 IP,并自动选择清华或默认 PyPI 源。 +- 网络位置:安装 Env 前先检测公网 IP;中国大陆使用 Gitee installer,并把 + `--gitee` 作为第一个安装参数。该参数不控制 Windows 首次激活的 PyPI 源。 - RT-Thread 版本和目标工程路径。 - 工具链类型与路径,如 `arm-none-eabi-gcc` 的 `bin` 目录。 - 是否允许修改 shell profile、PowerShell profile 或 `~/.env`。 ## File Map +- 安装行为基准:先读取 `~/.env/tools/scripts/README.md`、目标平台的 + `install_*`、`touch_env.*`,以及 Windows 的 `env.ps1`。 - 安装、升级、激活 Env:读取 [references/install-upgrade.md](references/install-upgrade.md)。 -- Linux / WSL / macOS 网络检测和 pip 包装:按需使用 +- Linux / WSL / macOS 安装镜像检测:按需使用 [scripts/env-network.sh](scripts/env-network.sh)。 -- Windows PowerShell 网络检测和 pip 包装:按需使用 +- Windows PowerShell 安装镜像检测:按需使用 [scripts/env-network.ps1](scripts/env-network.ps1)。 - EBuild 工程、组件脚本、级联 `SConscript` 模板:读取 [references/ebuild.md](references/ebuild.md)。 ## Workflow -1. 默认安装最新 Env git 仓库版本;仅在用户明确要求旧 Env 时切到 v1.5.x。 -2. 安装或升级 Env 前,先运行对应平台的网络脚本;中国大陆机器下载 Env - 时必须使用 `--gitee`,不要现场改写下载的官方安装脚本。 -3. Ubuntu / WSL、Windows、macOS、Arch Linux 和 openSUSE 优先使用对应的 +1. 安装前检查 `~/.env/tools/scripts` 当前提交,并复核 README、目标安装脚本、 + `touch_env.*` 和 Windows `env.ps1` 中的镜像行为。 +2. 默认安装最新 Env git 仓库版本;仅在用户明确要求旧 Env 时切到 v1.5.x。 +3. 安装 Env 前运行对应平台的网络脚本;中国大陆按当前官方 README 下载 + Gitee installer,并把 `--gitee` 作为第一个参数。其他地区不传该参数。 +4. Ubuntu / WSL、Windows、macOS、Arch Linux 和 openSUSE 优先使用对应的 官方安装脚本;无官方脚本的平台按手动目录结构安装。 -4. 升级 Env 时同时更新 `~/.env/tools/scripts`、`~/.env/packages/packages` +5. 升级 Env 时同时更新 `~/.env/tools/scripts`、`~/.env/packages/packages` 和 `~/.env/packages/sdk`,并用 `git pull --ff-only` 避免覆盖本地修改。 -5. 激活 Env 后检查 `scons`、`pkgs`、Python 依赖和 packages index。 -6. 创建 EBuild 工程或脚本时,先读取 `references/ebuild.md`,再生成文件。 +6. 激活 Env 后检查 `scons`、`pkgs`、Python 依赖和 packages index。 +7. 创建 EBuild 工程或脚本时,先读取 `references/ebuild.md`,再生成文件。 ## Env Directory @@ -91,7 +96,10 @@ Windows 首次运行 `~\.env\env.ps1` 时会创建 `~\.env\.venv`、升级 pip ## Done Checklist - [ ] 已默认选择最新 Env git 仓库版本,或按用户要求切到旧 Env。 -- [ ] 安装或升级前已运行网络检测;中国大陆下载 Env 时使用 `--gitee`。 +- [ ] 已根据 `~/.env/tools/scripts` 当前提交复核安装和镜像语义。 +- [ ] 安装前已运行镜像检测;中国大陆使用 Gitee installer 和 `--gitee`, + 其他地区使用 GitHub installer 且不传该参数。 +- [ ] 未把 `--gitee` 解释为统一 PyPI 开关;Windows 首次激活独立选择 PyPI。 - [ ] 未改写下载的官方安装脚本;需要更换 PyPI 源时修改用户侧激活配置。 - [ ] Env scripts 位于 `~/.env/tools/scripts` 并可执行。 - [ ] packages index 位于 `~/.env/packages/packages`,SDK 位于 diff --git a/rtthread-env/references/install-upgrade.md b/rtthread-env/references/install-upgrade.md index 808cb6a..5b13a34 100644 --- a/rtthread-env/references/install-upgrade.md +++ b/rtthread-env/references/install-upgrade.md @@ -1,9 +1,30 @@ # Env Install and Upgrade -## Network Setup +## Source Verification -Before downloading, installing, or upgrading Env, use the bundled network -script: +Treat the current local Env checkout as the installation source of truth. +Before giving installation commands, inspect its revision and all mirror +branches without modifying that checkout: + +```sh +git -C ~/.env/tools/scripts rev-parse HEAD origin/master +git -C ~/.env/tools/scripts status --short -- \ + README.md 'install_*' 'touch_env.*' env.ps1 +rg -n -- '--gitee|PIP_SOURCE|ipinfo' \ + ~/.env/tools/scripts/README.md \ + ~/.env/tools/scripts/install_* \ + ~/.env/tools/scripts/touch_env.* \ + ~/.env/tools/scripts/env.ps1 +``` + +If `HEAD` differs from `origin/master` or a relevant tracked file is modified, +determine which revision the user wants before using its behavior as current. +Keep the semantic summary below aligned with the inspected scripts. + +## Installer Mirror Selection + +Before downloading or installing Env, use the bundled helper to select the +installer and Git clone mirror: ```sh source rtthread-env/scripts/env-network.sh @@ -13,17 +34,47 @@ source rtthread-env/scripts/env-network.sh . .\rtthread-env\scripts\env-network.ps1 ``` -The script sets: +The helper sets only `RTT_ENV_MIRROR`: - `RTT_ENV_MIRROR="--gitee"` when public IP is in China mainland. -- `PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple` in China mainland. -- `PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn` in China mainland. +- `RTT_ENV_MIRROR=""` for other regions or when detection fails. + +Override region detection when the location is already known: + +```sh +export RTT_ENV_REGION=CN +source rtthread-env/scripts/env-network.sh +``` + +```powershell +$env:RTT_ENV_REGION = "CN" +. .\rtthread-env\scripts\env-network.ps1 +``` + +These helpers do not set `PIP_INDEX_URL`, install Python packages, or reproduce +the Windows activation script's PyPI selection. -If the user already knows the machine is in China mainland, set -`RTT_ENV_REGION=CN` before loading the script. Use `RTT_ENV_MIRROR` to select -the Git hosting mirror. The Windows installer and first-activation script may -select their own pip index; do not rewrite a downloaded official installer to -change it. +## `--gitee` Semantics + +The current Env scripts treat `--gitee` as a positional installer argument, +not as a global Env setting. It is recognized only as the first argument. + +- On Ubuntu, macOS, Arch Linux, and openSUSE, `--gitee` selects the Gitee copy + of `touch_env.sh`. The called `touch_env.sh --gitee` then clones packages, + SDK, and Env scripts from Gitee. It does not select a pip index. +- On Windows, `install_windows.ps1 --gitee` additionally selects the npm mirror + fallback for Git for Windows and the Aliyun pip index used by that installer. + It then runs `touch_env.ps1 --gitee` to clone the three Git repositories from + Gitee. +- Windows `~/.env/env.ps1` does not read `--gitee`. On first activation it + detects the public IP independently and selects Tsinghua or default PyPI for + the venv installation. +- Upgrade commands do not accept `--gitee`; each `git pull` uses the repository's + configured remote. + +These statements were verified against local Env `master` at commit +`65f6991045d3d0c030080ba5b9489cc91f63e893`. Do not infer a different meaning +for `--gitee`, and do not rewrite a downloaded official installer. All official installers eventually run `touch_env.sh` or `touch_env.ps1`. If `~/.env` already exists, that script asks whether to delete and recreate the @@ -46,7 +97,11 @@ else fi wget "$url" -O install_ubuntu.sh chmod 755 install_ubuntu.sh -./install_ubuntu.sh $RTT_ENV_MIRROR +if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then + ./install_ubuntu.sh --gitee +else + ./install_ubuntu.sh +fi rm install_ubuntu.sh ``` @@ -90,7 +145,11 @@ else fi wget "$url" -O "$installer" chmod 755 "$installer" -./"$installer" $RTT_ENV_MIRROR +if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then + ./"$installer" --gitee +else + ./"$installer" +fi rm "$installer" ``` @@ -106,7 +165,11 @@ else fi curl -fL "$url" -o "$installer" chmod 755 "$installer" -./"$installer" $RTT_ENV_MIRROR +if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then + ./"$installer" --gitee +else + ./"$installer" +fi rm "$installer" ``` @@ -137,9 +200,9 @@ if ($script:RTT_ENV_MIRROR -eq "--gitee") { ``` The installer may install Python or Git and ask the user to close PowerShell -and rerun it. Follow that instruction before continuing. It also supports an -optional second positional argument, `-y`, which skips only the final -completion pause: +and rerun it. Follow that instruction before continuing. It also supports +`-y` only as the second positional argument; it skips only the final completion +pause: ```powershell .\install_windows.ps1 --gitee -y # China mainland @@ -157,7 +220,7 @@ and SDK are installed at their latest default-branch versions. ```sh source rtthread-env/scripts/env-network.sh -pip_install --user -U pip scons requests tqdm kconfiglib pyyaml +python3 -m pip install --user -U pip scons requests tqdm kconfiglib pyyaml mkdir -p ~/.env/local_pkgs ~/.env/packages ~/.env/tools if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then pkg_url="https://gitee.com/RT-Thread-Mirror/packages.git" @@ -184,7 +247,6 @@ Update Env scripts, packages index, and SDK. Stop and report if a repo has local changes. ```sh -source rtthread-env/scripts/env-network.sh for repo in "$HOME/.env/tools/scripts" \ "$HOME/.env/packages/packages" \ "$HOME/.env/packages/sdk"; do @@ -192,11 +254,10 @@ for repo in "$HOME/.env/tools/scripts" \ git -C "$repo" status --short git -C "$repo" pull --ff-only done -pip_install --user -U scons requests tqdm kconfiglib pyyaml +python3 -m pip install --user -U scons requests tqdm kconfiglib pyyaml ``` ```powershell -. .\rtthread-env\scripts\env-network.ps1 $repos = @( "$HOME\.env\tools\scripts", "$HOME\.env\packages\packages", @@ -208,7 +269,7 @@ foreach ($repo in $repos) { git -C $repo pull --ff-only } } -Invoke-PipInstall -U scons requests tqdm kconfiglib pyyaml +python -m pip install -U scons requests tqdm kconfiglib pyyaml ``` After upgrading, reactivate Env and run `scons --menuconfig` or @@ -231,11 +292,10 @@ printf '%s\n' 'source ~/.env/env.sh' >> ~/.bashrc Python venv activation when Env scripts need it: ```sh -source rtthread-env/scripts/env-network.sh python3 -m venv ~/.env/.venv . ~/.env/.venv/bin/activate -pip_install -U pip -pip_install ~/.env/tools/scripts +python3 -m pip install -U pip +python3 -m pip install ~/.env/tools/scripts source ~/.env/env.sh ``` diff --git a/rtthread-env/scripts/env-network.ps1 b/rtthread-env/scripts/env-network.ps1 index 670d094..428f759 100755 --- a/rtthread-env/scripts/env-network.ps1 +++ b/rtthread-env/scripts/env-network.ps1 @@ -9,33 +9,21 @@ function Set-EnvNetwork { } } + # This value is only the official installer's first argument, not a pip setting. if ($country -eq "CN") { $script:RTT_ENV_MIRROR = "--gitee" - $script:PIP_INDEX_URL = "https://pypi.tuna.tsinghua.edu.cn/simple" - $script:PIP_TRUSTED_HOST = "pypi.tuna.tsinghua.edu.cn" } else { $script:RTT_ENV_MIRROR = "" - $script:PIP_INDEX_URL = "" - $script:PIP_TRUSTED_HOST = "" } - $env:PIP_INDEX_URL = $script:PIP_INDEX_URL - $env:PIP_TRUSTED_HOST = $script:PIP_TRUSTED_HOST - if (-not $country) { $country = "unknown" } - Write-Host "RT-Thread Env region: $country" -} - -function Invoke-PipInstall { - param([Parameter(ValueFromRemainingArguments = $true)][string[]]$Args) - if ($script:PIP_INDEX_URL) { - python -m pip install -i $script:PIP_INDEX_URL ` - --trusted-host $script:PIP_TRUSTED_HOST @Args - } else { - python -m pip install @Args + $mirror = "github" + if ($script:RTT_ENV_MIRROR) { + $mirror = "gitee" } + Write-Host "RT-Thread Env region: $country, installer mirror: $mirror" } Set-EnvNetwork diff --git a/rtthread-env/scripts/env-network.sh b/rtthread-env/scripts/env-network.sh index 4382399..acd9f0d 100755 --- a/rtthread-env/scripts/env-network.sh +++ b/rtthread-env/scripts/env-network.sh @@ -14,27 +14,17 @@ except Exception: PY )}" + # This value is only the official installer's first argument, not a pip setting. if [ "$country" = "CN" ]; then RTT_ENV_MIRROR="--gitee" - PIP_INDEX_URL="https://pypi.tuna.tsinghua.edu.cn/simple" - PIP_TRUSTED_HOST="pypi.tuna.tsinghua.edu.cn" + mirror="gitee" else RTT_ENV_MIRROR="" - PIP_INDEX_URL="" - PIP_TRUSTED_HOST="" + mirror="github" fi - echo "RT-Thread Env region: ${country:-unknown}" - export RTT_ENV_MIRROR PIP_INDEX_URL PIP_TRUSTED_HOST -} - -pip_install() { - if [ -n "$PIP_INDEX_URL" ]; then - python3 -m pip install -i "$PIP_INDEX_URL" \ - --trusted-host "$PIP_TRUSTED_HOST" "$@" - else - python3 -m pip install "$@" - fi + echo "RT-Thread Env region: ${country:-unknown}, installer mirror: $mirror" + export RTT_ENV_MIRROR } detect_env_region From 219e91fd5cdb12f9a3e8e49ba3bb307a2fe891ae Mon Sep 17 00:00:00 2001 From: bernard Date: Sat, 18 Jul 2026 11:14:23 +0800 Subject: [PATCH 4/4] rtthread-env: align installer workflow with upstream Use the README-defined bootstrap URLs and let official installers select follow-up mirrors automatically. Remove obsolete network helpers and legacy --gitee argument guidance. --- rtthread-env/SKILL.md | 30 ++-- rtthread-env/references/install-upgrade.md | 192 ++++++++------------- rtthread-env/scripts/env-network.ps1 | 29 ---- rtthread-env/scripts/env-network.sh | 30 ---- 4 files changed, 82 insertions(+), 199 deletions(-) delete mode 100755 rtthread-env/scripts/env-network.ps1 delete mode 100755 rtthread-env/scripts/env-network.sh diff --git a/rtthread-env/SKILL.md b/rtthread-env/SKILL.md index 066cb0a..557c5c3 100644 --- a/rtthread-env/SKILL.md +++ b/rtthread-env/SKILL.md @@ -14,8 +14,8 @@ description: Use when installing, upgrading, activating, or troubleshooting RT-T ## Env Version Policy - 安装 Env 默认使用最新版本:取 `RT-Thread/env` git 仓库当前默认分支。 - 中国大陆按当前官方 README 下载 Gitee installer,并把 `--gitee` 作为安装 - 脚本的第一个参数。 + Linux 中国大陆网络按当前官方 README 从 Gitee 下载 installer,其他地区从 + GitHub 下载;installer 会自行选择后续仓库镜像,执行时不传镜像参数。 - 默认使用 Env v2.0 风格流程:Python 3、`kconfiglib` 和 Env scripts。 - 只有用户明确要求维护旧 RT-Thread 工程或旧 Env 环境时,才选择 Env v1.5.x;此时不要安装或保留 `kconfiglib`,因为 v1.5.x 与 @@ -28,32 +28,29 @@ description: Use when installing, upgrading, activating, or troubleshooting RT-T 执行本 skill 前先确认: - 主机平台:Linux、Windows PowerShell、WSL、macOS 或容器。 -- 网络位置:安装 Env 前先检测公网 IP;中国大陆使用 Gitee installer,并把 - `--gitee` 作为第一个安装参数。该参数不控制 Windows 首次激活的 PyPI 源。 +- 网络位置:Linux 中国大陆网络使用 Gitee installer,其他地区使用 GitHub + installer;Windows 按官方 README 从 GitHub 下载安装脚本。 - RT-Thread 版本和目标工程路径。 - 工具链类型与路径,如 `arm-none-eabi-gcc` 的 `bin` 目录。 - 是否允许修改 shell profile、PowerShell profile 或 `~/.env`。 ## File Map -- 安装行为基准:先读取 `~/.env/tools/scripts/README.md`、目标平台的 +- 安装行为基准:先读取当前 `RT-Thread/env` 默认分支的 `README.md`、目标平台 `install_*`、`touch_env.*`,以及 Windows 的 `env.ps1`。 - 安装、升级、激活 Env:读取 [references/install-upgrade.md](references/install-upgrade.md)。 -- Linux / WSL / macOS 安装镜像检测:按需使用 - [scripts/env-network.sh](scripts/env-network.sh)。 -- Windows PowerShell 安装镜像检测:按需使用 - [scripts/env-network.ps1](scripts/env-network.ps1)。 - EBuild 工程、组件脚本、级联 `SConscript` 模板:读取 [references/ebuild.md](references/ebuild.md)。 ## Workflow -1. 安装前检查 `~/.env/tools/scripts` 当前提交,并复核 README、目标安装脚本、 +1. 安装前复核当前 `RT-Thread/env` 默认分支的 README、目标安装脚本、 `touch_env.*` 和 Windows `env.ps1` 中的镜像行为。 2. 默认安装最新 Env git 仓库版本;仅在用户明确要求旧 Env 时切到 v1.5.x。 -3. 安装 Env 前运行对应平台的网络脚本;中国大陆按当前官方 README 下载 - Gitee installer,并把 `--gitee` 作为第一个参数。其他地区不传该参数。 +3. Linux 按用户网络位置选择 README 给出的 Gitee 或 GitHub installer 下载 + 地址;Windows 使用 README 给出的 GitHub 地址。直接运行 installer,不传 + `--gitee` 等镜像参数,后续仓库镜像由 installer 自动选择。 4. Ubuntu / WSL、Windows、macOS、Arch Linux 和 openSUSE 优先使用对应的 官方安装脚本;无官方脚本的平台按手动目录结构安装。 5. 升级 Env 时同时更新 `~/.env/tools/scripts`、`~/.env/packages/packages` @@ -96,10 +93,11 @@ Windows 首次运行 `~\.env\env.ps1` 时会创建 `~\.env\.venv`、升级 pip ## Done Checklist - [ ] 已默认选择最新 Env git 仓库版本,或按用户要求切到旧 Env。 -- [ ] 已根据 `~/.env/tools/scripts` 当前提交复核安装和镜像语义。 -- [ ] 安装前已运行镜像检测;中国大陆使用 Gitee installer 和 `--gitee`, - 其他地区使用 GitHub installer 且不传该参数。 -- [ ] 未把 `--gitee` 解释为统一 PyPI 开关;Windows 首次激活独立选择 PyPI。 +- [ ] 已根据当前 `RT-Thread/env` 默认分支复核安装和镜像语义。 +- [ ] Linux 已按网络位置选择 Gitee 或 GitHub installer;Windows 已使用 + README 给出的 GitHub installer。 +- [ ] installer 已无镜像参数运行,并自行选择后续仓库镜像。 +- [ ] Windows 首次激活独立选择 PyPI。 - [ ] 未改写下载的官方安装脚本;需要更换 PyPI 源时修改用户侧激活配置。 - [ ] Env scripts 位于 `~/.env/tools/scripts` 并可执行。 - [ ] packages index 位于 `~/.env/packages/packages`,SDK 位于 diff --git a/rtthread-env/references/install-upgrade.md b/rtthread-env/references/install-upgrade.md index 5b13a34..ee6e395 100644 --- a/rtthread-env/references/install-upgrade.md +++ b/rtthread-env/references/install-upgrade.md @@ -2,109 +2,73 @@ ## Source Verification -Treat the current local Env checkout as the installation source of truth. -Before giving installation commands, inspect its revision and all mirror -branches without modifying that checkout: +Treat the current `RT-Thread/env` default-branch README as the installation +source of truth. When a local checkout is available, inspect it without +modifying it before giving installation commands: ```sh -git -C ~/.env/tools/scripts rev-parse HEAD origin/master -git -C ~/.env/tools/scripts status --short -- \ +env_repo=/path/to/RT-Thread/env +git -C "$env_repo" rev-parse HEAD origin/master +git -C "$env_repo" status --short -- \ README.md 'install_*' 'touch_env.*' env.ps1 -rg -n -- '--gitee|PIP_SOURCE|ipinfo' \ - ~/.env/tools/scripts/README.md \ - ~/.env/tools/scripts/install_* \ - ~/.env/tools/scripts/touch_env.* \ - ~/.env/tools/scripts/env.ps1 +rg -n -- 'gitee|github|PIP_SOURCE|ipinfo|set-url' \ + "$env_repo/README.md" \ + "$env_repo"/install_* \ + "$env_repo"/touch_env.* \ + "$env_repo/env.ps1" ``` If `HEAD` differs from `origin/master` or a relevant tracked file is modified, determine which revision the user wants before using its behavior as current. Keep the semantic summary below aligned with the inspected scripts. -## Installer Mirror Selection +## Installer Download Selection -Before downloading or installing Env, use the bundled helper to select the -installer and Git clone mirror: +The user's network location selects only where the installer itself is +downloaded: -```sh -source rtthread-env/scripts/env-network.sh -``` - -```powershell -. .\rtthread-env\scripts\env-network.ps1 -``` - -The helper sets only `RTT_ENV_MIRROR`: - -- `RTT_ENV_MIRROR="--gitee"` when public IP is in China mainland. -- `RTT_ENV_MIRROR=""` for other regions or when detection fails. - -Override region detection when the location is already known: - -```sh -export RTT_ENV_REGION=CN -source rtthread-env/scripts/env-network.sh -``` - -```powershell -$env:RTT_ENV_REGION = "CN" -. .\rtthread-env\scripts\env-network.ps1 -``` - -These helpers do not set `PIP_INDEX_URL`, install Python packages, or reproduce -the Windows activation script's PyPI selection. +- Linux in China mainland: use the Gitee installer URL listed by the README. +- Linux in other regions: use the GitHub installer URL listed by the README. +- Windows: use the GitHub installer URL listed by the README. -## `--gitee` Semantics +Run the downloaded installer without `--gitee` or any other mirror argument. +The current installer and `touch_env` scripts detect the network region and +select the mirror for subsequent downloads. After cloning Env, packages, and +the SDK, `touch_env` sets their `origin` remotes to GitHub. -The current Env scripts treat `--gitee` as a positional installer argument, -not as a global Env setting. It is recognized only as the first argument. - -- On Ubuntu, macOS, Arch Linux, and openSUSE, `--gitee` selects the Gitee copy - of `touch_env.sh`. The called `touch_env.sh --gitee` then clones packages, - SDK, and Env scripts from Gitee. It does not select a pip index. -- On Windows, `install_windows.ps1 --gitee` additionally selects the npm mirror - fallback for Git for Windows and the Aliyun pip index used by that installer. - It then runs `touch_env.ps1 --gitee` to clone the three Git repositories from - Gitee. -- Windows `~/.env/env.ps1` does not read `--gitee`. On first activation it - detects the public IP independently and selects Tsinghua or default PyPI for - the venv installation. -- Upgrade commands do not accept `--gitee`; each `git pull` uses the repository's - configured remote. - -These statements were verified against local Env `master` at commit -`65f6991045d3d0c030080ba5b9489cc91f63e893`. Do not infer a different meaning -for `--gitee`, and do not rewrite a downloaded official installer. +Linux installers fall back to GitHub when region detection fails in a +non-interactive session. In an interactive session, Ubuntu, Arch Linux, and +openSUSE installers ask whether to use Gitee. Windows falls back to GitHub when +region detection fails. All official installers eventually run `touch_env.sh` or `touch_env.ps1`. If -`~/.env` already exists, that script asks whether to delete and recreate the +`~/.env` already exists, `touch_env` asks whether to delete and recreate the whole directory. Do not answer yes automatically. Treat an existing Env as an upgrade unless the user explicitly approves recreation after preserving local packages and local changes. ## Ubuntu / WSL Install -Default install means latest Env: download the installer from the current -`RT-Thread/env` default install entry, or its Gitee mirror. Do not pin an old -Env branch unless the user explicitly asks for legacy Env. +Default install means latest Env. Choose one installer download command based +on the user's network location. Do not pin an old Env branch unless the user +explicitly asks for legacy Env. ```sh -source rtthread-env/scripts/env-network.sh -if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then - url="https://gitee.com/RT-Thread-Mirror/env/raw/master/install_ubuntu.sh" -else - url="https://raw.githubusercontent.com/RT-Thread/env/master/install_ubuntu.sh" -fi -wget "$url" -O install_ubuntu.sh -chmod 755 install_ubuntu.sh -if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then - ./install_ubuntu.sh --gitee -else - ./install_ubuntu.sh -fi +# China mainland network: +wget https://gitee.com/RT-Thread-Mirror/env/raw/master/install_ubuntu.sh + +# Other regions: +wget https://raw.githubusercontent.com/RT-Thread/env/master/install_ubuntu.sh + +chmod 777 install_ubuntu.sh +./install_ubuntu.sh rm install_ubuntu.sh ``` +Run only one of the two `wget` commands. The installer automatically chooses +the mirror used to download `touch_env.sh`; `touch_env.sh` independently +chooses the clone mirror. + The official script installs Python3, pip, gcc, git, ncurses dependencies, `scons`, `requests`, `tqdm`, `kconfiglib`, `pyyaml`, and creates: @@ -136,40 +100,26 @@ Select the installer that matches the host: For Arch Linux or openSUSE: ```sh -source rtthread-env/scripts/env-network.sh installer=install_arch.sh # Use install_suse.sh on openSUSE. -if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then - url="https://gitee.com/RT-Thread-Mirror/env/raw/master/$installer" -else - url="https://raw.githubusercontent.com/RT-Thread/env/master/$installer" -fi +# Use Gitee in China mainland; use GitHub in other regions. +url="https://raw.githubusercontent.com/RT-Thread/env/master/$installer" +# url="https://gitee.com/RT-Thread-Mirror/env/raw/master/$installer" wget "$url" -O "$installer" -chmod 755 "$installer" -if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then - ./"$installer" --gitee -else - ./"$installer" -fi +chmod 777 "$installer" +./"$installer" rm "$installer" ``` For macOS, use `curl` because it is available by default: ```sh -source rtthread-env/scripts/env-network.sh installer=install_macos.sh -if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then - url="https://gitee.com/RT-Thread-Mirror/env/raw/master/$installer" -else - url="https://raw.githubusercontent.com/RT-Thread/env/master/$installer" -fi +# Use Gitee in China mainland; use GitHub in other regions. +url="https://raw.githubusercontent.com/RT-Thread/env/master/$installer" +# url="https://gitee.com/RT-Thread-Mirror/env/raw/master/$installer" curl -fL "$url" -o "$installer" -chmod 755 "$installer" -if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then - ./"$installer" --gitee -else - ./"$installer" -fi +chmod 777 "$installer" +./"$installer" rm "$installer" ``` @@ -184,33 +134,21 @@ Afterward, normal PowerShell is enough. Default install uses the installer from the current default branch. ```powershell -. .\rtthread-env\scripts\env-network.ps1 -if ($script:RTT_ENV_MIRROR -eq "--gitee") { - $url = "https://gitee.com/RT-Thread-Mirror/env/raw/master/install_windows.ps1" -} else { - $url = "https://raw.githubusercontent.com/RT-Thread/env/master/install_windows.ps1" -} +$url = "https://raw.githubusercontent.com/RT-Thread/env/master/install_windows.ps1" wget $url -O install_windows.ps1 set-executionpolicy remotesigned -if ($script:RTT_ENV_MIRROR -eq "--gitee") { - .\install_windows.ps1 --gitee -} else { - .\install_windows.ps1 -} +.\install_windows.ps1 ``` +The installer detects the region itself and selects its Git, pip, `touch_env`, +packages, and SDK download mirrors. Do not pass a mirror argument. The official +README also warns that antivirus software may terminate the installation; any +temporary security-policy change must follow the user's organization policy. + The installer may install Python or Git and ask the user to close PowerShell and rerun it. Follow that instruction before continuing. It also supports -`-y` only as the second positional argument; it skips only the final completion -pause: - -```powershell -.\install_windows.ps1 --gitee -y # China mainland -.\install_windows.ps1 "" -y # Other regions -``` - -The `-y` option does not answer the prompt for an existing `~/.env`; never use -it as permission to replace an existing installation. +an internal unattended completion mode that is not part of the documented +README installation interface; do not rely on it. ## Other Linux Manual Install @@ -219,10 +157,10 @@ It clones the current default branch with `--depth=1`, so Env, packages index, and SDK are installed at their latest default-branch versions. ```sh -source rtthread-env/scripts/env-network.sh python3 -m pip install --user -U pip scons requests tqdm kconfiglib pyyaml mkdir -p ~/.env/local_pkgs ~/.env/packages ~/.env/tools -if [ "$RTT_ENV_MIRROR" = "--gitee" ]; then +download_site=github # Use gitee in China mainland. +if [ "$download_site" = gitee ]; then pkg_url="https://gitee.com/RT-Thread-Mirror/packages.git" sdk_url="https://gitee.com/RT-Thread-Mirror/sdk.git" env_url="https://gitee.com/RT-Thread-Mirror/env.git" @@ -234,6 +172,12 @@ fi git clone "$pkg_url" ~/.env/packages/packages --depth=1 git clone "$sdk_url" ~/.env/packages/sdk --depth=1 git clone "$env_url" ~/.env/tools/scripts --depth=1 +git -C ~/.env/packages/packages remote set-url origin \ + https://github.com/RT-Thread/packages.git +git -C ~/.env/packages/sdk remote set-url origin \ + https://github.com/RT-Thread/sdk.git +git -C ~/.env/tools/scripts remote set-url origin \ + https://github.com/RT-Thread/env.git printf '%s\n' 'source "$PKGS_DIR/packages/Kconfig"' > ~/.env/packages/Kconfig user_base="$(python3 -m site --user-base)" printf '%s\n' \ diff --git a/rtthread-env/scripts/env-network.ps1 b/rtthread-env/scripts/env-network.ps1 deleted file mode 100755 index 428f759..0000000 --- a/rtthread-env/scripts/env-network.ps1 +++ /dev/null @@ -1,29 +0,0 @@ -function Set-EnvNetwork { - $country = $env:RTT_ENV_REGION - if (-not $country) { - try { - $country = (Invoke-RestMethod -Uri "https://ipinfo.io/json" ` - -UseBasicParsing -TimeoutSec 5).country - } catch { - $country = "" - } - } - - # This value is only the official installer's first argument, not a pip setting. - if ($country -eq "CN") { - $script:RTT_ENV_MIRROR = "--gitee" - } else { - $script:RTT_ENV_MIRROR = "" - } - - if (-not $country) { - $country = "unknown" - } - $mirror = "github" - if ($script:RTT_ENV_MIRROR) { - $mirror = "gitee" - } - Write-Host "RT-Thread Env region: $country, installer mirror: $mirror" -} - -Set-EnvNetwork diff --git a/rtthread-env/scripts/env-network.sh b/rtthread-env/scripts/env-network.sh deleted file mode 100755 index acd9f0d..0000000 --- a/rtthread-env/scripts/env-network.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -detect_env_region() { - RTT_ENV_REGION="${RTT_ENV_REGION:-}" - country="${RTT_ENV_REGION:-$(python3 - <<'PY' -import json -import urllib.request - -try: - with urllib.request.urlopen("https://ipinfo.io/json", timeout=5) as res: - print(json.load(res).get("country", "")) -except Exception: - print("") -PY -)}" - - # This value is only the official installer's first argument, not a pip setting. - if [ "$country" = "CN" ]; then - RTT_ENV_MIRROR="--gitee" - mirror="gitee" - else - RTT_ENV_MIRROR="" - mirror="github" - fi - - echo "RT-Thread Env region: ${country:-unknown}, installer mirror: $mirror" - export RTT_ENV_MIRROR -} - -detect_env_region