xcodebuild -create-framework error: unable to read the file - swift

I have watched "binary framework in swift" and tried to build xcframework using xcodebuild -create-framework but it is not working properly.
I enabled "Build libraries for Distribution", then I archived and then used the command
xcodebuild -create-framework -framework /path/sample.xarchive -output sample.xcframework
But it is showing an error "unable to read the file at /path/sample/sample".
I am not sure what I am missing.
Sysytem Info:
MacOS: Catalina beta 1
Xcode 11

Here are step by step instructions, I think you might be missing step 2:
1) Set Build Library for Distribution in the build settings for the target framework to YES
2) Again in the build settings, set Skip Install to NO otherwise the framework won't show up in the Archive output folder.
3) Archive from the Xcode Product menu after selecting your Generic iOS Device the output will appear in the Organizer. Control-Click on the Archive. Select Show in Finder Drag that to the terminal to get the path to the archive and append the path (yellow part is the dragged path, gray is navigated in subfolders). In this case it looks like this, I used the ~ to avoid showing entire path.
~/Library/Developer/Xcode/Archives/2019-06-22/Output\ 6-22-19,\ 11.50\ AM.xcarchive/Products/Library/Frameworks/MyFramework.framework
4) Then create the XCFramework by inserting the command in front of the above path:
xcodebuild -create-xcframework -output Output.xcframework -framework ~/Library/Developer/Xcode/Archives/2019-06-22/Output\ 6-22-19,\ 11.50\ AM.xcarchive/Products/Library/Frameworks/MyFramework.framework
5) You then should see the output:
xcframework successfully written out to: ~/Project/Output.xcframework
I expect that someday soon Xcode will add a the ability to directly create the XCFramework without the command line.

You have to do a two step process via the command line.
xcodebuild archive
This will archive the framework and stick it likely in the build directory of your project.
xcodebuild -create-xcframework -output FrameworkName.xcframework -framework build/Release-iphoneos/ArchivedFramework.framework
This should successfully generate the XCFramework.

You typed the command wrong:
xcodebuild -create-xcframework -framework /path/sample.xarchive -output sample.xcframework

In my case it was failing for iPhone as arm64 architecture was added in the Excluded Architecture in Build Settings

Related

Error While creating Custom Framework and xcframework

I am creating a Framework where i am adding multiple Third Party Libraries manually. and creating a Fat framework SomeFrameworkName.framework using the script below
#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
After Archiving i am able to get the framework file but when i try to add that framework into the demo project it gives me multiple errors as follows:
dyld: Library not loaded: #rpath/TestIOS.framework/TestIOS
Referenced from: /private/var/containers/Bundle/Application/E76B5EA8-2E7C-44A4-BDCC-A8AB0B37E500/TestAshishDemo.app/TestDemo
Reason: image not found
dyld: launch, loading dependent libraries
DYLD_LIBRARY_PATH=/usr/lib/system/introspection
DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
or else any library names comes in the picture.
and whenever i try to create the xcframework file i get the following error
Failed to build module from its module interface; it may have been damaged or it may have triggered a bug in the Swift compiler when it was produced
i am on a crucial stage to solve this error. Anyone if facing the same issue or faced the same along the way they created framework Please Help me out
XCode Version - 12.5.1
In your target project, did you try to embed the Framework ?
(Old XCode screenshot of mine here)

How to generate Xcode project using SPM with extra build flags?

