Runtime Library Components
Overview
To run a .NET .exe assembly that uses wx.NET.dll you
may need to setup your environment and/or system to ensure the following
can be found:
- The
wx.NET.dll assembly
- The wx-c wrapper shared library
- The various wxWidgets shared libraries (Mac and Linux only)
The sections that follow describe each of these components
in more detail.
Finding the wx.NET Assembly
Making sure wx.NET.dll can be found is usually not
a problem. When searching for assemblies, all .NET runtimes will look
in the same directory that the .exe assembly resides in. So even if you
are in your home directory, if you run:
mono ~/src/wx.NET/Bin/html.exe
Mono will find wx.NET.dll . This is dubbed side-by-side
execution. It is the recommended approach when distributing your application
to end users.
If you want to have a single wx.NET.dll copy used
by multiple .NET assemblies, no matter where they reside, there are two
options:
- Install
wx.NET.dll into the global assembly cache (GAC)
- Tell
the .NET runtime where to find
wx.NET.dll
Installing wx.NET to the GAC
The GAC is an area all the various .NET runtimes (Mono,
PNET, and MS.NET) provide to store commonly used assemblies. MS.NET and
Mono require that the assembly be "strong named," which is
a combination of the assembly's name, version, public key, and digital
signature. PNET as of 0.6.6 does not support strong naming and does not
require a strong name for an assembly to be stored in the GAC.
Currently, wx.NET uses an unsecured private/public
keypair embedded in the source code to create a strong name. Given the
pre-release nature of the project this simplifies strong naming. The
key pair is in Src/wx.NET/keys.snk .
To install into the GAC you can use one of the following
commands:
- Mono:
gacutil -f -i wx.NET.dll
- PNET:
ilgac -f -i wx.NET.dll
- MS.NET:
gacutil /i wx.NET.dll /f
Note that if wx.NET.dll was built by PNET, it can not
be installed into a MS.NET or Mono GAC: PNET does not support strong
naming.
Telling Your .NET Runtime Where to Find wx.NET.dll
Mono provides the MONO_PATH environment variable,
where you can specify a colon separated list of directories in which
to search for assemblies. For example:
$ export MONO_PATH=/usr/local/wxnet/Bin
Note you do not need to specify "." or any
Mono system directories. They are always searched.
PNET's ilrun command accepts a --library-dir (or -L for short) option to specify an assembly directory. For example:
$ ilrun -L /usr/local/wxnet/Bin myprogram.exe
MS.NET does not provide any non-GAC/current directory
method of finding assemblies.
Finding the Support Shared Libraries
All operating systems make use of the C++ wxWidgets
wrapper library, wx-c. It's filename varies by platform:
Linux |
libwx-c.so |
Mac |
wx-c.dylib |
Windows |
wx-c.dll |
On Windows, the underlying wxWidgets libraries are
statically compiled into wx-c.dll . So there is only one shared library
to worry about.
On Linux and Mac, there are outstanding (and possibly
insurmountable) issues preventing the wxWidgets library from being statically
linked into libwx-c.so and
wx-c.dylib . So you also have to ensure that these libraries can be found
by the loader. If you are using the build system, these files get installed
to WXW_INSTALL_DIR /lib .
For example, on Linux:
libwx_baseu-2.5.so.2.0.0 |
|
libwx_gtk2u_core-2.5.so.2.0.0 |
libwx_baseu_net-2.5.so.2.0.0 |
|
libwx_gtk2u_html-2.5.so.2.0.0 |
libwx_baseu_xml-2.5.so.2.0.0 |
|
libwx_gtk2u_stc-2.5.so.2.0.0 |
libwx_gtk2u_adv-2.5.so.2.0.0 |
|
libwx_gtk2u_xrc-2.5.so.2.0.0 |
These are the "real names" of the wxWidgets
libraries. They have a major, minor, and release version number embedded
in them. In this case this is wxWidgets 2.5 release (obviously out of date example-wise but you get the gist). Because "2.5" is
already embedded in the actual library name, 2 is used as the release
version number by the wxWidgets team (at least that's what I think is
happening!).
You'll also see symlinks for two other versions:
libwx_baseu-2.5.so.2 |
» |
libwx_baseu-2.5.so.2.0.0 |
libwx_baseu-2.5.so |
» |
libwx_baseu-2.5.so.2 |
The first is the "soname" (libwx_baseu-2.5.so.2 ),
which only contains a major version number that in theory is incremented
when the public API of the library changes. The last link shown defines
the "linker name" ("libwx_baseu-2.5.so "), which contains
no version number at all.
The Macintosh gets a very similar set of wxWidgets
library files installed. For example:
libwx_base_carbonu-2.6.0.0.0.dylib |
|
libwx_macu_gl-2.6.0.0.0.dylib |
libwx_base_carbonu_net-2.6.0.0.0.dylib |
|
libwx_macu_html-2.6.0.0.0.dylib |
libwx_base_carbonu_xml-2.6.0.0.0.dylib |
|
libwx_macu_stc-2.6.0.0.0.dylib |
libwx_macu_adv-2.6.0.0.0.dylib |
|
libwx_macu_xrc-2.6.0.0.0.dylib |
libwx_macu_core-2.6.0.0.0.dylib |
|
|
With a similar set of symlinks for major and minor
version:
libwx_base_carbonu-2.5.dylib |
» |
libwx_base_carbonu-2.6.0.dylib |
libwx_base_carbonu-2.6.0.dylib |
» |
libwx_base_carbonu-2.6.0.0.0.dylib |
You may use different approaches to install/find shared
libraries on your development system and within a shipping application
on a user's system. The sections that follow will describe strategies
for ensuring that the wx-c wrapper library is found at runtime.
Linux
General rules and tips:
- The Linux loader will find
libwx-c.so if it is located in the current
working directory.
- The same does not hold true for the wxWidgets shared libraries:
if they are copied to a "bin" directory and you launch
your assembly from there, they will still not be found by default.
- You can install shared libraries to a directory that is listed
in
/etc/ld.so.conf . You can also add additional directories to
this file. After installing or editing this file, run the command ldconfig to re-cache the entries and create/re-create the various version
links.
- You can add directories to the
LD_LIBRARY_PATH environment variable,
which is searched at runtime. It contains a colon separated list
of directories.
Recommendations:
- On your development system, do a full "
make wxnet-install " so
that both libwx-c.so and the wxWidgets shared libraries
get installed to WXNET_INSTALL_DIR /Bin .
Edit /etc/ld.so.conf and add WXNET_INSTALL_DIR /Bin .
For
example:
/usr/local/packages/wxnet/Bin
Run ldconfig to cache these changes.
- In an install package,
install
wx.NET.dll , libwx-c.so , and
the wxWidgets libraries in a common bin directory. Have a shell
script wrapper around your application setup LD_LIBRARY_PATH to
include this bin before launching mono or PNET ilrun .For
example:
#!/bin/sh
dir=`dirname $0` cd $dir full_dir=`pwd`
export LD_LIBRARY_PATH=$full_dir:$LD_LIBRARY_PATH mono myapp.exe
You can use the wxnet-run script in WXNET_INSTALL_DIR /Bin as a template
for your own script.
For more information about shared libraries see:
If you receive the error:
Unhandled Exception: System.DllNotFoundException: wx-c
note that this can mean either libwx-c.so or one
of the wxWidgets shared libraries could not be found. To diagnose the
problem use the LD_DEBUG environment variable documented in the ld.so manual page. For example:
$ LD_DEBUG=files ./wxnet-run html.exe
will print out the shared libraries as they are loaded.
Mac OS X
Mac OS X works very similar to Linux in loading shared
libraries, with just a few differences.
General rules and tips:
- The loader will find
wx-c.dylib if it is located in
the current working directory.
- The same does not hold true for the wxWidgets shared libraries:
if they are copied to a "bin" directory and you launch
your assembly from there, they will still not be found by default.
- Mono 1.0 is not able to map the request for the shared
library "
wx-c " to
wx-c.dylib even though PNET's ilrun does.
On Mono you must do one of the following:
Create a symlink from libwx-c.so to wx-c.dylib
or ...
Create a mapping from libwx-c.so to wx-c.dylib inside
a Mono assembly configuration file for wx.NET.dll .
This file is named wx.NET.dll.config .
There is a copy of this file in Build/MacOSX .
This file is automatically copied to the source and install
Bin folders.
- The wxWidgets shared libraries will be automatically loaded
from the location where they were installed and linked against
(
WXW_INSTALL_DIR /lib ).
- You can
add directories to the
DYLD_LIBRARY_PATH environment variable,
which is searched at runtime. It contains a colon separated list
of directories.
You must run a wx.NET on the Mac inside of a bundle.
A bundle is a stand-alone application package that contains most everything
needed to run an app (icon, config files, libraries, executables, etc.).
You can get more information about bundles at Apple's
Website.
When you build wx.NET on the Mac, a MacBundles folder
will be created to hold bundles for each sample. You should review one
of these bundles to get an idea what the structure is like. The key piece
is a shell script that is created to launch your application under a
.NET runtime. The shell script is named the same as the bundle name.
For example:
MacBundles/minimal.app/Contents/MacOS/minimal
"minimal " is the app/bundle name. In the
MacOS directory is a script named "minimal " which will be executed
when the bundle is launched in the Finder.
A bundle script normally:
- Changes to a directory that the application expects to be rooted
in.
- Sets up the environment as necessary so that the wx-c and wxWidgets
shared libraries can be found.
- Passes an exe assembly into a .NET runtime (
mono or ilrun ), perhaps
with some arguments.
Bundle recommendations:
- On your development system, do a complete "
make
wxnet-install " so that both wx-c.dylib and the wxWidgets shared
libraries are copied to WXNET_INSTALL_DIR/Bin . Inside your application's
test bundle, add WXNET_INSTALL_DIR /Bin to DYLD_LIBRARY_PATH . For example:
export DYLD_LIBRARY_PATH=/usr/local/wxnet/Bin:$DYLD_LIBRARY_PATH
- In a bundle you give to others, copy
wx.NET.dll , wx-c.dylib , and
the wxWidgets libraries to a common bin directory. Have your bundle
script set DYLD_LIBRARY_PATH to include this bin before launching
mono or PNET ilrun.
For both of the above, take a look at one of the sample
bundles and use this as a starting point for your own bundles. The file
Info.plist in
the bundle is also very critical. It defines various properties used
by the Finder, including Finder name, icon, and version info.
Note that wxnet-install reduces the clutter of all
the various wxWidgets library version symlinks by running the Perl script
prune-wxw-libs that is included in the Build/MacOSX directory. Given
wxWidgets library files like:
libwx_macu_xrc-2.6.0.0.0.dylib |
(real) |
libwx_macu_xrc-2.5.dylib |
(link) |
libwx_macu_xrc-2.6.0.dylib |
(link) |
prune-wxw-libs will
delete the links and rename the actual real file to:
libwx_macu_xrc-2.6.0.dylib
which is what the loader will be looking for.
For more information about shared libraries see the
dyld manual page.
If you receive the error:
Unhandled Exception: System.DllNotFoundException: wx-c
note that this can mean either wx-c.dylib or one
of the wxWidgets shared libraries could not be found. The closest thing
on the Mac to the Linux LD_DEBUG environment variable is DYLD_PRINT_LIBRARIES and DYLD_PRINT_LIBRARIES_POST_LAUNCH . Unlike LD_DEBUG , however, they
only print out when a library load after it
has occurred, not before. So it is not that useful in diagnosing a problem
finding a shared library.
But it still yields some useful information. An example:
DYLD_PRINT_LIBRARIES_POST_LAUNCH=1 mono minimal.exe
Windows
Windows will automatically look in the current working
directory for the wx-c.dll library. After this it will search the Windows
system folder.
Recommendations:
- On your development system, copy
wx-c.dll to your system
folder. For example, C:\Windows\System32 .
- In an install package, install
wx.NET.dll , wx-c.dll ,
and your assemblies to a common bin folder.
Last changed on $Date: 2005/07/25 05:15:16 $ by $Author: t9mike
$ • Original Author: Michael S. Muegel
|