tre 在 HarmonyOS 上的构建与适配

目录


工具简介

tre 是一个现代化的 tree 命令替代工具,使用 Rust 语言开发。它提供了比传统 tree 命令更强大的功能和更好的用户体验。

什么是 tre?

tre 是一个命令行工具,用于以树状图的形式展示目录结构。它的名字来源于 "tree"(树),但提供了更多现代化的特性。

核心特性

  1. 智能文件过滤

    • 自动跳过 .gitignore 中指定的文件
    • 支持正则表达式模式排除
    • 可以只显示目录或特定类型的文件
  2. 颜色高亮

    • 支持 LS_COLORS 环境变量
    • 根据文件类型自动着色
    • 终端友好的输出格式
  3. 编辑器别名功能

    • 为每个文件创建快捷别名
    • 快速打开文件进行编辑
    • 支持自定义编辑器命令
  4. 多种输出格式

    • 传统的树状图输出
    • JSON 格式输出(-j 选项)
    • 可限制目录深度
  5. 跨平台支持

    • 支持 Linux、macOS、Windows
    • 单一可执行文件,零运行时依赖
    • 无需额外配置即可使用

开发语言与设计优势

Rust 语言的优势

  • 性能:编译后的二进制文件运行速度快,内存占用低
  • 安全性:内存安全保证,避免常见的内存错误
  • 可移植性:单一可执行文件,易于分发和部署
  • 现代特性:支持异步、模式匹配等现代编程特性

设计优势

  • 零依赖:编译后是单个可执行文件,不需要额外的库
  • 快速启动:启动速度快,适合频繁使用
  • 资源占用低:内存和 CPU 占用小
  • 易于集成:可以轻松集成到脚本和工具链中

核心用途与场景

基本用法

1. 查看当前目录结构
bash 复制代码
# 查看当前目录
tre

# 查看指定目录
tre /path/to/directory

# 显示所有文件(包括隐藏文件)
tre -a
2. 筛选特定类型文件
bash 复制代码
# 只显示目录
tre -d

# 排除特定模式的文件
tre -E "\.(o|a|so)$"  # 排除编译产物

# 只显示 Rust 源文件(配合 grep)
tre | grep "\.rs$"
3. 限制目录深度
bash 复制代码
# 只显示 2 层深度
tre -l 2

# 查看项目顶层结构
tre -l 1
4. JSON 输出
bash 复制代码
# 输出 JSON 格式,便于脚本处理
tre -j > structure.json

# 配合 jq 进行进一步处理
tre -j | jq '.[] | select(.type == "file") | .name'
5. 编辑器别名功能
bash 复制代码
# 启用编辑器别名
tre -e

# 使用自定义编辑器
tre -e vim

# 配置 shell 别名(在 ~/.bashrc 或 ~/.zshrc 中)
tre() { command tre "$@" -e && source "/tmp/tre_aliases_$USER" 2>/dev/null; }

使用后,每个文件前会显示一个数字,输入 e数字 即可打开对应文件。

实际应用场景

场景 1:快速查看项目结构
bash 复制代码
# 查看 Rust 项目的结构
tre -l 3

# 输出示例:
# .
# ├── Cargo.toml
# ├── src/
# │   ├── main.rs
# │   └── lib.rs
# └── tests/
#     └── integration_test.rs
场景 2:配合管道命令
bash 复制代码
# 导出目录结构到文件
tre > project_structure.txt

# 统计文件数量
tre | grep -c "├──\|└──"

# 查找特定文件
tre | grep "config"
场景 3:CI/CD 集成
bash 复制代码
# 在 CI 中生成项目结构文档
tre -j > docs/structure.json

# 验证项目结构是否符合规范
tre -d | grep -q "src" && echo "Structure OK" || echo "Missing src directory"

对比传统 tree 命令的优势

特性 tree tre
Git 忽略支持
编辑器别名
JSON 输出
正则过滤 有限
性能 中等
跨平台 需要编译 单一二进制
颜色支持 基础 完整 LS_COLORS

常见报错与解决方案

问题 1:安装失败

错误信息

