Creating A WxWidgets DLL In Linux

From WxWiki
Jump to: navigation, search

Creating a wxWidgets DLL in Linux, Cygwin or MSYS/MinGW

To create a wxWidgets DLL for Linux, MSYS/MinGW or Cygwin is actually relatively easy. For this example, you'll need either a Linux-based computer, Cygwin, or MSYS with the MSYS Developer Tool Kit. That is because I use the tools autoconf, automake and libtool.

Now the first step in this is to create the files. For this tutorial we'll create a class Test derived from wxObject.

Let's create the header file:

 #ifndef TESTDLL_H
 #define TESTDLL_H
 
 #include <wx/dlimpexp.h>
 
 #ifdef TEST_CREATING_DLL
 	#define TEST_EXPORT WXEXPORT
 #else
 	#define TEST_EXPORT WXIMPORT
 #endif
 
 /**
 Just testing external libraries and DLLs on Linux.
 */
 class TEST_EXPORT TestDll : public wxObject
 {
 public:
     TestDll();
 
     ~TestDll();
     void Test();
 
 };
 
 #endif

Now, I'll explain each part. The first two lines simply make sure that the class header file is only loaded once. The third line includes the wxWidgets DLL import and export macros. The fourth through eighth lines define our macro for the class. On Windows machines, you have to declare a class with two special identifiers commonly __declspec(dllexport) for creating the DLL, and __declspec(dllimport) for loading the DLL. Luckily, wxWidgets takes care of the compiler differences for us, and gives us the two macros WXEXPORT and WXIMPORT which expand out correctly for what ever compiler is being used. Now the #ifdef switch looks for a macro which will be defined at compile time. If the macro is not defined, then we're likely importing the library, if it is defined, then we're exporting or creating the library. This defines our own little macro TEST_EXPORT which will expand out when we compile based on WXEXPORT and WXIMPORT.

Now the next few lines are the class declaration, which there's only one thing special about. We use the macro we just declared right after the class statement and before our class declaration. The rest of the class is declared as usual. There's nothing different with the C++ part of the class either.

Now, for the autoconf file. Well create a directory (test) and add some directories within (mainly being 'src'). In the base directory, we'll create a file 'configure.in' (which I won't explain, but I will recommend GNU Autoconf, Automake and Libtool by Gary V. Vaughan, Ben Elliston, Tom Tromey, and Ian Lance Taylor under the Open Publication Liscense, available on the web at http://sources.redhat.com/autobook/). There is one thing special to add to the configure.in file. In there, you'll need to add to you're CPP_FLAGS and CXX_FLAGS �-DTEST_CREATING_DLL=1�. Then we'll create the Automake file (Makefile.am). Again, for information, I'll defer to the same book. Next we'll create another Makefile.am, this time in the source directory. This one is special, though. The contents of the file are as follows:

lib_LTLIBRARIES = libtestdll.la

libtestdll_la_LDFLAGS = -no-undefined $(WX_LIBS)

libtestdll_la_SOURCES = testdll.cpp include_HEADERS = testdll.h

What's special here is that we're declaring that we're creating a library of the files. On Linux, this will create libtestdll.so, and on windows, it'll create libtestdll.dll. And on wxWidgets supported platforms that for one reason or another don't support shared libraries, this will create a static library of the file.

We'll go ahead and create a directory test. Again, we'll create a configure.in file and Makefile.am file, and src directory. In the source directory, we'll include the header file of the library in our C++ source. Next, we'll create the Makefile.am for the src directory, like so:

noinst_HEADERS = test.h

bin_PROGRAMS = test

test_SOURCES = test.cpp test_LDFLAGS = $(WX_LIBS)

test_LDADD = -ltestdll

The only difference here is that we're linking to the shared library. This will link to libtestdll.a on Msys and Cygwin, while it'll link to libtestdll.so on Linux. On those platforms that don't understand shared libraries, it will link to the static library of libtestdll.

To get the sources of this example, download http://www.packhouse.org/test.tar.gz and http://www.packhouse.org/libtestlib.tar.gz.