Build a static library for iOS - specifically spatialite - ios

First, please forgive and point out if I am to use some other protocol for referencing another thread/post.
There was a previous thread how to compile spatialite for iOS where the top answer partly described building spatialite as a static library for iOS. The answer included the text:
"Once you've drag n drop the .a (both are required to work in the simulator AND on the real hardware), you can initialize spatialite by just invoking spatialite_init(1)."
I am guessing this is translated to some version of the following?
Xcode 4
File->New->New Target->iOS->Framework & Library->Cocoa Touch Static Library
Name the library - libSpatialite_TedS
Drag the header files to libSpatialite_TedS -> Copy Headers (question here ... there is a spatialite.h file in the 'headers' directory of the 'spatialite2.3.1.zip' download. Then in the subdirectory 'spatialite' there is another spatialite.h that is not an identical file and is obviously needed. Do we just drag the header files from 'headers' directory, then drag the directory 'spatialite' as a directory into 'Copy Headers' area of our Xcode static library 'myNewLibrary'?)
Drag the '.a files' libSPATIALITE2.3.1_arm.a & libSPATIALITE2.3.1_x86.a
Shouldn't we have some '.m' files to go with these headers in the 'Compile Sources' field?
Now, without referencing the libSpatialite_TedS in my project, when I 'Command-B' to build, the project build succeeds. However, when I look for the compiled product in
/Users/Admin/Library/Developer/Xcode/DerivedData/MyProject-gutnkbwqqonzgxbcmfzzzkadqhid/Build/Products/Release-iphonesimulator
I see build's products, but they do not include libSpatialite_TedS.
Is this because the compiler is 'smart' and recognizes that none of the header/.a files are referenced in the project so it does not bother compiling them?
And, is this the correct way to go about achieving the objective of the original poster how to compile spatialite for iOS?
Many thanks,
Ted S

I was running into linker errors with the original poster too, but solved it by including libsqlite3.dylib, libstc++.dylib, and libiconv.dylib in the target.
Hope this helps!

Ted, I believe that the .a (static library) files and headers are meant to be used in a project right away, rather than in another static library as you've described. They are the result of a project's output. I think you can find the project that built them, here:
http://lionel.gueganton.free.fr/spatialite/
And a little more on static library files:
What is a .a (as libcrypto.a) file?
EDITED
Here's another link that you might find helpful. It s a summary of the Static Library build process in iOS:
http://www.icodeblog.com/2011/04/07/creating-static-libraries-for-ios/

Related

Linking the correct variant of an iOS static library using Xcode

I have an iOS static library.
As a matter of fact, I have four variants of it:
Debug-iphoneos/libopende.a
Debug-iphonesimulator/libopende.a
Release-iphoneos/libopende.a
Release-iphonesimulator/libopende.a
I want to link my iOS app against this static library using Xcode.
To do so, I go to Build Phases, and in Link Binary With Libraries, I click the '+' to add one, using Add Other.
Now I have the problem of which variant I should be adding. So I just pick one of the .a files, and hope Xcode is smart enough to find the others?
Anyways, if I do this, the linking fails saying it can't find libopende.a file.
So, is it even possible to do what I want, without first building a 'Framework' instead of a set of static libraries?
Ok, so when linking against a static iOS library, you need to know that:
It does not matter which .a file you add in the Build Phases - Link Binary With Libraries panel. Any of the four .a files will do, it only takes the file name, not its path.
To actually differentiate between library variants for Debug/Release Device/Simulator, you need to specify the correct library paths in the Build Settings - Library Search Paths.

Where to put a custom .dylib in a Swift app?

I'm trying to load a custom .dylib library via the dlopen() function (in a Swift iOS app). It requires a path to the library.
Where to put the library in the project structure?
What will be the library's path on the iOS device?
Also, a tangential question, it seems more usual to include the library's sources directly into the project and let Xcode build it. Is that a preferable approach for some reason?
1 )
If you include the .dylib library in with your list of files and resources in your project, you can use the "Copy Files" build phase to copy the dylib into your shipping app.
A tutorial can be seen here.
2 )
For dlopen, try using just the .dylib name before you try to use relative paths including the "#executable_path" or "#rpath" run time variables. An example can be seen here in this related question.
As for why some developers prefer to include the library source code in a project, I believe it's mostly just a preference by folks who aren't comfortable with the "Copy Files" build phase or in using dlopen.

Adding and including LAME static libraries to xcode 5