I am creating a package that depends on OpenSSL on macOS. To use SPM to build the package, I need to pass it some build/linker flags:
swift build -Xlinker -L/usr/local/opt/openssl/lib -Xcc -I/usr/local/opt/openssl/include
The problem is that when I build my xcode project using SPM, I cannot pass the flags. In theory I would think the following would work,
swift package generate-xcodeproj -Xlinker -L/usr/local/opt/openssl/lib -Xcc -I/usr/local/opt/openssl/include
but it doesn't and once Xcode project is generated, to build in it, I need to go into the Settings and update the appropriate paths.
This is obviously ugly and also it wouldn't work for proper CI workflow, which depend on features that are currently only supported by xcode project and not SPM.
I have already tried passing these values when doing a command line xcodebuild like the following, but that also didn't work.
xcodebuild -project MyProj.xcodeproj -scheme MyProjScheme HEADER_SEARCH_PATHS=/usr/local/opt/openssl/include LIBRARY_SEARCH_PATHS=/usr/local/opt/openssl/lib build
Any suggestions?
To create an Xcode project with additional flags, we need to do the following 3 steps:
Step 1 - Obtain the proper mapping between compiler/linker flags and the equivalent xcode settings. In this case,
-Xlinker -L/usr/local/opt/openssl/lib -Xcc -I/usr/local/opt/openssl/include
is equivalent to
HEADER_SEARCH_PATHS=/usr/local/opt/openssl/include
LIBRARY_SEARCH_PATHS=/usr/local/opt/openssl/lib
Step 2 - Create an .xcconfig file. For example,
$ less openssl.xcconfig
HEADER_SEARCH_PATHS = /usr/local/opt/openssl/include
LIBRARY_SEARCH_PATHS = /usr/local/opt/openssl/lib
Step 3 - Use the --xcconfig-overrides flag with generate-xcodeproj to make the project use the config file.
swift package generate-xcodeproj --xcconfig-overrides openssl.xcconfig
Now the Xcode project builds out of the box and xcodebuild can be used without any extra flags.

Can't use FBSDKShareVideo without ENABLE_BITCODE Linker command error

I have the latest Bolts, FBSDKCoreKit, FBSDKLoginKit and FBSDKShareKit as part of the Facebook SDK frameworks which I am using in Swift. In a Swift file, I imported FBSDKCoreKit and FBSDKShareKit. If I use FBSDKShareVideo in any way, I get a Linker command error that reads
".../Frameworks/FBSDKShareKit.framework/FBSDKShareKit(FBSDKShareVideo.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)"
-I've looked up solutions to this online, mostly which were to set Enable Bitcode in the project's settings, which was already set to YES. I also tried setting it to NO. I've tried various combinations of YES and NO with the project and target's settings.
-I then added the frameworks to the Copy Bundle Resources and rebuilt. I still get the error.
-I've cleaned, rebuilt
-I quit out of Xcode and reopened the project and rebuilt.
The line in which I try to use FBSDKShareVideo reads:
let video : FBSDKShareVideo = FBSDKShareVideo()
Without using that line and having the FBSDKCoreKit and FBSDKShareKit imported, I get no errors. So how can I possibly resolve this so I can use FBSDKShareVideo?

Swift fat framework w/Objective-C Cocoapod

