#!/bin/bash
set -e
export PATH="/usr/bin:/bin:${PATH}"
export PKG_CONFIG=/usr/bin/false
LESS_VER=$(sed -e '/char version\[\]/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q version.c 2>/dev/null || echo "687")
export TREE_INSTALL_HNP_PATH=${HNP_PUBLIC_PATH}/gnu.org/less_${LESS_VER}
sys_prefix=${PREFIX}
export PREFIX=${TREE_INSTALL_HNP_PATH}
echo "${PREFIX}"
SDK_PATH=${OHOS_SDK:?错误: 未设置 OHOS_SDK,请从仓库根目录执行 ./build.sh --sdk <SDK路径> --module less}
SYSROOT=${SYSROOT:-${SDK_PATH}/native/sysroot}
LESS_TOP=$(pwd)
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/terminfo"
DEPS_DIR="${LESS_TOP}/.ohos_deps"
NCPREFIX="${DEPS_DIR}/ncurses-prefix"
NCURSES_VERSION=6.4
NCURSES_STAMP="${DEPS_DIR}/.ncurses_${NCURSES_VERSION}_built_fb2"
NCURSES_TGZ="${DEPS_DIR}/ncurses-${NCURSES_VERSION}.tar.gz"
_NPROC=$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
download_ncurses() {
local url ok=0
for url in \
"https://mirrors.ocf.berkeley.edu/gnu/ncurses/ncurses-${NCURSES_VERSION}.tar.gz" \
"https://mirrors.kernel.org/gnu/ncurses/ncurses-${NCURSES_VERSION}.tar.gz" \
"https://ftp.gnu.org/gnu/ncurses/ncurses-${NCURSES_VERSION}.tar.gz"
do
echo "Trying ${url} ..."
if curl -fsSL --connect-timeout 25 --max-time 600 "${url}" -o "${NCURSES_TGZ}.part"; then
mv -f "${NCURSES_TGZ}.part" "${NCURSES_TGZ}"
ok=1
break
fi
rm -f "${NCURSES_TGZ}.part"
done
if [ "${ok}" != 1 ]; then
echo "Error: could not download ncurses-${NCURSES_VERSION}.tar.gz from any mirror"
exit 1
fi
}
install_less_terminfo() {
local terminfo_src="${DEPS_DIR}/ncurses-${NCURSES_VERSION}/misc/terminfo.src"
local terminfo_out="${TREE_INSTALL_HNP_PATH}/usr/share/terminfo"
if [ ! -f "${terminfo_src}" ]; then
echo "Error: missing ${terminfo_src}"
exit 1
fi
mkdir -p "${terminfo_out}"
local copied=0
for src in /opt/homebrew/opt/ncurses/share/terminfo /usr/local/opt/ncurses/share/terminfo; do
if [ -d "${src}" ]; then
echo "Installing terminfo: copying full database from ${src}"
cp -a "${src}/." "${terminfo_out}/"
copied=1
break
fi
done
if [ "${copied}" != 1 ] && [ "$(uname -s)" = Linux ] && [ -d /usr/share/terminfo ]; then
local sz_k
sz_k=$(du -sk /usr/share/terminfo 2>/dev/null | awk '{print $1}')
if [ -n "${sz_k}" ] && [ "${sz_k}" -le 25600 ]; then
echo "Installing terminfo: copying /usr/share/terminfo ($((sz_k / 1024)) MB approx)"
cp -a /usr/share/terminfo/. "${terminfo_out}/"
copied=1
fi
fi
if [ "${copied}" != 1 ]; then
echo "Installing terminfo: compiling subset with tic (install Homebrew ncurses for a full DB)..."
local tic_bin=/usr/bin/tic
for c in /opt/homebrew/opt/ncurses/bin/tic /usr/local/opt/ncurses/bin/tic; do
if [ -x "$c" ]; then
tic_bin="$c"
break
fi
done
local entries="unknown,dumb,linux,linux-basic,linux2.6,linux3.0,vt100,vt100-am,vt102,ansi,\
xterm,xterm-256color,xterm-88color,xterm-color,xterm-mono,xterm-direct,\
screen,screen-256color,screen.xterm-256color,tmux,tmux-256color,\
alacritty,kitty,foot,foot-direct,vscode,vte-256color,gnome-256color,konsole-256color,\
st-256color,putty,putty-256color,mlterm,hterm,eterm-color,rxvt,rxvt-256color"
entries=$(echo "${entries}" | tr -d ' \n')
if ! "${tic_bin}" -x -e "${entries}" -o "${terminfo_out}" "${terminfo_src}" 2>/dev/null; then
echo "Note: extended terminfo subset failed with ${tic_bin}; retrying minimal entries..."
entries="unknown,dumb,linux,vt100,xterm,xterm-color,screen,ansi"
"${tic_bin}" -x -e "${entries}" -o "${terminfo_out}" "${terminfo_src}" || {
echo "Error: tic could not compile terminfo (macOS /usr/bin/tic is often too old; install: brew install ncurses)"
exit 1
}
fi
fi
}
build_ncurses_static() {
echo "Building static ncurses ${NCURSES_VERSION} for OHOS into ${NCPREFIX}..."
mkdir -p "${DEPS_DIR}"
cd "${DEPS_DIR}"
if [ ! -d "ncurses-${NCURSES_VERSION}" ]; then
if [ ! -f "${NCURSES_TGZ}" ]; then
download_ncurses
fi
echo "Extracting ncurses..."
tar -xzf "${NCURSES_TGZ}"
fi
cd "ncurses-${NCURSES_VERSION}"
if [ ! -f "${NCURSES_STAMP}" ]; then
[ -f Makefile ] && make distclean || true
case "$(uname -s)" in
Darwin)
for _ticp in /opt/homebrew/opt/ncurses/bin /usr/local/opt/ncurses/bin; do
if [ -x "${_ticp}/tic" ]; then
export PATH="${_ticp}:${PATH}"
echo "Using tic from ${_ticp} for ncurses build"
break
fi
done
_tic_which=$(command -v tic)
if [ "${_tic_which}" = "/usr/bin/tic" ]; then
echo "Error: macOS /usr/bin/tic (ncurses 6.0) cannot build ncurses 6.4 terminfo / fallbacks."
echo "Install: brew install ncurses (then re-run this script)"
exit 1
fi
;;
esac
./configure \
--host=aarch64-linux-gnu \
--prefix="${NCPREFIX}" \
--without-shared \
--enable-static \
--without-debug \
--without-ada \
--without-tests \
--without-manpages \
--without-progs \
--enable-widec \
--with-termlib \
--with-default-terminfo-dir=/usr/share/terminfo \
--with-fallbacks=unknown,dumb,vt100,vt102,ansi,linux,linux-basic,linux3.0,xterm,xterm-256color,xterm-color,xterm-mono,screen,screen-256color,tmux,tmux-256color \
--disable-stripping \
--without-cxx \
CC="${CC}" \
CPP="${CC} -E" \
AR="${AR}" \
RANLIB="${RANLIB}" \
CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" || {
echo "Error: ncurses configure failed"
exit 1
}
make -j"${_NPROC}" || {
echo "Error: ncurses make failed"
exit 1
}
make install.includes install.libs || {
echo "Error: ncurses install.includes/install.libs failed"
exit 1
}
touch "${NCURSES_STAMP}"
fi
cd "${LESS_TOP}"
}
build_ncurses_static
if [ ! -x ./configure ] || [ ! -f help.c ]; then
echo "Generating configure, help.c, funcs.h (git 源码树)..."
make -f Makefile.aut all || {
echo "Error: Makefile.aut all failed (need perl, autoconf, autoheader)"
exit 1
}
fi
if [ -f Makefile ]; then
make distclean 2>/dev/null || true
fi
echo "Configuring less..."
export CPP="${CC} -E"
./configure \
--host=aarch64-linux-gnu \
--prefix=/usr \
--with-regex=posix \
CC="${CC}" \
CPP="${CC} -E" \
CFLAGS="${CFLAGS}" \
CPPFLAGS="-I${NCPREFIX}/include -I${NCPREFIX}/include/ncursesw" \
LDFLAGS="${LDFLAGS} -L${NCPREFIX}/lib" \
|| {
echo "Error: less configure failed"
exit 1
}
echo "Building less..."
make -j"${_NPROC}" || {
echo "Error: less make failed"
exit 1
}
install_less_terminfo
export DESTDIR="${TREE_INSTALL_HNP_PATH}"
export prefix=/usr
install -d "${TREE_INSTALL_HNP_PATH}/usr/bin"
install -c -m 755 lesskey lessecho "${TREE_INSTALL_HNP_PATH}/usr/bin/" || {
echo "Error: lesskey/lessecho install failed"
exit 1
}
install -c -m 755 less "${TREE_INSTALL_HNP_PATH}/usr/bin/less.bin" || {
echo "Error: less binary install failed"
exit 1
}
_less_wrap="${TREE_INSTALL_HNP_PATH}/usr/bin/less"
cat > "${_less_wrap}" <<'WRAPPER'
_me=$0
case $_me in
*/*) ;;
*)
echo "less: 请通过带目录的路径调用本程序(例如 /path/to/usr/bin/less),勿依赖未解析的 PATH 名称。" >&2
exit 127
;;
esac
_bin=${_me%/*}
cd "$_bin" || exit 1
_binroot=$(pwd)
export TERMINFO_DIRS="${_binroot}/../share/terminfo${TERMINFO_DIRS:+:}${TERMINFO_DIRS:-}"
exec "${_binroot}/less.bin" "$@"
WRAPPER
chmod 755 "${_less_wrap}"
cp hnp.json "${TREE_INSTALL_HNP_PATH}/" || {
echo "Error: failed to copy hnp.json"
export PREFIX=${sys_prefix}
exit 1
}
echo "Packaging..."
pushd "${TREE_INSTALL_HNP_PATH}/../" > /dev/null
${HNP_TOOL} pack -i "${TREE_INSTALL_HNP_PATH}" -o "${ARCHIVE_PATH}/" || {
echo "Error: HNP pack failed"
popd > /dev/null
export PREFIX=${sys_prefix}
exit 1
}
tar -zvcf "${ARCHIVE_PATH}/ohos_less_${LESS_VER}.tar.gz" "less_${LESS_VER}/" || {
echo "Error: tar failed"
popd > /dev/null
export PREFIX=${sys_prefix}
exit 1
}
popd > /dev/null
export PREFIX=${sys_prefix}
echo ""
echo "=========================================="
echo "Build completed successfully!"
echo "=========================================="
echo "HNP: ${ARCHIVE_PATH}/less.hnp"
echo "Tar: ${ARCHIVE_PATH}/ohos_less_${LESS_VER}.tar.gz"
echo "=========================================="
echo ""