[Mono-osx] Not require Mono install for a DLL
Duane Wandless
duane at wandless.net
Wed Oct 1 17:19:07 EDT 2008
I was able to find a solution. What is different with my setup is I do not
have a mono executable, just a mono DLL. This
link<http://www.codeshorts.ca/2007/nov/01/leopard-linking-making-relocatable-libraries-movin>was
very useful. Be sure to check out this link!
Just some background.. my application is a real Cocoa/Xcode app with ObjC
running the GUI. The mono code, utilizing monobjc, is hooked up to the NIB
controllers. So the business logic is run by mono and the UI is run by
ObjC. I can send NSNotifications back and forth between the mono code and
the ObjC code. Mono loads data into the controllers, the UI then displays
the data. Another note, I use Dumbarton to load the DLL and init mono.
There probably is a way to init the DLL without Dumbarton but it works. Yes
yes I know monobjc can do all the UI work as well... but we already had UI
code on mac and windows. Now we truly have a common business layer!!!!!
To embed a DLL without mono being installed I am currently performing these
steps:
mkbundle -o xx.c -oo libxx.a --nomain -c --machine-config ... -L <mono lib
paths> all of the referenced libraries including mscorlib.dll
The xx.c is compiled into the Xcode app. And libxx.a is linked, with -lxx
as a linker flag. Add a library search path to where libxx.a is.
I then run these libraries (below) through install_name_tool. You only have
to do these next 2 steps once.
libglib-2.0.0.1400.1.dylib libgthread-2.0.0.1400.1.dylib
libmono.0.0.0.dylib
libgmodule-2.0.0.1400.1.dylib libintl.8.0.1.dylib
Two things have to be performed on these libraries. First the id of the
file has to be changed from the /Library/Frameworks/Mono.framework reference
to @loader_path/../Libraries/<name>. Run otool -L <the dylib file>.
install_name_tool -id @loader_path/../Libraries/libintl.8.0.1.dylib
libintl.8.0.1.dylib
The second operation is to change the references to other dynamic libraries
you are embedding.
install_name_tool -change
/Library/Frameworks/Mono.framework/Versions/1.9.1/lib/libintl.8.0.1.dylib
@loader_path/../Libraries/libintl.8.0.1.dylib libglib-2.0.0.1400.1.dylib
Basically what you are doing is telling the runtime app where to find these
dynmaic libraries. Rather than in the Frameworks directory look relative to
the application. Place these modified libraires in
<yourapp>.app/Contents/Libraries.
Compile the xcode application normally. Then run install_name_tool on it as
well, <yourapp>.app/Contents/MacOS/<yourapp>
install_name_tool -change
/Library/Frameworks/Mono.framework/Versions/1.9.1/lib/libgthread-2.0.0.1400.1.dylib
@loader_path/../Libraries/libgthread-2.0.0.1400.1.dylib <yourapp>
Now remember you have to run this install_name_tool many times. Once for
each library referenced by your application. And once for each reference in
the dynamic libraries to another dynamic library that you are trying to
embed. Use otool -L <file> to find the references you need to modify.
I naturally wanted to avoid the static option since that requires special
licensing. So far this appears to work. These steps are what mkbundle is
trying to do... but it appears it only really works on executables.... or
I'm missing something.
Hopefully this will prove useful to someone down the road.
Duane
On Wed, Oct 1, 2008 at 4:45 PM, David Rivera <mithril at me.com> wrote:
> Monobjc provides the ability to compile a Cocoa app with the required mono
> frameworks embedded within it so that it does not require mono to be
> installed on the system to run it. It is implemented as a couple Nant tasks.
> I'm not sure if it will work for you or not, but you might look into it, its
> what I use.
>
> www.monobjc.net
>
> -David Rivera
>
> On Wednesday, October 01, 2008, at 08:14AM, "Duane Wandless" <
> duane at wandless.net> wrote:
> >I am trying to create a DLL that does not require mono to be installed. I
> >have used mkbundle with this command line:
> >
> >mkbundle -o host.c --nomain -c -oo libhost.a -L <path to mono libraries>
> >MacMonoClient.dll System.dll System.Core.dll etc.
> >
> >I can successfully compile and link the host.c file and the libhost.a
> object
> >file into a Cocoa Objc application. At runtime I can use
> >mono_domain_assembly_open() to load the 'bundled' library. And it works.
> >
> >However, if I move the Mono.framework out of the way and run the
> application
> >I get this error:
> >dyld: Library not loaded: /Library/Frameworks/Mono.
> >framework/Versions/1.9.1/lib/libintl.8.0.1.dylib
> > Referenced from: /Users/username/MySrc/mycode/sandbox/My
> >Desktop/build/Debug/My Desktop.app/Contents/MacOS/My Desktop
> > Reason: image not found
> >
> >Now of course I'd like to do all of the relocation magic on the dylib's
> etc
> >so that I do not need Mono installed. I have had no success in this
> >effort. The result of mkbundle is not a file that otool can find symbols.
> >install_name_tool appears to do nothing.
> >
> >So the basic question is: can I fully embed a mono library so that it is
> not
> >required to have mono installed? And if yes... then what am I doing
> wrong?
> >
> >Thanks for any help!
> >
> _______________________________________________
> Mono-osx mailing list
> Mono-osx at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-osx
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-osx/attachments/20081001/b03ffeb2/attachment.html
More information about the Mono-osx
mailing list