通过vcpkg构建icu-for-android问题一则

本文约 900 字,阅读需 2 分钟。

我们的项目通过vcpkg依赖了icu,但在构建Android平台的icu制品时,却失败了。

Installing 15/45 icu:arm-neon-android@73.1#1...
Building icu:arm-neon-android@73.1#1...
/root/.cache/vcpkg/registries/git-trees/eaccfc7689fb55d4badf3d2321a8be62ae5be84e: info: installing overlay port from here
-- Downloading https://github.com/unicode-org/icu/releases/download/release-73-1/icu4c-73_1-src.tgz -> icu4c-73_1-src.tgz...
-- Extracting source /data/landun/workspace/tdf_build_env/.vcpkg/downloads/icu4c-73_1-src.tgz
-- Applying patch disable-escapestr-tool.patch
-- Applying patch remove-MD-from-configure.patch
-- Applying patch fix_parallel_build_on_windows.patch
-- Applying patch fix-extra.patch
-- Applying patch mingw-dll-install.patch
-- Applying patch disable-static-prefix.patch
-- Applying patch fix-win-build.patch
-- Using source at /data/landun/workspace/tdf_build_env/.vcpkg/buildtrees/icu/src/c-73_1-src-72ff750ba0.clean
-- Found external ninja('1.11.1').
-- Getting CMake variables for arm-neon-android-dbg
-- Getting CMake variables for arm-neon-android-rel
-- Generating configure for arm-neon-android
-- Finished generating configure for arm-neon-android
-- Configuring arm-neon-android-dbg
CMake Error at scripts/cmake/vcpkg_execute_required_process.cmake:112 (message):
    Command failed: /usr/bin/bash -c "V=1 ./../src/c-73_1-src-72ff750ba0.clean/source/configure --host=armv7a-linux-androideabi \"--disable-samples\" \"--disable-test
s\" \"--disable-layoutex\" \"--disable-extras\" \"--disable-tools\" \"--with-cross-build=/data/landun/workspace/out/build/Release/vcpkg_installed/x64-linux/tools/icu\
" \"--disable-silent-rules\" \"--verbose\" \"--disable-shared\" \"--enable-static\" \"--enable-debug\" \"--disable-release\" \"--prefix=/data/landun/workspace/out/bui
ld/Release/vcpkg_installed/arm-neon-android/debug\" \"--bindir=\\${prefix}/../tools/icu/debug/bin\" \"--sbindir=\\${prefix}/../tools/icu/debug/sbin\" \"--libdir=\\${p
refix}/lib\" \"--includedir=\\${prefix}/../include\" \"--datarootdir=\\${prefix}/share/icu\""
    Working Directory: /data/landun/workspace/tdf_build_env/.vcpkg/buildtrees/icu/arm-neon-android-dbg
    Error code: 1
    See logs for more information:
      /data/landun/workspace/tdf_build_env/.vcpkg/buildtrees/icu/config-arm-neon-android-dbg-config.log
      /data/landun/workspace/tdf_build_env/.vcpkg/buildtrees/icu/config-arm-neon-android-dbg-out.log
      /data/landun/workspace/tdf_build_env/.vcpkg/buildtrees/icu/config-arm-neon-android-dbg-err.log
Call Stack (most recent call first):
  scripts/cmake/vcpkg_configure_make.cmake:863 (vcpkg_execute_required_process)
  /root/.cache/vcpkg/registries/git-trees/eaccfc7689fb55d4badf3d2321a8be62ae5be84e/portfile.cmake:57 (vcpkg_configure_make)
  scripts/ports.cmake:175 (include)
error: building icu:arm-neon-android failed with: BUILD_FAILED
Elapsed time to handle icu:arm-neon-android: 11 s

比较特殊的是,这个错误只会在Linux上出现,Mac上是好的。

以此为切入口,对比config.log,发现以下差异:

// Mac上构建
configure:3563: checking for armv7a-linux-androideabi-clang
configure:3596: result: /Users/vimerzhao/Library/Android/sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang
configure:3677: checking for C compiler version
configure:3686: /Users/vimerzhao/Library/Android/sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang --version >&5
Android (10552028, +pgo, +bolt, +lto, -mlgo, based on r487747d) clang version 17.0.2 (https://android.googlesource.com/toolchain/llvm-project d9f89f4d16663d5012e5c09495f3b30ece3d2362)

// Linux上构建
configure:2936: checking for armv7a-linux-androideabi-clang
configure:2963: result: /root/.install/llvm16.0.0/bin/clang
configure:3038: checking for C compiler version
configure:3047: /root/.install/llvm16.0.0/bin/clang --version >&5
clang version 16.0.0
Target: x86_64-unknown-linux-gnu

此外,还有一些error的日志,但对于这个问题是干扰项。关注最后的exit 0即可(0表示这个过程正常退出)。

configure:3686: /Users/vimerzhao/Library/Android/sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -V >&5
clang-17: error: argument to '-V' is missing (expected 1 value)
clang-17: error: no input files
configure:3697: $? = 1
configure:3686: /Users/vimerzhao/Library/Android/sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -qversion >&5
clang-17: error: unknown argument '-qversion'; did you mean '--version'?
clang-17: error: no input files
configure:3697: $? = 1

......

#define SIZEOF_WCHAR_T 4

configure: exit 0

由以上日志容易判断:显然是Linux平台上,没有正确识别出Android-arm架构导致的。

那么为什么会这样?查看对应的config文件的2920行左右,注意到以下逻辑:

# Checks for compilers
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
  for ac_prog in clang gcc cc c99 c89 xlc_r xlc cl.exe icc
  do
 ......

立马反应过来,Linux平台一般会指定CC,方便CMake找到clang,不然会用系统默认的cc(也就是gcc编译器):

# 有的是手动设置的,有的是构建机配置了.....
export CC=`which clang` && export CXX=`which clang++`

而如果构建的是Android制品,这个环境变量会形成干扰,影响icu的构建脚本。

这个问题确实比较特殊且隐蔽,不那么容易发现,需要一点直觉和洞察

Note:

CC和CXX环境变量在编译C和C++程序时非常有用。它们分别指定C和C++编译器的名称或路径。 当你在构建一个项目时,编译系统(如Make、CMake或其他构建工具)会使用这些环境变量来确定应该使用哪个编译器进行编译。

From GPT.

总阅读量次。