lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Sometime on 9/5/2008, "RJP Computing" <> wrote:
>On Thu, Sep 4, 2008 at 5:49 PM, Ross Berteig wrote:
>> ....
>> In my projects, I follow Steve's list of functions to alias with
>> macros at compile time, and use a link line that ends with:
>>        $(LUADLL) -lgcc -lmsvcr80 $(MSVCR80)
>> ....
>How come you need  -lmsvcr80 and $(MSVCR80)? shouldn't $(MSVCR80)
>be enough? Can you explain a bit more?

Either could have been sufficient, but gcc doesn't seem to get
the linkage even remotely right without any reference to
libmsvcr80.a. If only MSVCR80.DLL is on the link line, the link
has actually satisfied all CRT symbols from MSVCRT.DLL and nearly
completely ignored MSVCR80.DLL.

The 19 functions identified by Steve all have the property that
they are documented in the MSDN with names of the form foo()
along with a companion function named _foo64(), but the functions
actually exported by MSVCR80.DLL are named _foo32() and _foo64().
Unfortunately, MSVCRT.DLL which is linked by libc.a (and/or
libmsvcrt.a) *does* export a function named foo(). Any code which
uses one of those functions (I needed mktime() most recently)
then gets at least part of its runtime from the wrong DLL.

Steve's kludge simply uses #define to map each foo() to _foo32()
at compile time, but now _foo32() is not an exported symbol of
any library in the link unless MSVCR80.DLL is explicitly included.

Even when not touching any of the 19 functions (which must be
aliased in VisualStudio's MSVCR80.LIB to the names actually
exported by the DLL), libgcc.a makes reference to abort(),
_assert(), and memset() and if it is named after libmsvr80.a in
the link command then it seems to get those symbols from
libmsvcrt.a instead. The reliable solution is to move libgcc.a
ahead of libmsvcr80.a in the link line. Alternatively, if the
code being linked itself already references each of those three
symbols then they will be properly satisfied by libmsvr80.a and
all is well.

>>.... I suppose I ought to go put this into the wiki page... (see
>Please add this. I would like to study this. I would prefer to
>use the GCC toolchain.

I added the basic recipe I've worked out to that wiki page. The
real lesson is that if binary compatibility is required (i.e.
when building a DLL for use with LfW) then the builder is
obligated to make certain that binary compatibility is actually
achieved. Dependency Walker is one way to validate that now
unintended dependencies are created. Regression testing is also a
good idea ;-)

One other caution is that executables (both .EXE and .DLL
flavors) built by VS will now (since VC7 I think) include a
manifest in their resource fork. The manifest is written for you
by VisualStudio unless you sieze manual control over it. That
manifest will make a "proper" reference to the C runtime as a
Side by Side assembly.

There are no tools in MinGW that handle that automatically, but
you can write the correct manifest "by hand" along with a
resource script that refers to it. I'll work out the details and
update the wiki page to include that bit of complication.

With the proper manifest, then the C runtime will be
automatically found in the SxS assembly cache and properly
maintained by Windows Update. Lua5.1.dll from LfW has such a
manifest, as does every other DLL they distribute that I checked.

If building and distributing your own application, you would then
be obligated to redistribute the C runtime (probably via
vcredist_x86.exe). However, if you are only building and
distributing components for use with another application, you
have luxury of assuming that the application took care of
installing the C runtime for you, as long as you arrange to use
the *very same* runtime.

>> ....
>Yes this dependency should not be forced on Windows. The rocks that >are available should be built and hosted as binaries that link to the
>VC8 CRT. Thoughts?

Exactly. I do worry about how to future-proof this against the
inevitable move to VC9 or VC10's CRT down the road. I get the
impression that LR's module versioning was not really meant for
that purpose. A separate rocks repository for each runtime might
be the right approach. That is probably a discussion better held
over at the LR list since we are already way off topic here... ;-)

Ross Berteig                     
Cheshire Engineering Corp.