本文記錄使用命令 OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh 構建 Talloc 2.4.3 的完整過程,包括環境、構建鏈路、關鍵日誌、常見問題與解決方案、產物驗證與重建方法,便於復現與運維。

Talloc 是一個層次化內存分配器,由 Samba 項目開發,用於管理內存分配和釋放。它提供了基於上下文的內存管理,允許在釋放父上下文時自動釋放所有子上下文,大大簡化了內存管理。

Talloc 是 Samba 項目的基礎庫,提供了:

  • 層次化內存管理:基於上下文的內存分配,自動管理內存生命週期
  • 類型安全:提供類型安全的分配函數
  • 調試支持:提供內存泄漏檢測和調試工具
  • 性能優化:高效的分配和釋放機制
1. 層次化內存管理
  • 基於上下文的內存分配
  • 自動釋放子上下文
  • 支持內存池管理
2. 主要功能
  • talloc_new() - 創建新的上下文
  • talloc_free() - 釋放上下文及其所有子上下文
  • talloc_realloc() - 重新分配內存
  • talloc_strdup() - 字符串複製
  • talloc_array() - 數組分配
  • 執行命令OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh
  • 入口腳本create-hnp.sh
  • 檢查必需的環境變量 OHOS_ARCHOHOS_ABI
  • 導出 LC_CTYPETOOL_HOMEOHOS_SDK_HOME
  • 執行 make -C build-hnp
  • 頂層構建build-hnp/Makefile
  • PKGS 變量定義需要構建的包列表(包含 talloc
  • 通過 check-pkgs 機制自動檢測 PKGS 變化並觸發重新構建
  • 自動合併 external-hnp 目錄下的外部 HNP 包
  • base.hnp 依賴所有包的 .stamp 和外部 HNP 包
  • 總目標 all: copy,打包 base.hnp 並拷貝到 entry/hnp/$(OHOS_ABI)

⚙️ Talloc 包的構建配置

  • 包目錄build-hnp/talloc/Makefile
  • 源地址:SOURCE_URL = https://www.samba.org/ftp/talloc/talloc-2.4.3.tar.gz
  • 版本:2.4.3
  • 構建系統:WAF(Python 構建系統)
  • 構建流程
  1. 下載源碼包
  2. 解包並應用補丁
  3. 創建交叉編譯答案文件(cross-answers.txt)
  4. 使用 WAF 配置交叉編譯
  5. 使用 WAF 編譯
  6. 使用 WAF 安裝
  7. 執行 ELF strip 減小體積
  8. 複製到 ../sysroot
  • 通用工具鏈與路徑build-hnp/utils/Makefrag
  • CC/CXX/LD/AR/RANLIB/... 均指向 OHOS SDK 的 LLVM 工具鏈
  • 通過 PKG_CONFIG_LIBDIR 指向 sysroot.pc 目錄,確保依賴發現
  • 下載支持多鏡像回退:wgetcurl,主鏡像失敗時自動嘗試備用鏡像
  • 下載與解包
  • www.samba.org 下載 talloc-2.4.3.tar.gz
  • 完成解包並進入 temp/talloc-2.4.3 目錄
  • 補丁應用
  • 0001-skip-largefile-check.diff - 跳過大文件支持檢查(交叉編譯時無法運行測試程序)
  • 修改 buildtools/wafsamba/wscript,在交叉編譯時假設大文件支持可用
  • 0002-skip-secure-mkstemp-check.diff - 跳過 secure mkstemp 檢查
  • 修改 lib/replace/wscript,將 execute=True 改為 execute=False
  • ⚙️ 配置階段
  • 創建交叉編譯答案文件(cross-answers.txt),包含:
  • 系統信息:uname sysname/machine/release/version
  • 基本檢查:stdio.hsimple C program
  • 大文件支持:LFS flagssizeof off_t/dev_t/ino_t/time_t(均為 8)
  • 鏈接器支持:rpath library support: OK-Wl,--version-script support: OK
  • 函數行為:strtoll: OKstrptime: OKC99 vsnprintf: OK
  • 內存映射:HAVE_SHARED_MMAP: OKHAVE_MREMAP: OKHAVE_INCOHERENT_MMAP: NO
  • 使用 WAF 配置交叉編譯:python3 buildtools/bin/waf configure --prefix=$(PREFIX) --cross-compile --cross-answers=cross-answers.txt --disable-python
  • WAF 會檢查大量系統特性,需要提供完整的 cross-answers.txt(格式:OKYESNOUNKNOWN
  • 配置成功完成,生成了 bin/config.h 和構建配置
  • 編譯與安裝
  • 使用 WAF 編譯:python3 buildtools/bin/waf build -j $(shell nproc)
  • 成功編譯生成 libtalloc.so.2.4.3 和符號鏈接
  • 使用 WAF 安裝:python3 buildtools/bin/waf install --destdir=$(shell pwd)/build
  • 安裝到臨時前綴 build$(PREFIX)/libbuild$(PREFIX)/include
  • 打包
  • 執行 ELF strip 減小文件大小
  • 複製到 ../sysroot
  • 完成 base.hnp 重打包,拷貝產物到 entry/hnp/arm64-v8a/
  • Talloc 庫已成功打包到 base.hnp

❌ 問題 1:WAF 構建系統不支持 Autotools

  • 症狀../configure: line 27: ./buildtools/bin/waf: No such file or directory
  • 原因:Talloc 使用 WAF 構建系統,而不是標準的 Autotools
  • ✅ 解決方法
  • 修改 build-hnp/talloc/Makefile,使用 WAF 構建系統
  • 直接調用 python3 buildtools/bin/waf 進行配置和構建
  • 位置:build-hnp/talloc/Makefile

❌ 問題 2:交叉編譯需要 cross-answers.txt

  • 症狀Cannot cross-compile without either --cross-execute or --cross-answers
  • 原因:WAF 在交叉編譯時需要提供交叉編譯答案文件
  • ✅ 解決方法
  • 創建 cross-answers.txt 文件,提供系統特性檢查的答案
  • 在 Makefile 中動態生成 cross-answers.txt
  • 位置:build-hnp/talloc/Makefile:11-18

❌ 問題 3:大文件支持檢查失敗

  • 症狀Samba requires large file support, but not available on this platform: sizeof(off_t) < 8
  • 原因:WAF 在交叉編譯時無法運行測試程序來檢測大文件支持
  • ✅ 解決方法
  • 創建補丁 0001-skip-largefile-check.diff,在交叉編譯時跳過大文件支持檢查
  • 在交叉編譯時假設大文件支持可用,設置 LFS_CFLAGS
  • 位置:build-hnp/talloc/0001-skip-largefile-check.diff

❌ 問題 4:secure mkstemp 檢查失敗

  • 症狀Checking for HAVE_SECURE_MKSTEMP: not found,配置失敗
  • 原因:WAF 在交叉編譯時無法運行測試程序來檢測 secure mkstemp
  • ✅ 解決方法
  • 創建補丁 0002-skip-secure-mkstemp-check.diff,將 execute=True 改為 execute=False
  • 這樣 WAF 只編譯和鏈接測試程序,不運行它
  • 位置:build-hnp/talloc/0002-skip-secure-mkstemp-check.diff

❌ 問題 5:cross-answers.txt 格式不正確

  • 症狀Cross answers file cross-answers.txt is incomplete
  • 原因
  • WAF 期望的答案格式是 OKYESUNKNOWNNOFAIL 等,而不是 oknot found
  • 需要為所有需要運行測試程序的檢查提供答案
  • ✅ 解決方法
  • 使用正確的格式:OK 表示成功,NO 表示失敗,UNKNOWN 表示未知(但會導致配置失敗)
  • 添加所有需要的答案:
  • rpath library support: OK
  • -Wl,--version-script support: OK
  • Checking correct behavior of strtoll: OK
  • Checking for working strptime: OK
  • Checking for C99 vsnprintf: OK
  • Checking for HAVE_SHARED_MMAP: OK
  • Checking for HAVE_MREMAP: OK
  • Checking for HAVE_INCOHERENT_MMAP: NO
  • 位置:build-hnp/talloc/Makefile:14-27

❌ 問題 6:Python 嵌入解釋器配置失敗

  • 症狀Testing pyembed configuration: Could not build a python embedded interpreter
  • 原因:Talloc 默認啓用 Python 支持,但在交叉編譯時無法構建 Python 嵌入解釋器
  • ✅ 解決方法
  • 添加 --disable-python 選項禁用 Python 支持
  • 位置:build-hnp/talloc/Makefile:28
1. 基本內存分配
#include <talloc.h>
  int main() {
  // 創建根上下文
  TALLOC_CTX *ctx = talloc_new(NULL);
  // 分配內存
  char *str = talloc_strdup(ctx, "Hello, Talloc!");
  // 釋放所有內存(包括 str)
  talloc_free(ctx);
  return 0;
  }
2. 層次化內存管理
#include <talloc.h>
  struct Person {
  char *name;
  int age;
  };
  int main() {
  TALLOC_CTX *ctx = talloc_new(NULL);
  // 在上下文中分配結構體
  struct Person *person = talloc(ctx, struct Person);
  person->name = talloc_strdup(person, "Alice");
  person->age = 30;
  // 釋放 ctx 會自動釋放 person 和 person->name
  talloc_free(ctx);
  return 0;
  }
3. 數組分配
#include <talloc.h>
  int main() {
  TALLOC_CTX *ctx = talloc_new(NULL);
  // 分配整數數組
  int *arr = talloc_array(ctx, int, 10);
  for (int i = 0; i < 10; i++) {
  arr[i] = i;
  }
  // 釋放所有內存
  talloc_free(ctx);
  return 0;
  }
4. 字符串操作
#include <talloc.h>
  int main() {
  TALLOC_CTX *ctx = talloc_new(NULL);
  // 字符串複製
  char *str1 = talloc_strdup(ctx, "Hello");
  char *str2 = talloc_strdup(ctx, "World");
  // 字符串連接
  char *combined = talloc_asprintf(ctx, "%s, %s!", str1, str2);
  // 釋放所有內存
  talloc_free(ctx);
  return 0;
  }
5. 內存重新分配
#include <talloc.h>
  int main() {
  TALLOC_CTX *ctx = talloc_new(NULL);
  // 分配內存
  char *str = talloc_strdup(ctx, "Hello");
  // 重新分配內存
  str = talloc_realloc(ctx, str, char, 20);
  strcpy(str, "Hello, World!");
  // 釋放所有內存
  talloc_free(ctx);
  return 0;
  }
6. 使用 pkg-config
# 編譯使用 Talloc 的程序
gcc -o program program.c $(pkg-config --cflags --libs talloc)
# 查看 Talloc 版本
pkg-config --modversion talloc
# 查看編譯標誌
pkg-config --cflags talloc
# 查看鏈接標誌
pkg-config --libs talloc

✅ 產物驗證

ls build-hnp/base.hnp  # 應存在
ls entry/hnp/arm64-v8a/*.hnp  # 應包含 base.hnp 與 base-public.hnp
# 檢查 talloc 庫
ls -lh build-hnp/sysroot/lib/libtalloc.so*
file build-hnp/sysroot/lib/libtalloc.so.2.4.3
# 檢查頭文件
ls -lh build-hnp/sysroot/include/talloc.h
# 檢查 pkg-config 文件
ls -lh build-hnp/sysroot/lib/pkgconfig/talloc.pc
cat build-hnp/sysroot/lib/pkgconfig/talloc.pc

✅ 構建驗證結果

  • ✅ talloc 庫已成功安裝:
  • libtalloc.so.2.4.3 (39K) - 主庫文件
  • libtalloc.so.2 - 版本符號鏈接
  • libtalloc.so - 通用符號鏈接
  • ✅ 文件類型:ELF 64-bit LSB shared object, ARM aarch64
  • ✅ 頭文件已安裝:talloc.h (64K)
  • ✅ pkg-config 文件已安裝:talloc.pc (332 bytes)
  • ✅ 版本信息:2.4.3
  • 重建單包
make -C build-hnp rebuild-talloc  # 觸發子包重新編譯並刷新 .stamp
  • 清理
make -C build-hnp clean  # 清理 sysroot、所有 .stamp 和 PKGS_MARKER
  • 擴展:Talloc 是 Samba 項目的基礎庫,許多其他包依賴它
  • 自動重建機制
  • 修改 PKGS 後,check-pkgs 會自動檢測變化並觸發重新構建
  • 新增外部 HNP 包到 external-hnp 目錄後,會自動合併到 base.hnp
  • WAF 構建系統:Talloc 使用 WAF 構建系統,需要特殊處理
  • ️ 交叉編譯支持:WAF 的交叉編譯需要提供完整的 cross-answers.txt
  • 補丁管理:需要應用補丁來跳過無法在交叉編譯時運行的測試
  • 依賴管理:Talloc 是 Samba 項目的基礎庫,確保正確構建和安裝
  • ✅ 本次已在 aarch64 環境下完成 Talloc 2.4.3 的交叉編譯與打包,talloc 庫已安裝到 sysroot/lib 並納入 HNP 包。
  • 為保證構建穩定
  • 固定可靠的上游鏡像,避免下載階段隨機失敗(已實現自動回退機制)
  • 對 WAF 構建系統需要特殊處理,提供完整的交叉編譯答案
  • 應用必要的補丁來跳過無法在交叉編譯時運行的測試
  • 利用 check-pkgs 機制自動檢測包列表變化,無需手動清理