Tree 命令行工具鸿蒙化构建过程问题及解决方法

本文记录使用命令 OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh 构建 Tree 2.2.1 的完整过程,包括环境、构建链路、关键日志、常见问题与解决方案、产物验证与重建方法,便于复现与运维。

📖 Tree 简介

Tree 是一个递归目录树显示工具,用于以树状结构显示目录和文件。它可以帮助用户快速了解目录结构,是系统管理和开发调试中常用的可视化工具。

🎯 Tree 的作用与重要性

Tree 是目录结构可视化的核心工具,提供了:

  • 目录树显示:以树状结构递归显示目录和文件
  • 格式化输出:美观的树状格式,易于阅读
  • 过滤功能:支持按文件类型、名称模式等过滤显示
  • 统计信息:显示文件数量、目录数量等统计信息
  • 多种输出格式:支持 ASCII、HTML、XML 等多种输出格式
  • 跨平台兼容:支持多种操作系统和文件系统

🔧 Tree 核心特性

1. 显示选项
  • 目录树结构:递归显示目录和文件的树状结构
  • 文件信息:显示文件大小、权限、修改时间等信息
  • 符号链接:显示符号链接的目标
  • 隐藏文件:可选择显示或隐藏隐藏文件
  • 深度限制:限制显示的目录深度
2. 过滤功能
  • 文件类型过滤:只显示特定类型的文件
  • 名称模式过滤:使用通配符或正则表达式过滤文件名
  • 目录过滤:排除特定目录(如 node_modules、.git)
  • 大小过滤:只显示大于或小于特定大小的文件
3. 输出格式
  • ASCII 格式:默认的 ASCII 树状格式
  • HTML 格式:生成 HTML 格式的目录树
  • XML 格式:生成 XML 格式的目录树
  • JSON 格式:生成 JSON 格式的目录树(部分版本支持)
4. 统计信息
  • 文件计数:统计文件和目录数量
  • 大小统计:统计总文件大小
  • 类型统计:统计不同文件类型的数量
5. 应用场景
  • 目录导航:快速了解目录结构
  • 项目文档:生成项目目录结构文档
  • 系统管理:查看系统目录结构
  • 调试定位:定位文件和目录位置
  • 备份规划:规划备份目录结构