I've built a framework in Swift. The framework uses Cocoapods, one of the pods is written in Objective C.
I also use a custom script to make the framework a fat framework so it supports 32/64 bit systems. (This runs in a separate target on the project and I'm wondering if that has something to do with it?)
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"
// Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
//Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
// Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
// Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
// Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
// Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
fi
When I create this fat framework and put it into a project I'd like to use it on the compiler always fails b/c the project can't see the objective C cocoa pod module.
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ld: framework not found Pusher for architecture x86_64
It is not found for any architecture when I change the build platform.
Any solution where I can produce a framework that I can use in a separate Xcode project (for all iOS or OS X) would be awesome.
You can't run xcodebuild with -target when using CocoaPods. When you use -target, Xcode will only consider the active project and fail to pull in the Pod dependencies, similar to if you just opened the project file in Xcode and tried building.
You should be running xcodebuild -workspace "${PROJECT_NAME}.xcworkspace" -scheme "${PROJECT_NAME}" ..., assuming that CocoaPods generated the workspace and Xcode generated a scheme using the target name. You will also need to make sure your scheme is marked as shared if running this on another device.
Once your framework is built you will need to include it and the frameworks it depends on in apps that will be using it. For your framework, that means including it in General > Embedded Binaries and General > Linked Frameworks and Libraries. For frameworks you depend on, (e.g. AlamoFire), you could instruct users to include it in their Podfile, you could package it and ship it along with your framework, or you could do both and let the user do what works for them.
Apparently you are missing the 64bit architecture for Simulator.
When you build a target from Xcode, depending on what kind of simulator you have selected - the produced library will contains i386 or x86_64 respectively for selected 32bit or 64bit version of the simulator.
I guess that the cli build is producing only i386 version.
You can try to set the architectures in the script:
xcodebuild -target "${PROJECT_NAME}" ARCHS="i386 x86_64" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
As an alternative You can try to build by hand using 64bit simulator (iPhone 5S +), then extract the missing architecture and then put it into the final library using lipo command.

iPhone static library distribution and release build errors (but not for debug)

Update
Daniel was close, it just wasn't the search path. The Prefix Header under GCC 4.2 was set to:
$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h
I missed that when I was combing through the first 2 times.
I removed it and now all is well.
Original Question
I have been using/building products with a static libraries for about a week now with no issues.
For the first time, I tried to make a distribution build (for ad hoc testing) and I am getting errors all over the place.
The errors, strangely say that it can't find Appkit headers. Which is odd because it is an iPhone app and shouldn't be linking to Appkit headers
Additionally, the library name, "libFJSCodeDebug.a" turns red while when I switch from debug to distribution/release. I figure this must be a big clue.
To test, I duplicated the debug configuration and renamed it release. This built fine. So it seems the problem is somewhere in the configuration. Below is a snippet of what I get in Xcode when I build. (Note: I named my target FJSCodeDebug even though it will be used for both debug and release builds)
Building target “FJSCodeDebug” of project “FJSCode” with configuration “Release” — (169 errors)
Checking Dependencies
cd /[redacted]/FJSCode
setenv PATH "/DeveloperBeta/Platforms/iPhoneOS.platform/Developer/usr/bin:/DeveloperBeta/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/DeveloperBeta/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -x objective-c-header -arch armv6 -fmessage-length=0 -pipe -std=c99 -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -Wreturn-type -Wunused-variable -isysroot /DeveloperBeta/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk -gdwarf-2 -mthumb -miphoneos-version-min=3.0 -iquote /[redacted]/build/FJSCode.build/Release-iphoneos/FJSCodeDebug.build/FJSCodeDebug-generated-files.hmap -I/[redacted]/build/FJSCode.build/Release-iphoneos/FJSCodeDebug.build/FJSCodeDebug-own-target-headers.hmap -I/[redacted]/build/FJSCode.build/Release-iphoneos/FJSCodeDebug.build/FJSCodeDebug-all-target-headers.hmap -iquote /U[redacted]/build/FJSCode.build/Release-iphoneos/FJSCodeDebug.build/FJSCodeDebug-project-headers.hmap -F/[redacted]/build/Release-iphoneos -I/[redacted]/build/Release-iphoneos/include -I/Users/coreyfloyd/Xcode/ProductionProjects/build/FJSCode.build/Release-iphoneos/FJSCodeDebug.build/DerivedSources/armv6 -I/[redacted]/build/FJSCode.build/Release-iphoneos/FJSCodeDebug.build/DerivedSources -c /System/Library/Frameworks/AppKit.framework/Headers/AppKit.h -o /var/folders/R+/R+ofDLtuH1GOYQ1ZQ2C5mk+++TI/-Caches-/com.apple.Xcode.501/SharedPrecompiledHeaders/AppKit-gihvhjsfuggoevbehiszhgrzcska/AppKit.h.gch
/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:11:33: error: AppKit/AppKitDefines.h: No such file or directory
/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:12:32: error: AppKit/AppKitErrors.h: No such file or directory
/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:13:37: error: AppKit/NSGraphicsContext.h: No such file or directory
/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:14:35: error: AppKit/NSAccessibility.h: No such file or directory
/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:15:32: error: AppKit/NSActionCell.h: No such file or directory
...... (continues for everything in AppKit)......
Build failed (169 errors)
I'm looking for 1 of 2 solutions:
Obviously, fix the release build to not get these errors
OR
Tweak the debug configuration to have all the important settings that a release configuration requires.
Any ideas??
This
-c /System/Library/Frameworks/AppKit.framework/Headers/AppKit.h
leads me to believe your build target is trying to compile AppKit.h for some reason (while I don't think it should be doing that at all), and/or it's looking for it in the wrong place (i.e. in the root /System instead of in the SDK /Developer/Platforms/...).
You should double check your build settings library/frameworks search paths, and that AppKit.h isn't in the compile phase.
Does your project include Mac OS products? Are you sure you haven't accidently included a Mac library/framework in your frameworks group?
In SDK2.2.1, I don't know why, but the thing that always gets me is when "Active SDK" and "Active Executable" become out of sync (in the build configuration dropdown). This leads to weird linker errors where the iPhone tries to dynamically link against its libraries. This setting seems to occasionally go out of sync whenever I switch from debug/release or device/simulator.
Perhaps its a similar case, its hard to tell without seeing the actual project settings.