Home  >  Article  >  Backend Development  >  Use go build to build static libraries for the iPhone simulator

Use go build to build static libraries for the iPhone simulator

PHPz
PHPzforward
2024-02-09 22:33:08956browse

使用 go build 为 Iphone 模拟器构建静态库

php editor Zimo introduced: When developing iOS applications, we often need to use static libraries to extend functions or provide some common tool functions. Developers who develop using the Go language may wonder how to use the go build command to build a static library for the iPhone simulator. In this article, we will introduce in detail how to use the go build command to build a static library, and provide some practical tips and precautions to help developers successfully complete the static library building process. Whether you are a beginner or an experienced developer, you can read this article to gain practical knowledge and tips on building static libraries.

Question content

I use the following method to build a c archive in my ios project:

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 in xcode and try to run it using the simulator, 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 to position the simulator of go build as a static library used in a swift project?

Solution

Requirements

  • Create a static library for the iphone simulator
  • Use apple silicon instead of intel emulator
  • Ability to achieve a specific minimum version

tl;dr

If you select the simulator as the run destination, you can do something similar to xcode.

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 minimum version is encoded in -target (e.g. 16.2), it takes precedence (the correct option for the emulator is anyway -miphonesimulator-version-min) .

Then, as cgo_ldflags, also specify the -target option as well as -syslibroot and the path to the sdk.

With a slight tweak to your build script, it might look like this:

This specifies the emulator as the target, with a minimum version of 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

Then clangwrap.sh simplifies to:

#!/bin/zsh

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

exec "$clang" -target "$target" -isysroot "$sdk_path" "$@"

details

Different sdk

Must specify different sdk for ios device and iphone simulator. You can find them next to other platforms supported by xcode Under /applications/xcode.app/contents/developer/platforms. For example, in xcode 14.2 etc., there is a iphoneos platform with iphoneos16.2.sdk and a with iphonesimulator16.2.sdk iphonesimulator platform.

An apple employee in the apple developer forum posted this interesting post: https://developer.apple.com/forums/thread/673387#662260022

To inspect the generated static library for the load command, you can call:

otool -l libuplink.a

The generated static library for the apple silicon simulator should display the following:

...
load command 1
      cmd lc_build_version
  cmdsize 24
 platform 7
    minos 15.0
      sdk 16.2
...

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

See the section in the include file loader.h which 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

Built specifically for iphone devices

To build a static library for the iphone sdk you need to change the following:

export sdk=iphoneos

In the build.sh script above.

otool -l The output will appear as:

...
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 the emulator.

This of course works perfectly on the device.

The above is the detailed content of Use go build to build static libraries for the iPhone simulator. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete