less 应用 OpenHarmony PC适配实践

news/2026/1/23 22:43:23/文章来源:https://www.cnblogs.com/gccbuaa/p/19524205

less 工具 OpenHarmony PC适配实践

目录


工具概述

less 是一个功能强大的终端分页器(terminal pager),用于在终端中查看文本文件的内容。它是 more 命令的增强版本,提供了更丰富的功能和更好的用户体验。

主要特点

效果

image-20251115130506193

版本信息


主要用途

1. 查看大型文件

less 特别适合查看大型日志文件或配置文件,因为它不会一次性加载整个文件到内存中,而是按需加载:

less /var/log/system.log
less /etc/config.conf

2. 查看命令输出

可以将命令的输出通过管道传递给 less

ps aux | less
history | less

3. 代码查看

支持语法高亮,适合查看源代码文件:

less source.c
less Makefile

4. 交互式浏览

提供了丰富的交互命令:

  • 空格键:向下翻页
  • b:向上翻页
  • /:向前搜索
  • ?:向后搜索
  • g:跳转到文件开头
  • G:跳转到文件结尾
  • q:退出

适配过程

1. 项目结构

less 使用传统的 autotools 构建系统(autoconf/automake),需要先运行 configure 脚本生成 Makefile

2. 构建系统分析

3. 适配步骤

步骤 1:配置构建脚本

创建 build_ohos.sh 脚本,设置 OpenHarmony 交叉编译环境:

#!/bin/bash
# less 工具 OpenHarmony 构建脚本
export LESS_INSTALL_HNP_PATH=${HNP_PUBLIC_PATH}/less.org/less_1.0.0
export PREFIX=${LESS_INSTALL_HNP_PATH}
mkdir -p ${LESS_INSTALL_HNP_PATH}
步骤 2:运行 configure

配置构建系统,指定目标平台:

sh configure \
--prefix=${PREFIX} \
--host=aarch64-linux-gnu \
CC="${CC}" \
CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" \
TERMLIBS="-ltermcap"
步骤 3:修复配置问题

由于交叉编译时 configure 无法运行测试程序,需要手动修复 defines.h 中的宏定义。

步骤 4:编译和安装
make VERBOSE=1
make install
步骤 5:打包 HNP

使用 HNP 工具打包应用:

${HNP_TOOL} pack -i ${LESS_INSTALL_HNP_PATH} -o ${ARCHIVE_PATH}/
tar -zvcf ${ARCHIVE_PATH}/ohos_less_1.0.0.tar.gz less_1.0.0/

遇到的问题与解决方案

问题 1:FILE 类型未定义

错误信息

error: unknown type name 'FILE'

原因分析
defines.hHAVE_STDIO_H 被设置为 #undef,导致 stdio.h 没有被包含,FILE 类型未定义。

解决方案
build_ohos.sh 中添加自动修复逻辑:

sed -i.bak 's/^#undef HAVE_STDIO_H$/#define HAVE_STDIO_H 1/' defines.h

问题 2:PATTERN_TYPE 类型未定义

错误信息

error: unknown type name 'PATTERN_TYPE'

原因分析
less 支持多种正则表达式库(GNU regex、POSIX regex、PCRE 等),但 OpenHarmony SDK 中这些库都不可用。PATTERN_TYPE 类型定义在 pattern.h 中,依赖于正则表达式库的宏定义。

解决方案
启用 NO_REGEX 宏,使 PATTERN_TYPE 定义为 void *

sed -i.bak 's/^#undef NO_REGEX$/#define NO_REGEX 1/' defines.h

问题 3:sprintf 未声明警告

错误信息

warning: call to undeclared library function 'sprintf'

原因分析
HAVE_SNPRINTF 未定义,代码回退到使用 sprintf,但 sprintf 未声明。

解决方案
启用 HAVE_SNPRINTF,使用 snprintf 替代 sprintf

sed -i.bak 's/^#undef HAVE_SNPRINTF$/#define HAVE_SNPRINTF 1/' defines.h

问题 4:sgtty.h 文件未找到

错误信息

fatal error: 'sgtty.h' file not found

