如何配置库以使其在 Xcode iOS 模拟器中运行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8796922/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 22:57:11  来源:igfitidea点击:

How to configure a library so it runs in the Xcode iOS Simulator?

xcodeios-simulatorconfigureicu

提问by egrunin

I've got an iPhone app that runs on the device. Now I need to run it in the Simulator.

我有一个在设备上运行的 iPhone 应用程序。现在我需要在模拟器中运行它。

It uses an open source project (http://site.icu-project.org/), which I build from the command line to create arm-compatible .afiles. I can link these with my iPhone project, and it runs on the device.

它使用一个开源项目 ( http://site.icu-project.org/),我从命令行构建它来创建与 arm 兼容的.a文件。我可以将这些链接到我的 iPhone 项目,并在设备上运行。

If I switch the target to Simulator, the build fails, as I expected:

如果我将目标切换到模拟器,构建将失败,正如我所料:

ld: warning: in libicudata.a, file was built for unsupported file format which is not the architecture being linked (i386)

ld:警告:在 libicudata.a 中,文件是为不受支持的文件格式构建的,这不是所链接的体系结构 (i386)

But if I use libs compiled for local use (x86_64), I get the same error, which has got be baffled. Do I have to specify a third architecture for the Simulator? Which one? How do I set the configuration?

但是,如果我使用为本地使用而编译的库 (x86_64),则会出现相同的错误,这让我感到困惑。我是否必须为模拟器指定第三种架构?哪一个?如何设置配置?

For reference, this is how I configured the icu project for the two different targets: How to build ICU so I can use it in an iPhone app?

作为参考,这是我为两个不同目标配置 icu 项目的方式:如何构建 ICU 以便我可以在 iPhone 应用程序中使用它?

Edited to add:

编辑添加:

As Guillaume suggested (and Connect iPhone App to PostgreSQL Using Libpqconfirmed), I now see that the emulator needs a 32-bit build. So that's the last part: how do I set the configuration?

正如 Guillaume 建议的(并确认使用 Libpq 将 iPhone 应用程序连接到 PostgreSQL),我现在看到模拟器需要 32 位构建。所以这是最后一部分:如何设置配置

The library has a standard configurescript, as far as I know, but I'm still pretty new at this.

configure据我所知,该库有一个标准脚本,但我对此还是很陌生。

Edited to add:

编辑添加:

I've gotten this far, but the references to i686 are obviously wrong.

我已经走了这么远,但对 i686 的引用显然是错误的。

I don't know if i386 is considered a cross-compile, if it is I need "host" and "target" options, too.

我不知道 i386 是否被认为是交叉编译,如果是,我也需要“主机”和“目标”选项。

ICU_PATH=/Users/eric.grunin/Documents/dev/icu2

DEVROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
SDKROOT=$DEVROOT/SDKs/iPhoneSimulator4.3.sdk
SYSROOT=$SDKROOT

ICU_FLAGS="-I$ICU_PATH/source/common/ -I$ICU_PATH/source/tools/tzcode/ "

export CXXPP=
export CXXPPFLAGS=
export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/include/ -I$SDKROOT/usr/include/c++/4.2.1/armv7-apple-darwin10/ -I./include/ -miphoneos-version-min=2.2 $ICU_FLAGS"

export CFLAGS="$CPPFLAGS -pipe -no-cpp-precomp -isysroot $SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS" 

export CC="$DEVROOT/usr/llvm-gcc-4.2/bin/i686-apple-darwin10-llvm-gcc-4.2"
export CXX="$DEVROOT/usr/llvm-gcc-4.2/bin/i686-apple-darwin10-llvm-g++-4.2"
export LDFLAGS="-L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip -miphoneos-version-min=2.0"

cd $ICU_PATH
mkdir simbuild
cd simbuild

$ICU_PATH/source/configure --enable-static --disable-shared 
gnumake

回答by Guillaume

You need to build a fat library: a fat library is a library that embed the code of many architectures in one file.
For the devices, you need to add the architectures armv6and armv7. For the simulator, i386.

您需要构建一个胖库:胖库是将许多架构的代码嵌入到一个文件中的库。
对于设备,您需要添加架构armv6armv7. 对于模拟器,i386.

Look into this answer for details and a script on how to do this from Xcode: https://stackoverflow.com/a/3647187/272342

查看此答案以获取有关如何从 Xcode 执行此操作的详细信息和脚本:https: //stackoverflow.com/a/3647187/272342

回答by egrunin

This is how I got it to work. I'm putting it here so I can look it up later.

这就是我让它工作的方式。我把它放在这里,以便稍后查看。

It's likely this is imperfect, feel free to correct it. Comments try to separate what's generic from what's specific to the ICU library I was building.

这可能是不完美的,请随时纠正它。评论试图将通用的内容与我正在构建的 ICU 库的特定内容分开。

// This is is required by the ICU configure step

# must be ABSOLUTE PATH
ICU_PATH=/Users/eric.grunin/Documents/dev/icu2

// First crucial bit: specify the Simulator

DEVROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
SDKROOT=$DEVROOT/SDKs/iPhoneSimulator4.3.sdk
SYSROOT=$SDKROOT

// for convenience

ICU_FLAGS="-I$ICU_PATH/source/common/ -I$ICU_PATH/source/tools/tzcode/ "

export CXXPP=
export CXXPPFLAGS=

// current version of gcc is missing some #include files, we have to get them elsewhere

export CPPFLAGS="-I$SDKROOT/usr/include/c++/4.2.1/i686-apple-darwin10/ -I$SDKROOT/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/include/ -I$SDKROOT/usr/include/c++/4.2.1/armv7-apple-darwin10/ -I./include/ -miphoneos-version-min=2.2 $ICU_FLAGS"

// MUST specify -arch i386

export CFLAGS="$CPPFLAGS -pipe -arch i386 -no-cpp-precomp -isysroot $SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS" 

export CC="$DEVROOT/usr/bin/gcc"
export CXX="$DEVROOT/usr/bin/g++"

// MUST add -arch i386 here.
// Also: to avoid "undefined symbol: _Unwind_Resume", add -lgcc_eh

export LDFLAGS="-arch i386 -L$SDKROOT/usr/lib/ -lgcc_eh -isysroot $SDKROOT -Wl,-dead_strip -miphoneos-version-min=2.0"

cd $ICU_PATH
mkdir simbuild
cd simbuild

// Not sure if --host is really needed

$ICU_PATH/source/configure --enable-static --disable-shared --host=i686-apple-darwin10
gnumake

I'm probably not going to make a fat binary, because the ICU library is already very large and I need to keep the final app as small as possible.

我可能不会制作胖二进制文件,因为 ICU 库已经非常大,我需要使最终的应用程序尽可能小。

Edited to add

编辑添加

I tried the fat library approach: it tripledthe size of my app, alas.

我尝试了胖库方法:它使我的应用程序的大小增加了两倍,唉。

回答by Steven R. Loomis

That's just the data library. You don't need to build it several times. Use --with-data-packaging=archivewhen you build ICU, and then it will generate a file icudt*.dat.. when your app starts up, call u_setDataDirectory()to tell it which directory contains that .dat file. u_setDataDirectory()

那只是数据库。您不需要多次构建它。--with-data-packaging=archive在构建ICU时使用,然后它会生成一个文件icudt*.dat..当你的应用程序启动时,调用u_setDataDirectory()告诉它哪个目录包含那个.dat文件。u_setDataDirectory()