目录
- 项目简介
- [exa 是什么](#exa 是什么)
- [exa 的主要特性](#exa 的主要特性)
- [exa 的使用方法](#exa 的使用方法)
- [HarmonyOS 适配过程](#HarmonyOS 适配过程)
- 环境准备
- 构建脚本详解
- 关键问题解决
- [HNP 包配置](#HNP 包配置)
- 构建结果
- 使用示例
- 总结
- FAQ
- 相关链接
项目简介
exa 是一个现代化的 ls 命令替代品,使用 Rust 语言编写,提供了更丰富的功能和更好的默认设置。本文将详细介绍如何将 exa 适配到 HarmonyOS 平台,包括交叉编译配置、构建脚本编写以及使用说明。
仓库地址: git@gitcode.com:nutpi/exa.git
版本: v0.10.1
Tag: v0.10.1-harmonyos
exa 是什么
exa 是一个命令行工具,用于列出目录内容,是传统 Unix/Linux ls 命令的现代化替代品。它使用颜色来区分文件类型和元数据,支持符号链接、扩展属性和 Git 集成。
主要优势
- 彩色显示:自动使用颜色区分文件类型
- Git 集成:显示 Git 仓库中文件的修改状态
- 树形视图:支持递归显示目录树结构
- 图标支持:可选的文件类型图标
- 高性能:Rust 编写,单二进制文件,运行速度快
- 更好的默认设置 :相比
ls提供更友好的默认行为
exa 的主要特性
1. 多种显示模式
- 网格视图(默认):以网格形式显示文件
- 长列表视图 (
-l):显示详细信息,包括权限、大小、时间等 - 树形视图 (
-T):递归显示目录树 - 单行视图 (
-1):每行显示一个文件
2. 智能排序和过滤
- 按名称、大小、修改时间等排序
- 支持目录优先显示
- Git 忽略文件过滤
- 支持 glob 模式过滤
3. Git 集成
- 显示 Git 仓库中文件的修改状态
- 支持 Git 忽略文件过滤
- 在长列表中显示 Git 状态
4. 丰富的元数据
- 文件权限(支持八进制格式)
- 文件大小(支持二进制和十进制前缀)
- 时间戳(修改、访问、创建时间)
- 扩展属性
- 硬链接数
- inode 号
exa 的使用方法
基本用法
bash
# 列出当前目录(网格视图)
exa
# 长列表视图
exa -l
# 显示所有文件(包括隐藏文件)
exa -a
# 树形视图
exa -T
# 递归显示目录
exa -R
常用选项
显示选项
bash
# 单行显示
exa -1
# 网格视图(默认)
exa -G
# 长列表视图
exa -l
# 树形视图
exa -T
# 显示文件类型指示符
exa -F
# 显示图标
exa --icons
排序和过滤
bash
# 按大小排序
exa -l --sort=size
# 按修改时间排序
exa -l --sort=modified
# 反向排序
exa -l --sort=size --reverse
# 目录优先
exa --group-directories-first
# 只显示目录
exa -D
Git 集成
bash
# 显示 Git 状态
exa -l --git
# 忽略 Git 忽略的文件
exa --git-ignore
长列表选项
bash
# 显示文件组
exa -l -g
# 显示硬链接数
exa -l -H
# 显示 inode
exa -l -i
# 显示扩展属性
exa -l -@
# 二进制大小前缀
exa -l -b
# 字节大小
exa -l -B
实际使用示例
bash
# 查看当前目录的详细信息,按大小排序
exa -l --sort=size
# 查看 Git 仓库的文件状态
exa -l --git
# 递归显示目录树,深度为 2
exa -T --level=2
# 显示所有文件(包括隐藏文件),目录优先
exa -a --group-directories-first
# 长列表视图,显示图标
exa -l --icons
# 查看特定目录
exa -l /path/to/directory
HarmonyOS 适配过程
项目特点
exa 是一个 Rust 项目,使用 Cargo 作为构建系统。与之前适配的 C/C++ 项目(如 unzip、whois)不同,Rust 项目的交叉编译需要特殊的配置。
适配挑战
- 构建系统差异:从 Makefile 转向 Cargo
- 交叉编译配置:需要配置 Rust 工具链和目标平台
- 链接器配置:需要正确配置 HarmonyOS SDK 的链接器
- 依赖管理:Rust 的依赖管理需要特殊处理
环境准备
1. 系统要求
- macOS(本文示例)或 Linux
- Rust 工具链(rustc 和 cargo)
- HarmonyOS SDK
- Python 3(用于构建脚本)
2. 安装 Rust 工具链
bash
# 检查 Rust 版本
rustc --version
cargo --version
# 如果未安装,使用 rustup 安装
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
3. 安装交叉编译目标
bash
# 添加 aarch64-unknown-linux-musl 目标
rustup target add aarch64-unknown-linux-musl
注意 :HarmonyOS 使用 musl libc,因此选择 aarch64-unknown-linux-musl 作为目标平台。
4. 环境变量设置
构建脚本会自动设置以下环境变量:
bash
export CC=${COMPILER_TOOLCHAIN}clang
export CXX=${COMPILER_TOOLCHAIN}clang++
export AR=${COMPILER_TOOLCHAIN}llvm-ar
export RANLIB=${COMPILER_TOOLCHAIN}llvm-ranlib
export STRIP=${COMPILER_TOOLCHAIN}llvm-strip
构建脚本详解
build_ohos.sh 完整代码
bash
export TREE_INSTALL_HNP_PATH=${HNP_PUBLIC_PATH}/exa.org/exa_0.10.1
# 创建安装目录
mkdir -p ${TREE_INSTALL_HNP_PATH}/usr/bin
mkdir -p ${TREE_INSTALL_HNP_PATH}/usr/share/man/man1
mkdir -p ${TREE_INSTALL_HNP_PATH}/usr/share/man/man5
# 设置 Rust 交叉编译目标
# HarmonyOS 使用 musl libc,目标架构是 aarch64
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}
# 清理之前的构建
echo "Cleaning previous build..."
cargo clean 2>/dev/null || true
# 构建 release 版本
echo "Building exa with cargo..."
cargo build --release --target ${TARGET} --verbose || {
echo "Error: Cargo build failed"
exit 1
}
# 检查构建产物
BINARY_PATH=${CARGO_TARGET_DIR}/${TARGET}/release/exa
if [ ! -f "${BINARY_PATH}" ]; then
echo "Error: Binary not found at ${BINARY_PATH}"
exit 1
fi
# 安装二进制文件
echo "Installing exa binary..."
cp ${BINARY_PATH} ${TREE_INSTALL_HNP_PATH}/usr/bin/exa || {
echo "Error: Failed to copy binary"
exit 1
}
# 设置可执行权限
chmod +x ${TREE_INSTALL_HNP_PATH}/usr/bin/exa
# 构建并安装 man pages(如果 pandoc 可用)
if command -v pandoc &> /dev/null; then
echo "Building man pages..."
pandoc --standalone -f markdown -t man man/exa.1.md > ${TREE_INSTALL_HNP_PATH}/usr/share/man/man1/exa.1 2>/dev/null || true
pandoc --standalone -f markdown -t man man/exa_colors.5.md > ${TREE_INSTALL_HNP_PATH}/usr/share/man/man5/exa_colors.5 2>/dev/null || true
fi
# 复制 hnp.json
cp hnp.json ${TREE_INSTALL_HNP_PATH}/ || {
echo "Error: Failed to copy hnp.json"
exit 1
}
# 打包
echo "Packaging..."
pushd ${TREE_INSTALL_HNP_PATH}/../
${HNP_TOOL} pack -i ${TREE_INSTALL_HNP_PATH} -o ${ARCHIVE_PATH}/ || {
echo "Error: HNP pack failed"
popd
exit 1
}
tar -zvcf ${ARCHIVE_PATH}/ohos_exa_0.10.1.tar.gz exa_0.10.1/ || {
echo "Error: Tar packaging failed"
popd
exit 1
}
popd
# 打印构建结果
echo ""
echo "=========================================="
echo "Build completed successfully!"
echo "=========================================="
echo "HNP Package: ${ARCHIVE_PATH}/exa.org_exa_0.10.1.hnp"
echo "Tar Archive: ${ARCHIVE_PATH}/ohos_exa_0.10.1.tar.gz"
echo "Installation Path: ${TREE_INSTALL_HNP_PATH}"
echo "=========================================="
echo ""
脚本关键点解析
1. 目标平台设置
bash
export TARGET=aarch64-unknown-linux-musl
选择 aarch64-unknown-linux-musl 是因为:
- HarmonyOS 使用 musl libc 而不是 glibc
- 目标架构是 aarch64(ARM64)
- Rust 标准库支持此目标平台
2. 工具链配置
bash
export CC_aarch64_unknown_linux_musl=${CC}
export CXX_aarch64_unknown_linux_musl=${CXX}
export AR_aarch64_unknown_linux_musl=${AR}
Cargo 使用特定格式的环境变量来配置交叉编译工具链:
CC_<target>:C 编译器CXX_<target>:C++ 编译器AR_<target>:归档工具RANLIB_<target>:归档索引工具STRIP_<target>:符号剥离工具
3. 链接器配置
bash
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=${CC}
设置链接器为 HarmonyOS SDK 的 clang,它会自动调用正确的链接器。
4. Cargo 构建
bash
cargo build --release --target ${TARGET} --verbose
--release:构建优化版本--target:指定目标平台--verbose:显示详细构建信息
关键问题解决
1. Cargo 配置文件
为了正确配置链接器参数,我们创建了 .cargo/config.toml 文件:
toml
[target.aarch64-unknown-linux-musl]
linker = "/var/folders/v9/zphc2yds1r568z2cy41mlrtc0000gn/T/linker-wrapper-XXXXXX.I4RDah500e"
rustflags = [
"-C", "link-arg=--target=aarch64-linux-ohos",
"-C", "link-arg=--sysroot=/Users/jianguo/Desktop/ohosdk/native/sysroot",
"-C", "link-arg=-fuse-ld=lld",
"-C", "link-arg=--ld-path=/Users/jianguo/Desktop/ohosdk/native/llvm/bin/ld.lld",
# 禁用 --as-needed 选项(LLD 不支持)
"-C", "link-arg=-Wl,--no-as-needed",
]
注意:这个配置文件中的路径是硬编码的,在实际使用中可能需要根据 SDK 路径调整。更好的做法是在构建脚本中动态生成此文件。
2. 链接器参数
HarmonyOS SDK 使用 LLD 链接器,需要传递特定的参数:
--target=aarch64-linux-ohos:指定目标平台--sysroot:指定系统根目录-fuse-ld=lld:使用 LLD 链接器--ld-path:指定链接器路径-Wl,--no-as-needed:禁用--as-needed选项(LLD 不支持)
3. Man Pages 构建
Man pages 是可选的,如果系统安装了 pandoc,会自动构建:
bash
if command -v pandoc &> /dev/null; then
pandoc --standalone -f markdown -t man man/exa.1.md > ${TREE_INSTALL_HNP_PATH}/usr/share/man/man1/exa.1
fi
HNP 包配置
hnp.json
json
{
"type":"hnp-config",
"name":"exa",
"version":"0.10.1",
"install":{}
}
这是一个简单的 HNP 包配置,定义了包的基本信息。
安装目录结构
exa_0.10.1/
├── usr/
│ ├── bin/
│ │ └── exa # 可执行文件
│ └── share/
│ └── man/
│ ├── man1/
│ │ └── exa.1 # 用户手册(如果可用)
│ └── man5/
│ └── exa_colors.5 # 颜色配置手册(如果可用)
└── hnp.json # HNP 包配置
构建结果
构建成功后,会生成以下文件:
-
HNP 包 :
exa.org_exa_0.10.1.hnp- HarmonyOS 原生包格式
- 可以直接安装到 HarmonyOS 设备
-
Tar 归档 :
ohos_exa_0.10.1.tar.gz- 压缩的 tar 归档
- 包含完整的安装目录结构
构建输出示例
==========================================
Build completed successfully!
==========================================
HNP Package: /path/to/archive/exa.org_exa_0.10.1.hnp
Tar Archive: /path/to/archive/ohos_exa_0.10.1.tar.gz
Installation Path: /path/to/data/service/hnp/exa.org/exa_0.10.1
==========================================
使用示例
在 HarmonyOS 上使用 exa
安装 HNP 包后,可以在 HarmonyOS 设备上使用 exa:
bash
# 基本使用
exa
# 长列表视图
exa -l
# 显示图标
exa --icons
# 树形视图
exa -T
# Git 集成
exa -l --git
# 按大小排序
exa -l --sort=size
# 递归显示,限制深度
exa -T --level=2
与 ls 的对比
bash
# 传统 ls 命令
ls -lah
# exa 等效命令
exa -lah
# exa 的优势:自动颜色、更好的格式、Git 集成
exa -l --git --icons
总结
适配要点
- 构建系统转换:从 Makefile 转向 Cargo,需要理解 Rust 的构建系统
- 交叉编译配置:正确配置 Rust 工具链和目标平台
- 链接器配置 :通过
.cargo/config.toml配置 HarmonyOS SDK 的链接器 - 环境变量:使用 Cargo 特定的环境变量格式配置工具链
优势
- 单二进制文件:exa 编译后是单个可执行文件,部署简单
- 高性能:Rust 编写,运行速度快
- 功能丰富 :相比
ls提供更多功能 - 现代化:支持 Git、图标、颜色等现代特性
适用场景
- 需要更好的文件列表显示体验
- 需要 Git 集成功能
- 需要树形视图显示目录结构
- 需要更丰富的文件元数据展示
FAQ
Q1: 为什么选择 aarch64-unknown-linux-musl 作为目标平台?
A: HarmonyOS 使用 musl libc 而不是 glibc,因此选择 musl 变体。架构是 aarch64(ARM64),这是 HarmonyOS 的主要架构。
Q2: 如何更新 .cargo/config.toml 中的 SDK 路径?
A: 可以在构建脚本中动态生成此文件,或者使用相对路径。当前版本使用硬编码路径,需要根据实际情况调整。
Q3: 构建失败怎么办?
A: 检查以下几点:
- Rust 工具链是否正确安装
- 交叉编译目标是否已添加:
rustup target add aarch64-unknown-linux-musl - HarmonyOS SDK 路径是否正确
- 环境变量是否正确设置
Q4: Man pages 是必需的吗?
A: 不是必需的。Man pages 是可选的,只有在系统安装了 pandoc 时才会构建。即使没有 man pages,exa 也可以正常使用。
Q5: 可以在其他架构上构建吗?
A: 当前配置针对 aarch64 架构。如果需要支持其他架构(如 x86_64),需要修改目标平台和相应的工具链配置。
Q6: 如何验证构建的二进制文件?
A: 可以使用 file 命令检查二进制文件:
bash
file target/aarch64-unknown-linux-musl/release/exa
应该显示类似:ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), ...
相关链接
- exa 官方网站:https://the.exa.website/
- exa GitHub 仓库:https://github.com/ogham/exa
- HarmonyOS 适配仓库:https://gitcode.com/nutpi/exa
- Rust 交叉编译文档:https://rust-lang.github.io/rustup/cross-compilation.html
- Cargo 配置文档:https://doc.rust-lang.org/cargo/reference/config.html
- HarmonyOS 开发者文档:https://developer.harmonyos.com/
- PC代码仓
- PC社区