Subject: Re: bug#13414: Valid DLL def file mangled by libtool

From: Peter Rosin <[email-masked]>
Date: Fri, 18 Jan 2013 11:29:43 +0100

On 2013-01-16 16:03, Earnie Boyd wrote:
> On Mon, Jan 14, 2013 at 9:13 AM, Peter Rosin wrote:
>> On 2013-01-13 16:56, Earnie Boyd wrote:
>>> On Fri, Jan 11, 2013 at 7:26 PM, Peter Rosin wrote:
>>>>         $SED -n \
>>>>             -e '/^[     ]*//' \
>>>>             -e '/^;/D' \
>>>>             -e '/^$/D' \
>>>>             -e 's/^EXPORTS.*/DEF/p' \
>>>>             -e 's/^LIBRARY.*/DEF/p' \
>>>>             -e q \
>>>>             $export_symbols

After some experimenting, I now have:

	$SED -n \
	    -e 's/^[ 	]*//' \
	    -e '/^\(;.*\)*$/d' \
	    -e 's/^\(EXPORTS\|LIBRARY\)\([ 	].*\)*$/DEF/p' \
	    -e q \
	    $export_symbols

>> I'm using libtool with MSVC, but I have never used a LIBRARY statement
>> myself.
>>
> 
> This alone is enough for libtool to consider it.

Consider what? Did you forget a negation?

>>> I.E.: The file containing LIBRARY tells the link command to create a
>>> DLL and the import library file (unless a .exp file is also used) but
>>> only if the /DLL switch is used.
>>
>> I don't understand this, I thought the /DLL switch accomplished most of
>> that by itself? I thought LIBRARY only provided the library name, which
>> can also be specified on the command line (using the -Fe option to cl.exe
>> or the -OUT option to link.exe). Since the command line overrides the
>> LIBRARY statement, it seems a bit useless from the libtool p.o.v. as
>> libtool is always providing the library name on the command line. No?
>>
> 
> So even though it exists it should be pretty much meaningless to libtool.

I did some tests to see how LIBRARY affects things and it turns out it
is not meaningless. What the MSDN documentation appears to mean is that
if you do not specify any library name on the command line, the LIBRARY
statements set the name of the DLL file. But the name referred to inside
the import library will always be the name provided with the LIBRARY
statement, regardless of any command line options.

I.e., when libtool is called like this:

	./libtool --mode=link ./compile cl foo.lo -o foo.la \
	-no-undefined -rpath /nowhere

the relevant parts (after going through a bunch of layers) with a
libtool configured for MSVC is:

	cl .libs/foo.obj -Fe.libs/foo-0.dll \
	-link -dll -implib:.libs/foo.dll.lib

(which means, link foo.obj into a -dll named foo-0.dll and also generate
an import library named foo.dll.lib)

If you then mix in a .def file starting with

	LIBRARY bar

you will get the same names of the files (foo-0.dll and foo.dll.lib), but
executables linked with foo.dll.lib will require the non-existing bar.dll
at runtime.

Similarly, the relevant parts with a libtool configured for GNU is:

	gcc -shared .libs/a.o -o .libs/cyga-0.dll \
	-Xlinker --out-implib -Xlinker .libs/liba.dll.a

and mixing in a .def file starting with

	LIBRARY bar

seems to have the same effect here, namely still create a cyga-0.dll
and an import lib liba.dll.a, but executables linked with liba.dll.a
will request bar.dll at runtime.

So, the LIBRARY statement does have an effect (not that you can currently
use it with libtool, I had to patch things to make it work for the
above tests) but I'm not sure how you can make any sane use of the
feature. I mean, whats the point of referring to a non-existant dll?
I guess you can rename the .dll file manually as a post-processing
step so that the import library is pointing to something that exists,
but that seems a bit convoluted.

>> To me, this is only about libtool recognizing preexisting .def files
>> that are written without libtool in mind (or at least, not with only
>> libtool in mind), and not about supporting constructs in .def that are
>> actually needed by libtool. From the libtool side, the .def file needs
>> to (currently) start with EXPORTS, and since LIBRARY (and NAME)
>> statements are of no use to libtool they might just as well be zapped
>> so that EXPORTS actually is first. But if you want to use the same .def
>> file from a non-libtool setting, you might have some very good reason
>> to include LIBRARY (or NAME) in it, and then you'd want to have that
>> as the first statement (according to MSDN). But that kills things in
>> libtool, since it then prepends a faulty EXPORTS to the .def file (it's
>> wrongly assuming that the perfectly fine .def file is a plain symbol
>> list when the file doesn't start with EXPORTS).
> 
> There can be only one LIBRARY statement and it must be on the first
> non-empty line of the file.
> 
> However from http://msdn.microsoft.com/en-us/library/hyx1zcd3(v=vs.71).aspx
> we see:
> 
> The EXPORTS statement introduces a section of one or more definitions
> that are exported functions or data. Each definition must be on a
> separate line. The EXPORTS keyword can be on the same line as the
> first definition or on a preceding line. The .def file can contain one
> or more EXPORTS statements.

This .def file seems to work just fine to export a "v1" data item and
a "v2" function using GNU tools:

	EXPORT v1 DATA v2

But the MSVC linker barf and wants one symbol per line, e.g. like this

	EXPORT v1 DATA
	v2

When reading the MSDN about .def files, I agree with the GNU interpretation,
but I have found MSDN to be lacking in a great many places, so one should
never put more than one symbol on one line I suppose...

> Notice the last sentence of the quote.  Also notice that the first
> definition can be on the same line as the EXPORTS keyword.

Yes, I saw that.

Cheers,
Peter