原因分析
screen.c 中的包含逻辑会尝试包含 sgtty.h(旧式终端控制头文件),但 OpenHarmony SDK 不支持这个文件。

解决方案
启用 POSIX termios.h 支持:

sed -i.bak 's/^#undef HAVE_TERMIOS_H$/#define HAVE_TERMIOS_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_TERMIOS_FUNCS$/#define HAVE_TERMIOS_FUNCS 1/' defines.h

问题 5:INT_MAX 未定义

错误信息

error: use of undeclared identifier 'INT_MAX'

原因分析
HAVE_LIMITS_H 未定义,limits.h 没有被包含。

解决方案
启用 HAVE_LIMITS_H

sed -i.bak 's/^#undef HAVE_LIMITS_H$/#define HAVE_LIMITS_H 1/' defines.h

问题 6:termcap 函数未声明

错误信息

warning: call to undeclared function 'tgetflag'
warning: call to undeclared function 'tgetnum'
warning: call to undeclared function 'tgetstr'

原因分析
OpenHarmony SDK 中没有 termcap.h 头文件,termcap 函数未声明。

解决方案
创建 termcap_stub.htermcap_stub.c 提供 termcap 函数的声明和 stub 实现:

termcap_stub.h

#ifndef TERMCAP_STUB_H
#define TERMCAP_STUB_H
#include <stdio.h>extern int tgetflag(const char *id);extern int tgetnum(const char *id);extern char *tgetstr(const char *id, char **area);extern char *tgoto(const char *cap, int col, int row);extern int tgetent(char *bp, const char *name);extern int tputs(const char *str, int affcnt, int (*putc)(int));#ifndef TGETENT_OK#define TGETENT_OK 1#endif#endif /* TERMCAP_STUB_H */

termcap_stub.c

#include "termcap_stub.h"
#include <stdlib.h>#include <string.h>int tgetflag(const char *id) {(void)id;return 0;}int tgetnum(const char *id) {(void)id;return -1;}char *tgetstr(const char *id, char **area) {(void)id;(void)area;return NULL;}char *tgoto(const char *cap, int col, int row) {static char buf[32];snprintf(buf, sizeof(buf), "\033[%d;%dH", row + 1, col + 1);return buf;}int tgetent(char *bp, const char *name) {(void)bp;(void)name;return TGETENT_OK;}int tputs(const char *str, int affcnt, int (*putc)(int)) {(void)affcnt;if (str != NULL && putc != NULL) {while (*str) {putc(*str++);}}return 0;}

修改 screen.c,在找不到 termcap.h 时使用 stub:

#if HAVE_TERMCAP_H
#include <termcap.h>#else/* OpenHarmony doesn't have termcap.h, use stub */#include "termcap_stub.h"#endif

问题 7:termcap 函数链接错误

错误信息

ld.lld: error: undefined symbol: tgetstr
ld.lld: error: undefined symbol: tgetent

原因分析
termcap_stub.o 没有被添加到 Makefile 的 OBJ 变量中。

解决方案
build_ohos.sh 中添加逻辑,自动将 termcap_stub.o 添加到 Makefile:

if [ -f "./termcap_stub.c" ] && ! grep -q "termcap_stub" Makefile 2>/dev/null; then
echo "Adding termcap_stub.c to Makefile..."
awk '/^OBJ = /{in_obj=1} in_obj && /xbuf\.\${O}/{sub(/$/, " termcap_stub.${O}"); in_obj=0} {print}' Makefile > Makefile.tmp && mv Makefile.tmp Makefile || \
sed -i.bak '/^\t.*xbuf\.\${O}/s/$/ termcap_stub.${O}/' Makefile 2>/dev/null || \
sed -i '' '/^\t.*xbuf\.\${O}/s/$/ termcap_stub.${O}/' Makefile 2>/dev/null || true
fi

问题 8:open/time/strerror 函数未声明

错误信息

warning: call to undeclared function 'open'
warning: call to undeclared function 'time'
error: static declaration of 'strerror' follows non-static declaration

原因分析
相应的头文件宏定义未启用。

