【问题标题】:libxml2 linking error for iOS libraryiOS 库的 libxml2 链接错误
【发布时间】:2017-05-09 03:57:55
【问题描述】:

在 C 库上创建过程会导致与架构相关的链接错误。我正在尝试为 iOS 构建库,但它依赖于 libxml2,在这种情况下我猜这是仅限 Mac 的库

lipo -info 也证实了这一点

admin$lipo -info /usr/local/lib/libxml2.dylib 非胖文件:/usr/local/lib/libxml2.dylib 是架构:x86_64

ld:警告:忽略文件 /usr/local/lib/libxml2.dylib,文件是 为 x86_64 构建,它不是被链接的架构(armv7): /usr/local/lib/libxml2.dylib 架构 armv7 的未定义符号: “_xmlAddChild”,引用自: libspatialite.a(gg_xml.o) 中的 _setIsoId 参考自: libspatialite.a(libsplite_la-virtualxpath.o) ld 中的 _vxpath_eval_expr:未找到符号 对于架构 armv7 clang:错误:链接器命令失败并退出 代码 1(使用 -v 查看调用) make[4]: * [demo1] 错误 1 make[3]: [install-recursive] 错误 1 ​​make[2]: [install-strip] 错误 2 make1: * [/Users/admin/Downloads/libspatialite-ios-master/build/armv7/lib/libspatialite.a] 错误 2 make: *** [build_arches] 错误 2

编辑#1

在对 make 文件中的 libspatailite 配置和 make 部分进行注释后,我注意到其余的依赖项,如 get、proj、sqlite 正在为所有平台 armv7、armv7s、arm64、i386、x86_64 生成。

这些库上的 lipo -info 确认相同。所以问题仅限于构建 libspatialite。

Makefile(仅构建 libspatialite.a)

XCODE_DEVELOPER = $(shell xcode-select --print-path)
IOS_PLATFORM ?= iPhoneOS

# Pick latest SDK in the directory
IOS_PLATFORM_DEVELOPER = ${XCODE_DEVELOPER}/Platforms/${IOS_PLATFORM}.platform/Developer
IOS_SDK = ${IOS_PLATFORM_DEVELOPER}/SDKs/$(shell ls ${IOS_PLATFORM_DEVELOPER}/SDKs | sort -r | head -n1)

