зеркало из https://github.com/github/putty.git
Makefile.clangcl: provide a way to tell lld-link about crt0.obj.
I've been experimenting with using clang-cl with older versions of the Visual Studio libraries and headers, and found that the older VS libraries have a quirk which can cause link failure in a way that doesn't happen with the newer one. I assume the corresponding old VS linker must be doing some kind of special-case handling that lld isn't mimicking. The quirk arises because lld tries to pull in more than one of the *crt0.obj startup objects which set things up before calling main or WinMain (or whatever), and those objects define some of the same symbols as each other. The fix is to explicitly ask for the right one of those objects on the link command line, so that it's already been loaded _before_ the linker starts searching libraries for unresolved symbols; then the disputed symbols are never unresolved in the first place during the library search phase. But this means you have to pick your crt0 object differently depending on which subsystem you're compiling for. Accordingly, here's an extra feature in Makefile.clangcl to make that possible by means of the right definitions on the make command line.
This commit is contained in:
Родитель
8d2755c55f
Коммит
f02587f7ac
28
mkfiles.pl
28
mkfiles.pl
|
@ -492,6 +492,31 @@ if (defined $makefiles{'clangcl'}) {
|
|||
# paths in $LIB) it's reasonable to have the choice of
|
||||
# compilation target driven by another environment variable
|
||||
# set in parallel with that one.
|
||||
# - for older versions of the VS libraries you may also have to
|
||||
# set EXTRA_console and/or EXTRA_windows to the name of an
|
||||
# object file manually extracted from one of those libraries.
|
||||
# * This is because old VS seems to manage its startup code by
|
||||
# having libcmt.lib contain lots of *crt0.obj objects, one
|
||||
# for each possible user entry point (main, WinMain and the
|
||||
# wide-char versions of both), of which the linker arranges
|
||||
# to include the right one by special-case code. But lld
|
||||
# only seems to mimic half of that code - it does include
|
||||
# the right crt0 object, but it doesn't also deliberately
|
||||
# _avoid_ including the _wrong_ ones, and since all those
|
||||
# objects define a common set of global symbols for other
|
||||
# parts of the library to use, lld may well select an
|
||||
# arbitrary one of them the first time it sees a reference
|
||||
# to one of those global symbols, and then later also select
|
||||
# the _right_ one for the application's entry point, causing
|
||||
# a multiple-definitions crash.
|
||||
# * So the workaround is to explicitly include the right
|
||||
# *crt0.obj file on the linker command line before lld even
|
||||
# begins searching libraries. Hence, for a console
|
||||
# application, you might extract crt0.obj from the library
|
||||
# in question and set EXTRA_console=crt0.obj, and for a GUI
|
||||
# application, do the same with wincrt0.obj. Then this
|
||||
# makefile will include the right one of those objects
|
||||
# alongside the matching /subsystem linker option.
|
||||
|
||||
open OUT, ">$makefiles{'clangcl'}"; select OUT;
|
||||
print
|
||||
|
@ -539,7 +564,8 @@ if (defined $makefiles{'clangcl'}) {
|
|||
print &splitline("\t\$(LD) \$(LFLAGS) \$(XLFLAGS) ".
|
||||
"/out:\$(BUILDDIR)$prog.exe ".
|
||||
"/lldmap:\$(BUILDDIR)$prog.map ".
|
||||
"/subsystem:$subsys\$(SUBSYSVER) $objstr")."\n\n";
|
||||
"/subsystem:$subsys\$(SUBSYSVER) ".
|
||||
"\$(EXTRA_$subsys) $objstr")."\n\n";
|
||||
}
|
||||
foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res.o", $dirpfx, "/", "vc")) {
|
||||
$extradeps = $forceobj{$d->{obj_orig}} ? ["*.c","*.h","*.rc"] : [];
|
||||
|
|
Загрузка…
Ссылка в новой задаче