解决方案
启用 HAVE_FCNTL_HHAVE_TIME_HHAVE_STRERROR

sed -i.bak 's/^#undef HAVE_FCNTL_H$/#define HAVE_FCNTL_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_TIME_H$/#define HAVE_TIME_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_STRERROR$/#define HAVE_STRERROR 1/' defines.h

问题 9:lsystem 函数未定义

错误信息

ld.lld: error: undefined symbol: lsystem

原因分析
lsystem 函数在 lsystem.c 中被 #if HAVE_SYSTEM 条件编译保护,但 HAVE_SYSTEM 未定义。

解决方案
启用 HAVE_SYSTEM

sed -i.bak 's/^#undef HAVE_SYSTEM$/#define HAVE_SYSTEM 1/' defines.h

问题 10:手册页文件缺失

错误信息

make: *** No rule to make target 'lesskey.nro', needed by 'install'. Stop.

原因分析
make install 需要 lesskey.nrolessecho.nro 手册页文件,但这些文件不存在。

解决方案
在安装前创建占位文件:

if [ ! -f "./lesskey.nro" ]; then
cp lesskey.nro.VER lesskey.nro 2>/dev/null || touch lesskey.nro
fi
if [ ! -f "./lessecho.nro" ]; then
cp lessecho.nro.VER lessecho.nro 2>/dev/null || touch lessecho.nro
fi

构建脚本说明

build_ohos.sh 关键部分

1. 环境设置
export LESS_INSTALL_HNP_PATH=${HNP_PUBLIC_PATH}/less.org/less_1.0.0
export PREFIX=${LESS_INSTALL_HNP_PATH}
mkdir -p ${LESS_INSTALL_HNP_PATH}
2. Configure 配置
sh configure \
--prefix=${PREFIX} \
--host=aarch64-linux-gnu \
CC="${CC}" \
CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" \
TERMLIBS="-ltermcap"
3. 自动修复 defines.h
# 修复关键宏定义
sed -i.bak 's/^#undef HAVE_STDIO_H$/#define HAVE_STDIO_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_SNPRINTF$/#define HAVE_SNPRINTF 1/' defines.h
sed -i.bak 's/^#undef NO_REGEX$/#define NO_REGEX 1/' defines.h
sed -i.bak 's/^#undef HAVE_TERMIOS_H$/#define HAVE_TERMIOS_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_TERMIOS_FUNCS$/#define HAVE_TERMIOS_FUNCS 1/' defines.h
sed -i.bak 's/^#undef HAVE_LIMITS_H$/#define HAVE_LIMITS_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_FCNTL_H$/#define HAVE_FCNTL_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_TIME_H$/#define HAVE_TIME_H 1/' defines.h
sed -i.bak 's/^#undef HAVE_STRERROR$/#define HAVE_STRERROR 1/' defines.h
sed -i.bak 's/^#undef HAVE_SYSTEM$/#define HAVE_SYSTEM 1/' defines.h
4. 添加 termcap_stub 到 Makefile
if [ -f "./termcap_stub.c" ] && ! grep -q "termcap_stub" Makefile 2>/dev/null; then
awk '/^OBJ = /{in_obj=1} in_obj && /xbuf\.\${O}/{sub(/$/, " termcap_stub.${O}"); in_obj=0} {print}' Makefile > Makefile.tmp && mv Makefile.tmp Makefile
fi
5. 创建手册页占位文件
if [ ! -f "./lesskey.nro" ]; then
cp lesskey.nro.VER lesskey.nro 2>/dev/null || touch lesskey.nro
fi
if [ ! -f "./lessecho.nro" ]; then
cp lessecho.nro.VER lessecho.nro 2>/dev/null || touch lessecho.nro
fi

关键修复总结

修复的宏定义

