iOS 14, lipo error while creating library for both device and simulator - xcodebuild

We have been using lipo command to create a framework which works on both device and simulator when integrated in other project.
following are the build commands used to generate device and simulator builds
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds"
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds"
after this we are copying swift modules from iphonesimulator(if it exists) to the copied framework dir
cp -R "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/Modules/SampleSDK.swiftmodule/" "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}/Modules/${PROJECT_NAME}.swiftmodule/"
and then lipo command
lipo -create "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}/${PROJECT_NAME}" -output "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}/${PROJECT_NAME}"
the above command is failing with following error
fatal error: lipo: /path/to/Library/Developer/Xcode/DerivedData/Sample-bhfmlauxsdympmdjkjyvujaljevg/Build/Products/Debug-iphonesimulator/SampleSDK.framework/SampleSDK and /Users/rramshettysiddaraju/Library/Developer/Xcode/DerivedData/Sample-bhfmlauxsdympmdjkjyvujaljevg/Build/Products/Debug-iphoneos/SampleSDK.framework/SampleSDK have the same architectures (arm64) and can't be in the same fat output file
I tried one of the answers in stackoverflow, about adding user-defined setting VALID_ARCHS and then removing it. but that didnt work

The reason for the error is that Xcode 12 includes a slice for the "arm64" architecture when building for the simulator (in addition to the usual "i386" and "x86_64" architectures for Xcode <12). This is probably for supporting the simulator on (future) Macs using Apple Silicon processors. As your device build also includes the "arm64" architecture, lipo does not know which of the two "arm64" slices you want and refuses to create a combined fat binary framework.
As a workaround, you can either exclude the "arm64" architecture from the simulator build by appending the EXCLUDED_ARCHS build variable:
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds" EXCLUDED_ARCHS="arm64"
Alternatively, use lipo -remove to remove the "arm64" architecture from the simulator build before combining the simulator and device frameworks into one:
lipo -remove arm64 "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}" -output "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}"
In the long run, you might be better off building an XCFramework, which should support devices and simulators without the need for using lipo. But I haven’t tested this yet.

styv is right.
You can also set Excluded Architectures in the Xcode Build Settings

#xtyv's suggestion is spot on: using an XCFramework is the way to go.
Here is a Makefile to generate an XCFramework (apply substitutions and add other architectures accordingly to your scenario):
ARCHS = aarch64-apple-ios aarch64-apple-ios-sim
LIB = lib<library_name>.a
XCFRAMEWORK = <framework_name>-iOS.xcframework
all: $(XCFRAMEWORK)
.PHONY: $(ARCHS)
$(ARCHS): %:
cargo build --target $#
$(XCFRAMEWORK): $(ARCHS)
xcodebuild -create-xcframework $(addprefix -library , $(foreach arch, $(ARCHS),$(wildcard target/$(arch)/debug/$(LIB)))) -headers <header_file> -output $#

Related

Using an objective c library (pop) with the swift package manager

I'm trying to migrate a project from Cocoapods to SPM and there is one dependency – pop framework – that I can't make work with SPM.
I've tried to compile it into xcframework and use it as a binaryTarget in SPM but it didn't work. This framework seems to be only visible from objective c projects.
These are the commands I used to make xcframework:
xcodebuild archive -scheme pop-ios-framework -archivePath pop-iphoneos.xcarchive -sdk iphoneos SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild archive -scheme pop-ios-framework -archivePath pop-iphonesimulator.xcarchive -sdk iphonesimulator SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild -create-xcframework -framework pop-iphoneos.xcarchive/Products/Library/Frameworks/pop.framework -framework pop-iphonesimulator.xcarchive/Products/Library/Frameworks/pop.framework -output pop.xcframework
and this is how I imported this project to my package:
targets: [
.binaryTarget(name: "pop", path: "pop.xcframework"),
.target(
name: "...",
dependencies: [... "SnapKit", "pop"],
path: "Sources",
resources: [
...
]
),
]
The package compiles and even allows writing import pop. However, it doesn't see any of the classes defined inside the framework.
So, the problem was that I forgot to set Skip Install to No and Build Libraries for Distribution to YES. I thought that the eponymous params at the end of the commands will override these options.

Xamarin iOS Objective-C library binding - Build errors when creating a fat binary using "make" command

