Xcode Multiple Static Libraries and Duplicate Symbols - objective-c

I'm developing an iPad application which relies on two static utility libraries (libBFSDK & libBetfair-Platform). Both static libraries include AFNetworking. When I try to include the two static libraries in my iPad application, I get a linking error like:
duplicate symbol _OBJC_METACLASS_$_AFImageCache in:
/Users/osheas/Library/Developer/Xcode/DerivedData/Betfair-gnnjnwtovdmtoxakuxbjyvetciyy/Build/Products/Debug-iphonesimulator/libBFSDK.a(UIImageView+AFNetworking.o)
/Users/osheas/Library/Developer/Xcode/DerivedData/Betfair-gnnjnwtovdmtoxakuxbjyvetciyy/Build/Products/Debug-iphonesimulator/libBetfair-Platform.a(UIImageView+AFNetworking.o)
ld: 86 duplicate symbols for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
UIImageView+AFNetworking is part of AFNetworking. Both static libraries include AFNetworking. As a result, I get duplicate symbols for UIImageView+AFNetworking.
Anyone have ideas on a workaround for this? I have access to the source code for the two static libraries, but I'm still not sure how to solve this problem.
Thanks & please let me know if you need any other details,
Sean
PS - FWIW I'm running Xcode 4.5 & I need to be able to deploy to iOS 4.x devices.

Since you have access to the source for the static libs, you could use the preprocessor to rename the AFNetworking symbols to something unique.
Add flags for each duplicate symbol to your "Other C Flags" build setting with the format
-AFNetworkingSymbol=UniqueAFNetworkingSymbol
This will still result in duplicate code, but should allow you to have multiple copies of AFNetworking without modifying the source.
More info
Ideally, most open source Obj-C code will move to solutions like CocoaPods and just specify dependencies instead of bundling them.

Apparently, this is a relatively common occurrence. See https://github.com/square/PonyDebugger/issues/36 for more details.

This is the simplest solution I have seen to this problem. I have tested it and it works.
http://blog.sigmapoint.pl/avoiding-dependency-collisions-in-ios-static-library-managed-by-cocoapods/

you check _AFImageCache has tow file in your project and remove one.
this can help you.

Related

How do I include cufft.h file in a fortran code?

I have a Fortran code which has been made to work on CPUs, but I need to accelerate it using GPUs and I chose to do that with OpenACC.
This code uses FFTW libraries when compiled with gfortran. However, as you may know, these libraries cannot be used with nvfortran. So, I have to go with cufft libraries.
Therefore, I used this conversion giude. The problem is, fftw allows users to build a Fortran module with iso_c_binding including the file fftw.f, while cufft does not have this kind of feature and you need to include the cufft.h header.
When compiling with nvfortran (I use -cpp, -Mfree, -lcufft and -l cufftw flags, checked the include and lib directories given to -I and -L flags) I get many errors:
The paths in all the #include inside the cufft.h file are wrong and I had to change them manually
All the comments ("//") in the header files are seen as errors (had to remove them manually)
“Label field of continuation line is not blank” errors everywhere in header files, starting from line 2 (in lines 1 I solved that giving 7 spaces - but didn’t I use -Mfree for that?)
Please help me, I don’t think that the right way to do so is to change files manually…
Thanks in advance for helping
You cannot include headers for the C programming language in Fortran source code. Instead use the Fortran interfaces to any libraries you need (provided such interfaces exist).
We ship a cuFFT interface module with the compilers. You should just be able to add "use cufft".
Full documentation can be found at: https://docs.nvidia.com/hpc-sdk/compilers/fortran-cuda-interfaces/index.html#cf-fft-runtime
Example codes are shipped with the NVHPC SDK which can be found in the "<INSTALL_DIR>/Linux_x86_64/<RELEASE>/examples/CUDA-Libraries/cuFFT/"" directory

error in porting code from ios to osx project

