I have a three Objective-C libraries and an Objective-C application.
The application uses library A, library B and library C.
Library A uses library B.
I need to link library C to the project with the -ObjC flag.
(All libraries are static cocoa touch libraries)
But then i get the problem that I get a compiler warning for dubplicate symbols in library B.
When I leave out the -ObjC flag the -ObjC flag, library C is not used properly.
How can i solve this?
Thanks
You can add
force_load
with path to library needed to be loaded with -ObjC
from linker man:
-force_load path_to_archive
Loads all members of the specified static archive library.
Note: -all_load forces all members of all archives to be
loaded. This option allows you to target a specific archive.
Related
I need to link two libraries in a project, Cordova and a library from a hardware manufacturer. The hardware manufacturer's library gives an error if you compile with -ObjC but Cordova requires -ObjC flag.
Is there a way to force the -ObjC flag for a library and not for the other (or vice-versa)?
Thanks!
Specific error: Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_MPMusicPlayerController", referenced from:
objc-class-ref in libdtdev.a(AudioStream.o)
It looks like a posted the question just before I figured it out (like always). Instead of deleting the post, someone might want to know what the solution was...
If I keep the -ObjC flag in place and add the frameworks it's complaining about to the "Link Binary With Libraries" section (in my case "MediaPlayer.framework").
My Xcode project has a two frameworks: one of them requires other linker flags -ObjC in order to compile, but when the -ObjC flag is used, the second can't compile and shows many errors.
Is there a way to compile a project without the -ObjC flag when a specific framework requires it?
I haven't tried this but it might very well work:
what -objc does is basically loading symbols (of categories) that are the linker doesn't find because they don't seem used. See this answer for more details:
Why is the -ObjC linker flag needed to link categories in static libraries? (LLVM)
so you should very well be able to emulate this with the -all_load linker flag
BUT that doesn't help you because that would still affect all your linked libraries
BUT you can tell load_all to only affect certain libs.. you'd use -force_load %NAMEOFLIB%
That way, you might get around -ObjC
I have define some default values in My static library's Prefix header and using in a category. When I compile the library stand alone it compiles fine. but when I attached the library to a projects it compliance variable not defined. I am pretty sure I have missed something when I attaching library.
This is how I attached the Library - I dragged and dropped static library project on to the new project and added dependency. I am wondering what was my mistake.
Go to Build setting of the main Project(not the static Library).
Search for "other Linker Flags" add -ObjC
You have to add this flag in the targets as well.
some other useful flags description for static library
-all_load Loads all members of static archive libraries.
-ObjC Loads all members of static archive libraries that implement an Objective-C class or category.
-force_load (path_to_archive) Loads all members of the specified static archive library. Note: -all_load forces all members of all archives to be loaded. This option allows you to target a specific archive.
Some libraries require the -all_load linker flag when linking to an Xcode project. However, this leads to a linker error if there are symbol conflicts among libraries. The solution is to use -force_load, which effectively lets you use -all_load on some libraries, but not on others.
However, this in turn leads to a new problem, at least for me. Whenever I use -force_load with a relative path to a library, the linker always finds symbol conflicts between the library and itself. It appears that the linker thinks that the library with its absolute path and the library with its relative path are different libraries, and therefore finds conflicts between the library and itself.
I can avoid this by using an absolute path with the flag. But this is not a wonderful solution, as it is convenient to keep source code for libraries within my documents directory. But the path to the documents directory will be different on other machines.
Question: Can anyone get force_load to work with a relative path to the library?
EDIT: for background information, see this question
With Xcode 4, if you include the library project into your app project, then you can add this to the Other Linker Flags:
-force_load $(BUILT_PRODUCTS_DIR)/<library_name.a>
You still need the dependency, and you need to add the library in the Link Phase list of frameworks and libraries too.
EDIT: Apple now says as of some Xcode 4 release that you can simply use this linker flag: "-ObjC" to get libraries with categories to properly load. That flag is working just fine for me in Xcode 5. People are still up voting this answer, but I suspect that the -ObjC flag is the best solution now.
This worked for me. Like the above answers you still need to include the library in the project.
-force_load $(SRCROOT)/pathToLibraryFromProject/libname.a
For the path it's just the folders in your project that lead to where you put your library, for example BaseFoler/Subfolder/libName.a.
My C++ compiler creates "dylib" files which contain dynamic libraries. Whats the difference between .dylib and .so files?
And what is the difference between files in Mach-O format and files in an ELF format? I have to build files for later use under iOS (static libraries only/Mach-O) and Android (ELF).
Thanx!
I found that:
One Mach-O feature that hits many people by surprise is the strict
distinction between shared libraries and dynamically loadable modules.
On ELF systems both are the same; any piece of shared code can be used
as a library and for dynamic loading. Use otool -hv some_file to see
the filetype of some_file.
Mach-O shared libraries have the file type MH_DYLIB and carry the
extension .dylib. They can be linked against with the usual static
linker flags, e.g. -lfoo for libfoo.dylib. However, they can not be
loaded as a module. (Side note: Shared libraries can be loaded
dynamically through an API. However, that API is different from the
API for bundles and the semantics make it useless for an dlopen()
emulation. Most notably, shared libraries can not be unloaded.) [This
is no longer true—you can use dlopen() with both dylibs and bundles.
However, dylibs still can't be unloaded.]
Loadable modules are called "bundles" in Mach-O speak. They have the
file type MH_BUNDLE. Since no component involved cares about it, they
can carry any extension. The extension .bundle is recommended by
Apple, but most ported software uses .so for the sake of
compatibility. Bundles can be dynamically loaded and unloaded via dyld
APIs, and there is a wrapper that emulates dlopen() on top of that
API. [dlopen is now the preferred API.] It is not possible to link
against bundles as if they were shared libraries. However, it is
possible that a bundle is linked against real shared libraries; those
will be loaded automatically when the bundle is loaded.
To compile a normal shared library on OS X, you should use -dynamiclib
and the extension .dylib. -fPIC is the default.