I'm trying to create a Xamarin iOS binding for this Objective C library SPSlideTabController.
I have created a static library and am now in the process of creating a fat binary. I have the Makefile set up correctly and saved in the same folder as my static library. Not inside the static library folder though. Then I run the make command in the terminal.
Each time I have tried, only one file is generated libSPSlideTabController-i386.a then I get 4 build errors:
** BUILD FAILED **
The following build commands failed:
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPAppearance.o SPSlideTabBarController/Appearance/SPAppearance.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPSlideTabBarItem.o SPSlideTabBarController/SPSlideTabBar/SPSlideTabBarItem.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPSlideTabBar.o SPSlideTabBarController/SPSlideTabBar/SPSlideTabBar.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC build/SPSlideTabBarController.build/Release-iphoneos/SPSlideTabBarController.build/Objects-normal/armv7/SPSlideTabBarController.o SPSlideTabBarController/SPSlideTabBarController.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(4 failures)
make: *** [libSPSlideTabBarController-armv7.a] Error 65
The ---armv7.a and the ---SDK.a files are not generated.
What am I doing wrong?
Here's my Makefile
XBUILD=/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
PROJECT_ROOT=./SPSlideTabBarController
PROJECT=$(PROJECT_ROOT)/SPSlideTabBarController.xcodeproj
TARGET=SPSlideTabBarController
all: lib$(TARGET).a
lib$(TARGET)-i386.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator
-configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphonesimulator/lib$(TARGET).a $#
lib$(TARGET)-armv7.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch
armv7 -configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $#
lib$(TARGET)-arm64.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch
arm64 -configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $#
lib$(TARGET).a: lib$(TARGET)-i386.a lib$(TARGET)-armv7.a
lib$(TARGET)-
arm64.a
xcrun -sdk iphoneos lipo -create -output $# $^
clean:
-rm -f *.a *.dll
It's better that you share your MAKE file.
I normally open the code in XCode then add a runscript using my GIST here
You could follow this guide for more details.

How do I extract object files from an iOS library (on a Mac)?

I have a third party iOS library that links and runs fine in my app and in the simulator. I am trying to extract the object files from it in order to integrate it with another piece of third party software that repackages the object files with their own code. However, I am unable to extract the object files via ar; I consistently get the error, "Inappropriate file type or format".
The library in question is a fat library with armv7, armv7s, and i386 included. Stock lipo doesn't know about armv7s on my machine, but Xcode's does:
$ lipo -info library.a
Architectures in the fat file: library.a are: armv7 (cputype (12) cpusubtype (11)) i386
$ xcrun -sdk iphoneos lipo -info library.a
Architectures in the fat file: library.a are: armv7 armv7s i386
I can successfully thin it out with lipo:
$ xcrun -sdk iphoneos lipo library.a -thin armv7 -output library-armv7.a
$ xcrun -sdk iphoneos lipo -info library-armv7.a
Non-fat file: library-armv7.a is architecture: armv7
However, even after thinning it out, I can't manipulate it with ar:
$ xcrun -sdk iphoneos ar -tv library-armv7.a
ar: library-armv7.a: Inappropriate file type or format
$ xcrun -sdk iphoneos ar -xv library-armv7.a
ar: library-armv7.a: Inappropriate file type or format
I'm on OS X 10.8.2, Xcode 4.6 with development tools installed.
Is there any additional step I can take for this troublesome library?
Update in response to Martin's comment
file shows the following:
$ file library.a
library.a: Mach-O universal binary with 3 architectures
library.a (for architecture armv7): Mach-O object arm
library.a (for architecture cputype (12) cpusubtype (11)): Mach-O object arm
library.a (for architecture i386): Mach-O object i386
$ file library-armv7.a
library-armv7.a: Mach-O object arm
Looks like it's not a library at all!
The "library" is not actually a library, but is an object file itself. There is nothing further to extract.
This script works well. Try it.
https://code.google.com/p/ompt-intel-openmp/source/browse/itt/libomp_oss/tools/extract-objects.pl

Discrepancy with issues found in scan-build vs. xcode

I am using scan-build (checker-258) from the command line to do static analysis on my iOS project and find that uncovers far fewer issues than xcode (about 60% less). If I set xcode 4.2 to use scan-build from checker-258 it finds all the issues (and more). This may be because the command line version us using the old (not modern) run time as it is finding issues like:
error: synthesized property 'foo' must either be named the same as a compatible ivar or must explicitly name an ivar
#synthesize foo;
^
Here is the command I'm using to run the analysis:
scan-build --use-cc=`which clang` -k -o scan-reports xcodebuild -target MyTarget -project myproject.xcodeproj -sdk iphonesimulator5.0 -configuration Debug clean build
Thanks in advance.
Yes, the version of the static analyzer that ships with Xcode 4.2 is older than the version on the clang website. There are instructions here on how to use the newer version within Xcode: http://clang-analyzer.llvm.org/xcode.html
Try to use this command: scan-build -k -V -o scan-reports xcodebuild clean build -configuration Debug -sdk iphoneos5.0 -xcconfig="myConfig.xcconfig"
Where myconfig contains the CODE_SIGNING_IDENTITY="", PROVISIONING_PROFILE=""

GHUnit CLI Build: Availability.h errors

I am trying to do a command line build of a GHUnit target which builds fine inside Xcode. I am running the following command to build:
GHUNIT_CLI=1 xcodebuild -target
BasicBrowserUnitTest -configuration
Debug -sdk iphonesimulator4.0 build
It gets along pretty nice, until it finds an error in Availability.h, an SDK header:
/Xcode4
GM/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.0.sdk/usr/include/AvailabilityInternal.h:56:42:
error: operator '<' has no left
operand
Obviously, I haven't made any changes to Apple's stuff, why am I getting this error and how do I fix it?
The problem is that I wasn't specifying the correct SDK version:
GHUNIT_CLI=1 xcodebuild -target
BasicBrowserUnitTest -configuration
Debug -sdk iphonesimulator4.0 build
Needed to be:
GHUNIT_CLI=1 xcodebuild -target
BasicBrowserUnitTest -configuration
Debug -sdk iphonesimulator4.3
build
Or in this case, the latest SDK version.