all: lib/libspatialite.a
lib/libspatialite.a: build_arches
    mkdir -p lib
    mkdir -p include

    # Copy includes
    cp -R build/armv7/include/geos include
    cp -R build/armv7/include/spatialite include
    cp -R build/armv7/include/*.h include

    # Make fat libraries for all architectures
    for file in build/armv7/lib/*.a; \
        do name=`basename $$file .a`; \
        lipo -create \
            -arch armv7 build/armv7/lib/$$name.a \
            -arch armv7s build/armv7s/lib/$$name.a \
            -arch arm64 build/arm64/lib/$$name.a \
            -arch i386 build/i386/lib/$$name.a \
            -arch x86_64 build/x86_64/lib/$$name.a \
            -output lib/$$name.a \
        ; \
        done;

# Build separate architectures
build_arches:
    ${MAKE} arch ARCH=armv7 IOS_PLATFORM=iPhoneOS HOST=arm-apple-darwin
    ${MAKE} arch ARCH=armv7s IOS_PLATFORM=iPhoneOS HOST=arm-apple-darwin
    ${MAKE} arch ARCH=arm64 IOS_PLATFORM=iPhoneOS HOST=arm-apple-darwin
    ${MAKE} arch ARCH=i386 IOS_PLATFORM=iPhoneSimulator HOST=i386-apple-darwin
    ${MAKE} arch ARCH=x86_64 IOS_PLATFORM=iPhoneSimulator HOST=x86_64-apple-darwin

PREFIX = ${CURDIR}/build/${ARCH}
LIBDIR = ${PREFIX}/lib
BINDIR = ${PREFIX}/bin
INCLUDEDIR = ${PREFIX}/include

CXX = ${XCODE_DEVELOPER}/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
CC = ${XCODE_DEVELOPER}/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
CFLAGS = -isysroot ${IOS_SDK} -I${IOS_SDK}/usr/include -arch ${ARCH} -I${INCLUDEDIR} -miphoneos-version-min=7.0
CXXFLAGS = -stdlib=libc++ -std=c++11 -isysroot ${IOS_SDK} -I${IOS_SDK}/usr/include -arch ${ARCH} -I${INCLUDEDIR} -miphoneos-version-min=7.0
LDFLAGS = -stdlib=libc++ -isysroot ${IOS_SDK} -L${LIBDIR} -L${IOS_SDK}/usr/lib -arch ${ARCH} -miphoneos-version-min=7.0

arch: ${LIBDIR}/libspatialite.a

${LIBDIR}/libspatialite.a: ${LIBDIR}/libproj.a ${LIBDIR}/libgeos.a ${LIBDIR}/libsqlite3.a ${CURDIR}/spatialite
    cd spatialite && env \
    CXX=${CXX} \
    CC=${CC} \
    CFLAGS="${CFLAGS} -Wno-error=implicit-function-declaration" \
    CXXFLAGS="${CXXFLAGS} -Wno-error=implicit-function-declaration" \
    LDFLAGS="${LDFLAGS} -liconv -lgeos -lgeos_c -lc++" ./configure --host=${HOST} --disable-freexl --prefix=${PREFIX} --with-geosconfig=${BINDIR}/geos-config --disable-shared && make clean install-strip


clean:
    rm -rf build geos proj spatialite sqlite3 include lib

@gagan-ios,@kristina-brooks - 似乎空间目录中的 Makefile 是从 Makefile 上方自动生成的。我不确定如何控制 lib,动态包含 libxml2 的路径。

编辑2 进一步的调查显示,为 i386 和 x86_64 生成了库,而为 armv7、armv7s 和 arm64 生成了库

${MAKE} ARCH=armv7 IOS_PLATFORM=iPhoneOS HOST=arm-apple-darwin ${MAKE} 拱 ARCH=armv7s IOS_PLATFORM=iPhoneOS 主机=arm-apple-darwin ${MAKE} 拱 ARCH=arm64 IOS_PLATFORM=iPhoneOS 主机=arm-apple-darwin ${MAKE} 拱 ARCH=i386 IOS_PLATFORM=iPhoneSimulator HOST=i386-apple-darwin ${MAKE} ARCH=x86_64 IOS_PLATFORM=iPhoneSimulator HOST=x86_64-apple-darwin

【问题讨论】:

  • 检查集成并按照 SDK 文档中的建议添加其他链接器标志。

标签: c++ ios c libxml2 spatialite


【解决方案1】:

iPhoneOS SDK 中应该存在合适的 libxml2 存根,只需将 -lxml2 添加到链接器标志即可。我猜您已经明确指定了libxml2.dylib 的绝对路径,而不是让链接器使用 SDK 相对路径,因此您尝试将 ARM 静态库与操作系统发行版中的 x86_64 版本的 libxml2 链接。

【讨论】:

  • 我正在尝试从这里构建 github.com/gstf/libspatialite-ios ,根据您的建议,我注意到 Makefile 包含以下条目 LIBXML2_LIBS = -L/usr/local/lib -lxml2 .....也许我有编辑它以指向另一个位置..
  • 没有运气编辑 Makefile 导致同样的错误
【解决方案2】:

终于能够在Compiling external C++ library for use with iOS projectCompiling external C++ library for use with iOS project的 Makefile 的帮助下找到解决方法

解决方法是合并 2 个不同的 make 文件并涉及以下步骤。

1.部分使用Makefile为所有平台生成依赖库(pros,geos,sqlite3)https://github.com/gstf/libspatialite-ios

2.使用来自Compiling external C++ library for use with iOS project的Makefile从源代码编译libxml2

3.来自Compiling external C++ library for use with iOS project的Makefile用于为所有平台生成空间库

4.使用Step#1 Makefile中的lipo生成fat库

#!/bin/bash

PLATFORMPATH="/Applications/Xcode.app/Contents/Developer/Platforms"
TOOLSPATH="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin"
export IPHONEOS_DEPLOYMENT_TARGET="8.0"
pwd=`pwd`

findLatestSDKVersion()
{
    sdks=`ls $PLATFORMPATH/$1.platform/Developer/SDKs`
    arr=()
    for sdk in $sdks
    do
       arr[${#arr[@]}]=$sdk
    done

    # Last item will be the current SDK, since it is alpha ordered
    count=${#arr[@]}
    if [ $count -gt 0 ]; then
       sdk=${arr[$count-1]:${#1}}
       num=`expr ${#sdk}-4`
       SDKVERSION=${sdk:0:$num}
    else
       SDKVERSION="8.0"
    fi
}

buildit()
{
    target=$1
    hosttarget=$1
    platform=$2

    if [[ $hosttarget == "x86_64" ]]; then
        hostarget="i386"
    elif [[ $hosttarget == "arm64" ]]; then
        hosttarget="arm"
    fi

    export CC="$(xcrun -sdk iphoneos -find clang)"
    export CPP="$CC -E"
    export CFLAGS="-arch ${target} -isysroot $PLATFORMPATH/$platform.platform/Developer/SDKs/$platform$SDKVERSION.sdk -miphoneos-version-min=$SDKVERSION"
    export AR=$(xcrun -sdk iphoneos -find ar)
    export RANLIB=$(xcrun -sdk iphoneos -find ranlib)
    export CPPFLAGS="-arch ${target}  -isysroot $PLATFORMPATH/$platform.platform/Developer/SDKs/$platform$SDKVERSION.sdk -miphoneos-version-min=$SDKVERSION"
    export LDFLAGS="-arch ${target} -isysroot $PLATFORMPATH/$platform.platform/Developer/SDKs/$platform$SDKVERSION.sdk"

    mkdir -p $pwd/output/$target

     ./configure --prefix="$pwd/output/$target" --disable-shared --disable-sqlite --host=$hosttarget-apple-darwin

    make clean
    make
    make install
}

findLatestSDKVersion iPhoneOS

buildit armv7 iPhoneOS
buildit armv7s iPhoneOS
buildit arm64 iPhoneOS
buildit i386 iPhoneSimulator
buildit x86_64 iPhoneSimulator

将这些库添加到新的 Xcode 项目并开始使用它。 那么这是我使用这个库的第一次成功

包括这些库

#include <sqlite3.h>
#include <spatialite/gaiageo.h>
#include <spatialite.h>

使用以下 API 获取 Spatialite 版本

spatialite_init(0);
printf("Spatialite version: %s\n", spatialite_version());

输出

Spatialite version: 4.3.0

【讨论】:

    猜你喜欢
    • 2013-01-20
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    相关资源
    最近更新 更多