Reputation: 380
I've created a framework in which is inserted the second framework, the so-called "umbrella framework". When I insert the framework in the test application(embedded binaries and linked frameworks and libraries, both) can not build app, I get the following error:
ld: framework not found 'embeddedInMyFramework' for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Than add that framework(embeddedInMyFramework) also in embedded binaries and linked frameworks and libraries and try to build than works ok. Later remove that framework from both, embedded binaries and linked frameworks and libraries and still works fine. Can someone help me with this, not sure what happens when I add framework to embedded binaries for the first time, and how to fix that (could it work somehow without adding to embedded binaries at all)
Upvotes: 14
Views: 13895
Reputation: 1656
I was able to set up a working Umbrella Framework and wrote down my approach.
Step 5 should remove your linker error ld: framework not found ..
A Swift based "client" project that has the Umbrella Framework as dependency
A dynamic Framework (mainly C++ and ObjC) that is a dependency of the Umbrella Framework
2. Add the location of the dependent (sub-)framework to the Framework Search Paths
of the Umbrella Framework project.
3. In the "client" project make sure to link and embed the Umbrella Framework
4. Make sure the Umbrella Framework is copied into the (client-) app bundle to avoid dyld: Library not loaded: @rpath/...
errors.
The (client-) app, usually under ...Build/Products/Debug-iphoneos/YOUR_CLIENT_APP.app
should now contain your Umbrella Framework in a folder called Frameworks
.
5. In the "client" project Make sure to add the path to the Umbrella Framework to Framework Search Paths
.
If the ld: framework not found '[Framework_Name]' for
architecture ...
error persists you can also add the path to the (sub-) Framework here.
Upvotes: 23
Reputation: 429
HERE IS AN DEMO PROJECT:
All answers under this line are wrong, cause they just do the thing that manually copy sub frameworks into "umbrella framework"
Embedding a framework within a framework (iOS 8+)
How to create an umbrella framework in iOS SDK?
How to add a framework inside another framework (Umbrella Framework)
First thing we should know that "umbrella framework" is a conception in Mac OS not in iOS, the official document is here
if you want to create an un-recommend "UmbrellaFramework", you must do these process step by step, and know details during the compile and link periods
!!Here is an example of "FakeBundleShellScript" you can refer
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
BUNDLE_IN_ROOT="$APP_PATH/${FRAMEWORK_EXECUTABLE_NAME}.bundle"
if [[ -e "$FRAMEWORK_EXECUTABLE_PATH" ]]; then
FRAMEWORK_MACH_O="$(otool -a "$FRAMEWORK_EXECUTABLE_PATH" | head -n 1)"
FRAMEWORK_FAT_ARCH="$(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")"
else
FRAMEWORK_MACH_O="NO EXIST"
FRAMEWORK_FAT_ARCH="NO EXIST"
fi
echo "FRAMEWORK_EXECUTABLE_NAME is $FRAMEWORK_EXECUTABLE_NAME"
echo "FRAMEWORK_EXECUTABLE_PATH is $FRAMEWORK_EXECUTABLE_PATH"
echo "FRAMEWORK_MACH_O is $FRAMEWORK_MACH_O"
echo "FRAMEWORK_FAT_ARCH is $FRAMEWORK_FAT_ARCH"
echo "BUNDLE_IN_ROOT is $BUNDLE_IN_ROOT"
if [[ "$FRAMEWORK_MACH_O" =~ "Archive :" ]]; then
echo "Rmove Static-Mach-O is $FRAMEWORK_EXECUTABLE_PATH"
rm "$FRAMEWORK_EXECUTABLE_PATH"
defaults write "$FRAMEWORK/Info.plist" CFBundlePackageType "BNDL"
defaults delete "$FRAMEWORK/Info.plist" CFBundleExecutable
if [[ -d "$BUNDLE_IN_ROOT" ]]; then
rm -rf "$BUNDLE_IN_ROOT"
fi
mv -f "$FRAMEWORK" "$BUNDLE_IN_ROOT"
elif [[ "$FRAMEWORK_FAT_ARCH" =~ "Architectures in the fat file" ]]; then
#statements
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
fi
done
As all I said, the key point of to make an un-recommend "UmbrellaFramework" is !!!! [Compile the sub-frameworks as Static, process the resources via fake a bundle], REMEMBER!! Apple always said DONT'T CREATE AN UmbrellaFramework
if you can understand Chinese, more details to make an "UmbrellaFramework" can be obtained from my blog
Upvotes: 4
Reputation: 19602
Adding to embedded libraries also sets certain Build Settings, which are not removed when removing the library from embedded libraries.
Most probably the Framework Search Paths
contain the path to the previously missing library.
It will not work without somehow adding the embedded library. You might want to use some dependency management tool (like CocoaPods or Carthage) to do the more or less of the work for you.
Upvotes: 2