使用`go build`命令为iPhone模拟器构建静态库。

huangapple go评论105阅读模式
英文:

Building a static library with go build for Iphone simulator

问题

我正在使用以下命令在我的iOS项目中构建一个C存档:

GOOS=ios GOARCH=arm64 CGO_ENABLED=1 SDK=iphonesimulator CGO_CFLAGS="-fembed-bitcode" CC=pwd/clangwrap.sh go build -buildmode=c-archive -o libuplink.a

Clangwrap.sh的内容如下:

#!/bin/sh

# go/clangwrap.sh

SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
CLANG=`xcrun --sdk $SDK --find clang`

if [ "$GOARCH" == "amd64" ]; then
    CARCH="x86_64"
elif [ "$GOARCH" == "arm64" ]; then
    CARCH="arm64"
fi

exec $CLANG -arch $CARCH -isysroot $SDK_PATH -mios-version-min=10.0 "$@"

然而,当我在XCode中链接并尝试在模拟器上运行时,我只能在设备本身上运行:

building for iOS Simulator, but linking in object file built for iOS ... for architecture arm64

如何为在Swift项目中使用的静态库的go build目标模拟器?

英文:

I an building a c archive in my iOS project using following:

GOOS=ios GOARCH=arm64 CGO_ENABLED=1 SDK=iphonesimulator CGO_CFLAGS="-fembed-bitcode" CC=pwd/clangwrap.sh go build -buildmode=c-archive -o libuplink.a

Clangwrap.sh looks like this

#!/bin/sh

# go/clangwrap.sh

SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
CLANG=`xcrun --sdk $SDK --find clang`

if [ "$GOARCH" == "amd64" ]; then
    CARCH="x86_64"
elif [ "$GOARCH" == "arm64" ]; then
    CARCH="arm64"
fi

exec $CLANG -arch $CARCH -isysroot $SDK_PATH -mios-version-min=10.0 "$@"

When I link it up in XCode and attempt to run with simulator however, I can only run it on the device itself:

building for iOS Simulator, but linking in object file built for iOS ... for architecture arm64

How do I target the simulator for a go build for a static library that's used in Swift project?

答案1

得分: 1

要求

  • 为iPhone模拟器创建一个静态库
  • 使用Apple Silicon而不是Intel模拟器
  • 能够指定最低版本

TL;DR

如果选择模拟器作为运行目标,可以执行类似于Xcode的操作。

因此,使用类似于-target arm64-apple-ios16.2-simulator而不是-arch arm64。还省略-mios-version-min=10.0,因为实际的最低版本已经编码在-target中(例如16.2),它具有优先权(模拟器的正确选项应该是-miphonesimulator-version-min)。

然后,作为CGO_LDFLAGS,还要指定-target选项以及带有SDK路径的-syslibroot

稍微调整了您的构建脚本,可能如下所示:

这将将模拟器指定为目标,最低版本为15。

build.sh

#!/bin/sh
export GOOS=ios
export GOARCH=arm64
export CGO_ENABLED=1
export SDK=iphonesimulator
export CGO_CFLAGS="-fembed-bitcode"
export MIN_VERSION=15

. ./target.sh

export CGO_LDFLAGS="-target ${TARGET} -syslibroot \"${SDK_PATH}\""
CC="$(pwd)/clangwrap.sh"
export CC

go build -buildmode=c-archive -o libuplink.a

target.sh

#!/bin/sh

SDK_PATH=$(xcrun --sdk "$SDK" --show-sdk-path)
export SDK_PATH

if [ "$GOARCH" = "amd64" ]; then
    CARCH="x86_64"
elif [ "$GOARCH" = "arm64" ]; then
    CARCH="arm64"
fi

if [ "$SDK" = "iphoneos" ]; then
  export TARGET="$CARCH-apple-ios$MIN_VERSION"
elif [ "$SDK" = "iphonesimulator" ]; then
  export TARGET="$CARCH-apple-ios$MIN_VERSION-simulator"
fi

clangwrap.sh

clangwrap.sh 简化为:

#!/bin/zsh

CLANG=$(xcrun --sdk "$SDK" --find clang)

exec "$CLANG" -target "$TARGET" -isysroot "$SDK_PATH" "$@"

详细信息


不同的SDK

必须为iOS设备和iPhone模拟器指定不同的SDK。您可以在Xcode支持的其他平台旁边找到它们,路径为/Applications/Xcode.app/Contents/Developer/Platforms。例如,在Xcode 14.2中,其中包括iPhoneOS平台具有iPhoneOS16.2.sdkiPhoneSimulator平台具有iPhoneSimulator16.2.sdk

在Apple开发者论坛上有一篇来自Apple员工的有趣帖子:https://developer.apple.com/forums/thread/673387#662260022

要检查生成的静态库以显示load命令,可以调用:

otool -l libuplink.a

为与Apple Silicon模拟器一起使用生成的静态库应该显示如下内容:

...
Load command 1
      cmd LC_BUILD_VERSION
  cmdsize 24
 platform 7
    minos 15.0
      sdk 16.2
...    

注意:platform 7表示模拟器,minos表示最低部署目标,sdk表示实际使用的SDK版本。

请参阅包含文件loader.h中的部分,其中写道:

