Xcode: build all the dependent targets when building a framework target - ios

I have an Xcode project with a Framework A target.
That target depends on a few other modules, e.g. SubFramework A and SubFramework B.
When running the Xcodebuild command:
xcodebuild archive \
-scheme SchemeName \
-configuration Release \
-destination 'generic/platform=iOS Simulator' \
-archivePath './build/SchemeName.framework-iphonesimulator.xcarchive' \
SKIP_INSTALL=NO \
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
I'm getting only the resulting library out, i.e. SchemeName.framework. When I then try to bundle it into the application, of course, I cannot compile it as SubFramework A and SubFramework B are not included.
Q:
Is it possible to modify the scheme's build settings, xcodebuild command or target settings in order to get the SubFramework A and SubFramework B as the build output results too?

Related

xcodebuild -create-xcframework - BCSymbolMaps missing - on M1 Xcode 14.0

I use the same bash script for building the XCFramework for at least 2 years and everything worked successfully until the moment I switched my Mac to M1 and my Xcode is 14.0.
The script is pretty standard (see below).
On MacPro M1, Xcode 14.0 I get the following error (the same script works just fine on Xcode 13.1).
error: the path does not point to a valid debug symbols file: /Users/*******/build/Release-iphoneos.xcarchive/BCSymbolMaps/*
Indeed when I look at build/Release-iphoneos.xcarchive folder - the BCSymbolMaps is not there. I verified that the Xcode setting "debug information format" is dwarf with dsym file.
Can someone please help me understand what is this error? and why it started happening on M1, Xcode 14.0 ?
Thank you
See my bash build script below.
# Build the framework for device and for simulator (using
# all needed architectures).
xcodebuild archive -scheme "${TARGET_NAME}" -destination="iOS" -sdk iphonesimulator SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -archivePath "${SRCROOT}/build/Release-iphonesimulator"
xcodebuild archive -scheme "${TARGET_NAME}" -destination="iOS" -sdk iphoneos SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -archivePath "${SRCROOT}/build/Release-iphoneos"
ls -l "${SRCROOT}/build/"
# https://developer.apple.com/forums/thread/655768
# First, get all the UUID filepaths for BCSymbolMaps, because these are randomly generated and need to be individually added as the `-debug-symbols` parameter. The dSYM path is always the same so that one is manually added
echo "XCFramework: Generating IPHONE BCSymbolMap paths..."
IPHONE_BCSYMBOLMAP_PATHS=(${SRCROOT}/build/Release-iphoneos.xcarchive/BCSymbolMaps/*)
IPHONE_BCSYMBOLMAP_COMMANDS=""
for path in "${IPHONE_BCSYMBOLMAP_PATHS[#]}"; do
IPHONE_BCSYMBOLMAP_COMMANDS="$IPHONE_BCSYMBOLMAP_COMMANDS -debug-symbols $path "
echo $IPHONE_BCSYMBOLMAP_COMMANDS
done
echo "XCFramework: Generating IPHONE BCSymbolMap paths... --> Done"
# XCFramework with debug symbols - see https://pspdfkit.com/blog/2021/advances-in-xcframeworks/#built-in-support-for-bcsymbolmaps-and-dsyms
xcodebuild -create-xcframework -allow-internal-distribution \
-framework "${SRCROOT}/build/Release-iphoneos.xcarchive/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework" \
-debug-symbols "${SRCROOT}/build/Release-iphoneos.xcarchive/dSYMs/${FRAMEWORK_NAME}.framework.dSYM" \
$IPHONE_BCSYMBOLMAP_COMMANDS \
-framework "${SRCROOT}/build/Release-iphonesimulator.xcarchive/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework" \
-debug-symbols "${SRCROOT}/build/Release-iphonesimulator.xcarchive/dSYMs/${FRAMEWORK_NAME}.framework.dSYM" \
-output "${SF_RELEASE_DIR}/${FRAMEWORK_NAME}.xcframework"
bit code is not supported by xcode14 so bcsymbolmaps are no more relevant for xcode14

How to load framework at runtime in Xcode?

I have a third party framework customx.framework (iOS) customx.framework (Simulator).
To run project on simulator customx.framework (Simulator) to be imported & for device
customx.framework (iOS) to be imported
simultaneously importing is not supported by xcode
At present i am manually importing framework, so i am looking for runtime scrip changes or combined (iOS+Simulator) framework to import in xcode project.
For that
I have tried lipo & libtool but seems didn't worked.
I used validate workspace but it fails when importing modules.
tried links -
iOS merge several framework into one
Building for iOS Simulator, but the linked framework '****.framework' was built for iOS
simultaneously importing is not supported by Xcode
Supported. It is named XCFramework.
So assuming each variant of frameworks have been built correctly (pay attention that BUILD_LIBRARY_FOR_DISTRIBUTION=YES, just in case - Xcode set it to YES automatically), join them in terminal or Xcode script phase with next command:
$ xcodebuild -create-xcframework
-framework "/full_path_to_iOS_variant/customx.framework"
-framework "/full_path_to_Simulator_variant/customx.framework"
-output "/full_path_to_result/customx.xcframework"
and then add it once in target dependency
and that's it.
You can archive for iOS device and iOS simulator and merge them to one xcframework. This is my current project xcodebuild command for it.
- Archive for iOS devices
xcodebuild archive \
-scheme Framework-scheme \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath './build/native/Framework-Name.framework-iphoneos.xcarchive' \
SKIP_INSTALL=NO \
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
- Archive for iOS simulator
xcodebuild archive \
-scheme Framework-scheme \
-configuration Release \
-destination 'generic/platform=iOS Simulator' \
-archivePath './build/native/Framework-Name.framework-iphonesimulator.xcarchive' \
SKIP_INSTALL=NO \
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
- build framework from archives
xcodebuild -create-xcframework \
-framework './build/native/AdTrue-Native.framework-iphoneos.xcarchive/Products/Library/Frameworks/Framework-Name.framework' \
-framework './build/native/AdTrue-Native.framework-iphonesimulator.xcarchive/Products/Library/Frameworks/Framework-Name.framework' \
-output './build/native/Framework-Name.xcframework'

How to specify output dir name for ios simulator when using xcodebuild cli in combination with a xcworkspace?

I build a xcode (6.3.1) project that uses workspace because I'm using Pods.
When I do:
xcodebuild \
build \
-workspace MyProject.xcworkspace \
-scheme MyProject \
-configuration Debug \
-sdk iphonesimulator \
-ARCHS=i386 \
VALID_ARCHS=i386 \
SYMROOT="/tmp/build/emulator" \
SHARED_PRECOMPS_DIR="/tmp/build/sharedpch"
It outputs the app to:
/tmp/build/emulator/Debug-iphonesimulator/MyProject.app
Is there a way with the xcodebuild command to get it build to
/tmp/build/emulator/MyProject.app
I have tried to replace SYMROOT with
CONFIGURATION_BUILD_DIR="/tmp/build/emulator"
Now it builds to
/tmp/build/emulator/Monsenso.app
but that do not work smoothly with CocoaPods frameworks (e.g. Typhoon for DI) ~ build fails with:
The following build commands failed:
GenerateDSYMFile /tmp/build/emulator/Typhoon.framework.dSYM /run/emulator/Typhoon.framework/Typhoon

XCodeBuild is not picking a configuration from my workspace

This is my build command
xcodebuild -workspace MyApp.xcworkspace \
-scheme MySchemeName \
-configuration AdHoc \
clean archive
It works but its uses the default configuration for the archive scheme (which is release) instead of AdHoc which I specified. In fact if you specify -scheme ASchemeNameThatDosnNotExist it still works and silently ignores the configuration name.
The project is setup like this:
xcodebuild -list
Targets:
MyApp
MyAppTests
Build Configurations:
Debug
AdHoc
Release
If no build configuration is specified and -scheme is not passed then "Release" is used.
This project contains no schemes.
And the workspace like this:
xcodebuild -workspace MyApp.xcworkspace -list
Schemes:
MyApp
Pods
Pods-AFNetworking
.. More pods
I.e. There are no targets and no configurations in the workspace.
How do I make a target visible to the workspace? Or is there another way?
It's impossible to configure target for workspace. You can create a scheme based on a particular target and then build a project passing scheme name. Setting configuration via '-configuration' switch works fine for me. I use xcode v. 5.0.2.
In general a configuration is set via action. You can create multiple schemes for archiving (with different configurations) and there's no need to pass configuration at all. Default configuration will be taken.
Thank you #Opal for your answer. I was initially mislead by your statement that '-configuration' was working. In fact, this does not work, and the specified configuration is silently ignored when performing an xcodebuild via the workspace:
xcodebuild -workspace $WORKSPACE.xcworkspace \
-scheme $SCHEME \
-configuration QA \
clean archive -archivePath archives/$APP_NAME
xcodebuild -exportArchive \
-archivePath archives/$APP_NAME.xcarchive \
-exportPath . \
-exportOptionsPlist $WORKSPACE/ExportOptions.plist
mv $APP_NAME.ipa $APP_NAME.$VERSION.$BUILD_NUMBER.ipa
However, after creating a custom shared scheme for that configuration, "myapp-QA", the build completes correctly:
xcodebuild -workspace $WORKSPACE.xcworkspace \
-scheme $SCHEME-QA \
clean archive -archivePath archives/$APP_NAME-QA
xcodebuild -exportArchive \
-archivePath archives/$APP_NAME-QA.xcarchive \
-exportPath . \
-exportOptionsPlist $WORKSPACE/ExportOptions.plist
mv $APP_NAME-QA.ipa $APP_NAME.$VERSION.$BUILD_NUMBER.qa.ipa
There is an issue with using configuration & scheme arguments. A scheme has its own configuration and most probably it overrides configuration specified via xcodebuild -configuration.
You can solve it by using configuration & target:
xcodebuild -project <project>.xcodeproj \
-configuration <configuration> \
-target <target> \
-sdk iphonesimulator \
clean build

Creating Static Library from a workspace

I managed to get static libraries working and its all fine. Now that I have moved onto the proper library I want to create Im having issues. Im using cocoapods to import other files and it creates a workspace. Now the script I have for compiling no longer works and my assumption is because I am working in a framework now. I have been googling for hours trying to get an answer but all the things I have found only relate to turning a single project into a library
My questions are:
1) Is it possible to combine a workspace into one single library?
2) should I be trying to create a framework instead?
3) Is it just my script that isnt right?
XCODEBUILD_PATH=/Applications/Xcode.app/Contents/Developer/usr/bin
XCODEBUILD=$XCODEBUILD_PATH/xcodebuild
$XCODEBUILD -project T5Pusher.xcodeproj -target "T5Pusher" -sdk "iphoneos" - configuration "Release" clean build
$XCODEBUILD -project T5Pusher.xcodeproj -target "T5Pusher" -sdk "iphonesimulator" - configuration "Release" clean build
lipo -create -output "build/libT5Pusher.a" "build/Release-iphoneos/libT5Pusher.a" "build/Release-iphonesimulator/libT5Pusher.a"
also tried this
XCODEBUILD_PATH=/Applications/Xcode.app/Contents/Developer/usr/bin
XCODEBUILD=$XCODEBUILD_PATH/xcodebuild
$XCODEBUILD -workspace T5Pusher.xcworkspace -scheme "T5Pusher" -sdk "iphoneos" - configuration "Release" clean build
$XCODEBUILD -workspace T5Pusher.xcworkspace -scheme "T5Pusher" -sdk "iphonesimulator" - configuration "Release" clean build
lipo -create -output "build/libT5Pusher.a" "build/Release-iphoneos/libT5Pusher.a" "build/Release-iphonesimulator/libT5Pusher.a"
The errors I get are
** BUILD FAILED **
The following build commands failed:
Libtool build/PusherTest.build/Release-iphoneos/PusherTest.build/Objects- normal/armv7/libPusherTest.a normal armv7
Libtool build/PusherTest.build/Release-iphoneos/PusherTest.build/Objects-normal/armv7s/libPusherTest.a normal armv7s
(2 failures)
lipo: can't open input file: build/Release-iphoneos/libPusherTest.a (No such file or directory)
Showing first 200 notices only
and for the second, the build succeeds but the library (.a) files are never created so it cannot combine them
I have found the solution. You have to use the command:
pod install --no-integrate
when installing the pod. This will not create a workspace and allow the use of the script
XCODEBUILD_PATH=/Applications/Xcode.app/Contents/Developer/usr/bin
XCODEBUILD=$XCODEBUILD_PATH/xcodebuild
$XCODEBUILD -project T5Pusher.xcodeproj -target "T5Pusher" -sdk "iphoneos" - configuration "Release" clean build
$XCODEBUILD -project T5Pusher.xcodeproj -target "T5Pusher" -sdk "iphonesimulator" - configuration "Release" clean build
lipo -create -output "build/libT5Pusher.a" "build/Release-iphoneos/libT5Pusher.a" "build/Release-iphonesimulator/libT5Pusher.a"
Then to set the config file for pods:
-Go to project editor -> info -> configuration
-Set the target to use pods.xconfig file for debug and release
I was having the same issue myself and found that if I specified the output directories and then told lipo to look there then it worked while still letting me use the workspace. The may be different in Xcode 5 but when I use it as a custom build phase then it works without specifying the output directories and I only have to direct lipo to ${BUILD_DIR} to find the generated files.
$XCODEBUILD -project T5Pusher.xcodeproj \
-target "T5Pusher" \
-sdk "iphoneos" \
-configuration "Release"
OBJROOT=${env_variable_to_some_directory}/Obj.root \
SYMROOT=${env_variable_to_some_directory}/Sym.root \
DSTROOT=${env_variable_to_some_directory}/Dst.root \
clean build

Resources