宏定义修复前修复后用途
HAVE_STDIO_H#undef#define HAVE_STDIO_H 1FILE 类型定义
HAVE_SNPRINTF#undef#define HAVE_SNPRINTF 1使用 snprintf
NO_REGEX#undef#define NO_REGEX 1PATTERN_TYPE 定义
HAVE_TERMIOS_H#undef#define HAVE_TERMIOS_H 1POSIX termios 支持
HAVE_TERMIOS_FUNCS#undef#define HAVE_TERMIOS_FUNCS 1termios 函数支持
HAVE_LIMITS_H#undef#define HAVE_LIMITS_H 1INT_MAX 定义
HAVE_FCNTL_H#undef#define HAVE_FCNTL_H 1open 函数声明
HAVE_TIME_H#undef#define HAVE_TIME_H 1time 函数声明
HAVE_STRERROR#undef#define HAVE_STRERROR 1使用系统 strerror
HAVE_SYSTEM#undef#define HAVE_SYSTEM 1lsystem 函数编译

创建的新文件

  1. termcap_stub.h - termcap 函数声明
  2. termcap_stub.c - termcap 函数 stub 实现

修改的文件

  1. screen.c - 添加 termcap_stub.h 包含逻辑
  2. build_ohos.sh - 添加自动修复和构建逻辑

使用示例

基本使用

# 查看文件
less filename.txt
# 查看命令输出
ps aux | less
# 搜索文本(在 less 中)
/pattern    # 向前搜索
?pattern    # 向后搜索
n           # 下一个匹配
N           # 上一个匹配

常用命令

命令功能
空格键向下翻页
b向上翻页
g跳转到文件开头
G跳转到文件结尾
/pattern向前搜索
?pattern向后搜索
q退出
h显示帮助

总结

适配难点

  1. 交叉编译限制configure 脚本无法运行测试程序,需要手动修复配置
  2. 依赖库缺失:OpenHarmony SDK 中没有 termcap 库,需要创建 stub 实现
  3. 头文件缺失:多个标准头文件的宏定义需要手动启用
  4. 条件编译:大量使用条件编译,需要正确设置宏定义

适配成果

经验总结

  1. 交叉编译适配:对于使用 autotools 的项目,需要仔细检查 configure 生成的 defines.h,手动修复无法正确检测的宏定义
  2. 依赖库处理:对于缺失的系统库,可以创建 stub 实现,提供最小功能支持
  3. 自动化构建:使用脚本自动修复配置问题,提高构建效率
  4. 文档记录:详细记录遇到的问题和解决方案,便于后续维护

后续优化建议

  1. termcap 功能增强:可以改进 termcap_stub.c 的实现,提供更完整的终端控制功能
  2. 正则表达式支持:如果 OpenHarmony SDK 未来支持正则表达式库,可以启用相应的宏定义
  3. 测试验证:在实际的 OpenHarmony 设备上测试 less 的功能,确保所有特性正常工作

参考资料

参考资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1206775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

导师严选10个AI论文写作软件,专科生搞定毕业论文!

导师严选10个AI论文写作软件&#xff0c;专科生搞定毕业论文&#xff01; AI工具如何让论文写作变得轻松高效 对于专科生来说&#xff0c;撰写毕业论文往往是一项既紧张又复杂的任务。从选题、查资料到撰写和降重&#xff0c;每一个环节都可能成为压力源。而随着AI技术的不断发…

opencode.ai

opencode.ai 是一个基于终端的 AI 编程助手平台&#xff0c;为开发者提供了一个集成式的智能编程环境。通过深入研究该平台的官方文档&#xff0c;我们将全面梳理其技术架构体系和使用指南&#xff0c;为技术选型和学习路径提供参考。 本报告重点关注两个核心维度&#xff1a;…

