麒麟 V10(ARM64 / aarch64)源码编译 3dtiles 全步骤
| 内容 | 描述 |
|---|---|
| 适用环境 | 银河麒麟 V10(aarch64) |
| 项目源码 | github.com/fanvanzh/3d... |
| 项目技术栈 | Rust(CLI 与格式解析)+ C++(CMake 构建,OSG / GDAL 几何处理),第三方依赖全部由 vcpkg 从源码编译 |
| 文档说明 | 本文按最终验证通过的顺序编排,命令可直接复制执行 |
| 问题归类 | 文档末尾「问题归类」汇总了本次编译遇到的全部 14 个问题及其解决方案 |
前言:总览与路径约定
1、关键路径与变量
**后续命令统一使用以下路径,若你的实际路径不同,请整体替换:
| 变量 | 本项目取值 | 说明 |
|---|---|---|
| VCPKG_ROOT | /usr/local/gis-sources/vcpkg | vcpkg 安装目录 |
| 源码目录 | /data/build/3dtiles | 3dtiles 源码根目录 |
| 编译器 | /usr/local/bin/gcc、/usr/local/bin/g++ | 版本需大于或等于C++20 |
| binutils | /usr/local/bin/as、/usr/local/bin/ld | 升级到 2.42 后的新版 |
| 2、全过程流程 | ||
| **```diff |
- 环境准备:基础工具 / binutils 2.42 / cc 软链 / Rust / vcpkg / ninja / 下载加速
- 获取源码:git clone --recursive
- 打源码补丁:build.rs 4 处 + cargo 配置 + shape.rs
- 装 vcpkg 依赖:vcpkg install(最耗时,1~3 小时)
- cargo 编译:链接顺序 + C++ 运行库
- 验证产物:验证 ELF 架构与数据目录
**3、编译期常用环境变量(编译前必须设置)**
**```bash
# vcpkg 安装目录(build.rs 强制要求,未设置会直接 panic)
export VCPKG_ROOT=/usr/local/gis-sources/vcpkg
# 目标三元组:ARM64 Linux
export VCPKG_DEFAULT_TRIPLET=arm64-linux
# 声明依赖已手工装好,让 cmake 复用而不是往 cargo 输出目录重装一遍(关键,省数小时)
export VCPKG_HAS_BEEN_INSTALLED=1
# 让 cmake 能找到 vcpkg 工具链脚本
export PATH="$VCPKG_ROOT:/usr/local/bin:$PATH"
第一部分:环境准备
1.1 安装系统基础工具与开发库
**```bash
安装 vcpkg 编译众多 C/C++ 库所需的基础构建工具
autoconf 系列:大量第三方库仍使用 autotools 构建
sudo dnf install -y autoconf autoconf-archive automake libtool pkgconf-pkg-config
bison flex perl perl-IPC-Cmd curl wget zip unzip tar patch which
安装 OpenGL 与 X11 开发库(OSG 配置、编译、链接必需,缺失会直接导致 osg 构建失败)
sudo dnf install -y mesa-libGL-devel mesa-libGLU-devel
libX11-devel libXrandr-devel libXi-devel libXxf86vm-devel
安装 glibc 开发包(链接分体式 .o 时必需)
sudo dnf install -y glibc-devel
安装 texinfo(提供 makeinfo,用于生成 binutils 手册)
如果装不上或不需要文档,可跳过;后续编译 binutils 时用 MAKEINFO=true 绕过
sudo dnf install -y texinfo
**1.2、确认编译器版本(必须支持 C++20)**
**```bash
# 查看 g++ 版本:项目 CMakeLists 写死 CMAKE_CXX_STANDARD 20,要求 g++ ≥ 11
g++ --version | head -1
# 查看 gcc 版本
gcc --version | head -1
# 查看 CMake 版本:项目要求 ≥ 3.22(vcpkg 会自备更高版本 cmake,一般无需单独升级)
cmake --version | head -1
说明:若系统自带 gcc/g++ 低于 11,需要单独升级。本次采用把新版安装到 /usr/local 的方式(未覆盖系统 /usr/bin/gcc)。 注意:build.rs 把编译器路径硬编码为 /usr/bin/gcc、/usr/bin/g++,若新版装在 /usr/local/bin,必须在第三部分把这两处路径改掉,否则新编译器不会被使用,编译仍会因 C++20 失败。 或者可以创建软链接将/usr/bin/gcc指向/usr/local/bin/gcc,命令如下:
bash
# 备份旧工具
mv /usr/bin/gcc /usr/bin/gcc.bak
mv /usr/bin/g++ /usr/bin/g++.bak
# 创建软链接
ln -sf /usr/local/bin/gcc /usr/bin/gcc
ln -sf /usr/local/bin/g++ /usr/bin/g++
1.3、升级 binutils 到 2.42(解决 libdeflate 的 eor3 汇编报错)
**```bash
进入临时目录
cd /tmp
下载 binutils 2.42 源码(sourceware 官方源,走 mirrorservice 镜像)
curl -L -o binutils-2.42.tar.xz
"https://mirrorservice.org/sites/sourceware.org/pub/binutils/releases/binutils-2.42.tar.xz"
解压源码
tar xf binutils-2.42.tar.xz
进入源码目录
cd binutils-2.42
清理旧构建目录,新建干净的构建目录(避免上次失败配置残留)
rm -rf build && mkdir build && cd build
配置:只编译核心工具,禁用所有在麒麟 ARM 上会报错的附属组件
--disable-gprofng 禁用高性能分析器(libgp_collector 在 ARM 上编译失败)
--disable-gold 禁用 gold 链接器(用不到,且可能与系统库冲突)
--disable-libctf 禁用 CTF 调试格式(用不到)
--disable-nls 禁用多语言支持(精简依赖)
--disable-werror 不让警告中断编译(新版 gcc 告警更严格)
--without-zstd / --without-debuginfod 去掉两个可选依赖
--disable-shared 核心组件静态化,避免运行库依赖问题
../configure --prefix=/usr/local
--disable-nls
--disable-werror
--disable-gprofng
--disable-gold
--disable-libctf
--without-zstd
--without-debuginfod
--disable-shared
编译:MAKEINFO=true 让文档目标变成空操作,绕过缺少 makeinfo 导致的 bfd.info 报错
该操作不影响功能:tarball 自带预生成的 bfd.info,make install 时照样能装
不装 texinfo 时这一步是必需的
make MAKEINFO=true -j"$(nproc)" 2>&1 | tee /tmp/binutils-make.log
安装到 /usr/local(需要 sudo)
sudo make MAKEINFO=true install
验证核心工具版本(应输出 2.42)
/usr/local/bin/as --version | head -1
/usr/local/bin/ld --version | head -1
make install 只会生成无前缀名(as、ld、ar、ranlib...),不会自动创建 /usr/bin/as 的软链接,需要下一步手工处理。
**1.4、让系统使用新版 as/ld,并补齐 cc / c++ 软链接**
**```bash
# 让 shell 优先命中 /usr/local/bin 下的新版工具
export PATH=/usr/local/bin:$PATH
# 写入 shell 配置,保证新终端也生效
echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bashrc
# 确认 gcc 实际调用的汇编器(输出完整路径即为新版;只输出裸 as 则按 PATH 查找)
gcc -print-prog-name=as
# 验证新版 as / ld
as --version | head -1
ld --version | head -1
# 建立 cc / c++ 软链接
# 原因:Rust 在 Linux 上默认用 "cc" 作为链接器驱动名,系统若无 cc 会直接报 linker `cc` not found
# 指向与 vcpkg 编译依赖时一致的编译器,避免工具链不一致导致依赖被判定过期而重装
sudo ln -sfn /usr/local/bin/gcc /usr/bin/cc
sudo ln -sfn /usr/local/bin/g++ /usr/bin/c++
# 验证 cc 可用并能完成一次链接
cc --version | head -1
printf 'int main(void){return 0;}\n' > /tmp/t.c && cc /tmp/t.c -o /tmp/t && /tmp/t && echo "cc 链接正常"
# 自检:编译一条 eor3 指令,通过则说明汇编器已支持(libdeflate 的问题从根上解决)
cat > /tmp/eor3_test.c <<'EOF'
#include <arm_neon.h>
__attribute__((target("+crypto,+crc,+sha3")))
void test(uint8x16_t *a, uint8x16_t *b, uint8x16_t *c, uint8x16_t *out) {
*out = veor3q_u8(*a, *b, *c);
}
EOF
/usr/local/bin/gcc -march=armv8-a -c /tmp/eor3_test.c -o /tmp/eor3_test.o \
&& echo "✓ 汇编器接受 eor3"
1.5、安装 Rust 工具链
**```bash
安装 Rust 稳定版(含 rustc / cargo / rustup)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
加载 cargo 环境变量
source "$HOME/.cargo/env"
验证:Host 应为 aarch64-unknown-linux-gnu
rustc -vV
若 crates.io 拉包慢,可在 \~/.cargo/config.toml 配置国内镜像源。
**1.6、安装 vcpkg**
**```bash
# 创建源码存放目录
mkdir -p /usr/local/gis-sources && cd /usr/local/gis-sources
# 完整克隆 vcpkg(不要加 --depth 1)
# 原因:项目 vcpkg.json 锁定了 builtin-baseline 提交,浅克隆拿不到该提交
git clone https://github.com/microsoft/vcpkg.git
# 进入 vcpkg 目录
cd vcpkg
# 切换到与项目 builtin-baseline 完全一致的提交
# 好处:各 port 版本与官方 CI 一致,避开"新版 port 在 ARM 上炸了"的随机问题
git checkout 84bab45d415d22042bd0b9081aea57f362da3f35
# 引导生成 vcpkg 可执行文件
./bootstrap-vcpkg.sh
# 配置环境变量并验证
export VCPKG_ROOT=/usr/local/gis-sources/vcpkg
export PATH="$VCPKG_ROOT:$PATH"
vcpkg version
1.7、安装 ninja(≥ 1.12.1)
**```bash
先检查系统是否已有满足要求的 ninja(vcpkg 要求 ≥ 1.12.1)
ninja --version 2>/dev/null || echo "系统未安装 ninja"
若未安装或版本过低:下载官方 aarch64 二进制(走加速通道)
cd /tmp
curl -L -o ninja.zip
"https://gh-proxy.com/https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux-aarch64.zip"
解压并安装到 /usr/local/bin
unzip -o ninja.zip -d ninja-pkg
sudo install -m 755 ninja-pkg/ninja /usr/local/bin/ninja
验证版本
ninja --version
系统里有了合格 ninja,vcpkg 就不会去联网下载,可彻底避开 ninja-linux-aarch64-1.13.1.zip 的 404 问题。
**1.8、配置 vcpkg 下载加速**
**```bash
# 安装下载包装脚本(脚本文末见附录 A)
sudo install -m 755 vcpkg-dl.sh /usr/local/bin/vcpkg-dl.sh
# 让 vcpkg 通过该脚本获取所有资源
# 注意占位符顺序必须是 {url} {sha512} {dst},脚本会按镜像优先、失败回源,并用 sha512 校验
export X_VCPKG_ASSET_SOURCES="x-script,/usr/local/bin/vcpkg-dl.sh {url} {sha512} {dst}"
# 写入 shell 配置,保证长期生效
echo 'export X_VCPKG_ASSET_SOURCES="x-script,/usr/local/bin/vcpkg-dl.sh {url} {sha512} {dst}"' >> ~/.bashrc
# 清理已废弃的旧变量(新版 vcpkg 已不再识别 VCPKG_DOWNLOAD_MIRROR,留着反而可能干扰)
unset VCPKG_DOWNLOAD_MIRROR
sed -i '/VCPKG_DOWNLOAD_MIRROR/d' ~/.bashrc
第二部分:获取源码
bash
# 创建编译工作目录
mkdir -p /data/build && cd /data/build
# 克隆项目并同时初始化所有子模块(thirdparty/ufbx、thirdparty/base64 等)
git clone --recursive https://github.com/fanvanzh/3dtiles.git
# 进入源码目录
cd 3dtiles
# 若上一步漏了 --recursive,用这条补拉子模块
git submodule update --init --recursive
第三部分:打源码补丁(必做,共 3 类 6 处)
3.1、build.rs 四处补丁
**为什么必须打:build.rs 的目标匹配表只认 4 个平台,ARM64 Linux 会落进空分支,导致 cmake 根本不执行、C++ 静态库不生成、vcpkg 依赖不触发,最终链接时报找不到符号。
bash
# 先备份原始文件(便于出错时还原)
cp build.rs build.rs.bak
# 打印关键位置,便于核对(正常输出:723 目标匹配、219 x64-linux、189/190/191 编译器与 make)
grep -n 'x86_64-unknown-linux-gnu" =>\|join("x64-linux")\|CMAKE_MAKE_PROGRAM\|CMAKE_C_COMPILER\|CMAKE_CXX_COMPILER' build.rs
# 一次性完成四处补丁(幂等,可重复执行)
python3 - <<'PY'
import pathlib
p = pathlib.Path('build.rs'); s = p.read_text(encoding='utf-8')
# ① 补 aarch64 Linux 目标分支(原表只匹配 x86_64 Linux / Windows / macOS)
if '"aarch64-unknown-linux-gnu" =>' not in s:
s = s.replace('"x86_64-unknown-linux-gnu" => build_linux_unknown(),',
'"x86_64-unknown-linux-gnu" => build_linux_unknown(),\n'
' "aarch64-unknown-linux-gnu" => build_linux_unknown(),', 1)
# ② vcpkg 依赖目录的 triplet 名:x64-linux -> arm64-linux(全文件仅此一处,可安全替换)
s = s.replace('.join("x64-linux")', '.join("arm64-linux")')
# ③④ 仅修改 build_linux_unknown 段,避免误伤 macOS / Windows 两个函数
i, j = s.find('fn build_linux_unknown'), s.find('fn build_macos')
seg = s[i:j]
# ③ 给 Linux 分支传 --allow-unsupported
# 原因:cmake 每次配置都会无条件执行一次 vcpkg install,而 basisu 的 supports 封条会直接 fatal
# 上游只给 macOS 分支加了这一行,Linux 分支漏了
if 'VCPKG_INSTALL_OPTIONS' not in seg:
seg = seg.replace('.define("CMAKE_MAKE_PROGRAM", "/usr/bin/make")',
'.define("CMAKE_MAKE_PROGRAM", "/usr/bin/make")\n'
' .define("VCPKG_INSTALL_OPTIONS", "--allow-unsupported")', 1)
# ④ 编译器路径改为与 vcpkg 编译依赖时一致的新版编译器
# 原因:路径不一致会导致 vcpkg 重算 ABI、判定依赖过期并把几十个包全部重装
seg = seg.replace('.define("CMAKE_C_COMPILER", "/usr/bin/gcc")',
'.define("CMAKE_C_COMPILER", "/usr/local/bin/gcc")')
seg = seg.replace('.define("CMAKE_CXX_COMPILER", "/usr/bin/g++")',
'.define("CMAKE_CXX_COMPILER", "/usr/local/bin/g++")')
s = s[:i] + seg + s[j:]
p.write_text(s, encoding='utf-8'); print('build.rs 补丁完成')
PY
# 核对:应看到 aarch64 目标分支 1 行、arm64-linux 1 行、VCPKG_INSTALL_OPTIONS 2 行(Linux + macOS)
grep -n 'aarch64-unknown-linux-gnu" =>\|join("arm64-linux")\|VCPKG_INSTALL_OPTIONS\|CMAKE_CXX_COMPILER' build.rs
不能全局替换 CMAKE_MAKE_PROGRAM:它在文件中出现 3 次(191 / 331 / 476 行,分属三个平台函数),全局替换会误伤另外两个平台。上面的脚本已按函数段定位。 不要改 x64-windows / x64-osx / arm64-osx 那几处。
3.2、.cargo/config.toml:链接器与链接参数配置
**为什么必须改:前者解决 linker cc not found,后者解决 C++ 运行库与静态库的链接顺序问题。
bash
# 备份 cargo 配置
cp .cargo/config.toml .cargo/config.toml.bak
# 先查看现有内容,确认是否已有 [target.aarch64-unknown-linux-gnu] 段
# 若已有该段,请把下面两行合并进去,不要重复写段头
cat .cargo/config.toml
# 追加目标平台配置:指定链接器包装脚本 + 在链接命令末尾补 C++ 运行库
cat >> .cargo/config.toml <<'EOF'
[target.aarch64-unknown-linux-gnu]
linker = "/usr/local/bin/3dtiles-link-wrapper.sh"
rustflags = ["-C", "link-arg=-lstdc++"]
EOF
- linker 指向链接器包装脚本(脚本文末见附录 B),它把所有 -l 库包进 --start-group/--end-group,彻底消除静态库顺序依赖,这是解决大批 undefined reference 的关键。
- rustflags 里的 -C link-arg=-lstdc++ 位于链接命令最末端,确保 C++ 运行库在静态库之后被解析。
- cargo 规则:target..rustflags 优先于且不合并 build.rustflags。因此项目自带的那句 rustflags = "-D", "warnings" 会被自动忽略------这恰好也避免了新版 Rust 的告警中断构建。
若你希望保留 build 段的写法而不额外指定 rustflags,可只保留 linker 一行(仅用 g++ 驱动也有同等效果),但要确保包装脚本存在。
3.3、src/shape.rs:修复 Rust 1.99 的弃用常量
**为什么必须改:项目 .cargo/config.toml 里 rustflags = "-D", "warnings" 把警告升级为错误,而 Rust 1.99.0 起 std::f64::{INFINITY, NEG_INFINITY} 等一批模块级常量被弃用,直接导致编译中断。
bash
# 备份源文件
cp src/shape.rs src/shape.rs.bak
# 把弃用的导入改成关联常量常量定义(4 个使用点无需改动)
python3 - <<'PY'
import pathlib
p = pathlib.Path('src/shape.rs'); s = p.read_text(encoding='utf-8')
old = 'use std::f64::{INFINITY, NEG_INFINITY};'
new = ('const INFINITY: f64 = f64::INFINITY;\n'
'const NEG_INFINITY: f64 = f64::NEG_INFINITY;')
assert s.count(old) == 1, '未找到唯一匹配,请手工检查第 48 行'
p.write_text(s.replace(old, new), encoding='utf-8'); print('shape.rs 补丁完成')
PY
# 核对(第 48 行起应已变成两条 const 定义)
sed -n '48,50p' src/shape.rs
注意:不要改成 use std::f64::consts::{INFINITY, NEG_INFINITY};------consts 子模块里现在只有数学常数,不含这两个符号,会直接报 E0432 导入失败。 正确替代就是编译器提示的关联常量 f64::INFINITY / f64::NEG_INFINITY。
3.4、安装链接器包装脚本
**```bash
创建包装脚本(完整内容也可对照附录 B)
sudo tee /usr/local/bin/3dtiles-link-wrapper.sh >/dev/null <<'SCRIPT'
#!/bin/bash
链接器包装脚本:把所有 -l 库包进 --start-group/--end-group,
消除 GNU ld 单遍扫描造成的静态库顺序依赖(解决大批 undefined reference)
GXX="{GXX:-/usr/local/bin/g++}"
args=("@"); out=(); opened=0
for a in "{args[@]}"; do
case "a" in
-l*) if [ "opened" -eq 0 ]; then out+=("-Wl,--start-group"); opened=1; fi
out+=("a");;
*) out+=("a");;
esac
done
if [ "opened" -eq 1 ]; then out+=("-Wl,-Bdynamic" "-Wl,--end-group"); fi
exec "GXX" "{out[@]}"
SCRIPT
赋予执行权限
sudo chmod +x /usr/local/bin/3dtiles-link-wrapper.sh
验证脚本可执行
bash -n /usr/local/bin/3dtiles-link-wrapper.sh && echo "脚本语法正常"
第四部分:安装 vcpkg 依赖(最耗时,1~3 小时)
进入项目目录
cd /data/build/3dtiles
配置环境变量
export VCPKG_ROOT=/usr/local/gis-sources/vcpkg
export PATH="VCPKG_ROOT:PATH"
export VCPKG_DEFAULT_TRIPLET=arm64-linux
安装全部依赖
--allow-unsupported:放行 basisu 在 arm64 上的平台限制(该 port 的 supports 元数据只写了 x86|x64,
但其构建脚本没有 x86 硬依赖,非 MSVC 下默认关闭 SSE,可正常编译)
vcpkg install --triplet arm64-linux --allow-unsupported
成功标志:项目根目录出现 vcpkg_installed/arm64-linux/,其下有 lib/、include/、share/。
若内存 8GB 左右,建议先限并发防 OOM:export VCPKG_MAX_CONCURRENCY=4。 若个别源码包下载失败,脚本会自动切换镜像;确实卡住时可手工把文件按原名放入 $VCPKG_ROOT/downloads/(vcpkg 命中且哈希一致时会跳过下载)。
### 第五部分:编译
```bash
# 进入项目目录
cd /data/build/3dtiles
# 清掉可能残留的 RUSTFLAGS(它会整体覆盖配置文件里的 rustflags)
unset RUSTFLAGS
# 配置四条关键环境变量(缺一不可)
export VCPKG_ROOT=/usr/local/gis-sources/vcpkg
export VCPKG_DEFAULT_TRIPLET=arm64-linux
export VCPKG_HAS_BEEN_INSTALLED=1
export PATH="$VCPKG_ROOT:/usr/local/bin:$PATH"
# 编译 release 版本,并把详细日志写入 build.log
cargo build --release -vv 2>&1 | tee build.log
四条环境变量的作用:
| 变量 | 作用 |
|---|---|
| VCPKG_ROOT | build.rs 里 expect("VCPKG_ROOT ..."),未设置直接 panic |
| VCPKG_DEFAULT_TRIPLET | 指定 arm64-linux 三元组 |
| VCPKG_HAS_BEEN_INSTALLED=1 | 让 build.rs 把 vcpkg_installed 软链进 cargo 输出目录,使 cmake 阶段跳过重复安装 |
| PATH | 让 cmake 能找到 vcpkg 工具链脚本 |
| 日志判读:若看到大量 Installing xxx 重新开始装包,说明 cmake 侧编译器与 vcpkg 编译依赖时用的不是同一个(回到 3.1 的 ④ 检查路径)。 |
第六部分:验证与使用
bash
# 确认产物架构(期望 ELF 64-bit LSB ... ARM aarch64)
file target/release/_3dtile
# 查看文件大小
ls -lh target/release/_3dtile
# 确认三类数据目录已自动拷贝到位
ls -d target/release/gdal target/release/proj target/release/osgPlugins-3.6.5
# 查看帮助,确认程序可运行
./target/release/_3dtile --help
使用示例:
bash
# 进入产物目录
cd target/release
# OSGB 转 3D Tiles
# -f 指定输入格式,-i 指定输入目录(osgb 需定位到 Data 目录的上一级),-o 指定输出目录
./_3dtile -f osgb -i /path/to/数据目录 -o /path/to/输出目录
# SHP 转换需额外指定高度字段
./_3dtile -f shp -i /path/to/shp文件 -o /path/to/输出目录 --height <高度字段名>
第七部分:问题归类与解决方案
A.网络与下载类
**1、问题描述:配置清华镜像后 vcpkg install 报 404,找不到 ninja-linux-aarch64-1.13.1.zip
原因分析:两个配置都无效。① 清华站上 /vcpkg/ 与 /vcpkg/assets/ 路径本身不存在(实测 404);② VCPKG_DOWNLOAD_MIRROR 在新版 vcpkg 中已经废弃,源码里只识别 X_VCPKG_ASSET_SOURCES。
解决方案:
bash
# 清理无效变量
unset X_VCPKG_ASSET_SOURCES
unset VCPKG_DOWNLOAD_MIRROR
sed -i '/X_VCPKG_ASSET_SOURCES/d; /VCPKG_DOWNLOAD_MIRROR/d' ~/.bashrc
# 改用官方支持的 x-script 资产源(配合附录 A 的下载脚本)
export X_VCPKG_ASSET_SOURCES="x-script,/usr/local/bin/vcpkg-dl.sh {url} {sha512} {dst}"
2、问题描述:curl (52) Empty reply from server,下载 madler-zlib-v1.3.1.tar.gz 失败
原因分析:GitHub 直连在部分网络下传输中断。这是网络通道问题,与 vcpkg 配置无关。
解决方案:
bash
# 由下载脚本自动改走 GitHub 加速通道(gh-proxy / ghproxy / ghfast),并逐源校验 sha512
# 脚本已内置于附录 A,无需额外操作,重新执行 vcpkg install 即可
# 若有可用代理,最省事的做法是直接走代理(可一次性解决所有站点)
export https_proxy=http://<代理地址>:<端口>
3、问题描述:gaia-gis.it 上的 freexl 包,所有候选源均失败
原因分析:www.gaia-gis.it 服务器能建立 TCP 连接但不返回任何数据(20 秒 0 字节超时),重试无效。该源在本网络下不可用,必须换源。freexl 与 libspatialite 均在 gaia-gis.it 上,属同一问题。
解决方案:
bash
# 方案一(推荐):脚本自动改走 Debian 官方镜像(同一份上游 tar.gz,仅文件名不同,sha512 完全一致)
# 已在附录 A 脚本中实现:gaia-gis.it 的 freexl / libspatialite 自动映射到清华、阿里 Debian 源
# 方案二:手工预置到 vcpkg 下载缓存(vcpkg 命中且哈希一致时跳过下载)
# freexl
curl -L -o "$VCPKG_ROOT/downloads/freexl-2.0.0.tar.gz" "https://mirrors.tuna.tsinghua.edu.cn/debian/pool/main/f/freexl/freexl_2.0.0.orig.tar.gz"
# 校验(期望以 663ccc321c2f0dcab8ad9255b2a77066c2046d531a0aa723fb114301fa27b53b 开头)
sha512sum "$VCPKG_ROOT/downloads/freexl-2.0.0.tar.gz"
# libspatialite(Debian 源码包名为 spatialite)
curl -L -o "$VCPKG_ROOT/downloads/libspatialite-5.1.0.tar.gz" "https://mirrors.tuna.tsinghua.edu.cn/debian/pool/main/s/spatialite/spatialite_5.1.0.orig.tar.gz"
sha512sum "$VCPKG_ROOT/downloads/libspatialite-5.1.0.tar.gz"
4、问题描述:download.osgeo.org(geos)、sqlite.org(sqlite3)、sourceware.org(bzip2)等站点下载慢或中断
原因分析:这些站点在部分网络下带宽极低或连接不稳定。
解决方案:
bash
# 由附录 A 脚本自动换源,均实测 sha512 与 vcpkg 期望值一致:
# download.osgeo.org/geos -> GitHub Release(libGEOS 官方同文件)
# sqlite.org -> www3 / www2.sqlite.org 同源镜像(配合 -C - 断点续传)
# sourceware.org -> mirrorservice.org 镜像
# 无需手工干预,重新执行 vcpkg install 即可
B. 平台支持与依赖安装类
**1、问题描述:vcpkg install 报 basisu is only supported on '(x86 | x64) & !android', which does not match arm64-linux
原因分析:这是 vcpkg 给 basisu 打的"未验证平台"标记,来自端口元数据 "supports": "(x86 | x64) & !android"。实际上 basisu 的 CMakeLists 在非 MSVC 编译器下默认 BASISU_SUPPORT_SSE=0,走纯标量可移植路径,没有 x86 硬依赖,且上游新版端口已把条件改为 !android。项目自身 macOS 分支就是用 --allow-unsupported 在 Apple Silicon 上编译的。
解决方案:
bash
# 安装依赖时加上开关
vcpkg install --triplet arm64-linux --allow-unsupported
2、问题描述:cargo build 时报 CMake Error at .../vcpkg.cmake:953: vcpkg install failed
原因分析:cmake 的 vcpkg.cmake 在每次 configure 时都会无条件执行一次 vcpkg install,而 --allow-unsupported 只能通过 VCPKG_INSTALL_OPTIONS 这个 CMake 变量传入。项目 build.rs 里只有 macOS 分支写了这一行,Linux 分支缺失,导致 cargo 阶段又撞上 basisu 封条。
解决方案:
bash
# 给 build.rs 的 build_linux_unknown 段补上一行(详见 3.1 节 ③)
.define("VCPKG_INSTALL_OPTIONS", "--allow-unsupported")
# 核对:grep -n 'VCPKG_INSTALL_OPTIONS' build.rs 应输出 2 行(Linux 段 + macOS 段)
grep -n 'VCPKG_INSTALL_OPTIONS' build.rs
备选方案:
bash
再加一行 .define("VCPKG_MANIFEST_INSTALL", "OFF") 可让 cmake 完全跳过安装步骤,
但此时 VCPKG_HAS_BEEN_INSTALLED=1 与软链就成为必需项,建议先试上面的主方案。
3、问题描述:若 basisu 在 arm64 上真的编译失败
原因分析:3dtiles 只使用 basisu 的编码器(KTX2 纹理压缩,属可选功能)。
解决方案:
bash
# 从 vcpkg.json 去掉 basisu,并同步修改四处引用(保持两边一致):
# vcpkg.json 删除 "basisu" 依赖项
# CMakeLists.txt 注释 find_package(basisu CONFIG REQUIRED) 与 target_link_libraries(... basisu::basisu_encoder)
# build.rs 在 build_linux_unknown 段注释 rustc-link-lib=basisu_encoder
# src/mesh_processor.cpp / src/osgb23dtile.cpp 删除 basisu 头文件引用
# 代价:--enable-texture-compress(KTX2 压缩)失效,纹理自动回退 JPEG/PNG,其余功能不受影响
C. 工具链类
**1、问题描述:编译 libdeflate 报 /tmp/ccXXX.s: error: selected processor does not support 'eor3 v31.16b,...'
原因分析:新 gcc + 旧 binutils 错配。libdeflate 的 crc32_impl.h 假设"gcc ≥ 14 ⇒ binutils ≥ 2.41"(binutils 2.41 才取消 sha3 对 armv8.2-a 的版本依赖),于是只写 +crypto,+crc,+sha3,不再写 armv8.2-a。系统 binutils 早于 2.41,汇编器拒绝 eor3。项目自带的检测用带 armv8.2-a 的写法,旧汇编器恰好能过,所以兜底开关没打开。
解决方案:
bash
# 根治方案:升级 binutils 到 ≥ 2.41(见 1.3 节,本机采用 2.42)
# 升级后验证汇编器已支持 eor3:
/usr/local/bin/gcc -march=armv8-a -c /tmp/eor3_test.c -o /tmp/eor3_test.o && echo "OK"
# 应急替代(不升级 binutils 时可用):定义宏关掉该加速变体
# 代价:CRC-32 退到 pmullx12 变体,只影响 ZIP/gzip 校验速度,对 3dtiles 结果零影响
export CFLAGS="$CFLAGS -DLIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_SHA3=1"
# 清掉 libdeflate 的失败缓存后重试
rm -rf $VCPKG_ROOT/buildtrees/libdeflate
rm -rf $VCPKG_ROOT/packages/libdeflate_arm64-linux
2、问题描述:编译 binutils 时反复报 doc/bfd.info、info-recursive、all-bfd 三个错误
原因分析:三个报错是同一条故障链的三级回传(文档生成失败 → 递归目标失败 → 顶层 all 失败)。真实原因只有一条:环境缺少 makeinfo(texinfo 包提供),生成 bfd.info 的命令执行失败。as/ld 等功能代码在这之前早已编译完成,卡住的只是"顺手编文档"。
解决方案:
bash
# 方案一(推荐,零网络):把 MAKEINFO 覆盖成 true,文档目标变为空操作
# tarball 自带预生成的 bfd.info,make install 时照样安装,不丢任何东西
cd /tmp/binutils-2.42/build
make MAKEINFO=true -j"$(nproc)" 2>&1 | tee /tmp/binutils-make.log
sudo make MAKEINFO=true install
# 方案二:安装 texinfo
sudo dnf install -y texinfo
makeinfo --version | head -1
make -j"$(nproc)" && sudo make install
3、问题描述:编译 binutils 报 libgp_collector_la-mmaptrace.lo 失败
原因分析:该文件来自 binutils 新增的 gprofng 模块(性能分析器),其代码依赖较新的内核/glibc 特性,在麒麟 V10 + ARM64 上编译失败是常态。而升级 binutils 只需要 as、ld、ar、ranlib 等核心工具,gprofng / gold / libctf 完全用不上。
解决方案:
bash
# 重新 configure,禁用所有非核心组件(详见 1.3 节)
cd /tmp/binutils-2.42 && rm -rf build && mkdir build && cd build
../configure --prefix=/usr/local \
--disable-nls --disable-werror --disable-gprofng --disable-gold \
--disable-libctf --without-zstd --without-debuginfod --disable-shared
make MAKEINFO=true -j"$(nproc)" 2>&1 | tee /tmp/binutils-make.log
sudo make MAKEINFO=true install
4、问题描述:binutils 执行 ../configure 报 configure: error: C compiler cannot create executables
原因分析:configure 需要编译并链接一个最小测试程序来验证工具链,此环节失败。最常见原因是 /usr/bin/as 或 /usr/bin/ld 被改成了悬空软链(先替换软链、后编译 binutils,导致目标还不存在),或 as/ld 缺少共享库依赖、/tmp 为 noexec、磁盘满、环境变量污染等。
解决方案:
bash
# 1) 查看真实的失败原因(唯一权威证据)
cd /tmp/binutils-2.42/build
grep -n -B40 'C compiler cannot create executables' config.log | tail -60
# 2) 若是悬空软链:先恢复系统原状(有备份用备份)
ls -l /usr/bin/as /usr/bin/ld
sudo rm -f /usr/bin/as && [ -e /usr/bin/as.old ] && sudo mv /usr/bin/as.old /usr/bin/as
sudo rm -f /usr/bin/ld && [ -e /usr/bin/ld.old ] && sudo mv /usr/bin/ld.old /usr/bin/ld
# 3) 若无备份,用系统架构原生命名还原
sudo ln -sf /usr/bin/aarch64-linux-gnu-as /usr/bin/as
sudo ln -sf /usr/bin/aarch64-linux-gnu-ld /usr/bin/ld
# 4) 验证编译器恢复
printf 'int main(void){return 0;}\n' > /tmp/t.c && gcc /tmp/t.c -o /tmp/t && /tmp/t && echo "编译器正常"
# 5) 若为环境变量污染
unset CC CXX CFLAGS CXXFLAGS CPPFLAGS LDFLAGS AS LD AR RANLIB LIBS
正确顺序原则:必须先 make install 让 /usr/local/bin/as 真实存在,再做替换/软链,顺序反了会破坏系统编译能力。
5、问题描述:cargo build 报 error: linker 'cc' not found,连带 quote / proc-macro2 / crossbeam-utils 编译失败
原因分析:Rust 在 Linux/GNU 目标上默认调用的链接器名是 cc,而系统里不存在名为 cc 的可执行文件或软链。vcpkg/CMake 通过 CC/CMAKE_C_COMPILER 显式指定编译器,不依赖裸名 cc,所以只有 rustc 会撞上。多条报错的四个包都是 build script(为主机编译),共用同一个 cc,属同一根因。
解决方案:
bash
# 建立 cc / c++ 软链接(详见 1.4 节)
sudo ln -sfn /usr/local/bin/gcc /usr/bin/cc
sudo ln -sfn /usr/local/bin/g++ /usr/bin/c++
# 验证
cc --version | head -1
printf 'int main(void){return 0;}\n' > /tmp/t.c && cc /tmp/t.c -o /tmp/t && echo "链接正常"
# 临时替代方案(不改系统目录)
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/local/bin/gcc
6、问题描述:binutils make install 后,感觉缺少软链接
原因分析:make install 只生成无前缀名(as、ld、ar、ranlib...)和 /usr/local/<三元组>/bin/ 下的同名硬链接;带目标前缀的别名(如 aarch64-unknown-linux-gnu-as)是发行版打包时自己加的,binutils 原生构建不生成;/usr/bin/as 的指向也从来不属于 install 的职责。
解决方案:
bash
# 1) 查看 gcc 实际用哪个 as(输出完整路径 = 已走 tooldir 用上新版)
gcc -print-prog-name=as
# 2) 让新版生效:优先用 PATH(不动系统目录)
export PATH=/usr/local/bin:$PATH
which as ld
# 3) 或直接替换系统目录(此时 /usr/local/bin/as 已确实存在,不会悬空)
sudo mv /usr/bin/as /usr/bin/as.pre-binutils && sudo ln -s /usr/local/bin/as /usr/bin/as
sudo mv /usr/bin/ld /usr/bin/ld.pre-binutils && sudo ln -s /usr/local/bin/ld /usr/bin/ld
# 4) 需要带目标前缀的别名时,批量建立(三元组名以 gcc -dumpmachine 为准)
TRIPLE=$(gcc -dumpmachine); echo "$TRIPLE"
for t in as ld ar ranlib nm objcopy objdump readelf strip; do
[ -e /usr/local/bin/$t ] || continue
[ -e /usr/local/bin/$TRIPLE-$t ] || ln -s "$t" /usr/local/bin/$TRIPLE-$t
done
D. 源码兼容类
**1、问题描述:编译报 error: use of deprecated constant 'std::f64::NEG_INFINITY'
原因分析:Rust 1.99.0 起弃用了 std::f64 下的一批模块级常量(INFINITY、NEG_INFINITY、NAN、EPSILON、MAX、MIN 等),改用关联常量。项目源码 src/shape.rs:48 使用了旧写法,而 .cargo/config.toml 里的 -D warnings 把弃用警告升级成错误。全仓仅此一处。
解决方案:
bash
# 修改 src/shape.rs 第 48 行(详见 3.3 节)
# 原:use std::f64::{INFINITY, NEG_INFINITY};
# 改为两条 const 定义,4 个使用点无需改动:
const INFINITY: f64 = f64::INFINITY;
const NEG_INFINITY: f64 = f64::NEG_INFINITY;
# 或改为使用点全限定:f64::INFINITY / f64::NEG_INFINITY
不要用 std::f64::consts::{INFINITY, NEG_INFINITY}------consts 子模块已不含这两个符号,会报 E0432。
E. 链接类
**1、问题描述:undefined reference to 'vtable for __cxxabiv1::__class_type_info',collect2: error: ld returned 1 exit status
原因分析:__class_type_info 是 libstdc++ 的 RTTI 基类虚表,报未定义说明整个 libstdc++ 没有参与链接。build.rs 确实声明了 stdc++(第 227 行),但它排在 C++ 静态库 _3dtile(第 231 行)之前;链接器扫到 -lstdc++ 时还没有 C++ 未定义符号,在 --as-needed 下直接丢弃。
解决方案:
bash
# 1) 指定 g++ 作为链接驱动(g++ 会把 -lstdc++ 追加到命令末尾)
# 2) 追加 -C link-arg=-lstdc++,该参数位于链接命令最末端(详见 3.2 节)
cat >> .cargo/config.toml <<'EOF'
[target.aarch64-unknown-linux-gnu]
linker = "/usr/local/bin/3dtiles-link-wrapper.sh"
rustflags = ["-C", "link-arg=-lstdc++"]
EOF
# 3) 临时验证(只对当前终端有效)
export RUSTFLAGS="-C link-arg=-lstdc++"
# 4) 排查:查看真实链接命令里 -lstdc++ 与 -l_3dtile 的先后
cargo build --release -vv 2>&1 | grep -o 'cc .*' | tail -1
2、问题描述:出现大量 undefined reference,例如 freexl_ods.c:(.text+0x1454): undefined reference to 'unzOpen64'
原因分析:GNU ld 处理静态库是从左到右单遍扫描、不回头。build.rs 里 minizip(第 294 行,定义 unzOpen64)排在 freexl(第 296 行,调用 unzOpen64)之前,导致 minizip 被跳过。同类顺序违规在 Linux 分支共 27 处(如 kml* 四个库顺序整体颠倒:应为 kmlconvenience → kmldom → kmlengine → kmlbase;spatialite 排在 geos/proj/sqlite3/xml2/lzma/minizip/expat 之前等)。逐条调顺序是打地鼠,应让顺序变得无关紧要。
解决方案:
bash
# 使用链接器包装脚本,把所有 -l 库包进 --start-group/--end-group
# 分组内 ld 会反复扫描直到不再有新符号被解析,静态库顺序彻底无关(详见附录 B)
sudo tee /usr/local/bin/3dtiles-link-wrapper.sh >/dev/null <<'SCRIPT'
#!/bin/bash
# 把所有 -l 库包进 --start-group/--end-group,消除静态库顺序依赖
GXX="${GXX:-/usr/local/bin/g++}"
args=("$@"); out=(); opened=0
for a in "${args[@]}"; do
case "$a" in
-l*) if [ "$opened" -eq 0 ]; then out+=("-Wl,--start-group"); opened=1; fi
out+=("$a");;
*) out+=("$a");;
esac
done
if [ "$opened" -eq 1 ]; then out+=("-Wl,-Bdynamic" "-Wl,--end-group"); fi
exec "$GXX" "${out[@]}"
SCRIPT
sudo chmod +x /usr/local/bin/3dtiles-link-wrapper.sh
# 在 .cargo/config.toml 中把 linker 指向该包装脚本(详见 3.2 节)
# linker = "/usr/local/bin/3dtiles-link-wrapper.sh"
# 查看报错符号归属哪个静态库(排查用)
# 例:grep -rl 'unzOpen64' $VCPKG_ROOT/packages/*/lib/*.a 2>/dev/null
若仍有 undefined reference,先确认"符号是否真的存在于本地某个 .a 中"。若符号在本地根本找不到,属于另一类问题(例如 OSG 插件静态库因无人引用被丢弃,需要 --whole-archive 处理),而非顺序问题。
附录 A:vcpkg 下载加速脚本(vcpkg-dl.sh)
安装位置:/usr/local/bin/vcpkg-dl.sh
bash
#!/usr/bin/env bash
# =============================================================================
# vcpkg 资产下载包装脚本(适配麒麟 V10 / ARM64 国内网络)
#
# 用途:配置给 X_VCPKG_ASSET_SOURCES 的 x-script 模式,vcpkg 下载任何源码包/工具时
# 都会自动调用本脚本。脚本按"镜像优先、失败回源"的顺序尝试多个地址,
# 并用 vcpkg 给的 sha512 校验,只有哈希一致才算成功。
#
# 用法(由 vcpkg 自动调用,一般无需手动执行):
# vcpkg-dl.sh <url> <sha512> <dst>
#
# 配置方式:
# export X_VCPKG_ASSET_SOURCES='x-script,/usr/local/bin/vcpkg-dl.sh {url} {sha512} {dst}'
#
# 已验证的镜像映射(均已实测字节与 vcpkg 期望值一致):
# www.gaia-gis.it / freexl -> 清华/阿里 Debian 源
# www.gaia-gis.it / libspatialite -> 清华/阿里 Debian 源
# download.osgeo.org / geos -> GitHub Release(libGEOS)
# sqlite.org / www.sqlite.org -> www2 / www3 同源变体(慢,靠续传)
# sourceware.org / bzip2 -> mirrorservice
# 其它 GitHub 系 -> gh-proxy / ghproxy.net / ghfast
# =============================================================================
set -u
url="${1:?用法: vcpkg-dl.sh <url> <sha512> <dst>}"
sha="${2:-}"
dst="${3:?用法: vcpkg-dl.sh <url> <sha512> <dst>}"
mkdir -p "$(dirname "$dst")" 2>/dev/null || true
CURL_BIN="$(command -v curl 2>/dev/null || echo /usr/bin/curl)"
SHA_BIN="$(command -v sha512sum 2>/dev/null || echo /usr/bin/sha512sum)"
# ---- 各类镜像前缀(可按自己网络情况增删、调整顺序)---------------------------
GH_MIRRORS="https://gh-proxy.com/ https://ghproxy.net/ https://ghfast.top/"
DEBIAN_MIRRORS="https://mirrors.tuna.tsinghua.edu.cn/debian https://mirrors.aliyun.com/debian"
GNU_MIRRORS="https://mirrors.tuna.tsinghua.edu.cn/gnu https://mirrors.aliyun.com/gnu"
log() { echo "[vcpkg-dl] $*" >&2; }
# ---- 单个地址下载(带续传,最多 3 轮)--------------------------------------
fetch_one() {
local u="$1" i
rm -f "$dst"
for i in 1 2 3; do
# -C - 断点续传:专治 GitHub / sqlite.org 这类"下到一半被掐断"
if "$CURL_BIN" -fsSL -C - --connect-timeout 20 --max-time 3600 -o "$dst" "$u"; then
return 0
fi
sleep $((i * 4))
done
return 1
}
# ---- 试一个地址:下载 + 校验 sha512 ----------------------------------------
# 返回 0=成功 1=下载失败 2=哈希不符(换下一个源)
try_url() {
local u="$1" got
log "尝试 $u"
fetch_one "$u" || { log "下载失败: $u"; return 1; }
if [ -n "$sha" ]; then
got="$("$SHA_BIN" "$dst" 2>/dev/null | awk '{print $1}')"
if [ "$got" != "$sha" ]; then
log "哈希不符,弃用该源: $u"
return 2
fi
fi
log "成功: $u"
return 0
}
# ---- 按 URL 生成候选地址列表 -------------------------------------------------
base="$(basename "${url%%\?*}")"
cands=""
add() { case " $cands " in *" $1 "*) ;; *) cands="$cands $1" ;; esac; }
case "$url" in
# ---------- GitHub 全系:走加速通道 ----------
*github.com*|*githubusercontent.com*|*codeload.github.com*)
for m in $GH_MIRRORS; do add "${m}${url}"; done
add "$url"
;;
# ---------- freexl:gaia-gis.it -> Debian 源(同文件,仅文件名不同)----------
*gaia-gis.it*freexl-*.tar.gz)
ver="${base#freexl-}"; ver="${ver%.tar.gz}"
for m in $DEBIAN_MIRRORS; do
add "${m}/pool/main/f/freexl/freexl_${ver}.orig.tar.gz"
done
add "$url"
;;
# ---------- libspatialite:gaia-gis.it -> Debian 源(源码包名是 spatialite)--
*gaia-gis.it*libspatialite-*.tar.gz)
ver="${base#libspatialite-}"; ver="${ver%.tar.gz}"
for m in $DEBIAN_MIRRORS; do
add "${m}/pool/main/s/spatialite/spatialite_${ver}.orig.tar.gz"
done
add "$url"
;;
# ---------- geos:osgeo -> GitHub Release(libGEOS 官方同文件)-------------
*download.osgeo.org/geos/geos-*.tar.bz2)
ver="${base#geos-}"; ver="${ver%.tar.bz2}"
for m in $GH_MIRRORS; do
add "${m}https://github.com/libgeos/geos/releases/download/${ver}/geos-${ver}.tar.bz2"
done
add "$url"
;;
# ---------- bzip2:sourceware -> mirrorservice ----------------------------
*sourceware.org/*)
path="${url#*sourceware.org}"
add "https://www.mirrorservice.org/sites/sourceware.org${path}"
add "$url"
;;
# ---------- sqlite:sqlite.org 极慢,换同源镜像 + 续传 ---------------------
*sqlite.org/*)
v2="$(printf '%s' "$url" | sed -E 's#https?://(www\.)?sqlite\.org#https://www2.sqlite.org#')"
v3="$(printf '%s' "$url" | sed -E 's#https?://(www\.)?sqlite\.org#https://www3.sqlite.org#')"
add "$v3"; add "$v2"; add "$url"
;;
# ---------- GNU 系(libiconv 等,Linux 上通常为空包不会触发)---------------
*ftp.gnu.org/*|*ftpmirror.gnu.org/*)
path="${url#*gnu.org}"
for m in $GNU_MIRRORS; do add "${m}${path}"; done
add "$url"
;;
# ---------- 其它(sourceforge / gitlab / savannah 等实测可直连)------------
*)
add "$url"
;;
esac
# ---- 依次尝试 ---------------------------------------------------------------
for c in $cands; do
try_url "$c" && exit 0
done
log "所有候选源均失败: $url"
exit 1
附录 B:链接器包装脚本(3dtiles-link-wrapper.sh)
安装位置:/usr/local/bin/3dtiles-link-wrapper.sh
bash
#!/bin/bash
# =============================================================================
# 链接器包装脚本
#
# 作用:把链接命令里所有 -l 开头的库自动包进 --start-group/--end-group
# 分组内 GNU ld 会反复扫描直到不再有新符号被解析,
# 从而彻底消除静态库之间的顺序依赖(解决大批 undefined reference)。
#
# 同时以 g++ 作为链接驱动,g++ 会把 -lstdc++ 追加到命令末尾,
# 避免 C++ 运行库排在 C++ 静态库之前而被 --as-needed 丢弃。
# =============================================================================
# 链接驱动:默认用 /usr/local/bin/g++,可用环境变量 GXX 覆盖
GXX="${GXX:-/usr/local/bin/g++}"
args=("$@")
out=()
opened=0
for a in "${args[@]}"; do
case "$a" in
-l*)
# 遇到第一个 -l 时插入分组起始标记,后续所有库都纳入同一分组
if [ "$opened" -eq 0 ]; then
out+=("-Wl,--start-group")
opened=1
fi
out+=("$a")
;;
*)
out+=("$a")
;;
esac
done
# 关闭分组;-Bdynamic 防止分组内残留静态状态导致末尾 libstdc++ 被静态化
if [ "$opened" -eq 1 ]; then
out+=("-Wl,-Bdynamic" "-Wl,--end-group")
fi
exec "$GXX" "${out[@]}"
附录 C:环境变量速查
bash
# ---- 每次编译前必须设置 ----
export VCPKG_ROOT=/usr/local/gis-sources/vcpkg
export VCPKG_DEFAULT_TRIPLET=arm64-linux
export VCPKG_HAS_BEEN_INSTALLED=1
export PATH="$VCPKG_ROOT:/usr/local/bin:$PATH"
# ---- 编译前应清空(避免覆盖配置文件设置)----
unset RUSTFLAGS
# ---- 下载加速(长期生效可写入 ~/.bashrc)----
export X_VCPKG_ASSET_SOURCES="x-script,/usr/local/bin/vcpkg-dl.sh {url} {sha512} {dst}"
# ---- 不要设置:新版 vcpkg 已废弃 ----
# VCPKG_DOWNLOAD_MIRROR
```****************************************