mac app requires newer version of sqlite but uses the old one - macos

Trying to run / debug an app on mac (Mavericks), that has to use sqlite 3.8.6.
I have the .h and .c files in the project. I have the dylib added as a build resource
LIBS += sqlite3/libsqlite3.0.dylib
But I also must place the dylib somewhere and tell the program at run-time to use this version.
There is a SQLite version 3.7.13 installed on the system (in /usr/lib). It seems to be used preferentially. If I had admin rights (which I don't) I could move it to a different location... But the user system may have it in the default location so that would be useless.
I have tried to place MY sqlite3 in a place that will be used preferentially - like in myapp.app/Contents/Frameworks or myapp.app/Contents/MacOs... also tried to change the dependency with install_name_tool... no success.
Checking the dependencies with otool -L shows a dependency on sqlite3.0.dylib in /usr/local/lib (which does not contain any sqlite3)... even after running install_name_tool it still shows the same. Perhaps I am doing it wrong...
install_name_tool -id #executable_path/Frameworks/libsqlite3.0.dylib myapp.app/Contents/Frameworks/libsqlite3.0.dylib
install_name_tool -change myapp.app/Contents/Frameworks/libsqlite3.0.dylib #executable_path/Frameworks/libsqlite3.0.dylib myapp.app/Contents/Frameworks/mylib.dylib
install_name_tool -change myapp.app/Contents/Frameworks/libsqlite3.0.dylib #executable_path/Frameworks/libsqlite3.0.dylib myapp.app/Contents/MacOs/myapp
I am getting an SQL error that is caused by having the wrong (older) version of sqlite3, which does not support certain required features.
How can I force the app to see the version I added ?
Update: I added the c file and removed the dylib as a dependency...
I got the error no such module: fts4
I added the following in the .c file (from http://www.sqlite.org/fts3.html) - as suggested in comments below
#define SQLITE_ENABLE_FTS4
#define SQLITE_ENABLE_FTS4_PARENTHESIS
Adding the same in windows and linux, the effect is double the size of the library + sqlite3. And queries on a database run significantly slower (I actually thought they were not even performed).
If this is the only option I have on mac, I will have to use it... I am either stuck with very slow build, very large libs, and VERY SLOW QUERIES, or ... there must still be an option to use the sqlite3.dylib without building it into the lib I am creating.

You can just add the original (Amalgamation) files sqlite3.c and sqlite3.h (look for version 3.8.6) to your Xcode project. That's basically it.
If you need to change/add some compile options
you can do that at the top in sqlite3.c.
Here an example to activate FTS3/FTS4:
#define SQLITE_ENABLE_FTS4
All the compile options are here: http://www.sqlite.org/compile.html

Related

OSX: start app with runtime-dependent dylibs

OSX 10.10 Yosemite.
My application depends on Intel IPP.
At compile time it depends on 2 dylibs, but these depend from other dylibs, which are loaded at runtime (and not displayed in otool -L) . When starting my application does not find these libraries.
I do not understand how can I specify for my app (or for the compile time dependent dylibs) a folder to search a path for runtime dylibs.
As far as I can understand, it is necessary to use rpath. But what exactly should be done? How to set runtime search path? Do I need to set a 'rpath' for the executable file or for the dylibs?
I think you will have to use install_name_tool command to add the dylib.
Don't think you can setup a folder that can magically load all the dylib in it. It's against the purpose of code signing and security.

How do I deploy Assistant with my app on Mac without deploying multiple copies of Qt Frameworks?

I am trying to deploy a Qt application that uses the Assistant to show help, on mac (OS X 10.6-10.9, Qt 4.8)
QStringList args = "-collectionFile " + "my_help_file";
QString app = "path/"+"Assistant.app";
m_helpProcess->start(app, args);
I placed the Assistant.app inside the Resources folder.
Since I deploy the app on a system with no qt installed, I placed all he QT dependencies in Contents/Frameworks, and ran install_name_tool
# for QtCore:
install_name_tool -id #executable_path/../Frameworks/QtCore.framework/Version/QtCore.framework/Versions/4/QtCore xxx.app/Contents/Frameworks/QtCore.framework/Versions/4/QtCore
install_name_tool -change QtCore.framework/Versions/4/QtCore #executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore xxx.app/Contents/MacOs/xxx
install_name_tool -change QtCore.framework/Versions/4/QtCore #executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore xxx.app/Contents/Resources/Assistant.app/Contents/MacOS/Assistant
The app gets it, it is functional, but Assistant doesn't... obviously it is a different level.
I don't want to place multiple copies of the frameworks... besides I am sure there will be conflicts if i do...
Calling Assistant without its bundle didn't work... (I would love to place the executable next to the xxx executable)
Since I guess I set the id for the Frameworks as one directory down from #executable_path, I can't tell help to look elsewhere...
How do I link the Assistant properly with the Frameworks ?
Note: I have tried:
# for QtCore:
install_name_tool -id #executable_path/../Frameworks/QtCore.framework/Version/QtCore.framework/Versions/4/QtCore xxx.app/Contents/Frameworks/QtCore.framework/Versions/4/QtCore
install_name_tool -change QtCore.framework/Versions/4/QtCore #executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore xxx.app/Contents/MacOs/xxx
install_name_tool -change QtCore.framework/Versions/4/QtCore #executable_path/../../../Frameworks/QtCore.framework/Versions/4/QtCore xxx.app/Contents/Resources/Assistant.app/Contents/MacOS/Assistant
Did not find libraries... I guess the id has to match the path... but for a single instance of the lib, it just can't...
I also tried to make symbolic link (alias ?) to the Qt library, in the location where Assistant will look... It tried and failed, complaining of a malformed file.
Update to answer comment:
Running otool -L on the assistant in the Assistant bundle in the Resources folder:
#executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore
And the Assistant can't find the library which really is at
#executable_path/../../../Frameworks/QtCore.framework/Versions/4/QtCore
Unexpectedly, the Assistant opened correctly even from outside the QT Creator.. Once I gave both the assistant and the resource file absolute paths. (I could have done that for either the Assistant executable or an entire bundle)
I copied the executable Assistant inside the same folder as my app executable.
Of course, adding dependent libraries and setting the link paths to #executable_path/../Frameworks was required, like for deploying any app. (I just did it manually, not with macdeployqt because macdeployqt failed to copy the plugins)
And quite important, getting the sqldrivers Plugin required for Assistant was needed. And... that was a tough one... setting the dependencies for the Plugin on Frameworks as well.
It would have been great to have the Assistant in its own bundle (inside Resources)... but with the Qt library dependencies still in the resources of the main bundle, to avoid copying the same libraries multiple times. I was unable to do that. Placing Qt frameworks outside the bundle was not an option, since I cannot rely on users not to remove items or install other versions.

OSX Xcode - Packaging dependencies libmysqlclient.18.dylib

This may well have been asked before I just couldn't figure out the right term to search.
I'm writing a client-server application to run on an OSX desktop which will talk to a MySQL server on the local network. It seems long-winded to implement a web-services API when basically a bunch of SQL statements will be perfect internally.
I've wrestled with the install procedure for MySQL server on my development machine, ad had to resort to symlinking libmysqlclient.18.dylib into /usr/lib even though i'd put the include path in header search paths.
What I need to know is how do I create a .app file I can send to other machines that will have access to the libmysqlclient.18.dylib file?
I'm used to Windows having installers to do this and a bit new to OSX programming although i've been doing Obj-c for iDevices for 2 years.
Is there a setting which allows the library to be copied into the .app file or do I need to install the mysql connector on each machine - if so, how do I get around the symlink issue, ideally I need it to work from the stock folders.
If this has been answered somewhere else, please point me in the right direction.
At build time the static linker on OS X, ld, writes the shared library identifier of each library that your application links against in to the application binary. At run time the dynamic linker, dyld, attempts to load each shared library from the paths specified in the application binary. You can see this information using otool -L YourApp.app/Contents/MacOS/YourApp.
The fact you needed to symlink libmysqlclient.18.dylib in to /usr/lib suggests that the shared library identifier of libmysqlclient.18.dylib is something like /usr/lib/libmysqlclient.18.dylib. To include the library in your .app bundle in a way that your application will use it rather than looking in /usr/lib you need to:
Change the shared library identifier of libmysqlclient.18.dylib so that dyld will look for the binary relative to your application binary. This is typically done by running install_name_tool -id #executable_path/../Frameworks/libmysqlclient.18.dylib libmysqlclient.18.dylib.
Copy the modified libmysqlclient.18.dylib in to the Frameworks subdirectroy in your application bundle. This is typically done using a Copy Files build phase in your Xcode project.
You should then be able to verify that the install name written in to your application binary is #executable_path/../Frameworks/libmysqlclient.18.dylib rather than /usr/lib/libmysqlclient.18.dylib (using otool -L YourApp.app/Contents/MacOS/YourApp again). If the install name isn't correct then you'll need to ensure that your linker search path is set up to find your modified version of libmysqlclient.18.dylib ahead of any other versions you may have.

java bad version number in .class file in browser

I am receiving java bad version number in .class file when I try to open a simple applet in my browser (I have tried Firefox and Safari). My browsers stat that I am using a 1.5.X JRE, but my command line compiler is 1.6.x. I can't quite figure how to sync the two of these VM's, as I am not the most adept Mac user. I have tried the native software update feature, but there is no Java update available there. I've also tried updating in each browser, but I just get redirected to the Mac OS X Software Update feature.
while compiling files, you have to use -target option.
Example, javac -target 1.5 [source file]
More explanation is available at http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javac.html
For an Oracle JDK, you'd simply use the cross-compilation options of javac.
Note that is important to specify -source, -target & -bootclasspath for the compilation. That last one requires a JRE of the target version, to check the classes, methods & attributes used in the code actually existed in the target version.

Xcode, building and dylibs

I've looked at a few related questions and cannot seem to find a solution for myself.
Basically I'm using the libmp3lame.dylib in my Xcode project. The install process for lame produced the .dylib and placed it in usr/local/lib and to get Xcode to build and run the project I changed the Library Search Paths to include the above folder. This works fine.
Now it's come to producing a release version and I want to include the .dylib in the bundle so that the user doesn't have to put up with an install phase or anything similar. I created a copy files phase of the target and this dumps the .dylib into the Frameworks folder in the contents of the bundle. However, running otool on the binary shows that instead of using the .dylib inside the bundle, the compiler has linked it to the usr/local/lib version (even if I delete that version).
Looking at the other results in the otool output I have other frameworks being linked to inside the bundle, just not the .dylib. Looking at the properties for both these frameworks and the .dylib in Xcode I can't see any differences other than file type.
My searching suggests I need to use rpath or similar, but I've no clue where to apply this in Xcode.
My workaround for this issue was to do the following in terminal (I've used Automator to, well, automate this):
install_name_tool -id #executable_path/../Frameworks/libmp3lame.0.0.0.dylib ~/path/to/lib/in/app/libmp3lame.0.0.0.dylib
install_name_tool -change /usr/local/lib/libmp3lame.0.dylib #executable_path/../Frameworks/libmp3lame.0.0.0.dylib ~/path/to/app/Contents/MacOS/AppName
Basically swapping the path to the library from the one in the usr local lib to the one included in the bundle.
My tip is to look at the build output, how does it actually run ld?

Resources