简体   繁体   English

iOS库的libxml2链接错误

[英]libxml2 linking error for iOS library

Make process on a C library causing the linking errors related to architecure.I am trying to build library for iOS but it has got dependancy on libxml2 which in this case I guess is Mac only library 在C库上进行处理,导致与architecure有关的链接错误。我正在尝试为iOS构建库,但它依赖libxml2,在这种情况下,我猜这是Mac唯一的库

lipo -info confirms the same lipo -info确认相同

admin$lipo -info /usr/local/lib/libxml2.dylib Non-fat file: /usr/local/lib/libxml2.dylib is architecture: x86_64 admin $ lipo -info /usr/local/lib/libxml2.dylib非胖文件:/usr/local/lib/libxml2.dylib是体系结构:x86_64

ld: warning: ignoring file /usr/local/lib/libxml2.dylib, file was built for x86_64 which is not the architecture being linked (armv7): /usr/local/lib/libxml2.dylib Undefined symbols for architecture armv7: "_xmlAddChild", referenced from: _setIsoId in libspatialite.a(gg_xml.o) referenced from: _vxpath_eval_expr in libspatialite.a(libsplite_la-virtualxpath.o) ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation) make[4]: * [demo1] Error 1 make[3]: ld:警告:忽略文件/usr/local/lib/libxml2.dylib,该文件是为x86_64(不是链接的体系结构)构建的(armv7):/usr/local/lib/libxml2.dylib体系结构armv7的未定义符号:“ _xmlAddChild”,引用自:libspatialite.a中的_setIsoId(gg_xml.o)引用:libspatialite.a中的_vxpath_eval_expr(libsplite_la-virtualxpath.o)ld:找不到体系结构armv7 clang的符号:错误:链接器命令失败退出代码1(使用-v查看调用)make [4]: * [demo1]错误1 make [3]: [install-recursive] Error 1 make[2]: [install-recursive]错误1 make [2]: [install-strip] Error 2 make 1 : * [/Users/admin/Downloads/libspatialite-ios-master/build/armv7/lib/libspatialite.a] Error 2 make: *** [build_arches] Error 2 [install-strip]错误2生成1 :* [/Users/admin/Downloads/libspatialite-ios-master/build/armv7/lib/libspatialite.a]错误2生成:*** [build_arches]错误2

Edit#1 编辑#1

After commenting, the libspatailite configuration and make section in the make file, I noticed that rest of the dependencies like gets,proj,sqlite are getting generated for all platforms armv7,armv7s,arm64,i386,x86_64. 注释完make文件中的libspatailite配置和make部分后,我注意到所有平台armv7,armv7s,arm64,i386,x86_64的其余依赖项(如gets,proj,sqlite)都已生成。 取景器快照

lipo -info on these libraries confirm the same.So the problem lies limited to building libspatialite. 这些库上的lipo -info确认相同。因此问题仅限于构建libspatialite。

Makefile ( To build only libspatialite.a) 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 - It seems Makefile within spatialite directory is getting generated automatically from above Makefile.I am not sure how I can control the lib ,include path to libxml2 dynamically. @ gagan-ios,@ kristina-brooks-似乎spaceite目录中的Makefile是从Makefile上面自动生成的。我不确定如何控制lib,包括libxml2的动态路径。

Edit2 One more level of investigation shows ,library getting generated for i386 and x86_64 and failing for armv7,armv7s and arm64 Edit2进一步的调查显示,为i386和x86_64生成库,而为armv7,armv7s和arm64生成库失败

${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 $ {MAKE}拱ARCH = armv7 IOS_PLATFORM = iPhoneOS HOST = arm-apple-darwin $ {MAKE}拱ARCH = armv7s IOS_PLATFORM = iPhoneOS HOST = arm-apple-darwin $ {MAKE}拱ARCH = arm64 IOS_PLATFORM = iPhoneOS HOST = 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

A suitable libxml2 stub should be present in the iPhoneOS SDK, just adding -lxml2 to linker flags should work. iPhoneOS SDK中应该存在一个合适的libxml2存根,只需将-lxml2添加到链接器标志中就可以了。 I'm guessing you've explicitly specified an absolute path to libxml2.dylib instead of letting the linker use the SDK relative path, so you're trying to link an ARM static library against an x86_64 version of libxml2 from your OS distribution. 我猜您已经为libxml2.dylib明确指定了绝对路径,而不是让链接器使用SDK相对路径,因此您正尝试从OS发行版中将ARM静态库链接到libxml2的x86_64版本。

Finally able to find a workaround with the help of Makefile at Compiling external C++ library for use with iOS project 最终能够在Makefile的帮助下找到解决方法,用于编译与iOS项目一起使用的外部C ++库

The work around is an amalgamation of 2 different make files and involved below steps. 解决方法是将2个不同的make文件合并在一起,并涉及以下步骤。

1.Use the Makefile partially to generate libraries for all platforms for dependencies (pros,geos,sqlite3) https://github.com/gstf/libspatialite-ios 1.部分使用Makefile为所有平台生成依赖关系的库(pros,geos,sqlite3) https://github.com/gstf/libspatialite-ios

2.Compiled libxml2 from source using the Makefile from Compiling external C++ library for use with iOS project 2.使用来自编译外部C ++库的Makefile从源代码编译 libxml2 以用于iOS项目

3.Makefile from Compiling external C++ library for use with iOS project is used to generate spatialite libraries for all platforms 3. 编译用于iOS项目的外部C ++库中的 Makefile用于生成所有平台的spatialite库

4.Use lipo from Step#1 Makefile to generate fat library 4,使用步骤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

Add these libraries to a new Xcode project and start using it. 将这些库添加到新的Xcode项目中并开始使用它。 Well here is my first success using this library 好吧,这是我使用此库的第一个成功

Include these libraries 包括这些库

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

Use the below APIs to get the Spatialite version 使用以下API获取Spatialite版本

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

Output 产量

Spatialite version: 4.3.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM