Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Modules under Cygwin



I'm currently playing with Zsh under Cygwin (the latest Net release). So
far, it looks promising; of course, modules fail.

Cygwin supports dynamic loading, dlopen() & friends (and even
LD_LIBRARY_PATH), but in not very fiendly manner. From the Cygwin users
guide (I am sorry, if I repeat already known - but I thought, I better
quote it in full):

===

DLLs are Dynamic Link Libraries, which means that they're linked into
your program at run time instead of build time. There are three parts to
a DLL:


the exports

the code and data

the import library

The code and data are the parts you write - functions, variables, etc.
All these are merged together, like if you were building one big object
files, and put into the dll. They are not put into your .exe at all.

The exports contains a list of functions and variables that the dll
makes available to other programs. Think of this as the list of "global"
symbols, the rest being hidden. Normally, you'd create this list by hand
with a text editor, but it's possible to do it automatically from the
list of functions in your code. The dlltool program creates the exports
section of the dll from your text file of exported symbols.

The import library is a regular UNIX-like .a library, but it only
contains the tiny bit of information needed to tell the OS how your
program interacts with ("imports") the dll. This information is linked
into your .exe. This is also generated by dlltool.


=== and a bit later what is needed to really build DLL

OK, let's go through a simple example of how to build a dll. For this
example, we'll use a single file myprog.c for the program (myprog.exe)
and a single file mydll.c for the contents of the dll (mydll.dll).

Now compile everything to objects:

gcc -c myprog.c
gcc -c mydll.c


Unfortunately, the process for building a dll is, well, convoluted. You
have to run five commands, like this:

gcc -s -Wl,--base-file,mydll.base -o mydll.dll
mydll.o -Wl,-e,_mydll_init@12
dlltool --base-file mydll.base --def mydll.def --output-exp
mydll.exp --dllname mydll.dll
gcc -s -Wl,--base-file,mydll.base,mydll.exp -o mydll.dll
mydll.o -Wl,-e,_mydll_init@12
dlltool --base-file mydll.base --def mydll.def --output-exp
mydll.exp --dllname mydll.dll
gcc -Wl,mydll.exp -o mydll.dll mydll.o -Wl,-e,_mydll_init@12


The extra steps give dlltool the opportunity to generate the extra
sections (exports and relocation) that a dll needs. After this, you
build the import library:

dlltool --def mydll.def --dllname mydll.dll --output-lib mydll.a


Now, when you build your program, you link against the import library:

gcc -o myprog myprog.o mydll.a


Note that we linked with -e _mydll_init@12. This tells the OS what the
DLL's "entry point" is, and this is a special function that coordinates
bringing the dll to life withing the OS. The minimum function looks like
this:

#include <windows.h>

int WINAPI
mydll_init(HANDLE h, DWORD reason, void *foo)
{
  return 1;
}

===


So, in respect to Zsh, it means:

1. special dummy function in every module
2. special build process
3. linking final binary against these *.a libraries

The 1. is trivial; but 2. and 3. not. For 2. we probably can simply do
explicit check for Cygwin (I hope, this is the only so convoluted
plattform). For 3. I am not sure; may be, the best bet is to create all
*.a files in separate directory so that we have a single -L option.

I have yet to check, if Cygwin supports LD_RUN_PATH (or whatever) as
well.

-andrej

Have a nice DOS!
B >>



Messages sorted by: Reverse Date, Date, Thread, Author