Can't wrap static library in Cocoa Touch Framework - ios

I tried the steps in this link. I added all linked libraries which should also include a library called myLib.a, but I got an undefined symbols for architecture arm64 error.
Furthermore, when I used the command nm -arch arm64 -g myLibraryName, I found out that the symbols in myLib.a were missing.

Related

Weakly link static library via -weak_library

Question:
Is it possible to weakly link a static library (Obj-C)?
Short Details
I do want my custom static framework (MyFramework.framework) to weakly link my other custom static library (libMyLibrary.a).
The functionality behind libMyLibrary.a is optional and can be omitted if there is NO libMyLibrary.a being linked by any 3rd party application that uses MyFramework.framework.
I am using -weak_library. My test application complains that static linker is unable to find MyLibrary's symbol MyClass within MyFramework's ABCTracker.o symbol:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_MyClass", referenced from:
objc-class-ref in MyFramework(ABCTracker.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How to correctly setup weak linking?
Full Details
Setup
The Xcode project builds a static Mach-O binary and bundles it into a static framework. The result is MyFramework.framework bundle.
Other project builds a static Mach-O binary and the result is a static lib file libMyLibrary.a with a header MyLib.h
libMyLibrary.a is removed from MyFramework.framework target's Build Phases > Link Binary With Libraries (as suggested here). Only MyLib.h is available to use library's API from the framework's classes
NO Bitcode is used neither in the framework, nor in the library
MyFramework.framework, libMyLibrary.a and custom application are all written in Objective-C
The MyLib.h defines just one Objective-C class MyClass
MyFramework.framework uses MyClass from its own class ABCTracker conditionally checking for symbol availability during runtime, e.g. NSClassFromString(#"MyClass") == NULL
From MyFramework target's Build Settings I have set Other Librarian Flags and Other Linker Flags to same value -weak_library MyLibrary:
OTHER_LDFLAGS = (
"-weak_library",
MyLibrary,
);
OTHER_LIBTOOLFLAGS = "-weak_library MyLibrary";
Result
MyFramework.framework builds OK
After the build I have checked the symbols in the resulting binary and the output was emty (no symbols from the static library were built into static framework binary):
$ otool -L MyFramework.framework/MyFramework | grep MyClass
Despite that, my test application which is not linked with MyLibrary whatsoever, builds with ld error:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_MyClass", referenced from:
objc-class-ref in MyFramework(ABCTracker.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What am I doing wrong here?
Other Observations
In MyFramework target I set Other Librarian Flags and Other Linker Flags of to same value:
-lMyLibrary. Result: otool shows the library's symbols are built into the framework (expected).
-weak-lMyLibrary. Result is the same as for lMyLibrary (is it expected?)
In my application target I set Other Linker Flags to -force_load MyLibrary. Result: the linker error slightly changes:
ld: file not found: MyClass
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have also not been successful at getting XCode to properly weak link a static library, although I have the opposite problem from yours - for me nm showed all the symbols from the static library, and not with "U" (undefined) symbol type as you see when you weak link a framework.
But a workaround you can use is the following:
Create a new Cocoa Touch Framework project called MyWrapper.framework and add libMyLibrary.a to it
Add -ObjC to the linker flags to make sure all the symbols get
loaded (and -all_load if you need non Obj-C symbols)
Add your library's headers to the framework's Public Headers section in Build Phases
Build this framework (you'll want to set up an aggregate target to build for all architectures but that is a whole separate topic)
Open your MyFramework.framework project and add MyWrapper.framework to it, weakly linked (i.e. use the toggle to set it to Optional or if you prefer remove it from the Link Binary with Libraries phase and add it via -weak_framework to Other Linker Flags)
Now build MyFramework.framework
In your testing app, remove any reference to libMyLibrary.a
You should be able to run your testing app with no crash and your code should not detect the presence of symbols from libMyLibrary.a
Add MyWrapper.framework to your testing app and then you should see the opposite result - symbols from libMyLibrary.a will be found and usable.

missing required architecture x86_64

I have an old project, that I recompiled for an uodate, and it is now showing this error message:
…. missing required architecture x86_64 in file myLibrary.a ….
I have tried various tricks that I could find on the net after searching on missing required architecture x86_64 in file, but with no success. Anyone knows how to properly handle the issue?
I am using Xcode Version 7.0.1.
Running:
lipo -info myLibrary.a
shows:
Architectures in the fat file: myLibrary.a are: armv7 arm64
I have been able to add armv7s but not x86_64.
You are trying to build a universal library and it does not have all the architectures in it armv7 armv7s i386 x86_64 arm64. Compiler is complaining when you build with 64 bit architecture.
To fix this - Add the following to your architecture settings of static library project:
This needs manual addition of architectures something like this:
Build the library with these architecture both on device & simulator, create fat library using lipo -create -output "myLibrary.a" ./Simulator/myLibrary.a ./Device/myLibrary.a and use it.

Library not found for -lpj-arm-apple-darwin9 [duplicate]

This question already has answers here:
How can I "add existing frameworks" in Xcode 4?
(10 answers)
Closed 8 years ago.
I downloaded pjsip source code from online.It is running without any error.But, I integrated openssl lib and include file into that pjsip > ipjsua xcode project.After compiled xcode project, am getting library not found error and warning like below,
ld: warning: directory not found for option '-L"/Users/aahlaad/Desktop/swyxpjsip/iospj2/pjproject-2.2.1/pjsip-apps/src/pjsua/ios/../../../../pjlib/lib"'
ld: warning: directory not found for option '-L"/Users/aahlaad/Desktop/swyxpjsip/iospj2/pjproject-2.2.1/pjsip-apps/src/pjsua/ios/../../../../pjlib-util/lib"'
ld: warning: directory not found for option '-L"/Users/aahlaad/Desktop/swyxpjsip/iospj2/pjproject-2.2.1/pjsip-apps/src/pjsua/ios/../../../../pjmedia/lib"'
ld: warning: directory not found for option '-L"/Users/aahlaad/Desktop/swyxpjsip/iospj2/pjproject-2.2.1/pjsip-apps/src/pjsua/ios/../../../../pjnath/lib"'
ld: warning: directory not found for option '-L"/Users/aahlaad/Desktop/swyxpjsip/iospj2/pjproject-2.2.1/pjsip-apps/src/pjsua/ios/../../../../pjsip/lib"'
ld: warning: directory not found for option '-L"/Users/aahlaad/Desktop/swyxpjsip/iospj2/pjproject-2.2.1/pjsip-apps/src/pjsua/ios/../../../../third_party/lib"'
ld: library not found for -lpj-arm-apple-darwin9
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Delete your derived Data and
Go to Project->Build Settings->Search Paths
and remove everything from Framework/Header/Library Search Path respectively and add your frameworks again in Project -> General ->Linked Frameworks and Libraries
ld: library not found for -lpj-arm-apple-darwin9
Here's how to add headers and libraries under Xcode. Its shows how to add OpenSSL, but in your case, do the same for PJSIP.
Headers:
Libraries:
If your PJSIP library has both static archives and shared objects, then delete the shared objects. Even though iOS only allows static linking, Xcode will still link against a shared object if available. Apparently, the Xcode developers did not get the memo.
If you need help adding the PJSIP library to Xcode so it shows up under Frameworks and Libraries, then see How to “add existing frameworks” in Xcode 4?.
If you get the PJSIP library added but are missing architectures, you can use the following to see what's in the fat library:
$ xcrun -sdk iphoneos lipo -info /usr/local/ssl/ios/lib/libcrypto.a
Architectures in the fat file: libcrypto.a are: armv7 armv7s arm64 i386
Ideally, you will have the four architectures: ARMv7, ARMv7s, ARM64 and i386. i386 is for debug builds under the simulator.
If you are missing an architecture, then you should re-build the library with the missing architecture, and then use lipo to combine the different architectures into a single fat library.

iOS Static library compilation error - table of contents is empty

I am trying to create a Objective C static library for iOS. When I try to compile it gives following warnings.
Libtool /Users/******/Library/Developer/Xcode/DerivedData/MyLib-eyucoczochpovhcqduwoieknpyer/Build/Intermediates/MyLib.build/Debug-iphoneos/MyLib.build/Objects-normal/armv7/libMyLib.a normal armv7
cd /Users/******/Desktop/MyLib
export IPHONEOS_DEPLOYMENT_TARGET=7.1
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only armv7 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk -L/Users/******/Library/Developer/Xcode/DerivedData/MyLib-eyucoczochpovhcqduwoieknpyer/Build/Products/Debug-iphoneos -filelist /Users/******/Library/Developer/Xcode/DerivedData/MyLib-eyucoczochpovhcqduwoieknpyer/Build/Intermediates/MyLib.build/Debug-iphoneos/MyLib.build/Objects-normal/armv7/MyLib.LinkFileList -ObjC -framework Foundation -o /Users/shafraz/Library/Developer/Xcode/DerivedData/MyLib-eyucoczochpovhcqduwoieknpyer/Build/Intermediates/MyLib.build/Debug-iphoneos/MyLib.build/Objects-normal/armv7/libMyLib.a
I am getting similar errors for armv7s, arm64 also
(null): /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning for library: /Users/******/Library/Developer/Xcode/DerivedData/MyLib-eyucoczochpovhcqduwoieknpyer/Build/Products/Debug-iphoneos/libMyLib.a for architecture: armv7 the table of contents is empty (no object file members in the library define global symbols)
I am getting similar errors for armv7s, arm64 also
This worming shown only after removing MyLib.m and class declaration in MyLib.h file.
How can I fix this?
This generally happens if your static library contains nothing but categories or informal protocols. The linker is warning you that you don't seem to have any classes to link.
In my case, I realized that the library I wrote ended up being a header only library. That implies I don't even need to compile a library, just include the headers in "Header Search Paths" in "Build settings".

Undefined symbols when referencing PLCrashReporter 1.2 beta 2 in static library and build in client

I have created a static library and added an aggregated target to build a .framework static framework so I can release to the users.
I have to use PLCrashReporter to this static library so I downloaded the latest version 1.2 beta 2 since ARM64 support is added and added the .xcodeproj file in a group inside my static library. Added the User Header Search Paths in the build settings of the static library target, in build phases added in Target Dependencies the CrashReporter-iOS-Device (CrashReporter) static library and Link Binary With Libraries added the libCrashReporter-iphoneos.a static library.
My static library builds successfully all the targets with no problem, but when it comes to adding my .xcodeproj project as a dependency in a UI client test project or even adding directly the .framework that I generate, the build for the simulator breaks.
I can run it on a device and work properly but it is major to use it in a simulator too.
If I hit build I get the following errors.
Undefined symbols for architecture i386:
"std::terminate()", referenced from:
___clang_call_terminate in libReporter-iOS.a(PLCrashSignalHandler.o)
___clang_call_terminate in libReporter-iOS.a(PLCrashAsyncImageList.o)
"___cxa_begin_catch", referenced from:
___clang_call_terminate in libReporter-iOS.a(PLCrashSignalHandler.o)
___clang_call_terminate in libReporter-iOS.a(PLCrashAsyncImageList.o)
"___gxx_personality_v0", referenced from:
Dwarf Exception Unwind Info (__eh_frame) in libReporter-iOS.a(PLCrashSignalHandler.o)
Dwarf Exception Unwind Info (__eh_frame) in libReporter-iOS.a(PLCrashAsyncImageList.o)
Dwarf Exception Unwind Info (__eh_frame) in libReporter-iOS.a(PLCrashSignalHandler.o)
Dwarf Exception Unwind Info (__eh_frame) in libReporter-iOS.a(PLCrashAsyncImageList.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I miss something for sure here!
Thank you in advance.
It looks like the i386 architecture is missing from libCrashReporter-iphoneos.a (The name of that file also suggests that it's for device only). Try to run lipo -info libCrashReporter-iphoneos.a to see if all the required architectures are there, if the i386 (required for simulator) is not there, you have to find the lib for i386 (or build it if you are building it yourself) and use lipo -create lib-iphoneos.a lib-iphonesimulator.a -output lib-all.a to create a library with all required architectures.
P.S. I have just downloaded the latest build from https://www.plcrashreporter.org and it seems like the CrashReporter.framework in iOS Framework contains armv7, armv7s and i386, so you might try that if you don't require arm64 and x86_64.
EDIT: see this for arm64 support (it's a beta from September).
EDIT2: I didn't pay attention to the std::terminate() at first, so if all the required architectures are there you might have to add libstdc++ to the Linked Frameworks and Libraries.
By the way.. can be useful to others..
the same settings:
-lstdc++ in linker flags
may solve similar headache for using MySQL in C/C++ in Xcode in OSX.
in fact when you link against libmysqlclient.a or libmysqlclient.dylib, you get the same error.
It has been broken in respect to previous installation of mysql.
verify to have:
//:configuration = Debug
OTHER_LDFLAGS = -lstdc++
//:configuration = Distribution
OTHER_LDFLAGS = -lstdc++
//:completeSettings = some
OTHER_LDFLAGS
Hope this can help.

Resources