使用带有 -fembed-bitcode 的配置和制作构建 C++ 静态库失败 link

Building C++ static libraries using configure & make with -fembed-bitcode fails to link

我正在为 iOS 9 使用 -fembed-bitcode 重建一些开源库,其中涉及配置 configure 以使用 iPhone SDK 进行交叉编译。

基于 C 的库一切正常,但是 2 个 C++ 库 (libprotobuf and libexiv2) 我都无法 link 并出现同样的错误:

ld: -bind_at_load and -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES) cannot be used together

这是 libexiv2 的完整 link 命令:

../libtool --mode=link /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk -miphoneos-version-min=8.0 -fembed-bitcode  -ldl   -L/Users/pol/Source/Libraries/libexiv2/exiv2-0.25/../../libexpat/iPhoneOS/lib -L../xmpsdk/src -o libexiv2.la basicio.lo bmpimage.lo canonmn.lo casiomn.lo convert.lo cr2image.lo crwimage.lo datasets.lo easyaccess.lo epsimage.lo error.lo exif.lo futils.lo fujimn.lo gifimage.lo http.lo image.lo iptc.lo jp2image.lo jpgimage.lo makernote.lo metadatum.lo minoltamn.lo mrwimage.lo nikonmn.lo olympusmn.lo orfimage.lo panasonicmn.lo pentaxmn.lo pgfimage.lo pngimage.lo pngchunk.lo preview.lo properties.lo psdimage.lo rafimage.lo rw2image.lo samsungmn.lo sigmamn.lo sonymn.lo tags.lo tgaimage.lo tiffcomposite.lo tiffimage.lo tiffvisitor.lo types.lo value.lo version.lo xmp.lo xmpsidecar.lo  -rpath /Users/pol/Source/Libraries/libexiv2/exiv2-0.25/../iPhoneOS-armv7/lib -version-info 14:0:0 -liconv -lz     -lexpat -lxmpsdk
libtool: link: (cd .libs/libexiv2.lax/libxmpsdk.a && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar x "/Users/pol/Source/Libraries/libexiv2/exiv2-0.25/xmpsdk/src/.libs/libxmpsdk.a")
libtool: link: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar cru .libs/libexiv2.a  basicio.o bmpimage.o canonmn.o casiomn.o convert.o cr2image.o crwimage.o datasets.o easyaccess.o epsimage.o error.o exif.o futils.o fujimn.o gifimage.o http.o image.o iptc.o jp2image.o jpgimage.o makernote.o metadatum.o minoltamn.o mrwimage.o nikonmn.o olympusmn.o orfimage.o panasonicmn.o pentaxmn.o pgfimage.o pngimage.o pngchunk.o preview.o properties.o psdimage.o rafimage.o rw2image.o samsungmn.o sigmamn.o sonymn.o tags.o tgaimage.o tiffcomposite.o tiffimage.o tiffvisitor.o types.o value.o version.o xmp.o xmpsidecar.o  .libs/libexiv2.lax/libxmpsdk.a/ExpatAdapter.o .libs/libexiv2.lax/libxmpsdk.a/MD5.o .libs/libexiv2.lax/libxmpsdk.a/ParseRDF.o .libs/libexiv2.lax/libxmpsdk.a/UnicodeConversions.o .libs/libexiv2.lax/libxmpsdk.a/WXMPIterator.o .libs/libexiv2.lax/libxmpsdk.a/WXMPMeta.o .libs/libexiv2.lax/libxmpsdk.a/WXMPUtils.o .libs/libexiv2.lax/libxmpsdk.a/XML_Node.o .libs/libexiv2.lax/libxmpsdk.a/XMPCore_Impl.o .libs/libexiv2.lax/libxmpsdk.a/XMPIterator.o .libs/libexiv2.lax/libxmpsdk.a/XMPMeta-GetSet.o .libs/libexiv2.lax/libxmpsdk.a/XMPMeta-Parse.o .libs/libexiv2.lax/libxmpsdk.a/XMPMeta-Serialize.o .libs/libexiv2.lax/libxmpsdk.a/XMPMeta.o .libs/libexiv2.lax/libxmpsdk.a/XMPUtils-FileInfo.o .libs/libexiv2.lax/libxmpsdk.a/XMPUtils.o 
libtool: link: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib .libs/libexiv2.a
libtool: link: rm -fr .libs/libexiv2.lax
libtool: link: ( cd ".libs" && rm -f "libexiv2.la" && ln -s "../libexiv2.la" "libexiv2.la" )
mkdir -pv ../bin 2>&1 > /dev/null
libtool: link: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk -miphoneos-version-min=8.0 -fembed-bitcode -o ../bin/exiv2 exiv2.o actions.o utils.o -Wl,-bind_at_load  -L/Users/pol/Source/Libraries/libexiv2/exiv2-0.25/../../libexpat/iPhoneOS/lib -L/Users/pol/Source/Libraries/libexiv2/exiv2-0.25/xmpsdk/src ./.libs/libexiv2.a -liconv -lz -lexpat -ldl

我只是构建静态库,而不是共享库,以防万一。

更新: 关于基于 C 的库,link 命令不包括 -Wl,bind_at_load 例如libpng:

libtool: link: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk -arch arm64 -miphoneos-version-min=8.0 -fembed-bitcode -g -O2 -o pngvalid contrib/libtests/pngvalid.o  ./.libs/libpng16.a -lz

PS: 整个构建日志可用 here

我想通了:这是由于 configure 生成的 libtool 在链接 C++ 可执行文件时有一个旧的 OS X 错误的解决方法:

if test "$tagname" = CXX ; then
  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
    10.[0123])
      compile_command+=" ${wl}-bind_at_load"
      finalize_command+=" ${wl}-bind_at_load"
    ;;
  esac
fi

如果未定义 $MACOSX_DEPLOYMENT_TARGET,最有可能是这种情况,即使在 OS X 上构建,${MACOSX_DEPLOYMENT_TARGET-10.0} 的计算结果也是 10.0,因此解决方法开始。

解决方案是在使用 -fembed-bitcode:

为 iOS 设备构建库之前简单地执行此操作
export MACOSX_DEPLOYMENT_TARGET="10.4"