Compiling external C++ library for use with iOS project -
i'm new using c++ libraries, appreciate might bit specific case (let me know , can provide more details).
i have external c++ library i'm trying use ios project. library follows configure, make, make build pattern output .a library file. when try , add library file xcode, following error:
ignoring file /users/developer/ios/testproj/libpresage.a, file built archive not architecture being linked (i386):
/users/developer/ios/testproj/libpresage.a
based on this question, i've tried turning build active architecture no, , same error. makes me suspect i've compiled library incorrect architecture.
running lipo -info on .a file gives:
input file libpresage.a not fat file non-fat file: libpresage.a
is architecture: x86_64
given isn't armv7s, armv7, or arm64, try , compile c++ library again following parameters:
1) try
./configure cc="gcc -arch armv7s" \ cxx="g++ -arch armv7s" \ cpp="gcc -e" cxxcpp="g++ -e"
error in compiling, get:
ld: library not found -lcrt1.3.1.o clang: error: linker command failed exit code 1 (use -v see invocation)
2) try
./configure cc="gcc -arch arm64" \ cxx="g++ -arch arm64" \ cpp="gcc -e" cxxcpp="g++ -e"
error in compiling, get:
ld: warning: ld: warning: ignoring file /applications/xcode.app/contents/developer/platforms/macosx.platform/developer/sdks/macosx10.10.sdk/usr/lib/libsystem.dylib, missing required architecture arm64 in file /applications/xcode.app/contents/developer/platforms/macosx.platform/developer/sdks/macosx10.10.sdk/usr/lib/libsystem.dylib (2 slices)ignoring file /applications/xcode.app/contents/developer/platforms/macosx.platform/developer/sdks/macosx10.10.sdk/usr/lib/libstdc++.dylib, missing required architecture arm64 in file /applications/xcode.app/contents/developer/platforms/macosx.platform/developer/sdks/macosx10.10.sdk/usr/lib/libstdc++.dylib (2 slices)
ld: dynamic main executables must link libsystem.dylib architecture arm64 clang: error: linker command failed exit code 1 (use -v see invocation)
is there obvious i'm missing?
edit:
thanks replies, i've managed library xcode custom build target, pointing 'make' command libraries makefile. build fine.
my steps here:
- add dependency objective c ios app target custom build target.
- reference library , make objective c++ wrapper.
- this seems fine until need call external c++ library, error when compiling:
undefined symbols architecture armv7: "presage::presage(presagecallback*)", referenced from: -[presagebridge init] in presagebridge.o "presage::~presage()", referenced from: -[presagebridge init] in presagebridge.o ld: symbol(s) not found architecture armv7 clang: error: linker command failed exit code 1 (use -v see invocation)
my objective c++ wrapper (linking external c++ library header presage.h):
#import "presagebridge.h" #include "presage.h" @implementation presagebridge - (instancetype)init { if(self = [super init]) { presage hello(&callback); } return self; }
based on code above doesn't seem i'm missing header, , what's interesting i've tried creating instance of other classes in external library , seem working, suggests xcode can't link presage.h reason.
so i've used many 3rd party c++ library in ios projects. there different strategies people use this. have cited, can include code within project directly, build static lib xcode, or build command line. in case of cross platform c++ libs use gnu configure , build system, prefer command line. need build once , have revisit if need update version or add new architecture slice.
the generalized approach want is:
figure out right configure arguments use build each slice. typically, need focus on getting 1 of arm i386 working. rest easy 1 have done. in cases, need modify configure file add host or make other adjustments.
once can build slices, want run lipo build fat binary.
the best way deal create build script work you. way, it's easier redo. more importantly, can reuse script or permute build other external libs.
there many ways can build script. here one. happen have several variations of type of script. script used build curl. more or less worked presage little mod (ie. change curl presage). note didn't test in xcode (ie. linking , running it). did find had disable sqlite, else built tool items don't build right. if need it, can figure part out.
there many ways make more slick. example using array store architectures. brute force.
the key points of script are:
- getting latest sdk
- building each slice
- then running lipo
note should work out of box, however, ymmv. prepared have debug if necessary. example, haven't confirmed host type, i've used. want put @ directory presage (same directory configure). when done, architectures in output directory. universal lib in presage directory.
also remember responsibility link in universal lib have header files search path defined properly.
#!/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=() sdk in $sdks arr[${#arr[@]}]=$sdk done # last item current sdk, since alpha ordered count=${#arr[@]} if [ $count -gt 0 ]; 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" ]]; hostarget="i386" elif [[ $hosttarget == "arm64" ]]; 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 lipo=$(xcrun -sdk iphoneos -find lipo) $lipo -create $pwd/output/armv7/lib/libpresage.a $pwd/output/armv7s/lib/libpresage.a $pwd/output/arm64/lib/libpresage.a $pwd/output/x86_64/lib/libpresage.a $pwd/output/i386/lib/libpresage.a -output libpresage.a
Comments
Post a Comment