复制代码
error: failed to compile `tre-command`

原因:Rust 工具链未正确安装或版本过旧。

解决方案

bash 复制代码
# 安装 Rust(如果未安装)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 更新 Rust 工具链
rustup update stable

# 验证安装
rustc --version
cargo --version

问题 2:运行时权限错误

错误信息

复制代码
Permission denied: /path/to/directory

原因:没有读取目录的权限。

解决方案

bash 复制代码
# 检查目录权限
ls -ld /path/to/directory

# 使用 sudo(如果需要)
sudo tre /path/to/directory

# 或者修改目录权限(谨慎使用)
chmod +r /path/to/directory

问题 3:目录路径解析异常

错误信息

复制代码
No such file or directory: /path/to/directory

原因:路径不存在或路径格式错误。

解决方案

bash 复制代码
# 检查路径是否存在
ls -la /path/to/directory

# 使用绝对路径
tre /home/user/project

# 使用相对路径
cd /home/user/project
tre .

问题 4:颜色显示异常

错误信息:终端中颜色显示不正确或没有颜色。

原因 :终端不支持颜色或 LS_COLORS 未设置。

解决方案

bash 复制代码
# 强制启用颜色
tre -c always

# 禁用颜色
tre -c never

# 设置 LS_COLORS(Linux)
eval $(dircolors -b)

# 检查终端是否支持颜色
echo $TERM

问题 5:编辑器别名不工作

错误信息 :输入 e数字 后没有反应。

原因:Shell 配置未正确设置。

解决方案

bash 复制代码
# 检查 shell 配置
cat ~/.bashrc | grep tre
cat ~/.zshrc | grep tre

# 添加配置(Bash/Zsh)
echo 'tre() { command tre "$@" -e && source "/tmp/tre_aliases_$USER" 2>/dev/null; }' >> ~/.bashrc

# 重新加载配置
source ~/.bashrc

# 手动加载别名文件
source /tmp/tre_aliases_$USER

问题 6:编译时依赖问题

错误信息

复制代码
error: failed to resolve: use of undeclared crate or module

原因:依赖版本不兼容或 Cargo.lock 过期。

解决方案

bash 复制代码
# 更新依赖
cargo update

# 清理并重新构建
cargo clean
cargo build --release

# 检查 Cargo.toml 中的依赖版本
cat Cargo.toml

适配开源鸿蒙 PC 端的要点

系统环境差异

1. 包管理器

HarmonyOS PC 使用 HNP(HarmonyOS Native Package)作为包管理格式,而不是传统的 aptyumbrew

