From 4c01520cd33a1ad6058776e618117593db14d3a8 Mon Sep 17 00:00:00 2001 From: bernard Date: Tue, 14 Jul 2026 08:53:35 +0800 Subject: [PATCH] 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