I'm working on an iPhone app with Monotouch. In my app, I have to use a static library provided by 3rd party. This library is for Xcode and written in Objective-C. I bound it with Monotouch using Binding Project Template. When I add the resulting dll to my project it compiles fine, but when I use a class from the library it fails to compile with the following error:
Duplicate symbol _DeleteCriticalSection
So what can I do? Is there any way to remove the conflict?
Thank you in advance.
I've seen similar things inside FAT libraries where some files were duplicated, leading to duplicate objects. You can try to see if this is the same issue, e.g. if your library is named mystaticlibrary.a
$ nm mystaticlibrary.a | grep DeleteCriticalSection
Now it can be normal to have the symbol multiple times if you have a FAT library (more than one architecture). To see if that's the case do:
$ file mystaticlibrary.a
You should have the symbol for each architecture. If you see more symbols (e.g. 3x DeleteCriticalSection but only 2 arch) then you have a similar issue.
The fix (if it's the same issue) was to split the FAT library (lipo tool), then each architecture specific library, then re-merge everything (arch then FAT).
Your best bet might be to contact your library vendor and ask him for a fixed library (something was likely wrong in the build process). Give them the above command output and they'll likely find out what went wrong.
Related
I am developing a library .a file in Which i am using AFNetworking classes ... This library does also include one .framework which also using the AFNetworking classes (Adding this framework is optional)
Due to this I am getting following errors
duplicate symbol _OBJC_IVAR_$_AFHTTPRequestOperation._responseSerializer in:
.../KonySDK.framework/KonySDK(AFHTTPRequestOperation.o)
.../Core.a(AFHTTPRequestOperation.o)
Options i have already considered is removing AF***.o from one of the file lipo -thin and ar -d -sv commands
Using this Link
But this library is configurable from server and adding that particular .framework is optional.
My question is ... Is there any otherway by which i can resolve this issue ? ALso i can would rather not prefer to remove .m files of AFNetworking from my library source as the entire process of generating library is fully automatic and configurable in many ways
I have also tried to resolve this by removing -all_load from other linker flags but this resulted in crash as categories of some classes are not loaded due to this.
You will get the duplicate symbol linker error whenever you have included a binary version of a class. The way to get rid of it is to remove the superfluous object.
For building your library you only need the .h files of AFNetworking because those tell the compiler which classes and methods are available. You do not need to compile the AFNetworking source code because a .a file is essentially a collection of .o files which each contain the compiled versions of .m files.
Libraries are not linked
Only apps get linked and therefore need to have the symbols/objects present. i.e. if you provide your library without AFNetworking compiled in, then the developer using it needs to add AFNetworking via library, framework or cocoapod.
TL;DR
How do I build a static library without including a third party library that I'm referencing?
Hi,
Before I begin, I know how to compile a static library in Xcode targeted for iOS devices and simulators. However, this time around I have a dependency on a third party library that I do not want to include in the static library. I simply want to reference it. However, whenever I am building my static library I get a lexical or preprocessor error, which I know is common when the library is missing from the project. The error occurs because I removed the library from the project, because I didn't want to have it built into the static library.
The library in question is AFNetworking. I will be using CocoaPods to explicitly have the dependency installed when installing my static library.
Thank you.
When you reference external code, you will always need to have the headers accessible by your project, otherwise the compiler wouldn’t be able to tell you if you are referencing the external code in a proper manner. E.g. does the method exist, are you providing the right types, etc.
The duplicate symbol problem only exists when you actually define a symbol multiple times. For instance, defining class related Objective-C symbols only happens in a #implementation...#end block, not in a #interface...#end block. The latter is only for the compiler to make sense of things.
(This is also why you can define a #interface for e.g. a private class and use it as normal and not cause duplicate symbols.)
Therefore, you can include such ‘clean’ headers multiple times without having to worry about it. Note that I said ‘clean’, because you can actually define symbols in headers by, for instance, defining C functions in headers or even a Objective-C #implementation, if you feel especially wicked. But you will simply have to test this.
The linker will complain when you finally link the 3rd-party dependency and yours and there were duplicate symbols after all. In that case, be sure to look into tools such as nm which list the symbols in an archive.
you can add the lib.a and lib.h into your project.
My SDK uses a libssl.a library, but when I give it to a customer to use my SDK, they also uses a version of libssl.a and is causing duplicate symbol. Is there anyway to allow both to coexist?
Thanks
One option would be to rebuild libssl with a custom prefix on each symbol. I wrote a script for this purpose, which you can find here.
A simpler option might be to not link to libssl.a and require the customer to link to it instead. To do this, simply #import libssl's headers as usual, but leave libssl.a out from the link binary with libraries phase. The linker does not attempt to resolve symbols unless the target is an executable, so you will be able to compile a static library on this way without issues.
I am currently building a library which should be used internally in a few iOS projects but should also be distributed to customers accessing our services with the library. The Library itself consists purely of C++ code and I am basically able to create Apps with it on iOS which work fine. My problem is creating a single, easily distributable file that can be given out to customers which can easily install them, use the provided headers and don't need to have the headaches that I am currently facing when it comes to linking.
Our code depends on two other projects, namely boost and websocketpp. For boost there is the script on github which I took to generate a framework. For websocketpp, I imported it into XCode and used the scripts from this github project to build a framework. I added both frameworks to my (potential) framework as dependencies and used the same script to build one.
I have an app using my library as a sub-project working fine. Even including the framework into the project and running it on a device works fine. So far so good.
However, trying to create an archive of the App project lead to several questions and headaches.
My library did not seem to contain the code for all architectures. So I tried to archive the Framework projects, which after small modifications in the build scripts to use different locations to search for headers worked fine.
It does not seem to contain all binary code or references to local files (i.e. my specific location of boost). I gathered that from Linker errors that I still get that tell me that some boost calls could not be satisfied.
The second issue made me think that I am must be doing something fundamentally wrong and my intuition tells me that it can't be that difficult and "hackish" to create frameworks or libraries for others for iOS development.
As you probably have found out by now, I am not very experienced when it comes to iOS and I am wondering if I am missing something fundamentally. So, I am sure that this question is rather broad, so some more concrete questsions:
Is there a(nother) way to generate some kind of distributable (preferably a framework) which contains: my public headers, my binary code compiled for all platforms supported for iOS development, the binary code of dependencies?
Is the only way to do that by adding some handwritten scripts to the build process?
I have the feeling that the information I found is quite outdated since it's older than a year and mostly refers to Xcode 4.2 or 4.3 -- so has there anything changed in this regard recently?
For example one error I get is:
File is universal (2 slices) but does not contain a(n) armv7s slice: <file>
The <file> slice is the path to the file in the framework in the Products folder of a different XCode workspace (the library was build in a different workspace then the app). I dropped the framework folder into the project for this test from a completely different location.
What is going on here?
Why does it keep referencing to some internal XCode directory?
How do I properly export it?
Since I guess my setup is probably skrewed up and weird from all the different things I tried up to now: How does this setup look like in a ideal situation?
Yes, there are some questions regarding this on SO already, however, either I don't see or don't understand in those replies:
...how to handle depencies of my code to other third-party code properly.
...how to generate a distributable file.
Have you checked your project build phase under Compile Sources and Copy Files to see if you are including your framework source files in your build?
You may also try the C/C++ Library template under OSX -> Framework & Library.
Finally, there's also kstenerud’s iOS Universal Framework, which I found very useful. I wrote a few articles in my blog on using it.
I am linking a static framework for iOS, against an armv7 ios 6 application, I suspect that the original binaries are from XCode 3.x and were compiled with GCC, and that I'm now linking it using CLang compiler. I do not have the source code for the framework, only the binaries:
(null): warning: (armv7) /.../DerivedData/.../armv7/HardwareObjectFile.o unable to open object file
I get 69 warnings like the above, one for every .o file linked into the static framework.
Is this warning serious for any reason? I have simplified the giant path which appears to indicate that the binary files in the library have hardcoded a path in "/Users/somedeveloperthatisntme" that could hardly help but Not Exist since I'm using this library on a computer that doesn't even have a folder named "Users/somedeveloperthatisntme".
Dsymutil appears to be a tool to "manipulate archived DWARF debug symbol files", although I know precisely nothing about what it is and what it does, notwithstanding the thorough documentation from Apple, which tells me what, but never ever, why. What is it doing, and what will this warning mean for me? I suspect I need a new library/static-framework from the vendor to clear this up?
Update: I am unable to solve this and it appears the cause lays with very old binaries compiled by a very old XCODE version, shipped as part of a mobile framework from a third party vendor. The issue in this case would be resolved by having that vendor rebuild their library, something I asked them to do because the warnings drove me nuts, but which they seem unable to do. In the end I ditched their technology and replaced it with something else. (Grin)
These errors are to do with the architectures you are using and the resources you are referencing. I don't understand the reasons myself, but if you want them to go away, go to Build settings, then Build Options and then select Debug information format and select DWARF.
I am on the other side of this, building a library for others to use, and I was able to alter the library project by setting 'GCC_GENERATE_DEBUGGING_SYMBOLS = NO' in the Build Settings to make those warnings go away in an Application project that consumed the output framework.
This isn't a solution to your problem, but if you're in contact with this vendor, you could pass this along.
The other answers contain helpful information but I wish to put the real answer down succinctly:
You can not fix this, and the meaning of the errors is simple: The current linker sees these library files as containing elements that can not be opened.
To solve the warnings, contact the vendor and get a recompiled library that has been rebuilt with a later version of CLANG.
What I did was just delete the /Library/Developer/Xcode/DerivedData folder and it fixed everything for me.
Another reason these warnings could occur is because of incorrect symbol stripping settings for release builds in a project. Contact the author of the framework and tell them to make a new binary with the proper symbol stripping settings.