HHH*_*HHH 17 c++ xcode objective-c objective-c++ ios
我对使用C++库完全不熟悉,所以请理解这可能对我的情况有点具体(让我知道,我可以提供更多细节).
我有一个外部C++库,我正在尝试使用iOS项目.该库遵循configure,make,make构建模式以输出.a库文件.当我尝试将此库文件添加到Xcode时,我收到以下错误:
忽略文件/Users/Developer/iOS/TestProj/libpresage.a,文件是为归档而构建的,而不是被链接的体系结构(i386):
/Users/Developer/iOS/TestProj/libpresage.a
基于这个问题,我尝试将Build Active Architecture Only转为NO,我得到了同样的错误.这让我怀疑我为不正确的架构编译了库.
在.a文件上运行lipo -info给出:
输入文件libpresage.a不是胖文件非胖文件:libpresage.a
是架构:x86_64
鉴于这不是armv7s,armv7或arm64,我尝试使用以下参数再次编译C++库:
1)试试
./configure CC="gcc -arch armv7s" \
CXX="g++ -arch armv7s" \
CPP="gcc -E" CXXCPP="g++ -E"
Run Code Online (Sandbox Code Playgroud)
编译时出错,我得到:
ld: library not found for -lcrt1.3.1.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
2)试试
./configure CC="gcc -arch arm64" \
CXX="g++ -arch arm64" \
CPP="gcc -E" CXXCPP="g++ -E"
Run Code Online (Sandbox Code Playgroud)
编译时出错,我得到:
ld:警告:ld:警告:忽略文件/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib/libSystem.dylib,缺少所需的架构arm64 in文件/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib/libSystem.dylib(2个切片)忽略文件/Applications/Xcode.app/Contents/开发人员/平台/ MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib/libstdc ++.dylib,在文件/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer中缺少所需的架构arm64 /SDKs/MacOSX10.10.sdk/usr/lib/libstdc++.dylib(2片)
ld:动态主可执行文件必须与libSystem.dylib链接,用于体系结构arm64 clang:错误:链接器命令失败,退出代码为1(使用-v查看调用)
有什么明显的东西让我失踪吗?
编辑:
感谢您的回复,所以我设法将库作为自定义构建目标放入Xcode,将'make'命令指向库MakeFile.这个构建很好.
我从这里开始:
架构armv7的未定义符号:"Presage :: Presage(PresageCallback*)",引自: - PresageBridge.o中的[PresageBridge init]"Presage ::〜Presage()",引用自: - PresageBridge中的[PresageBridge init]. o ld:找不到架构armv7 clang的符号:错误:链接器命令失败,退出代码为1(使用-v查看调用)
我的目标C++包装器(链接外部C++库头文件presage.h):
#import "PresageBridge.h"
#include "presage.h"
@implementation PresageBridge
- (instancetype)init
{
if(self = [super init])
{
Presage hello(&callback);
}
return self;
}
Run Code Online (Sandbox Code Playgroud)根据上面的代码,它似乎不像我错过了标题,有趣的是我还尝试在外部库中创建其他类的实例,它们似乎正在工作,这表明Xcode可以由于某种原因,正确链接presage.h.
Mob*_*Ben 34
所以我在iOS项目中使用了很多第三方C++库.人们使用不同的策略.正如一些人已经提到的,您可以直接在项目中包含代码,使用Xcode构建静态库,或者构建命令行.对于使用GNU配置和构建系统的跨平台C++库,我更喜欢命令行.您只需要构建一次,如果需要更新版本或添加新的体系结构切片,则只需重新访问它.
您想要的通用方法是:
找出用于构建每个切片的正确配置参数.通常情况下,您只需要专注于让其中一个手臂以及i386正常工作.其余的很容易就可以完成.在某些情况下,您实际上需要修改配置文件以添加主机或进行一些其他调整.
一旦你可以构建所有切片,你想运行lipo来构建一个胖二进制文件.
处理此问题的最佳方法是创建一个构建脚本,它将为您完成所有工作.这样,重做更容易.更重要的是,您可以重用脚本或对其进行置换以构建其他外部库.
您可以通过多种方式构建脚本.这是一个.我碰巧有这种类型的脚本的几种变体.该脚本用于构建cURL.它或多或少地用于预设,具有非常少的mod(即改变卷曲到预期).注意我没有在Xcode中测试它(即链接它并运行它).我确实发现我必须禁用sqlite,否则它会构建不正确构建的工具项.如果你需要它,你可以找出那个部分.
有很多方法可以使它更光滑.例如,使用数组来存储所有体系结构.这只是蛮力.
该脚本的关键点是:
请注意,它应该开箱即用,但YMMV.如有必要,请准备好进行调试.例如,我还没有确认主机类型,但通常这是我一直使用的.你想把它放在预告的目录(配置相同的目录).完成后,所有体系结构都在输出目录中.通用lib位于presage目录中.
还要记住,您有责任正确链接通用库,并正确定义头文件搜索路径.
#!/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
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
Run Code Online (Sandbox Code Playgroud)
考虑到你是C++库的新手,我想你需要做更多的研究.
但是,我将尝试概述您需要考虑的一些步骤:
有多种方法可以解决这些问题.
对于第一个,我建议在您的工作区中包含静态库,并将其作为依赖项添加到构建目标.为此,您需要了解XCode构建.
我猜你实际上是在尝试制作一个手机应用程序,所以对于第三个选项,你需要配置你的g ++构建,以便在链接arm目标(看看iPhoneOS.platform)时从XCode查看iPhoneSDK.
制作手臂版只适用于iPhone.如果您希望它在模拟器上运行,您需要将静态库链接到iPhoneSimulator.platform中的库.
如果你想让你的静态库适用于iPhone和iPhone模拟器,你需要制作一个胖lib(基本上是一个包含两个平台符号的库)
如果您缺少这些平台,可以从XCode下载它们(但我相信它们在那里)
正如您所看到的,在此过程中事情将变得越来越复杂,因此我强烈建议使用XCode来编译静态库(它仍然可以使用g ++).
我相信您将有用于研究的以下概念:
希望这可以帮助 :).
归档时间: |
|
查看次数: |
19341 次 |
最近记录: |