本文記錄使用命令 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_ARCH和OHOS_ABI - 導出
LC_CTYPE、TOOL_HOME、OHOS_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
- 🔨 構建流程:
- 下載源碼包(支持多鏡像回退)
- 解包並進入
temp/tree-2.2.1目錄 - 使用自定義 Makefile 直接編譯(不使用 Autotools)
- 指定交叉編譯器:
CC=$(OHOS_SDK_HOME)/native/llvm/bin/$(OHOS_ARCH)-unknown-linux-ohos-clang - 使用
make install安裝 - 複製到
../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目錄 - 下載規則支持多鏡像回退:
wget→curl兜底
- 🔨 編譯階段:
- 使用交叉編譯器直接編譯
- 編譯警告:
strverscmp函數未聲明(不影響構建) - 編譯警告:
strverscmp.c中的 UTF-8 註釋無效(不影響構建) - 成功編譯生成靜態鏈接的
tree二進制
- 📦 安裝與打包:
- 使用
make install安裝到臨時前綴 - 複製到
../sysroot - 完成
base.hnp重打包,拷貝產物到entry/hnp/arm64-v8a/ - Tree 工具已成功打包到
base.hnp中
✅ 產物驗證
📦 檢查打包文件
ls build-hnp/base.hnp # 應存在
ls entry/hnp/arm64-v8a/*.hnp # 應包含 base.hnp 與 base-public.hnp
🔍 檢查二進制文件
# 檢查 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. 基本目錄樹顯示
# 顯示當前目錄樹
tree
# 顯示指定目錄樹
tree /path/to/directory
# 顯示目錄樹(限制深度)
tree -L 2
# 顯示目錄樹(只顯示目錄)
tree -d
# 顯示目錄樹(顯示隱藏文件)
tree -a
# 顯示目錄樹(顯示文件大小)
tree -h
# 顯示目錄樹(顯示權限)
tree -p
# 顯示目錄樹(顯示修改時間)
tree -D
2. 過濾和排除
# 排除特定目錄
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. 輸出格式
# 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. 統計信息
# 顯示統計信息
tree -s
# 顯示文件大小(人類可讀)
tree -h -s
# 只顯示統計信息(不顯示樹)
tree --du -h
# 顯示目錄大小
tree -d -h -s
# 顯示文件數量
tree | tail -1
5. 高級選項
# 顯示完整路徑
tree -f
# 顯示相對路徑
tree -f -L 2
# 顯示文件權限
tree -p
# 顯示文件所有者
tree -u
# 顯示文件組
tree -g
# 顯示文件修改時間
tree -D
# 顯示文件大小(字節)
tree -s
# 顯示文件大小(人類可讀)
tree -h
🌳 Tree 高級用法
6. 目錄深度控制
# 限制顯示深度為 2 層
tree -L 2
# 限制顯示深度為 3 層
tree -L 3
# 顯示完整深度
tree -L 999
# 只顯示當前目錄
tree -L 0
# 顯示兩層目錄
tree -L 2 -d
7. 文件類型過濾
# 只顯示目錄
tree -d
# 只顯示文件
tree -f -I '^$'
# 只顯示特定擴展名
tree -P '*.txt'
# 排除特定擴展名
tree -I '*.log'
# 只顯示 C 源文件
tree -P '*.c|*.h'
# 排除編譯產物
tree -I '*.o|*.a|*.so'
8. 輸出到文件
# 輸出到文件
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. 實際應用示例
# 查看項目目錄結構
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. 組合使用示例
# 查看項目結構(排除常見目錄,限制深度,顯示大小)
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 -
🧪 功能驗證腳本
#!/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 - 通用下載邏輯支持備用鏡像與重試(
wget→curl) - 位置:
build-hnp/utils/Makefrag:61-69
❌ 問題 6:架構不支持
- 🔍 症狀:
Unsupported OHOS_ARCH= - 🔎 原因:傳入的架構不在支持列表中
- ✅ 解決方法:
- 確保傳入支持架構(
aarch64或x86_64) - 位置:
build-hnp/Makefile:1-40
❌ 問題 7:二進制體積過大
- 🔍 症狀:靜態鏈接的二進制體積較大(約 1.1MB)
- 🔎 原因:靜態鏈接包含了所有依賴庫
- ✅ 解決方法:
- 這是靜態鏈接的正常現象
- 如果需要減小體積,可以移除
-static標誌使用動態鏈接 - 但需要確保目標設備有相應的動態庫
- 位置:
build-hnp/tree/Makefile:7
🔄 重建與擴展
- 🔧 重建單包:
make -C build-hnp rebuild-tree # 觸發子包重新編譯並刷新 .stamp
- 🧹 清理:
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 為目錄結構可視化提供了強大的工具支持
- 常見陷阱包括靜態鏈接失敗、大文件支持缺失、編譯警告;當前已通過編譯選項和宏定義處理
- 構建參數簡潔且針對設備環境做出靜態鏈接設計,保證可運行性
- 產物開箱即用,可用於設備上目錄結構快速查看與調試定位
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。