[mini] Use C++ linker iff building C++ that needs the C++ runtime (#12266)
commit988f4a2147669f57ece07df7607ca9f2f60f57a9
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Mon, 7 Jan 2019 19:51:31 +0000 (7 14:51 -0500)
committerLudovic Henry <luhenry@microsoft.com>
Mon, 7 Jan 2019 19:51:31 +0000 (7 17:51 -0200)
tree7f8bba7f3519c249d0e816bd74b99ba38d15aabe
parent65a2c8a39617eb6e4758a511ec571c173a20d151
[mini] Use C++ linker iff building C++ that needs the C++ runtime (#12266)

* [mini] Use C++ linker iff building C++ that needs the C++ runtime

(This has nothing to do with --enable-cxx.  This is about our LLVM .cpp files).

Explicitly set the linker for libmini.  The issue is that the automatic
linker selection (See
https://www.gnu.org/software/automake/manual/html_node/How-the-Linker-is-Chosen.html)
looks at all the _SOURCES for a target, even those that are only
conditionally added, even if the condition is false.  So because we sometimes
build mini-llvm-cpp.cpp we always get the c++ linker.  But that's not what we
want.

The goal is:
 - if there's any C++ code included into mono (either the shared lib or a
   program) that needs the C++ runtime library, ensure that we link using the C++
   linker.  This was already true, we just need to make sure it stays true.
 - if mono is built in such a way that it has no C++ code in it (that needs the
   C++ runtime library), ensure that we link with the C linker and without
   including the C++ runtime library.
   This will address issues like https://github.com/mono/mono/issues/12060

We do this in two steps:

1. We split out all the c++ source code to libmini-cxx.la and include that into
   libmini.la.

   That's enough to force C++ linking if libmini-cxx.la has any code in it.  If
   there's no C++ code (right now that means there's no --enable-llvm or
   --enable-llvm-runtime), we don't add libmini-cxx.la and all the C source in
   libmini links in the normal manner.

2. We have a hack where we sometimes include libmono.a (the static library)
   into the mono executable.  In that case, we could forget about the C++
   linker (which leads to build failures because llvm uses all the C++ runtime
   library stuff that we forgot to link in).

   So we use the "nodist_EXTRA_..._SOURCES=dummy.cpp` hack to make it look like
   the mono executable has C++ source, which in turn forces the use of the C++
   linker.

   The conditional logic here has to match exactly what we do for deciding
   whether to add libmini-cxx.la into libmini.la.  If we do, then force the use
   the C++ linker here.

   It may seem like another option is to use something like
   `mono_boehm_LINK=$(CXXLINK)` to set a target-specific linker.  But this is
   bad, actually, because in that case we will drop the `..._LDFLAGS` and other
   linker flags unless we're very diligent to include all of them.  The
   `nodist_EXTRA_..._SOURCES` hack is more resilient because automake will
   ensure that all the flags are kept.

* [llvm,wasm] Don't add -lstdc++ in llvm_config.mk

Leave it to the linker.

This is needed when building wasm cross compilers for windows which pass
-static-libstdc++ to configure.  As a result we would get duplicate symbols by
linking against a static libstdc++.a and also the export stubs of libstdc++.dll

In mini, link monow using the C++ linker same as with mono by using the nodist_EXTRA_..._SOURCES
trick.

In wasm, pass -static-libstdc++ to CXXFLAGS, not LDFLAGS.  c++ linking picks up
CXXFLAGS anyway, and -static-libstdc++ has no effect on the C linker and it
doesn't affect explicit -lstdc++ flags anyway.
llvm/build_llvm_config.sh
mono/mini/Makefile.am.in
sdks/builds/wasm.mk