i tried to port the SimpleFTPsample from apple from this IOS project to my OSX project, but when I try to build I get the following error.
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_NetworkManager", referenced from:
objc-class-ref in Document-DAE96E3625ECED63.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've searched online, and have been checking all the code I copied twice, all frameworks are added, and the headers included. could somebody please help me to find whats wrong, or even better explain what this means so i can solve it myself in the future? how can i find out what is wrong in the NetworkManager class? i dont get any errors before compiling.
thanks
---EDIT---
forgot to mention that i only need the PUT part of the code in the example, i am only examinating that part. all the rest hasnt been copied over. i copied the NetworkManager.h, NetworkManager.m and copied over the parts of the code that i need from the PUT file.
Usually, when the linker says “what? I've never heard of that class”, it means that the module that implements that class (SomeClass.m) didn't get compiled.
There are two ways that that happens:
Compilation failed
This one would cause an error asking for SomeClass.o (in your case, NetworkManager.o). That's not the error you got, but similar enough that I felt it was worth listing here.
The linker will want an object file, which is produced by a successful compilation. If compilation fails, the object file doesn't exist, so you'll get the “file not found: blah/blah/blah/SomeClass.o” error.
999‰ of compilation failures are because the module contains an error—a syntax error, an unrecognized name (e.g., spelling error/typo), or some other flaw that fails compilation.
Build errors causing other build errors is fairly common, so you should always tackle errors from the top of the list downward.
The solution to this one is to navigate to SomeClass.m and fix everything that's wrong with it, and then try the build again.
You didn't even try to compile it
This is the one you ran into.
Every target has a list of build phases, each describing something that needs to be done to build the target. Most targets have at least Compile Sources and Link Binary with Libraries phases. Every build phase has a list of input files.
The input files for a Compile Sources phase are the module files that Xcode will try to compile. Link Binary with Libraries will implicitly link in everything that the compiler produced—all of the object files—along with the libraries in its list, such as Cocoa.framework.
For each target, Xcode will only try to compile modules that are in that target's Compile Sources build phase.
It's quite possible to forget to add a module to a target but still try to use it in another module within the same target. Maybe you made the module a long time ago for another target, and now want to use that code in the target you're working on now, or maybe you simply forgot to check the box when you created the module or otherwise added it to the project.
Either way, you'll get that error message, telling you that the module whose contents you're trying to use isn't listed for compilation in the target you're trying to use it in.
There are two ways to fix it:
Select or navigate to the “missing” module and show the File Inspector (⌘⌥1), and check the box for the appropriate target under “Target Membership”.
Select the project object in the Project Navigator, select the target within the editor, switch to the Build Phases tab, and drag the “missing” module from the Project Navigator into the Compile Sources build phase.
The way to prevent it is to make sure the relevant targets are checked when you add the module to the project. This includes both creating new modules and adding modules you've obtained from other people (e.g., open source reusable classes).

Objective-C: How to make a Framework?

I'm new to Objective-C but has a lot experience with Java and .NET.
I'm trying to add EGOPhotoViewer to my iOS 5 project in Xcode 4.2.1. But I get a lot of release, dealloc, retain etc. issues while compiling their code, since I'm using Automatic Reference Counting (I think!).
How can I create a class library, framework or what it is called in Objective C for their code, that I can add to my project?
EDIT:
I've done the approach from JeremyP by inserting the code with a new target. I compiled in the beginning, but after a while I get this compile error:
Undefined symbols for architecture i386:
"_OBJC_METACLASS_$_EGOPhotoViewController", referenced from:
_OBJC_METACLASS_$_PhotoViewController in PhotoViewController.o
"_OBJC_CLASS_$_EGOPhotoViewController", referenced from:
_OBJC_CLASS_$_PhotoViewController in PhotoViewController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Does anybody know why?
For your purpose, a regular static library as described by beryllium would do fine.
Just for unashamed plug purposes and for spreading the word, this document describes how to create versioned, documented frameworks using Xcode, GIT and DoxyGen.
Creating a Versioned Framework 1.23
The main purpose of creating such frameworks is to redistribute them. I personally find it extremely annoying to manually include libraries and headers I receive from third parties - especially if the libraries are delivered in separate versions for simulator and device. That guide is meant for classic middleware developers. I have written it to allow people like those folks from Google Analytics to finally provide something worth their brand.
This document gives you a step by step explanation, bundled with loads of screenshots.
Open Xcode -> File -> New -> New Project -> Framework & Library -> Next -> Type Name, Choose Folder -> Create
It will be a library called yourApp.a. You can find it in Derived Data folder
You can't create frameworks for iOS. You can however, create static libraries using beryllium's technique. You can also add a static library to your existing project using File / New / New Target... Obviously, once you create the target you can change the Objective-C automatic reference counting build setting to "no" for your new target.
I thought it was possible to turn ARC on and off at the source file level, but I can't figure out how.
I've created frameworks on multiple occasions using the following method:
http://db-in.com/blog/2011/07/universal-framework-iphone-ios-2-0/

