exa 在 HarmonyOS 上的构建与适配

目录


项目简介

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 项目的交叉编译需要特殊的配置。

适配挑战

  1. 构建系统差异:从 Makefile 转向 Cargo
  2. 交叉编译配置:需要配置 Rust 工具链和目标平台
  3. 链接器配置:需要正确配置 HarmonyOS SDK 的链接器
  4. 依赖管理: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 包配置

构建结果

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

  1. HNP 包exa.org_exa_0.10.1.hnp

    • HarmonyOS 原生包格式
    • 可以直接安装到 HarmonyOS 设备
  2. 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

总结

适配要点

  1. 构建系统转换:从 Makefile 转向 Cargo,需要理解 Rust 的构建系统
  2. 交叉编译配置:正确配置 Rust 工具链和目标平台
  3. 链接器配置 :通过 .cargo/config.toml 配置 HarmonyOS SDK 的链接器
  4. 环境变量:使用 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: 检查以下几点:

  1. Rust 工具链是否正确安装
  2. 交叉编译目标是否已添加:rustup target add aarch64-unknown-linux-musl
  3. HarmonyOS SDK 路径是否正确
  4. 环境变量是否正确设置

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), ...


相关链接

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