建造一个静态图书馆,并建造手机模拟器
原标题:Building a static library with go build for Iphone simulator
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?
最佳回答
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.
问题回答
for Stephan Schlecht answer, I should add this
export SDKROOT=$(xcrun --sdk iphoneos --show-sdk-path)
export CC=$(xcrun --sdk iphoneos -f clang)
export CXX=$(xcrun --sdk iphoneos -f clang++)
this will fix the error in my case: Building for iOS-simulator , but linking in object file (***) built for macOS
with otool -l ***.a | grep platform, we can see the result is: platform 7
function validate_platform_for_library_at_path(){
#
# this function get platform of library at path and compare with input platform description
platform=${1}
library=${2}
n=
if [ ! -f "${library}" ]; then
echo "library not found ${library}"
return 127
fi
case "${platform}" in
"MacOSX") n=1;;
"iPhoneOS") n=2;;
"AppleTVOS") n=3;;
"WatchOS") n=4;;
"BridgeOS") n=5;;
"MacCatalyst") n=6;;
"iPhoneSimulator") n=7;;
"AppleTVSimulator") n=8;;
"WatchSimulator") n=9;;
"DriverKit") n=10;;
"XROS") n=11;;
"XRSimulator") n=12;;
*) return 127;;
esac
#
# binary can contain multiple archs but platform will be the same for all archs,
# so head can be used here to filter one entry of LC_BUILD_VERSION
#
# Loader.h
# LC_BUILD_VERSION 0x32 /* build for platform min OS version */
# define PLATFORM_MACOS 1
# all other platforms defined ...
text="$(otool -l ${library} | grep -A 5 LC_BUILD_VERSION | head -5)"
if [[ ! ${text} =~ "platform ${n}" ]]; then
lib_platform_n="$(otool -l ${library} | grep -A 5 LC_BUILD_VERSION | head -5 | grep -E platform [0-9]+ | grep -o [[:digit:]]+ )"
lib_platform=
case "${lib_platform_n}" in
"1") lib_platform="MacOSX";;
"2") lib_platform="iPhoneOS";;
"3") lib_platform="AppleTVOS";;
"4") lib_platform="WatchOS";;
"5") lib_platform="BridgeOS";;
"6") lib_platform="MacCatalyst";;
"7") lib_platform="iPhoneSimulator";;
"8") lib_platform="AppleTVSimulator";;
"9") lib_platform="WatchSimulator";;
"10") lib_platform="DriverKit";;
"11") lib_platform="XROS";;
"12") lib_platform="XRSimulator";;
*) lib_platform "unknown";;
esac
echo " -- test failed"
echo " -- valid-platform:${platform} num:${n}"
echo " -- detected-platform:${lib_platform} num:${lib_platform_n}"
echo " --
${text}
--"
exit 1
fi
}
相关问题
How to change out-of-focus text selection color in Xcode?
Okay, I ll bite.
I ve got really pleasant code/window colors set up in Xcode. Ordinarily, my selection color is very visible.
When I am doing a project search and iterating through the results, ...
How use Instruments and display the console in Command Lines applications [duplicate]
I m using Xcode on OSX to develop command line C applications. I would also like to use Instruments to profile and find memory leaks.
However, I couldn t find a way to display the console when ...
Iphone NSTimer Issue
Hi I am new to objective c. I am trying to make an app for iphone. I have a button on my view, and the click on which the function playSound is called. This is working properly. It does plays the ...
Include a .txt file in a .h in C++?
I have a number of places where I need to re-use some template code. Many classes need these items
In a .h could I do something like:
#include <xxx.txt>
and place all of this code in the ....
Iterating over string/strlen with umlauted characters
This is a follow-up to my previous question . I succeeded in implementing the algorithm for checking umlauted characters. The next problem comes from iterating over all characters in a string. I do ...
XCode未能在装置上运行,说正在破碎的方案没有运行。
我跑了X条码,试图把我的手套放在我的电话上。 I m 获取错误信息:“正在设计的方案没有运行”。
Xcode open two editor windows with same file
Is it possible to open the same file in two separate windows in Xcode. I can open a file in one window and the same file in the main Xcode editor window, but I wanted two separate fulltime editor ...
Forcing code signing refresh in Xcode
In our environment, we share resources across multiple projects and platforms. When building for iPhone, only a subset of those resources are needed. Since that subset is still considerable, we have ...