How to config xCode 4 to compile objective-c++ without adding a '.mm' file

I am trying to describe my problem clearly for you, so it might be a little long, and I really appreciate that if you can read it and provide some suggestion. Thanks.
I have a library project, let's call it MyCppLib, which contains some legacy c++ code, and I add a adapter class in this project so that I can use it with out using objective-c++ in other project. Here is an overview of MyCppLib project.
Project MyCppLib
- some legacy c++ code
- Adapter.h
- Adapter.mm
I have another project, let's call it Main project, which use the MyCppLib project as a static library. So I use xCode 4 to compile MyCppLib, and get libMyCppLib.a, and config Main project in xCode 4 to link it with Main project. Here is an overview of Main project.
Project Main
- Some objective-c classes which DO NOT contain '.mm' file
- Adapter.h
- libMyCppLib.a as a static library
While I compile the Main project in xCode 4 I get some errors:
Undefined symbols for architecture armv6:
"operator new(unsigned long)", referenced from:
-[Adapter init] in libMyCppLib.a(Adapter.o)
my::cpp::namespace::MyCppClass::MyCppClass()in libMyCppLib.a(MyCppClass.o)
... some other similar errors
ld: symbol(s) not found for architecture armv6
collect2: ld returned 1 exit status
I figure it might because the Main project do not have an objective-c++ capability, so I add a '.mm' file to the Main project. And now Main project should be like this:
Project Main
- Some objective-c classes which DO NOT contain '.mm' file
- Adapter.h
- libMyCppLib.a as a static library
- DummyObjCpp.h
- DummyObjCpp.mm
Then, I compile the Main project, and it succeed!
So, finally, my question is: how can I configure the Main project to have objective-c++ capability without adding a '.mm' file?
OK, I've read over the question a few times, but I'm still not sure I understand the problem.
While I've done a lot with Objective-C, C++, and Objective-C++, I haven't encountered the scenario you've described with static libraries (since most of my development is for OS X rather than iOS, where dynamic libraries are allowed and preferred).
It sounds like there might be an issue in your second project because the .h file by itself doesn't tell enough about what's contained in the .a (namely that when you combine it with the rest of your executable, you'll need to be linked against libstdc++.dylib). You might try changing the "File Type" of the Adapter.h header file from the default of C header to C++ header as shown in the image below:

Linking error in Xcode 4

I know this is a long shot but, I've been having trouble with a linker error that I specifically don't understand. Please refer to the picture below.
The project contains 4 targets. This error points specifically to one target that is a BSD/Shell helper tool written in c.
I'm sorry for being vague, as I don't fully understand what might be the problem. Any suggestions? Thank you.
Usually, this means that the source file that defines main() hasn’t been added to the corresponding target.
Another possible reason is that the source file that contains main() is being compiled for an architecture (e.g. i386 only) but the target/executable specifies a different architecture (e.g. x86_64 only or fat/universal).
One strategy to help with diagnosing this issue is running xcodebuild against your project+target to inspect the commands that are being issued to compile and link the target.
When all else fails, remove the target and add it again.
Did you #include the appropriate files?