Java计算机毕设之基于Java的歌唱演出网站订票系统基于SpringBoot的演唱会门票购票网站系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【毕业设计】基于springboot的高校食堂点餐系统(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【课程设计/毕业设计】基于Java+SpringBoot的演出购票系统基于springboot的演出网站订票系统【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

linux 安装 Nvidia 显卡驱动,配置 NVIDIA Container Toolkit

以 ubuntu-server 24.04 上运行 netdata v1.47 为例 一、驱动安装 1、安装显卡驱动 https://www.nvidia.com/en-us/drivers/ 选择显卡型号下载驱动安装文件,比如:NVIDIA-Linux-x86_64-580.126.09.run 执行安装:chmo…

Django REST Framework (DRF) 认证与异常处理完全指南

一、核心问题分析 在 DRF 开发中,身份认证失败时应返回 401 Unauthorized,但开发者常遇到以下问题:直接使用 raise ValidationError 导致返回错误状态码 400(Bad Request) 手动设置 Response(..., status=401) 破…

ESP32-S3定义输出引脚+延时亮灭

//空设置,void setup() //定义LED的引脚,第13脚 int led_pin =13; void setup() { //设定引脚为输出模式 pinMode(led_pin, OUTPUT);// put your setup code here, to run once: //放置你的设置代码只运行一次 //点…

使用cppcheck对代码静态分析

在 C/C++ 开发中,除了编译器的基础语法检查,静态代码分析工具能帮我们提前发现潜在的逻辑错误、内存泄漏、性能问题等“隐藏Bug”。cppcheck作为一款开源、跨平台、轻量级的静态分析工具,无需编译代码即可扫描,支持…

Java毕设选题推荐:基于SpringBoot+vue的演唱会门票购票网站系统基于springboot的演出网站订票系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

01vue3学习-创建项目

1、创建项目npm create vue@latest按提示输入 2、安装依赖包npm install3、安装插件TypeScript Vue Plugin (Volar)Vue Language Features (Volar 4、运行项目npm run dev

Java毕设项目:基于springboot的演出网站订票系统(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【毕业设计】基于springboot的演出网站订票系统(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

土壤水分温度盐分ph测定仪:可同步获取土壤水分、温度、盐分(电导率)及pH值等关键指标

土壤水分温度盐分pH测定仪是一款集多参数测量功能于一体的专业农业监测设备&#xff0c;可同步获取土壤水分、温度、盐分&#xff08;电导率&#xff09;及pH值等关键指标&#xff0c;为农业生产、土壤研究及环境监测提供全面数据支持。该测定仪采用一体化设计&#xff0c;体积…

LeGO-LOAM 激光里程计计算roll,pitch,tz增量详解

LeGO-LOAM 激光里程计计算\(t_z, \theta_{roll}/r_x, \theta_{pitch}/r_y\) 我们用点\(\boldsymbol{p_i}\)、\(\boldsymbol{p_i}\)分别代表原始点云、变换后(车子在动引起)点云中的点,目标是求得位姿变换\(\boldsym…

字符设备驱动程序

Linux 驱动程序开发概述①应用程序、库、内核、驱动程序的关系以点亮一个 LED 为例&#xff0c;这 4 层软件的协作关系如下所示&#xff1a;应用程序使用库提供的 open 函数打开代表 LED 的设备文件。库根据 open 函数传入的参数执行“swi”指令&#xff0c;这条指令会引起 CPU…

testing

今天是2026-01-23,是我注册博客园的第一天,让我们写个博客测试一下吧,好了,拜拜!

两个 Docker 容器如何通信?Docker 网络问题完整踩坑与解决指南

NebulaGraph Studio 连接失败&#xff1f;Docker 网络问题完整踩坑与解决指南&#xff08;小白友好&#xff09; 一、问题背景 我在本地使用 Docker 部署 NebulaGraph 集群&#xff0c;同时使用 Nebula Graph Studio&#xff08;Web UI&#xff09; 进行可视化管理。 Nebula Gr…

芒格的“避免失败“原则在前沿科技投资中的重要性

芒格的"避免失败"原则在前沿科技投资中的重要性关键词&#xff1a;芒格、避免失败原则、前沿科技投资、风险控制、投资策略摘要&#xff1a;本文深入探讨了芒格的“避免失败”原则在前沿科技投资领域的重要性。通过对该原则的背景介绍&#xff0c;阐述其核心概念及与…

关与短链接API,其中稳定无毒的少之又少。

关与短链接API,其中稳定无毒的少之又少。关与短链接,一直想自己开发,开发一个也不是很难,后来想了又想,自己搭建需要购买服务器和域名。 于是就在网上查找关于稳定的API接口,有各种各样的,其中稳定无毒的少之又少…