影响

  • 需要创建 HNP 包配置文件(hnp.json
  • 安装路径遵循 HNP 规范
  • 包管理命令不同
2. 依赖库

HarmonyOS 使用 musl libc 而不是 glibc,这影响:

  • 链接方式:需要使用静态链接或 musl 兼容的动态链接
  • 系统调用:某些系统调用可能不同
  • 库依赖:需要确保所有依赖都支持 musl
3. 终端交互兼容性

HarmonyOS 终端可能使用不同的:

  • 颜色支持:需要测试 LS_COLORS 兼容性
  • 字符编码:确保 UTF-8 支持
  • 终端特性:某些高级特性可能需要适配

Rust 工具链在鸿蒙上的编译适配

1. 目标平台选择

HarmonyOS 使用 aarch64-unknown-linux-musl 作为目标平台:

bash 复制代码
export TARGET=aarch64-unknown-linux-musl

原因

  • HarmonyOS 基于 Linux 内核
  • 使用 musl libc 而不是 glibc
  • 架构是 aarch64(ARM 64位)
2. 交叉编译配置

需要配置 Rust 工具链使用 HarmonyOS SDK:

bash 复制代码
# 设置工具链环境变量
export CC_aarch64_unknown_linux_musl=${CC}
export CXX_aarch64_unknown_linux_musl=${CXX}
export AR_aarch64_unknown_linux_musl=${AR}
export RANLIB_aarch64_unknown_linux_musl=${RANLIB}
export STRIP_aarch64_unknown_linux_musl=${STRIP}
3. 链接器配置

需要配置 .cargo/config.toml 使用 HarmonyOS 的链接器:

toml 复制代码
[target.aarch64-unknown-linux-musl]
linker = "clang"
rustflags = [
    "-C", "link-arg=--target=aarch64-linux-ohos",
    "-C", "link-arg=--sysroot=${SDK_PATH}/native/sysroot",
    "-C", "link-arg=-fuse-ld=lld",
    "-C", "link-arg=--ld-path=${SDK_PATH}/native/llvm/bin/ld.lld",
]

关键适配要点总结

  1. 目标平台 :使用 aarch64-unknown-linux-musl
  2. 链接器:使用 HarmonyOS SDK 的 LLD
  3. 系统根目录:指定 HarmonyOS SDK 的 sysroot
  4. 包格式:使用 HNP 格式打包
  5. 安装路径:遵循 HNP 规范

鸿蒙适配中的报错解决过程

报错 1:构建系统识别错误

错误信息

复制代码
make: *** No rule to make target `clean'. Stop.
make: *** No targets specified and no makefile found. Stop.

原因分析

tre 是一个 Rust 项目,使用 Cargo 作为构建系统,而不是 Makefile。原始的构建脚本错误地使用了 make 命令。

解决过程

  1. 识别构建系统

    bash 复制代码
    ls -la
    # 发现 Cargo.toml,确认是 Rust 项目
  2. 修改构建脚本

    • 移除 make cleanmake VERBOSE=1make install 命令
    • 改用 cargo build --release --target ${TARGET}
  3. 配置交叉编译

    • 设置目标平台为 aarch64-unknown-linux-musl
    • 配置工具链环境变量
    • 创建 .cargo/config.toml

最终解决方案

bash 复制代码
# 使用 Cargo 构建
cargo build --release --target aarch64-unknown-linux-musl

报错 2:链接器选项不兼容

错误信息

复制代码
ld: unknown option: --as-needed
clang-15: error: linker command failed with exit code 1

原因分析

Rust 默认会添加 -Wl,--as-needed 链接器选项,但 HarmonyOS SDK 使用的 LLD 链接器不支持这个选项。

排查思路

  1. 检查链接器类型

    bash 复制代码
    file ${SDK_PATH}/native/llvm/bin/ld.lld
    # 确认是 LLD 链接器
  2. 查看 Rust 传递的参数

    bash 复制代码
    cargo build --release --target ${TARGET} --verbose 2>&1 | grep "link-arg"
    # 发现 -Wl,--as-needed 选项
  3. 尝试禁用选项

    • rustflags 中添加 -Wl,--no-as-needed(无效)
    • Rust 仍然会添加 --as-needed

解决方案

创建链接器包装脚本,过滤掉不支持的选项:

bash 复制代码
# 创建链接器包装脚本
LINKER_WRAPPER=$(mktemp)
cat > "${LINKER_WRAPPER}" << 'EOF'
#!/bin/bash
ARGS=()
for arg in "$@"; do
    case "$arg" in
        *--as-needed*)
            # 跳过不支持的选项
            ;;
        *)
            ARGS+=("$arg")
            ;;
    esac
done
exec "${CC}" "${ARGS[@]}"
EOF
chmod +x "${LINKER_WRAPPER}"

# 在 .cargo/config.toml 中使用包装脚本
linker = "${LINKER_WRAPPER}"

关键代码

bash 复制代码
# 过滤掉 --as-needed 相关选项
case "$arg" in
    *--as-needed*)
        # 跳过
        ;;
    -Wl,--as-needed)
        # 跳过
        ;;
    -Wl,--no-as-needed)
        # 也跳过(LLD 不支持)
        ;;
    *)
        ARGS+=("$arg")
        ;;
esac

报错 3:目标平台配置错误

错误信息

复制代码
error[E0463]: can't find crate for `std`
= note: the `aarch64-apple-darwin` target may not be installed

原因分析

Rust 尝试为当前主机平台(macOS)编译,而不是为目标平台(HarmonyOS)编译。

解决过程

  1. 检查目标平台

    bash 复制代码
    rustup target list | grep aarch64
    # 确认 aarch64-unknown-linux-musl 存在
  2. 安装目标平台

    bash 复制代码
    rustup target add aarch64-unknown-linux-musl
  3. 确保使用正确的目标

    bash 复制代码
    cargo build --release --target aarch64-unknown-linux-musl

最终解决方案

bash 复制代码
export TARGET=aarch64-unknown-linux-musl
cargo build --release --target ${TARGET}

报错 4:安装路径错误

错误信息

复制代码
cp: directory /Users/jianguo/HarmonyOSPC/build/data/service/hnp//tre.org/tre_1.0.0 does not exist

原因分析

安装目录不存在,需要先创建。

解决方案

bash 复制代码
# 创建安装目录
mkdir -p ${TREE_INSTALL_HNP_PATH}/usr/bin
mkdir -p ${TREE_INSTALL_HNP_PATH}/usr/share/man/man1

适配过程中的关键决策

  1. 使用链接器包装脚本:解决 LLD 不支持的选项问题
  2. 静态链接优先:减少运行时依赖
  3. 遵循 HNP 规范:确保包格式正确
  4. 错误处理完善:添加详细的错误检查和提示

构建脚本详解

build_ohos.sh 完整代码

bash 复制代码
export TREE_INSTALL_HNP_PATH=${HNP_PUBLIC_PATH}/tre.org/tre_1.0.0

# 创建安装目录
mkdir -p ${TREE_INSTALL_HNP_PATH}/usr/bin
mkdir -p ${TREE_INSTALL_HNP_PATH}/usr/share/man/man1

# 设置 Rust 交叉编译目标
export CARGO_TARGET_DIR=${PWD}/target
export TARGET=aarch64-unknown-linux-musl

# 配置 cargo 使用 HarmonyOS 工具链
export CC_aarch64_unknown_linux_musl=${CC}
export CXX_aarch64_unknown_linux_musl=${CXX}
export AR_aarch64_unknown_linux_musl=${AR}
export RANLIB_aarch64_unknown_linux_musl=${RANLIB}
export STRIP_aarch64_unknown_linux_musl=${STRIP}

# 设置链接器
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=${CC}

# 创建 .cargo 配置目录
mkdir -p .cargo

# 创建链接器包装脚本
LINKER_WRAPPER=$(mktemp)
cat > "${LINKER_WRAPPER}" << LINKER_EOF
#!/bin/bash
ARGS=()
for arg in "\$@"; do
    case "\$arg" in
        *--as-needed*)
            ;;
        -Wl,--as-needed)
            ;;
        -Wl,--no-as-needed)
            ;;
        *)
            ARGS+=("\$arg")
            ;;
    esac
done
exec "${CC}" "\${ARGS[@]}"
LINKER_EOF
chmod +x "${LINKER_WRAPPER}"

# 动态生成 .cargo/config.toml
SDK_PATH=${OHOS_SDK:-/Users/jianguo/Desktop/ohosdk}
cat > .cargo/config.toml << EOF
[target.aarch64-unknown-linux-musl]
linker = "${LINKER_WRAPPER}"
rustflags = [
    "-C", "link-arg=--target=aarch64-linux-ohos",
    "-C", "link-arg=--sysroot=${SDK_PATH}/native/sysroot",
    "-C", "link-arg=-fuse-ld=lld",
    "-C", "link-arg=--ld-path=${SDK_PATH}/native/llvm/bin/ld.lld",
]
EOF

# 构建 release 版本
cargo build --release --target ${TARGET} --verbose

# 安装二进制文件
cp ${CARGO_TARGET_DIR}/${TARGET}/release/tre ${TREE_INSTALL_HNP_PATH}/usr/bin/tre
chmod +x ${TREE_INSTALL_HNP_PATH}/usr/bin/tre

# 复制 man pages
if [ -f manual/tre.1 ]; then
    cp manual/tre.1 ${TREE_INSTALL_HNP_PATH}/usr/share/man/man1/
fi

# 复制 hnp.json 并打包
cp hnp.json ${TREE_INSTALL_HNP_PATH}/
pushd ${TREE_INSTALL_HNP_PATH}/../
    ${HNP_TOOL} pack -i ${TREE_INSTALL_HNP_PATH} -o ${ARCHIVE_PATH}/
    tar -zvcf ${ARCHIVE_PATH}/ohos_tre_1.0.0.tar.gz tre_1.0.0/
popd

脚本关键点解析

1. 链接器包装脚本

作用 :过滤掉 LLD 不支持的 --as-needed 选项。

实现

  • 遍历所有链接器参数
  • 过滤掉包含 --as-needed 的参数
  • 将剩余参数传递给实际链接器
2. Cargo 配置

.cargo/config.toml

  • 指定链接器为包装脚本
  • 配置 HarmonyOS SDK 路径
  • 设置链接器参数
3. 构建流程
  1. 清理cargo clean
  2. 构建cargo build --release --target ${TARGET}
  3. 安装:复制二进制文件和文档
  4. 打包:创建 HNP 包和 tar 归档

HNP 包配置

hnp.json

json 复制代码
{
    "type": "hnp-config",
    "name": "tre",
    "version": "1.0.0",
    "install": {}
}

安装目录结构

复制代码
tre_1.0.0/
├── usr/
│   ├── bin/
│   │   └── tre              # 可执行文件
│   └── share/
│       └── man/
│           └── man1/
│               └── tre.1    # 用户手册
└── hnp.json                 # HNP 包配置

构建结果

构建成功后,会生成以下文件:

  1. HNP 包tre.org_tre_1.0.0.hnp

    • HarmonyOS 原生包格式
    • 可以直接安装到 HarmonyOS 设备
  2. Tar 归档ohos_tre_1.0.0.tar.gz

    • 压缩的 tar 归档
    • 包含完整的安装目录结构

构建输出示例

复制代码
==========================================
Build completed successfully!
==========================================
HNP Package: /path/to/archive/tre.org_tre_1.0.0.hnp
Tar Archive: /path/to/archive/ohos_tre_1.0.0.tar.gz
Installation Path: /path/to/data/service/hnp/tre.org/tre_1.0.0
==========================================

仓库地址与安装方式

仓库地址

HarmonyOS 适配版本

安装方式

Linux(通用)

使用 Cargo

bash 复制代码
cargo install tre-command

使用包管理器

bash 复制代码
# Debian/Ubuntu
sudo apt install tre-command

# Arch Linux (AUR)
yay -S tre-command

从源码编译

bash 复制代码
git clone https://github.com/dduan/tre.git
cd tre
cargo build --release
sudo cp target/release/tre /usr/local/bin/
macOS

使用 Homebrew

bash 复制代码
brew install tre-command

使用 MacPorts

bash 复制代码
sudo port install tre-tree

使用 Cargo

bash 复制代码
cargo install tre-command
Windows

使用 Scoop

bash 复制代码
scoop install tre-command

使用 Windows Package Manager

bash 复制代码
winget install tre-command

使用 Cargo

bash 复制代码
cargo install tre-command
开源鸿蒙 PC

使用 HNP 包

bash 复制代码
# 安装 HNP 包
hnp install tre.org_tre_1.0.0.hnp

# 或使用 tar 归档
tar -xzf ohos_tre_1.0.0.tar.gz
# 手动复制到系统路径

从源码交叉编译

bash 复制代码
# 1. 克隆仓库
git clone https://gitcode.com/nutpi/tre.git
cd tre
git checkout 1.0.0_ohos

# 2. 设置 HarmonyOS SDK 路径
export OHOS_SDK=/path/to/ohosdk

# 3. 运行构建脚本
./build_ohos.sh

# 4. 安装生成的 HNP 包
hnp install tre.org_tre_1.0.0.hnp

验证安装

bash 复制代码
# 检查版本
tre --version

# 测试基本功能
tre

# 查看帮助
tre --help

总结

适配要点

  1. 构建系统识别:Rust 项目使用 Cargo,不是 Makefile
  2. 目标平台选择 :使用 aarch64-unknown-linux-musl
  3. 链接器兼容性:使用包装脚本过滤不支持的选项
  4. 工具链配置:正确配置交叉编译环境变量
  5. 包格式:遵循 HNP 规范

关键决策

  1. 链接器包装脚本:解决 LLD 不支持的选项问题
  2. 动态配置生成 :根据 SDK 路径生成 .cargo/config.toml
  3. 错误处理:添加详细的错误检查和提示

优势

  • 零运行时依赖:单一可执行文件,部署简单
  • 高性能:Rust 编译,运行速度快
  • 功能强大:支持 Git 忽略、编辑器别名等高级特性
  • 易于集成:可以轻松集成到脚本和工具链中

适用场景

  • 项目结构可视化
  • 文档生成
  • CI/CD 集成
  • 开发工具集成
  • 文件管理辅助

FAQ

Q1: tre 和 tree 有什么区别?

A: tre 是 tree 的现代化替代品,主要区别:

  • tre 支持 Git 忽略文件
  • tre 提供编辑器别名功能
  • tre 支持 JSON 输出
  • tre 性能更好,启动更快
  • tre 是单一二进制文件,无需额外依赖

Q2: 为什么选择 Rust 开发?

A: Rust 的优势:

  • 内存安全,避免常见错误
  • 性能接近 C/C++
  • 单一可执行文件,易于分发
  • 跨平台支持好
  • 现代语言特性丰富

Q3: 编辑器别名功能如何工作?

A: tre 会:

  1. 为每个文件分配一个数字
  2. 创建 shell 别名(如 e1e2
  3. 将别名保存到临时文件
  4. Shell 配置会加载这些别名
  5. 输入 e数字 即可打开对应文件

Q4: 如何在 HarmonyOS 上使用 tre?

A:

  1. 安装 HNP 包:hnp install tre.org_tre_1.0.0.hnp
  2. 或从源码交叉编译
  3. 使用方式与 Linux 相同

Q5: 链接器包装脚本是必需的吗?

A: 是的,因为:

  • HarmonyOS SDK 使用 LLD 链接器
  • LLD 不支持 --as-needed 选项
  • Rust 默认会添加这个选项
  • 包装脚本可以过滤掉不支持的选项

Q6: 如何自定义编辑器?

A:

bash 复制代码
# 使用环境变量
export EDITOR=vim
tre -e

# 或直接指定
tre -e vim
tre -e code  # VS Code

Q7: 可以只显示特定类型的文件吗?

A: 可以配合其他工具:

bash 复制代码
# 只显示 .rs 文件
tre | grep "\.rs$"

# 排除特定模式
tre -E "\.(o|a|so)$"

Q8: JSON 输出格式是什么?

A: JSON 输出是一个数组,每个元素包含:

  • name: 文件/目录名
  • type: "file" 或 "directory"
  • path: 完整路径
  • children: 子项(如果是目录)

相关链接

相关推荐
m0_685535084 小时前
华为光学工程师笔试真题(含答案与深度解析)
华为·光学·光学设计·光学工程·镜头设计
lqj_本人5 小时前
鸿蒙原生与Qt混合开发:性能优化与资源管理
qt·harmonyos
lqj_本人5 小时前
鸿蒙Qt字体实战:消灭“豆腐块“乱码与自定义字体加载
qt·华为·harmonyos
大侠课堂5 小时前
海康大华大疆华为中兴追觅经典面试题200道完整版
华为
爱笑的眼睛115 小时前
深入探索HarmonyOS中RichText组件的HTML渲染机制
华为·harmonyos
IT闫5 小时前
figlet 在鸿蒙PC上的构建与适配
华为·harmonyos
全栈陈序员6 小时前
Whois 工具在 HarmonyOS PC 上的交叉编译实践
华为·harmonyos
空白诗7 小时前
tokei 在鸿蒙PC上的构建与适配
后端·华为·rust·harmonyos
汉堡黄7 小时前
鸿蒙开发:案例集合Tabs:分段按钮组件
harmonyos
哈__7 小时前
exa 在 HarmonyOS 上的构建与适配
elasticsearch·华为·harmonyos