I have a strange issue when trying to compile a static library using xcodebuild.
Project's configuration is:
ARCHS = $(ARCHS_STANDARD)
VALID_ARCHS = $ARCHS
It's executed using Xcode 5.1.1.
Now comes the weird part - the project built on machines connected to Jenkins produces fat libary with all 5 architectures (armv7 armv7s arm64, i386, x86_64), but when a build is launched on my (64bit) Mac I'm getting only four - x86_64 is missing. No code change, clean repo, exactly the same build routine.
I wonder what may be causing that difference. I guess it might be some kind of an environment setup on my side, but have no idea what it might be. Project configuration is not under suspicion - it creates proper fat library on a different machine.
I'd be thankful for your advices.
EDIT: No error is thrown either. xcodebuild behaves just like that architecture is not specified - compiles iphonesimulator build just for i386.
Also worth noticing - Xcode creates all architectures, only xcodebuild executed from command line has issues.
Try adding the -destination flag to your xcodebuild command.
xcodebuild -workspace MyWorkspace.xcworkspace -scheme MyScheme -destination 'platform=OS X,arch=x86_64' test
The above is an example from the xcodebuild manual page.
I had a similar issue where I wanted xcodebuild to make an i386 build for simulator and continued to create Armv7 until I added that flag to my command.
Related
I am working on an XCFramework that relies on a Rust library I compile and expose to Swift. However, when using that XCFramework inside a CocoaPod which is used as a dependency by another project, I get the following error:
Unable to install vendored xcframework FooFramework for Pod BarProject, because it contains both static and dynamic frameworks.
To clarify a bit what's going on, here's the compilation path beginning with Rust:
Rust Project
In the Rust project, I compile two shared libraries. One for iOS, and one for Mac Catalyst. The iOS library I compile using cargo lipo, with the following command:
cargo clean
cargo lipo --release
Then I just grab the shared library from ./target/universal/release/libfoo.a.
For Catalyst, I have a slightly more involved compilation process, which relies on Rust nightly.
cargo clean
rustup override set nightly
cargo build -Z build-std=panic_abort,std --target x86_64-apple-ios-macabi --release
I then grab the Catalyst library from ./target/x86_64-apple-ios-macabi/release/libfoo.a.
Swift Xcode Projects
Now that I have these two libraries, I actually have two Xcode projects that are fully identical, with the sole exception that they use different library search paths. One project is for iOS and simulator, whereas the other one is just for Mac Catalyst.
The only reason that I have two separate Xcode projects is that I haven't fully figured out how to make the modulemap organization work properly with one project and multiple targets yet, but that, I believe, is beyond the scope of this question.
I generate the iOS and Simulator XCArchives from the iOS project as follows:
xcodebuild archive -scheme FooFramework_iOS -destination "generic/platform=iOS" -archivePath ./FooFramework-iOS SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild archive -scheme FooFramework_iOS -destination "generic/platform=iOS Simulator" -archivePath ./FooFramework-Sim SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
Next, I generate the Catalyst XCArchive:
xcodebuild archive -scheme FooFramework_Mac -destination "platform=macOS,arch=x86_64,variant=Mac Catalyst" -archivePath ./FooFramework-macOS ONLY_ACTIVE_ARCH=YES SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
Finally, I merge them all into an XCFramework:
xcodebuild -create-xcframework \
-framework ./FooFramework-iOS.xcarchive/Products/Library/Frameworks/FooFramework_iOS.framework \
-framework ./FooFramework-Sim.xcarchive/Products/Library/Frameworks/FooFramework_iOS.framework \
-framework ./FooFramework-macOS.xcarchive/Products/Library/Frameworks/FooFramework_Mac.framework \
-output ./FooFramework.xcframework
For what it's worth, this XCFramework actually works perfectly within regular Xcode projects. However, as soon as it's a dependent Pod's dependency, when compiling that .xcworkspace project, the error I first described appears:
Unable to install vendored xcframework FooFramework for Pod BarProject, because it contains both static and dynamic frameworks.
When I modify the xcodebuild command to create separate *.xcframework files, one for iOS/Sim and the other for Mac, the Pod project compilation immediately starts working.
My question is, how can I generate an XCFramework for iOS/Simulator/Catalyst that will not result in the static/dynamic library error?
Xcode 12.3
Cocoapods 1.10.1
React Native CLI 4.13.1
I am having a recurring failure building a React Native app at the linking stage (library not found for -lRCTTypeSafety) in the Xcode "Archive" Build task. ("Product" > "Archive") It fails with the same error when I run the first "Build" after a "Clean Build Folder".
It does not occur when I run the "Build" task, which usually succeeds, but the "first build after a clean" behavior lines up with how the "Archive" task behaves, which appears to run an implicit "clean" first, so they appear to be a similar failure case.
None of the suggested remediations I've found on-line have worked. I am using the workspace, not the project file. FWIW, I have confirmed the same occurs using xcodebuild. (As opposed to the Xcode gui.) xcodebuild clean build fails reliably, as well as xcodebuild archive, but xcodebuild build succeeds if it isn't the first build after a clean.
Several Pod libraries are missing from the linker command when it fails. On a successful run, the xcodebuild build action has the following additional -L flags in the clang linking command that are missing on the failed attempts:
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/DoubleConversion
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/FBReactNativeSpec
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/Folly
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/RCTTypeSafety
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/RNCPicker
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-Core
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-CoreModules
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTAnimation
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTBlob
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTImage
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTLinking
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTNetwork
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTSettings
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTText
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-RCTVibration
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-cxxreact
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-jsi
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-jsiexecutor
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-jsinspector
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/ReactCommon
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/<project>.app
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/Yoga
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/glog
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/react-native-geolocation
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/react-native-maps
-L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/React-Core/AccessibilityResources.bundle
A successful build action has no WriteAuxiliaryFile, CompileC, or Libtool log lines, so it appears that the failed first attempt after a clean is actually building the Pod files correctly, just not providing the necessary paths to the linker command.
The Libtool lines for the missing library from a failed build look like:
Libtool /Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/RCTTypeSafety/libRCTTypeSafety.a normal (in target 'RCTTypeSafety' from project 'Pods')
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only arm64 -D -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.3.sdk -L/Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/RCTTypeSafety -filelist /Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Intermediates.noindex/Pods.build/Release-iphoneos/RCTTypeSafety.build/Objects-normal/arm64/RCTTypeSafety.LinkFileList -dependency_info /Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Intermediates.noindex/Pods.build/Release-iphoneos/RCTTypeSafety.build/Objects-normal/arm64/RCTTypeSafety_libtool_dependency_info.dat -o /Users/<user>/Library/Developer/Xcode/DerivedData/<project>-bcgmbzkfkmobskcxnhtpmhoehiux/Build/Products/Release-iphoneos/RCTTypeSafety/libRCTTypeSafety.a
and I've checked that the output file libRCTTypeSafety.a is present in the path specified for the -o flag above. The directory that contains the file is included in the missing -L flags provided, so it really looks like there's just some step between compilation and linking that is getting missed.
Any help would be greatly appreciated!
I am building a static library to be used with another project I'm working on, and eventually it will be included in a framework I'm developing. When I bring the library into my project, the arm builds work fine, but the simulator builds fail with missing symbols for the x86_64 build. I have set the build architectures in the library to
arm64 arm64e armv7 armv7s x86_64
I have tried various settings, like $(ARCHS_STANDARD) to no avail. I have also tried all of the potential solutions I could find on SO, most of which are pretty old.
Any and all suggestions would be greatly appreciated.
As mentioned in the comments and the edit, you have to build a fat library, but there are steps missing in all of the answers and many of them are badly out of date. Hopefully this will help.
Build a version of the static library for iPhoneOS and iPhoneSimulator.
On the command line, cd to the derived data directory for your project.
You will see directories for the OS and simulator libraries.
Execute the lipo command as below
lipo -create -output [desired fat library name] [path to iPhoneOS library] [path to iPhoneSimulator library]
Drag the fat library from finder to your target project.
You can probably automate this with a build script, but I was under a deadline so it was faster to just build and drag. If you come up with a good script, feel free to post it here.
P.S. The script presented in the Agile Warrior post did not work.
I am trying to solve a cryptic puzzle that I really appreciate the explanation for as this will help me understand the tools and be confident about what i do.
I came across the puzzle when cranking up xcodebuild commandline to build my iPhone app. I found it to reject '-sdk iphonesimulator6.0" with this message:
"No architectures to compile for (ARCHS=i386, VALID_ARCHS=armv7)."
I then saw my VALID_ARCHS were set to armv7 and that appeared to explain why xcodebuild refused to build for simulator (which i led myself to believe was intel).
But how on earth does my XCode IDE go around it and manages to build for simulator (which it does)?
Changing VALID_ARCHS to:
VALID_ARCHS = "$(ARCHS_STANDARD_32_BIT)";(which expands to armv7 and armv7a)
or
VALID_ARCHS = armv7 i386
Seemed to have satisfied xcodebuild enough to agree to build for simulator. Mind you, the first case still doesn't list i386! And I must conclude i386 becomes, in certain conditions, implicit. Can anyone confirm and/or expand on any of this?
When xcode build on i386 it changes these variables, you can witness this in xcode Log navigator...
These are the Variables xcode manipulate in order to allow running on i386
VALID_ARCHS=i386
ARCHS=i386
You can do the same by invoking xcodebuild command in the following manner:
xcrun xcodebuild VALID_ARCHS=i386 ARCHS=i386 ONLY_ACTIVE_ARCH=NO -arch i386 -sdk iphonesimulator7.1 -configuration Debug
I have legacy code that relies on pointers being 32-bit and want to use xCodeBuild to build that code from command line. This doesn't work for some reason. Here's the command I use:
xcodebuild -configuration Debug -arch i386
-workspace MyProject.xcworkspace -scheme MyLib
here's the output I get
[BEROR]No architectures to compile for
(ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).
Clearly it's trying to build x86_64 code and failing miserably since I only enabled i386 from VALID_ARCHS in xCode project settings.
Is there a way to make it understand I don't want a 64-bit library?
You have to set the ONLY_ACTIVE_ARCH to NO if you want xcodebuild to use the ARCHS parameters. By passing these parameters, you can force the proper architecture.
xcodebuild ARCHS=i386 ONLY_ACTIVE_ARCH=NO -configuration Debug -workspace MyProject.xcworkspace -scheme MyLib
See this reference for details.
Build Active Architecture Only(ONLY_ACTIVE_ARCH)
xcodebuild ONLY_ACTIVE_ARCH...
//or
Build Settings -> Build Active Architecture Only -> ONLY_ACTIVE_ARCH
YES - build binary with a single architecture for a connected device
NO - build binary for a specific -arch(valid architectures aka VALID_ARCHS) if it was specified or for all the architectures in other cases
The recommendation is to use Yes for Debug (to save on build time) and No for Release build.
Note: it is safe to run on simulator
To check the version use lipo -info[About]