This is the mail archive of the cygwin@sourceware.cygnus.com mailing list for the Cygwin project. See the Cygwin home page for more information.
[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

Re: .lib files to .a



"Russell K. Thompson II" wrote:
> 
>         I know there is a section on this topic on the FAQ however I do not
> fully understand it.  I want to convert the .lib files for glut and
> opengl. I tried a method I found searching the list archive but it did
> not work for me.  It suggested using nm to create a .def file and then
> using dlltool to create the library file.  But when I tried this I got
> syntax errors from dlltool.

I am in the process of enhancing libtool so that it can create a def
file and cygwin .a library on the fly for linking dlls (i.e. you don't
even need the .lib file).  The guts of this process is a short program
adapted from DJ Delories similar work for gld which I have attached.

Compile the attached program and run it with the dll as an argument and
redirect the output to a file, say opengl.def, and then use dlltool as
follows:

  dlltool --dllname /path/to/opengl.dll --def /path/to/opengl.def \
--output-lib opengl.a

When you link a program with the newly created import library (.a file),
it will load the associated dll when it is executed.

Please report any problems to me if you have an interest in seeing this
work in an upcoming release of libtool...

Cheers,
	Gary V. Vaughan
#include <stdio.h>		/* for printf() */
#include <unistd.h>		/* for open(), lseek(), read() */
#include <fcntl.h>		/* for O_RDONLY, O_BINARY */
#include <string.h>		/* for strdup() */

static unsigned int
pe_get16 (fd, offset)
     int fd;
     int offset;
{
  unsigned char b[2];
  lseek (fd, offset, SEEK_SET);
  read (fd, b, 2);
  return b[0] + (b[1]<<8);
}

static unsigned int
pe_get32 (fd, offset)
    int fd;
    int offset;
{
  unsigned char b[4];
  lseek (fd, offset, SEEK_SET);
  read (fd, b, 4);
  return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
}

static unsigned int
pe_as32 (ptr)
     void *ptr;
{
  unsigned char *b = ptr;
  return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
}

int
main (argc, argv)
    int argc;
    char *argv[];
{
    int dll;
    unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
    unsigned long export_rva, export_size, nsections, secptr, expptr;
    unsigned long name_rvas, nexp;
    unsigned char *expdata, *erva;
    char *filename, *dll_name;

    filename = argv[1];

    dll = open(filename, O_RDONLY|O_BINARY);
    if (!dll)
	return 1;

    dll_name = filename;
    
    for (i=0; filename[i]; i++)
	if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
	    dll_name = filename + i +1;

    pe_header_offset = pe_get32 (dll, 0x3c);
    opthdr_ofs = pe_header_offset + 4 + 20;
    num_entries = pe_get32 (dll, opthdr_ofs + 92);

    if (num_entries < 1) /* no exports */
	return 1;

    export_rva = pe_get32 (dll, opthdr_ofs + 96);
    export_size = pe_get32 (dll, opthdr_ofs + 100);
    nsections = pe_get16 (dll, pe_header_offset + 4 +2);
    secptr = (pe_header_offset + 4 + 20 +
	      pe_get16 (dll, pe_header_offset + 4 + 16));

    expptr = 0;
    for (i = 0; i < nsections; i++)
    {
	char sname[8];
	unsigned long secptr1 = secptr + 40 * i;
	unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
	unsigned long vsize = pe_get32 (dll, secptr1 + 16);
	unsigned long fptr = pe_get32 (dll, secptr1 + 20);
	lseek(dll, secptr1, SEEK_SET);
	read(dll, sname, 8);
	if (vaddr <= export_rva && vaddr+vsize > export_rva)
	{
	    expptr = fptr + (export_rva - vaddr);
	    if (export_rva + export_size > vaddr + vsize)
		export_size = vsize - (export_rva - vaddr);
	    break;
	}
    }

    expdata = (unsigned char*)malloc(export_size);
    lseek (dll, expptr, SEEK_SET);
    read (dll, expdata, export_size);
    erva = expdata - export_rva;

    nexp = pe_as32 (expdata+24);
    name_rvas = pe_as32 (expdata+32);

    printf ("EXPORTS\n");
    for (i = 0; i<nexp; i++)
    {
	unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
	printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
    }

    return 0;
}

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com