I need convert M4A files to MP3 and i guess this link is the answer : ios - convert .m4a to .mp3 file programmatically.
I was searching , how use LAME on iOS? and i find this :
https://gist.github.com/Superbil/7689556.
Once i execute, "build_ios.sh" 4 files are generated:
libmp3lame-armv7.a
libmp3lame-armv7s.a
libmp3lame-i686.a
libmp3lame.a
I understand the first two, are the libs that i need , for use this code :
ios - convert .m4a to .mp3 file programmatically.
How i can add this statics libraries to XCode and import for use the code?
I'm using the version 5.1.
Thanks in advance.
When using a static library, you need 2 things:
The static library itself (.a)
Header files to access its public interface
In the list of libraries you've posted, it would seem libmp3lame.a is the one you require. The three listed above it are for individual architectures, whereas the last one is a 'fat library', which is a collection of the individual architecture libraries. You can confirm this by running lipo on the fat library:
lipo -info libmp3lame.a
In order to incorporate it within your application, you need to:
Add the .a and header files to your project (with the application
being the intended target)
Add the library to the "Link binary with libraries" build phase,
found under 'Build Phases' for your target, within the Project
settings
Import/include the header files where you wish to use LAME
Ideally, it's worth having 2 sets of fat libraries; one for the simulator, and the other for the device. You can then include the appropriate one for the respective build target. This ensures the size of the application is the lowest it can be, but it's fairly harmless to include the simulator library within an App Store binary (it doesn't cause side effects).
Your question doesn't mention header files, and I don't see any reference within the build script as part of the build artefacts. You may need to copy the ones you require from the source itself into the project.

How to make XCode add the linked project headers and implementaion files to the static library and framework

I have a static library project and in that project I linked a .xcodeproj to the source code so I can update easily actually and to not copy and paste files in the static library project for easy update.
The purpose thought it's to embed this .xcodeproj with my code into the result static library or .framework that I will build using a script.
Although I can see that there is nothing added in the compile sources or the copy header files which I added. If I try to add with drag and drop files from the linked project to my static library build phases copy header section it copies the file to my project again, but I don't want this.
And if I add a header file #import to one of my public headers and try to use the static library to the client project it complains that the header is not found!
So, in the end, what I want is the whole linked project files to be copied in the resulting static library or .framework with the scripts and target I have.
Is this possible to achieve, I think I miss some project setting that I'm not aware about that will see and copy all header and implementation files to my result static library or .framework?
Is my approach overall correct? I don't think that there is no option to use a linked project in a static library and embed it when the build is happening since I am using it in my project!
I could add the .framework of the third party component too and merge to my static library. I have created this question earlier today. Is it possible to include a .framework in a .framework and how?
Regards.
Not sure if your #import-not-found issue is a linker issue, but...
Make sure to use the -ObjC flag in "Other Linker Flags" in the library's Build Settings. This gets the linker to build everything in the library.
Mentioned here:
https://developer.apple.com/library/ios/technotes/iOSStaticLibraries/Articles/configuration.html
And also make sure you link in the library in the build settings for the project that needs it.

Duplicate Symbol Error: SBJsonParser.o?

I currently have ShareKit in my project that is compiled as a static library. It is properly implemented. I also have implemented Amazon's AWS SDK by just adding their framework into my project.
It seems that the duplicate symbol is coming from Amazon's AWS SDK file, "AWSIOSSDK". This is what it looks like:
And that file is colliding with ShareKit's file, libShareKit.a. This is what that file looks like:
Anyway both of these files are ones that I haven't seen before. And it seems that some JSON files are colliding within them.
I have looked at other SO questions and they say to do some things with the compiled sources but none of these files are in the compiled sources from either library.
Here is the exact error Xcode gives:
ld: duplicate symbol _OBJC_CLASS_$_SBJsonParser
Anyway, does anyone have any ideas what I should do? My app does not compile unless I fix this issue.
Thanks!
You could go ahead and split a library archive into its object files and merge them again by leaving out the duplicates.
See the following walkthrough for getting an idea to manage that task:
Avoiding duplicate symbol errors during linking by removing classes from static libraries
Both of these have built SBJsonParser into their static libraries. This is not the correct way to build a static library. Each should build without SBJson and then you should link all of them together with SBJson. There are a couple of solutions:
Rebuild these libraries (or have their maintainers do so) to not include third-party libraries directly into a static library. This is the ideal solution.
Remove the incorrect SBJson files from the .a files using ar. You should be able to do this using ar -t to list the objects in the .a and then ar -d to delete the ones that shouldn't be in there. You could of course also ar -x to extract all the .o files and link them directly.
I had the same issue with FaceBookConnect Framework (let's call it project B) and my project (project A). Both were linking again JSON framework.
The solution is :
Go to Project B > Target > Build Phase > Remove JSON from the "Link Binary with libraries"
Make sure the JSON framework is still in the project (don't remove it) so project B can build
Build your project B you shouldn't get any error. The project should build but not embed the JSON frameworks symbols
Add both project B product (a framework) AND JSON framework in project A
Go to Project A > Target > Build Phase and check that both project B and JSON have been added to the "Link binary with libraries" section
Build your project A
Regards,

Resources