Subject: Re: Apologies
From: [email-masked]

20 Feb 1998 20:25:52 -0800
Message-ID: <[email-masked]>
References: <[email-masked]>
To: [email-masked]
Cc: [email-masked], [email-masked]

>   Every week there is somebody that points that the example in the cygnus
>   page copied verbatim will not work. What makes me mad, is that either the
>   example DOES work, and then you put it in the FAQ (or better in the page
>   itself) HOW TO MAKE IT WORK, or either it DOESN'T, then you take that
>   page away! But I am getting mad again.

This is what I do to create a DLL with correct relocation
information.  This example is taken from the Tcl Makefile which will
be included with the b19 release.

Geoff, perhaps you could include something like this in the FAQ.

IMPORTANT NOTE: I have not tested this with b18.  I don't even have
b18 loaded.  I have only tested it with the upcoming b19 release.

You must execute the following sequence of five commands, in this
order:

	$(LD) -s --base-file BASEFILE --dll -o DLLNAME OBJS LIBS -e ENTRY

	$(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE --base-file BASEFILE --output-exp EXPFILE

	$(LD) -s --base-file BASEFILE EXPFILE -dll -o DLLNAME OBJS LIBS -e ENTRY

	$(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE --base-file BASEFILE --output-exp EXPFILE

	$(LD) EXPFILE --dll -o DLLNAME OBJS LIBS -e ENTRY

$(LD) is the linker, ld.

$(DLLTOOL) is dlltool.

$(AS) is the assembler, as.

DLLNAME is the name of the DLL you want to create, e.g., tcl80.dll.

OBJS is the list of object files you want to put into the DLL.

LIBS is the list of libraries you want to link the DLL against.  For
example, you may or may not want -lcygwin.  You may want -lkernel32.
Tcl links against -lcygwin -ladvapi32 -luser32 -lgdi32 -lcomdlg32
-lkernel32.

DEFFILE is the name of your definitions file.  A simple DEFFILE would
consist of ``EXPORTS'' followed by a list of all symbols which should
be exported from the DLL.  Each symbol should be on a line by itself.
Other programs will only be able to access the listed symbols.

BASEFILE is a temporary file that is used during this five stage
process, e.g., tcl.base.

EXPFILE is another temporary file, e.g., tcl.exp.

ENTRY is the name of the function which you want to use as the entry
point.  This function should be defined using the WINAPI attribute,
and should take three arguments:
    int WINAPI startup (HINSTANCE, DWORD, LPVOID)
This means that the actual symbol name will have an appended @12, so
if your entry point really is named startup, the string you should use
for ENTRY in the above examples would be entry@12.

If your DLL calls any cygwin32 functions, the entry function will need
to initialize the cygwin32 impure pointer.  You can do that by
declaring a globale variable _impure_ptr, and then initializing it in
the entry function.  Be careful not to export the global variable
_impure_ptr from your DLL; that is, do not put it in DEFFILE.

/* This is a global variable.  */
struct _reent *_impure_ptr;
extern struct _reent *__imp_reent_data;

int entry (HINSTANT hinst, DWORD reason, LPVOID reserved)
{
  _impure_ptr = __imp_reent_data;
  /* Whatever else you want to do.  */
}

You may put an optional `--subsystem windows' on the $(LD) lines.  The
Tcl build does this, but I admit that I no longer remember whether
this is important.

You may put an optional `--image-base BASEADDR' on the $(LD) lines.
This will set the default image base.  Programs using this DLL will
start up a bit faster if each DLL occupies a different portion of the
address space.  Each DLL starts at the image base, and continues for
whatever size it occupies.

Now that you've built your DLL, you may want to build a library so
that other programs can link against it.  This is not required: you
could always use the DLL via LoadLibrary.  However, if you want to be
able to link directly against the DLL, you need to create a library.
Do that like this:

	$(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE --output-lib LIBFILE

$(DLLTOOL), $(AS), DLLNAME, and DEFFILE are the same as above.  Make
sure you use the same DLLNAME and DEFFILE, or things won't work right.

LIBFILE is the name of the library you want to create, e.g.,
libtcl80.a.  You can then link against that library using something
like -ltcl80 in your linker command.

Ian
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".