[英]libxml2 linking error for iOS library
在C库上进行处理,导致与architecure有关的链接错误。我正在尝试为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中的_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]错误1 make [2]: [install-strip]错误2生成1 :* [/Users/admin/Downloads/libspatialite-ios-master/build/armv7/lib/libspatialite.a]错误2生成:*** [build_arches]错误2
编辑#1
注释完make文件中的libspatailite配置和make部分后,我注意到所有平台armv7,armv7s,arm64,i386,x86_64的其余依赖项(如gets,proj,sqlite)都已生成。
这些库上的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-似乎spaceite目录中的Makefile是从Makefile上面自动生成的。我不确定如何控制lib,包括libxml2的动态路径。
Edit2进一步的调查显示,为i386和x86_64生成库,而为armv7,armv7s和arm64生成库失败
$ {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
iPhoneOS SDK中应该存在一个合适的libxml2存根,只需将-lxml2
添加到链接器标志中就可以了。 我猜您已经为libxml2.dylib
明确指定了绝对路径,而不是让链接器使用SDK相对路径,因此您正尝试从OS发行版中将ARM静态库链接到libxml2的x86_64版本。
最终能够在Makefile的帮助下找到解决方法,用于编译与iOS项目一起使用的外部C ++库
解决方法是将2个不同的make文件合并在一起,并涉及以下步骤。
1.部分使用Makefile为所有平台生成依赖关系的库(pros,geos,sqlite3) https://github.com/gstf/libspatialite-ios
2.使用来自编译外部C ++库的Makefile从源代码编译 libxml2 以用于iOS项目
3. 编译用于iOS项目的外部C ++库中的 Makefile用于生成所有平台的spatialite库
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
将这些库添加到新的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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.