/* Known values for the above platform field. */
#define PLATFORM_UNKNOWN 0
#define PLATFORM_ANY 0xFFFFFF
#define PLATFORM_MACOS 1
#define PLATFORM_IOS 2
#define PLATFORM_TVOS 3
#define PLATFORM_WATCHOS 4
#define PLATFORM_BRIDGEOS 5
#define PLATFORM_MACCATALYST 6
#define PLATFORM_IOSSIMULATOR 7
#define PLATFORM_TVOSSIMULATOR 8
#define PLATFORM_WATCHOSSIMULATOR 9
#define PLATFORM_DRIVERKIT 10

您可以使用以下命令在您的系统上查看它们:

cat `xcrun --sdk iphonesimulator --show-sdk-path`/usr/include/mach-o/loader.h

为iPhone设备构建

要为iPhone SDK构建静态库,您需要更改上述build.sh脚本中的以下内容:

export SDK=iphoneos

如果您尝试在模拟器中使用此库,它将失败并显示消息building for iOS Simulator, but linking in object file built for iOS, file 'libuplink.a' for architecture arm64

otool -l的输出将如下所示:

...
Load command 1
      cmd LC_BUILD_VERSION
  cmdsize 24
 platform 2
    minos 15.0
      sdk 16.2
   ntools 0
...

注意:Platform 2代表PLATFORM_IOS而不是模拟器。

当然,这将在设备上完美运行。

英文:

Requirements

  • Create a static library for the iPhone simulator
  • Use Apple Silicon instead of Intel simulator
  • Ability to specific minimum version

TL;DR

You could do something similar to Xcode if you choose a simulator as run destination.

So basically use something like -target arm64-apple-ios16.2-simulator instead of -arch arm64. Also omit -mios-version-min=10.0, since the actual minimal version is encoded in the -target (e.g. 16.2), which takes precedence (the correct option for the simulator would be -miphonesimulator-version-min anyway).

Then as CGO_LDFLAGS also specify the -target option plus -syslibroot with the path to the SDK.

Your build scripts tweaked a bit, it might look something like this:

This specifies the simulator as the target and the minimum version is 15.

build.sh

#!/bin/sh
export GOOS=ios
export GOARCH=arm64
export CGO_ENABLED=1
export SDK=iphonesimulator
export CGO_CFLAGS="-fembed-bitcode"
export MIN_VERSION=15

. ./target.sh

export CGO_LDFLAGS="-target ${TARGET} -syslibroot \"${SDK_PATH}\""
CC="$(pwd)/clangwrap.sh"
export CC

go build -buildmode=c-archive -o libuplink.a

target.sh

#!/bin/sh

SDK_PATH=$(xcrun --sdk "$SDK" --show-sdk-path)
export SDK_PATH

if [ "$GOARCH" = "amd64" ]; then
    CARCH="x86_64"
elif [ "$GOARCH" = "arm64" ]; then
    CARCH="arm64"
fi

if [ "$SDK" = "iphoneos" ]; then
  export TARGET="$CARCH-apple-ios$MIN_VERSION"
elif [ "$SDK" = "iphonesimulator" ]; then
  export TARGET="$CARCH-apple-ios$MIN_VERSION-simulator"
fi

clangwrap.sh

The clangwrap.sh then simplifies to:

#!/bin/zsh

CLANG=$(xcrun --sdk "$SDK" --find clang)

exec "$CLANG" -target "$TARGET" -isysroot "$SDK_PATH" "$@"

Details


Different SDKs

Different SDKs must be specified for an iOS device and the iPhone simulator. You can find them next to the other platforms supported by Xcode
under /Applications/Xcode.app/Contents/Developer/Platforms. For example, in Xcode 14.2, among others, there is an iPhoneOS platform with an iPhoneOS16.2.sdk and an iPhoneSimulator platform with iPhoneSimulator16.2.sdk.

There is this interesting post from an Apple employee in the Apple developer forum: https://developer.apple.com/forums/thread/673387#662260022

To check a generated static library to display the load commands, you can call:

otool -l libuplink.a

A static library generated for use with an Apple Silicon simulator should display something like the following:

...
Load command 1
      cmd LC_BUILD_VERSION
  cmdsize 24
 platform 7
    minos 15.0
      sdk 16.2
...    

Note: platform 7 denotes the simulator, minos the minimum deployment target, and sdk the actual SDK version used.

See the section in the include file loader.h that reads:

/* Known values for the above platform field. */
#define PLATFORM_UNKNOWN 0
#define PLATFORM_ANY 0xFFFFFF
#define PLATFORM_MACOS 1
#define PLATFORM_IOS 2
#define PLATFORM_TVOS 3
#define PLATFORM_WATCHOS 4
#define PLATFORM_BRIDGEOS 5
#define PLATFORM_MACCATALYST 6
#define PLATFORM_IOSSIMULATOR 7
#define PLATFORM_TVOSSIMULATOR 8
#define PLATFORM_WATCHOSSIMULATOR 9
#define PLATFORM_DRIVERKIT 10

You can view them yourself on your system as follows:

cat `xcrun --sdk iphonesimulator --show-sdk-path`/usr/include/mach-o/loader.h

Build for iPhone device

To build a static library for the iPhone SDK, you would change this:

export SDK=iphoneos

in the build.sh script above.

If you tried to use this library in the simulator, it would fail with the message building for iOS Simulator, but linking in object file built for iOS, file 'libuplink.a' for architecture arm64.

The output of otool -l would read:

...
Load command 1
      cmd LC_BUILD_VERSION
  cmdsize 24
 platform 2
    minos 15.0
      sdk 16.2
   ntools 0
...

Note: Platform 2 stands for PLATFORM_IOS and not for the simulator.

This will of course run perfectly on the device.

huangapple
  • 本文由 发表于 2023年1月9日 20:01:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056984.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定