🚀 构建入口与环境

  • 📝 执行命令OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh
  • 🔧 入口脚本create-hnp.sh
    • 检查必需的环境变量 OHOS_ARCHOHOS_ABI
    • 导出 LC_CTYPETOOL_HOMEOHOS_SDK_HOME
    • 执行 make -C build-hnp
  • 📦 顶层构建build-hnp/Makefile
    • PKGS 变量定义需要构建的包列表(包含 tree
    • 通过 check-pkgs 机制自动检测 PKGS 变化并触发重新构建
    • 自动合并 external-hnp 目录下的外部 HNP 包
    • base.hnp 依赖所有包的 .stamp 和外部 HNP 包
    • 总目标 all: copy,打包 base.hnp 并拷贝到 entry/hnp/$(OHOS_ABI)

⚙️ Tree 包的构建配置

  • 📁 包目录build-hnp/tree/Makefile
    • 继承通用规则:include ../utils/Makefrag
    • 源地址:https://github.com/Old-Man-Programmer/tree/archive/refs/tags/2.2.1.tar.gz
    • 版本:2.2.1
  • 🔨 构建流程
    1. 下载源码包(支持多镜像回退)
    2. 解包并进入 temp/tree-2.2.1 目录
    3. 使用自定义 Makefile 直接编译(不使用 Autotools)
    4. 指定交叉编译器:CC=$(OHOS_SDK_HOME)/native/llvm/bin/$(OHOS_ARCH)-unknown-linux-ohos-clang
    5. 使用 make install 安装
    6. 复制到 ../sysroot
  • ⚙️ 关键编译参数
    • CFLAGS="-O3 -static -std=c11 -pedantic -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DLINUX"
      • -O3 - 最高优化级别
      • -static - 静态链接
      • -std=c11 - 使用 C11 标准
      • -pedantic -Wall - 严格编译检查和警告
      • -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 - 大文件支持
      • -DLINUX - 定义 Linux 平台
    • LDFLAGS="-static" - 静态链接标志
  • 🔧 静态链接策略
    • 采用静态链接,确保在目标设备上无需额外依赖即可运行
    • 适合在设备环境不完整时使用
    • 缺点:二进制体积增大(约 1.1MB)

📋 关键日志与过程节点

  • 📥 下载与解包
    • 从 GitHub Releases 下载 2.2.1.tar.gz
    • 完成解包并进入 temp/tree-2.2.1 目录
    • 下载规则支持多镜像回退:wgetcurl 兜底
  • 🔨 编译阶段
    • 使用交叉编译器直接编译
    • 编译警告:strverscmp 函数未声明(不影响构建)
    • 编译警告:strverscmp.c 中的 UTF-8 注释无效(不影响构建)
    • 成功编译生成静态链接的 tree 二进制
  • 📦 安装与打包
    • 使用 make install 安装到临时前缀
    • 复制到 ../sysroot
    • 完成 base.hnp 重打包,拷贝产物到 entry/hnp/arm64-v8a/
    • Tree 工具已成功打包到 base.hnp

✅ 产物验证

📦 检查打包文件

bash 复制代码
ls build-hnp/base.hnp  # 应存在
ls entry/hnp/arm64-v8a/*.hnp  # 应包含 base.hnp 与 base-public.hnp

🔍 检查二进制文件

bash 复制代码
# 检查 tree 二进制
ls -lh build-hnp/sysroot/bin/tree
file build-hnp/sysroot/bin/tree

# 测试 tree 版本(在目标设备上)
build-hnp/sysroot/bin/tree --version

✅ 构建验证结果

  • ✅ Tree 二进制已成功安装:
    • tree (1.1M) - 主程序二进制(静态链接)
  • ✅ 文件类型:ELF 64-bit LSB executable, ARM aarch64
  • ✅ 链接方式:statically linked
  • ✅ 包含调试信息:with debug_info, not stripped
  • ✅ 已打包到 base.hnp 中(1,059,232 字节)

💻 终端中执行的示例命令

🌳 Tree 基本使用

1. 基本目录树显示
bash 复制代码
# 显示当前目录树
tree

# 显示指定目录树
tree /path/to/directory

# 显示目录树(限制深度)
tree -L 2

# 显示目录树(只显示目录)
tree -d

# 显示目录树(显示隐藏文件)
tree -a

# 显示目录树(显示文件大小)
tree -h

# 显示目录树(显示权限)
tree -p

# 显示目录树(显示修改时间)
tree -D
2. 过滤和排除
bash 复制代码
# 排除特定目录
tree -I 'node_modules|.git'

# 只显示特定文件类型
tree -P '*.txt'

# 排除特定文件类型
tree -I '*.log'

# 排除多个模式
tree -I 'node_modules|.git|*.log|*.tmp'

# 只显示匹配的文件
tree -P '*.c|*.h'

# 排除匹配的文件
tree -I '*.o|*.a'
3. 输出格式
bash 复制代码
# ASCII 格式(默认)
tree

# HTML 格式
tree -H . -o tree.html

# XML 格式
tree -X -o tree.xml

# JSON 格式(如果支持)
tree -J -o tree.json

# 彩色输出
tree -C

# 不使用颜色
tree --noreport
4. 统计信息
bash 复制代码
# 显示统计信息
tree -s

# 显示文件大小(人类可读)
tree -h -s

# 只显示统计信息(不显示树)
tree --du -h

# 显示目录大小
tree -d -h -s

# 显示文件数量
tree | tail -1
5. 高级选项
bash 复制代码
# 显示完整路径
tree -f

# 显示相对路径
tree -f -L 2

# 显示文件权限
tree -p

# 显示文件所有者
tree -u

# 显示文件组
tree -g

# 显示文件修改时间
tree -D

# 显示文件大小(字节)
tree -s

# 显示文件大小(人类可读)
tree -h

🌳 Tree 高级用法

6. 目录深度控制
bash 复制代码
# 限制显示深度为 2 层
tree -L 2

# 限制显示深度为 3 层
tree -L 3

# 显示完整深度
tree -L 999

# 只显示当前目录
tree -L 0

# 显示两层目录
tree -L 2 -d
7. 文件类型过滤
bash 复制代码
# 只显示目录
tree -d

# 只显示文件
tree -f -I '^$'

# 只显示特定扩展名
tree -P '*.txt'

# 排除特定扩展名
tree -I '*.log'

# 只显示 C 源文件
tree -P '*.c|*.h'

# 排除编译产物
tree -I '*.o|*.a|*.so'
8. 输出到文件
bash 复制代码
# 输出到文件
tree > tree.txt

# 输出 HTML 格式
tree -H . -o tree.html

# 输出 XML 格式
tree -X -o tree.xml

# 输出并显示统计
tree -s > tree.txt

# 输出并限制深度
tree -L 2 > tree.txt
9. 实际应用示例
bash 复制代码
# 查看项目目录结构
tree -I 'node_modules|.git|dist|build' -L 3

# 查看系统目录结构
tree -L 2 /etc

# 查看用户目录结构
tree -L 2 ~

# 生成项目文档
tree -H . -o docs/tree.html

# 查看目录大小
tree -d -h -s /path/to/directory

# 查找特定文件
tree -f | grep filename

# 统计文件数量
tree | tail -1

# 查看目录树并保存
tree -L 3 -I 'node_modules|.git' > project_structure.txt

# 查看目录树(带权限)
tree -p -L 2

# 查看目录树(带时间戳)
tree -D -L 2

# 查看目录树(带大小)
tree -h -s -L 2

# 排除多个目录
tree -I 'node_modules|.git|dist|build|.cache' -L 3

# 只显示特定文件类型
tree -P '*.md|*.txt' -L 2

# 查看目录树并过滤
tree -L 2 | grep -v 'node_modules'

# 生成目录结构文档
tree -H . -T "Project Structure" -o docs/structure.html

# 查看目录树(JSON 格式,如果支持)
tree -J -L 2

# 查看目录树(XML 格式)
tree -X -L 2 -o structure.xml

# 查看目录树并统计
tree -s -L 2 | tail -5

# 查看目录树(彩色输出)
tree -C -L 2

# 查看目录树(不显示报告)
tree --noreport -L 2

# 查看目录树(显示完整路径)
tree -f -L 2

# 查看目录树(只显示目录)
tree -d -L 2

# 查看目录树(显示文件大小)
tree -h -L 2

# 查看目录树(显示权限)
tree -p -L 2

# 查看目录树(显示修改时间)
tree -D -L 2
10. 组合使用示例
bash 复制代码
# 查看项目结构(排除常见目录,限制深度,显示大小)
tree -I 'node_modules|.git|dist|build' -L 3 -h -s

# 生成项目文档(HTML 格式,排除构建目录)
tree -H . -I 'node_modules|.git|dist|build' -o docs/structure.html

# 查看目录树(只显示源代码文件)
tree -P '*.c|*.h|*.cpp|*.hpp' -L 3

# 查看目录树(排除编译产物和依赖)
tree -I '*.o|*.a|*.so|node_modules|.git' -L 3

# 查看目录树(显示统计信息)
tree -s -L 2 | tail -1

# 查看目录树(带权限和时间)
tree -p -D -L 2

# 查看目录树(只显示目录,带大小)
tree -d -h -s -L 2

# 查看目录树(输出到文件并显示)
tree -L 3 | tee tree_output.txt

# 查看目录树(过滤后输出)
tree -L 3 | grep -v 'node_modules' | grep -v '.git'

# 查看目录树(JSON 格式,如果支持)
tree -J -L 2 | jq .

# 查看目录树(XML 格式)
tree -X -L 2 | xmllint --format -

🧪 功能验证脚本

bash 复制代码
#!/bin/bash
# Tree 工具验证脚本

TREE_BIN="build-hnp/sysroot/bin"

echo "=== Tree 工具验证 ==="

# 检查 tree 二进制
if [ -f "$TREE_BIN/tree" ]; then
    echo "✓ tree: 存在"
    file "$TREE_BIN/tree"
    echo "文件大小: $(ls -lh "$TREE_BIN/tree" | awk '{print $5}')"
    echo "架构信息: $(file "$TREE_BIN/tree" | grep -o "ARM aarch64")"
    echo "链接方式: $(file "$TREE_BIN/tree" | grep -o "statically linked")"
    
    # 测试版本信息(在目标设备上)
    echo ""
    echo "版本信息(需要在目标设备上运行):"
    echo "  $TREE_BIN/tree --version"
    
    # 测试基本功能(在目标设备上)
    echo ""
    echo "=== 功能测试(需要在目标设备上运行)==="
    echo "测试显示目录树:"
    echo "  $TREE_BIN/tree -L 2"
    echo ""
    echo "测试显示目录(只显示目录):"
    echo "  $TREE_BIN/tree -d -L 2"
    echo ""
    echo "测试显示文件大小:"
    echo "  $TREE_BIN/tree -h -L 2"
    echo ""
    echo "测试排除目录:"
    echo "  $TREE_BIN/tree -I 'node_modules|.git' -L 2"
else
    echo "✗ tree: 缺失"
fi

🐛 常见问题与处理

❌ 问题 1:strverscmp 函数未声明

  • 🔍 症状 :编译警告 call to undeclared function 'strverscmp'
  • 🔎 原因strverscmp 函数在某些平台上可能未声明
  • ✅ 解决方法
    • 这是编译警告,不影响构建
    • Tree 源码中包含了 strverscmp 的实现
    • 位置:编译阶段日志

❌ 问题 2:UTF-8 注释无效

  • 🔍 症状 :编译警告 invalid UTF-8 in comment
  • 🔎 原因:源码中的注释包含无效的 UTF-8 字符
  • ✅ 解决方法
    • 这是编译警告,不影响构建
    • 可以忽略或修复源码中的注释
    • 位置:编译阶段日志(strverscmp.c:4

❌ 问题 3:静态链接失败

  • 🔍 症状:链接错误,无法创建静态链接的二进制
  • 🔎 原因:缺少静态库或静态库不完整
  • ✅ 解决方法
    • 确保交叉工具链提供完整的静态库
    • 检查 sysroot 中是否有必要的静态库
    • 如果静态链接失败,可以尝试移除 -static 标志使用动态链接
    • 位置:build-hnp/tree/Makefile:7

❌ 问题 4:大文件支持问题

  • 🔍 症状:无法正确处理大文件或深目录
  • 🔎 原因:缺少大文件支持宏定义
  • ✅ 解决方法
    • 确保 CFLAGS 中包含 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
    • 这些宏定义确保正确处理大文件和深目录
    • 位置:build-hnp/tree/Makefile:7

❌ 问题 5:GitHub Releases 不可达

  • 🔍 症状:下载失败,无法获取源码包
  • 🔎 原因:网络问题或 GitHub 访问受限
  • ✅ 解决方法
    • 手动下载源码包放置到 build-hnp/tree/download/2.2.1.tar.gz
    • 通用下载逻辑支持备用镜像与重试(wgetcurl
    • 位置:build-hnp/utils/Makefrag:61-69

❌ 问题 6:架构不支持

  • 🔍 症状Unsupported OHOS_ARCH=
  • 🔎 原因:传入的架构不在支持列表中
  • ✅ 解决方法
    • 确保传入支持架构(aarch64x86_64
    • 位置:build-hnp/Makefile:1-40

❌ 问题 7:二进制体积过大

  • 🔍 症状:静态链接的二进制体积较大(约 1.1MB)
  • 🔎 原因:静态链接包含了所有依赖库
  • ✅ 解决方法
    • 这是静态链接的正常现象
    • 如果需要减小体积,可以移除 -static 标志使用动态链接
    • 但需要确保目标设备有相应的动态库
    • 位置:build-hnp/tree/Makefile:7

🔄 重建与扩展

  • 🔧 重建单包

    bash 复制代码
    make -C build-hnp rebuild-tree  # 触发子包重新编译并刷新 .stamp
  • 🧹 清理

    bash 复制代码
    make -C build-hnp clean  # 清理 sysroot、所有 .stamp 和 PKGS_MARKER
  • 📦 扩展:Tree 是目录结构可视化的基础工具

  • 🔄 自动重建机制

    • 修改 PKGS 后,check-pkgs 会自动检测变化并触发重新构建
    • 新增外部 HNP 包到 external-hnp 目录后,会自动合并到 base.hnp

💡 实践建议

  • 🔧 构建配置:使用静态链接确保在目标设备上无需额外依赖即可运行
  • 🚀 功能使用:根据需求选择合适的显示选项和过滤条件
  • 📦 输出格式:使用 HTML 或 XML 格式生成文档
  • 🔗 过滤选项 :使用 -I 排除不需要的目录,使用 -P 只显示特定文件类型
  • 🌐 深度控制 :使用 -L 限制显示深度,避免输出过长

📝 结论与建议

  • ✅ 本次已在 aarch64 环境下完成 Tree 2.2.1 的交叉编译与打包,tree 工具已安装到 sysroot 并纳入 HNP 包。
  • 💡 为保证构建稳定
    • 使用静态链接确保在目标设备上无需额外依赖即可运行
    • 启用大文件支持宏定义以正确处理大文件和深目录
    • 编译警告不影响构建,可以忽略
    • 确保通过 create-hnp.sh 触发构建以获得完整环境变量
    • 利用 check-pkgs 机制自动检测包列表变化,无需手动清理
    • Tree 为目录结构可视化提供了强大的工具支持
    • 常见陷阱包括静态链接失败、大文件支持缺失、编译警告;当前已通过编译选项和宏定义处理
    • 构建参数简洁且针对设备环境做出静态链接设计,保证可运行性
    • 产物开箱即用,可用于设备上目录结构快速查看与调试定位

📚 以上为 Tree 构建的深度解读与实践记录。

相关推荐
坚果派·白晓明5 天前
面向新手的鸿蒙跨平台开发技术选型指南
开源鸿蒙·鸿蒙跨平台应用开发·鸿蒙跨平台应用
坚果派·白晓明5 天前
Windows 11 OpenHarmony版React Native开发环境搭建完整指南
react native·开源鸿蒙·rnoh
fakerth6 天前
【OpenHarmony】升级服务组件(UpdateService)
操作系统·openharmony
fakerth6 天前
【OpenHarmony】Updater 升级包安装组件
操作系统·openharmony
鸿蒙小白龙8 天前
OpenHarmony轻量系统智能模块开发实战指南
arm开发·openharmony·liteos
鸿蒙小白龙8 天前
OpenHarmony轻量系统(Hi3861)RTOS API开发详解
openharmony·rtos·liteos·轻量系统
夏小鱼的blog16 天前
【HarmonyOS应用开发入门】第四期:ArkTS语言基础(二)
harmonyos·openharmony
黑臂麒麟16 天前
Electron for OpenHarmony 跨平台实战开发(二):文件树组件实现与优化
electron·openharmony
爱艺江河16 天前
[鸿蒙2025领航者闯关]基于MetaStudio的数字人与鸿蒙PC本地智能体融合:金融法务合规业务的技术实现与场景创新
金融·openharmony·鸿蒙2025领航者闯关
fakerth17 天前
【OpenHarmony】Hiview架构
架构·操作系统·openharmony