jabberd 1.4.3 will be released the next days. It's a maintenance release including some fixes and several features. http://jabberd.jabberstudio.org/1.4/release-1.4.3.shtml
Please check out the jabberd14 HEAD code from CVS for testing and post comments here.
Maqi,
Hope it's ok that I post this updated info here, but figured anyone out there considering doing modules/plugins might care to know what I've discovered (though odds are you all knew this already).
In short, attached here are submissions for newly updated Makefiles for Jabberd v1.4.3, including a diff file--jabberd143.diff--generated with 'cvs diff -u'...hope I did that right, and a tar/gz file--newMakes.tar.gz--containing the full Makefiles in case the diff file is no good.These Makefiles are much streamlined compared to my last submission, as I've learned that my hack was doing things "the old way."
End result:
* cleaner Makefiles--only differences between Cygwin build and
*nix build of dynamic libraries--beyond the file extension
.dll vs. .so respectively--is the compile line itself. * elimination on the dependence/need for ./cygwin/dllinit.c
(though I'd suggest leaving it in 1.4.3 just...in...case). * compiled modules that are 30-50% SMALLER than before (in
a few cases, over 50%)!!I have set up two different Windows XP Pro boxes with Cygwin, built Jabberd 1.4.3 from CVS as of today (6Nov2003), and tested communications from 1-on-1 chat to JUD lookups to MU-Conference to s2s communications. I even fired up a Jabber client which I connected to an account at Rhymbox.com, then chatted with myself via an account on one of the two servers. Yeah, it's so bad I'm talking to myself...again. :-)
With this last submission (and respective submissions to the authors of JUD, MU-C, xdb_ldap, and xdb_sql), I think I'm finished.
____________________________________________________________ MORE DETAIL FOR THOSE SO INCLINED
[Rather long, so get caffeine or skip if not interested.]
I achieved my original hack using various information, including that on the Cygwin FAQ page at
http://cygwin.com/faq/faq_4.html#SEC109
As you can see, this page indicates it's out-of-date (though I don't recall seeing that message when I read it awhile ago).
The basic process was an ugly one, but it all revolves around the same fundamental principles involved when working on dynamic libraries. Typically, in order to build an application which relies on dynamic libraries, you write the main code and link in stub files (in *nix, these tend to be lib<modulename>.a files). These stub files are to dynamic libraries what .h files are to .c files in many cases: they provide the linker with enough information to resolve functions/etc. in your main code so that your program will link into an executable. At runtime, the OS will then "hook in" the matching dynamic library (again, in *nix these tend to be lib<modulename>.so files), making the functionality of that library available to your running program.
However, dynamic libraries are built/handled differently by different OSes. Since Jabberd was built "the Unix way", let's look at that first. When you compile a dynamic library in Linux, for example, a lot of the dirty work is done by gcc and ld. For example, even though libraries must somehow "export" a list of functions/variables that are accessible to the calling program, you don't really have to do much as the programmer to make this happen. You just type the appropriate gcc/ld switches on the command line, and magically all that is done for you.
Windows is not quite so elegant, howver, and when it comes to Cygwin and trying to build *nix style libraries under Windows, it gets messy. Windows calls these files Dynamic Link Libraries (DLLs), and their file extension is just that, ".DLL". That's a cosmetic difference.
OLD WAY
But up until the more recent net release of Cygwin, building such DLLs under Cygwin was a royal pain. You had to manually build the DEFinition list of EXPORTed functions/etc., then take extra steps to basically "wrap" this information around your *nix dynamic library. The procedure went something like this:
* Create a .DEF text file containing the list of EXPORTed
functions a library offered.
* run a special "wrapper" command which would wrap this
information around your library so that, when compiled into a
.DLL, it would work correctly.The trick is, how do you build the .DEF file and what are the special commands?
The .DEF file is just a text file of the form
____________________
EXPORT
function1
function2
...
____________________where the first line literally says "EXPORT", and the functions/etc. the library offers are written one per line after that. Often (as was done in Jabberd 1.4.2's Cygwin code), these .DEF files were made by hand, which gave the programmer control over what functions were "visible" outside the library (for you C++ types, this is similar to public vs. private methods).
However, a tool named 'nm' does exist in Cygwin which will automatically list all the symbols in given object files, letting you automate that step in the process. But it does require organizing the output from 'nm' to match what is expected in a .DEF file.
Next up is the tool which takes the .DEF file and object code, links everything together and builds the library. This is 'dlltool'. However, to speed up the process, another tool exists called 'dllwrap' which uses 'dlltool' by default, saving you a bit of work.
As an example of how this works, here is the relevant portion of the Jabberd dialback module Makefile, as it was written by me originally so Jabberd compiled under Cygwin:
________________________________________
ifeq ($(__CYGWIN__),1)
# Make .def file:
echo EXPORTS > dialback.def
nm $(dialback_OBJECTS) $(PTHLIB) | grep '^........ [T] _' | \
sed 's/[^_]*_//' | sort >> dialback.def
dllwrap --def dialback.def --driver-name $(CC) -o dialback.dll\
$(dialback_OBJECTS) ../jabberd/jabberd.a $(LDFLAGS) \
$(LIBS)
else
$(CC) $(CFLAGS) $(MCFLAGS) -o dialback.so $(dialback_OBJECTS) \
$(LDFLAGS) $(LIBS)
endif
________________________________________
NEW WAY
As it turns out, this is no longer necessary, as the gcc folks have added a wonderful switch called '-shared' that works under Cygwin just as it does elsewhere, allowing the creation of shared libraries to be much more painless. Now, in short, the above can be reduced to just
________________________________________
ifeq ($(__CYGWIN__),1)
$(CC) $(CFLAGS) $(MCFLAGS) -o dialback.dll $(dialback_OBJECTS) \
../jabberd/jabberd.a $(LDFLAGS) $(LIBS)
else
$(CC) $(CFLAGS) $(MCFLAGS) -o dialback.so $(dialback_OBJECTS) \
$(LDFLAGS) $(LIBS)
endif
________________________________________NOTE: Since "MCFLAGS = -shared" in ./platform-settings, we did not
need to set that explicitly. Otherwise we would have simply
added that to the list of compiler switches.Notice in the above revised section that the only difference, besides the file extension of the library, is one additional object called "../jabberd/jabberd.a". This brings us to the one crux in developing in Cygwin currently.
MAIN EXECUTABLES SHARING SYMBOLS
The 'jabberd.a' file looks like a stub file because it is. However, there is no jabberd.so or jabberd.dll in the ./jabberd directory. That 'jabberd.a' file is actually a stub file for the main executable, 'jabberd.exe'! This is due to the modular/plugin nature of the Jabberd program.
When you think of how Jabberd works, with the various modules like jsm and dialback hooked into the main server via the jabber.xml configuration file, it becomes clear that the server process "hooks into" the modules. This is how it is with most dynamic libraries. However, unlike more common coding, there are also times when the modules interact with the server processes functions/variables, and this requires that the modules can "see" the executables symbols just as the executable can see theirs. [Think Netscape/Mozilla with plugins, for example.]
In *nix this isn't much of an issue, as compiling an executable and exporting its symbols takes no more effort than doing so with libraries. Unfortunately, at least at this point, 'ld' under Cygwin doesn't work that way. It seems that you can EITHER
1. build an executable, or
2. build a shared library with its matching .a stub file.You cannot do both.
If you try to pass linker options on the compiler line as you might in *nix, attempting to build an executable AND a stub file, things just don't work right.
$(CC) -shared -o library.dll -Wl,--out-implib,liblibrary.dll.a
is the usual way to build a library and matching stub, and this works. However,
$(CC) -shared -o program.exe -Wl,--out-implib,program.a
currently results in 'program.exe' and 'program.a' being generated, but 'program.exe' isn't actually an executable. It's a library! And attempts to run it fail.
$(CC) -o program.exe -Wl,--out-implib,program.a
results in a working 'program.exe', but a silent failure on creating 'program.a', so no such file exists when this command is done.
And the reason all this is necessary is so that you can compile/link the various modules like dialback, jsm, pthsock, etc., where they may be coded to hook back into the main executable. In *nix, these kinds of issues don't seem to exist as they do currently in Cygwin.
End result: For the main executable code in ./jabberd, I simply left the Makefile alone for now, using a very old way of building such things under Cygwin. Please see that Makefile or read the outdated Cygwin FAQ page for more details.
Anyway, hopefully this information might be of use to someone. I'll quit now as my fingers are a little sore :-/ and I'm getting tired. Please note, as I've stated more than once, I don't code professionally, so please go easy on the flaming if I'm way off-base here.
newMakes.tar.gz
Description: GNU Zip compressed data
Index: jabberd14/cygwin/dnsrv/Makefile
===================================================================
RCS file: /home/cvs/jabberd14/cygwin/dnsrv/Makefile,v
retrieving revision 1.2
diff -u -r1.2 Makefile
--- jabberd14/cygwin/dnsrv/Makefile 2 Nov 2003 13:36:10 -0000 1.2
+++ jabberd14/cygwin/dnsrv/Makefile 6 Nov 2003 21:01:40 -0000
@@ -3,7 +3,7 @@
CFLAGS:=$(CFLAGS) -I../jabberd/
dnsrv_HEADERS=srv_resolv.h ../jabberd/jabberd.h
-dnsrv_OBJECTS=dnsrv.o ../cygwin/dllinit.o
+dnsrv_OBJECTS=dnsrv.o
dnsrv_COOBJECTS=dnsrv_coprocess.o srv_resolv.o win32_resolv.o
jabberd_EXOBJECTS= ../jabberd/lib/xml*.o \
../jabberd/lib/hashtable.o \
@@ -23,13 +23,10 @@
dnsrv_build: $(dnsrv_OBJECTS) $(dnsrv_COOBJECTS) $(dnsrv_HEADERS)
$(CC) $(CFLAGS) -o jabadns $(dnsrv_COOBJECTS) $(jabberd_EXOBJECTS) $(XLDFLAGS)
$(LDFLAGS) $(SLIBS) $(PLINK) -liphlpapi
-# Make .def file:
- echo EXPORTS > dnsrv.def
- nm $(dnsrv_OBJECTS) $(PTHLIB) | grep '^........ [T] _' | sed 's/[^_]*_//' >>
dnsrv.def
- dllwrap --def dnsrv.def --driver-name $(CC) -o dnsrv.dll $(dnsrv_OBJECTS)
../jabberd/jabberd.a $(LDFLAGS)
+ $(CC) $(CFLAGS) $(MCFLAGS) -o dnsrv.dll $(dnsrv_OBJECTS) ../jabberd/jabberd.a
$(LDFLAGS)
static: $(dnsrv_OBJECTS) $(dnsrv_COOBJECTS) $(dnsrv_HEADERS)
$(CC) $(CFLAGS) -o jabadns $(dnsrv_COOBJECTS) $(jabberd_EXOBJECTS) $(XLDFLAGS)
$(LDFLAGS) $(SLIBS) $(PLINK) -liphlpapi
clean:
- rm -f $(dnsrv_OBJECTS) $(dnsrv_COOBJECTS) dnsrv.dll jabadns.exe *.a *.def *.exp
+ rm -f $(dnsrv_OBJECTS) $(dnsrv_COOBJECTS) dnsrv.dll jabadns.exe
Index: jabberd14/dialback/Makefile
===================================================================
RCS file: /home/cvs/jabberd14/dialback/Makefile,v
retrieving revision 1.5
diff -u -r1.5 Makefile
--- jabberd14/dialback/Makefile 3 Nov 2003 11:59:34 -0000 1.5
+++ jabberd14/dialback/Makefile 6 Nov 2003 21:01:40 -0000
@@ -7,18 +7,11 @@
dialback_in.o \
dialback_out.o
-ifeq ($(__CYGWIN__),1)
-dialback_OBJECTS+= ../cygwin/dllinit.o
-endif
-
all: dialback
dialback: $(dialback_OBJECTS)
ifeq ($(__CYGWIN__),1)
-# Make .def file:
- echo EXPORTS > dialback.def
- nm $(dialback_OBJECTS) $(PTHLIB) | grep '^........ [T] _' | sed 's/[^_]*_//' |
sort >> dialback.def
- dllwrap --def dialback.def --driver-name $(CC) -o dialback.dll
$(dialback_OBJECTS) ../jabberd/jabberd.a $(LDFLAGS) $(LIBS)
+ $(CC) $(CFLAGS) $(MCFLAGS) -o dialback.dll $(dialback_OBJECTS)
../jabberd/jabberd.a $(LDFLAGS) $(LIBS)
else
$(CC) $(CFLAGS) $(MCFLAGS) -o dialback.so $(dialback_OBJECTS) $(LDFLAGS)
$(LIBS)
endif
@@ -30,7 +23,7 @@
clean:
ifeq ($(__CYGWIN__),1)
- rm -f $(dialback_OBJECTS) dialback.dll *.a *.def *.exp
+ rm -f $(dialback_OBJECTS) dialback.dll
else
rm -f $(dialback_OBJECTS) dialback.so
endif
Index: jabberd14/jsm/Makefile
===================================================================
RCS file: /home/cvs/jabberd14/jsm/Makefile,v
retrieving revision 1.43
diff -u -r1.43 Makefile
--- jabberd14/jsm/Makefile 3 Nov 2003 11:59:37 -0000 1.43
+++ jabberd14/jsm/Makefile 6 Nov 2003 21:01:40 -0000
@@ -18,10 +18,6 @@
users.o \
util.o
-ifeq ($(__CYGWIN__),1)
-jsm_OBJECTS+= ../cygwin/dllinit.o
-endif
-
jsm_EXOBJECTS = \
modules/mod_admin.o \
modules/mod_announce.o \
@@ -58,10 +54,7 @@
all-local: $(jsm_OBJECTS) $(jsm_HEADERS)
ifeq ($(__CYGWIN__),1)
-# Make .def file:
- echo EXPORTS > jsm.def
- nm $(jsm_OBJECTS) $(jsm_EXOBJECTS) $(PTHLIB) | grep '^........ [T] _' | sed
's/[^_]*_//' | sort >> jsm.def
- dllwrap --def jsm.def --driver-name $(CC) -o jsm.dll $(jsm_OBJECTS)
$(jsm_EXOBJECTS) ../jabberd/jabberd.a $(LDFLAGS) $(LIBS) -lcrypt
+ $(CC) $(CFLAGS) $(MCFLAGS) -o jsm.dll $(jsm_OBJECTS) $(jsm_EXOBJECTS)
../jabberd/jabberd.a $(LDFLAGS) $(LIBS) -lcrypt
else
$(CC) $(CFLAGS) $(MCFLAGS) -o jsm.so $(jsm_OBJECTS) $(jsm_EXOBJECTS)
$(LDFLAGS) $(LIBS) -lcrypt
endif
@@ -95,7 +88,7 @@
clean-local:
ifeq ($(__CYGWIN__),1)
- rm -f $(jsm_OBJECTS) jsm.dll *.a *.def *.exp
+ rm -f $(jsm_OBJECTS) jsm.dll
else
rm -f $(jsm_OBJECTS) jsm.so
endif
Index: jabberd14/pthsock/Makefile
===================================================================
RCS file: /home/cvs/jabberd14/pthsock/Makefile,v
retrieving revision 1.24
diff -u -r1.24 Makefile
--- jabberd14/pthsock/Makefile 3 Nov 2003 11:59:40 -0000 1.24
+++ jabberd14/pthsock/Makefile 6 Nov 2003 21:01:40 -0000
@@ -6,10 +6,6 @@
pthsock_client_OBJECTS= client.o
-ifeq ($(__CYGWIN__),1)
-pthsock_client_OBJECTS+= ../cygwin/dllinit.o
-endif
-
single: static
all: pthsock_client
@@ -18,10 +14,7 @@
pthsock_client: $(pthsock_client_OBJECTS) $(HEADERS)
ifeq ($(__CYGWIN__),1)
-# Make .def file:
- echo EXPORTS > pthsock_client.def
- nm $(pthsock_client_OBJECTS) $(PTHLIB) | grep '^........ [T] _' | sed
's/[^_]*_//' | sort >> pthsock_client.def
- dllwrap --def pthsock_client.def --driver-name $(CC) -o pthsock_client.dll
$(pthsock_client_OBJECTS) ../jabberd/jabberd.a $(LDFLAGS) $(LIBS)
+ $(CC) $(CFLAGS) $(MCFLAGS) -o pthsock_client.dll $(pthsock_client_OBJECTS)
../jabberd/jabberd.a $(LDFLAGS) $(LIBS)
else
$(CC) $(CFLAGS) $(MCFLAGS) -o pthsock_client.so $(pthsock_client_OBJECTS)
$(LDFLAGS) $(LIBS)
endif
@@ -30,7 +23,7 @@
clean:
ifeq ($(__CYGWIN__),1)
- rm -f $(pthsock_client_OBJECTS) pthsock_client.dll *.a *.def *.exp
+ rm -f $(pthsock_client_OBJECTS) pthsock_client.dll
else
rm -f $(pthsock_client_OBJECTS) pthsock_client.so
endif
Index: jabberd14/xdb_file/Makefile
===================================================================
RCS file: /home/cvs/jabberd14/xdb_file/Makefile,v
retrieving revision 1.12
diff -u -r1.12 Makefile
--- jabberd14/xdb_file/Makefile 3 Nov 2003 11:59:42 -0000 1.12
+++ jabberd14/xdb_file/Makefile 6 Nov 2003 21:01:40 -0000
@@ -4,20 +4,13 @@
xdb_file_OBJECTS= xdb_file.o
-ifeq ($(__CYGWIN__),1)
-xdb_file_OBJECTS+= ../cygwin/dllinit.o
-endif
-
single: static
all: xdb_file
xdb_file: $(xdb_file_OBJECTS)
ifeq ($(__CYGWIN__),1)
-# Make .def file:
- echo EXPORTS > xdb_file.def
- nm $(xdb_file_OBJECTS) $(PTHLIB) | grep '^........ [T] _' | sed 's/[^_]*_//' |
sort >> xdb_file.def
- dllwrap --def xdb_file.def --driver-name $(CC) -o xdb_file.dll
$(xdb_file_OBJECTS) ../jabberd/jabberd.a $(LDFLAGS) $(LIBS)
+ $(CC) $(CFLAGS) $(MCFLAGS) -o xdb_file.dll $(xdb_file_OBJECTS)
../jabberd/jabberd.a $(LDFLAGS) $(LIBS)
else
$(CC) $(CFLAGS) $(MCFLAGS) -o xdb_file.so $(xdb_file_OBJECTS) $(LDFLAGS)
$(LIBS)
endif
@@ -26,7 +19,7 @@
clean:
ifeq ($(__CYGWIN__),1)
- rm -f $(xdb_file_OBJECTS) xdb_file.dll *.a *.def *.exp
+ rm -f $(xdb_file_OBJECTS) xdb_file.dll
else
rm -f $(xdb_file_OBJECTS) xdb_file.so
endif
