aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/cc/compile-rule.cxx77
-rw-r--r--libbuild2/cc/link-rule.cxx14
2 files changed, 83 insertions, 8 deletions
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx
index 8f1bba9..cf2f2a8 100644
--- a/libbuild2/cc/compile-rule.cxx
+++ b/libbuild2/cc/compile-rule.cxx
@@ -3038,14 +3038,23 @@ namespace build2
}
case compiler_class::gcc:
{
+ // See perform_update() for details on the choice of options.
+ //
if (ot == otype::s)
{
- // On Darwin, Win32 -fPIC is the default.
- //
if (tclass == "linux" || tclass == "bsd")
args.push_back ("-fPIC");
}
+ if (ctype == compiler_type::clang && tsys == "win32-msvc")
+ {
+ if (!find_options ({"-nostdlib", "-nostartfiles"}, args))
+ {
+ args.push_back ("-D_MT");
+ args.push_back ("-D_DLL");
+ }
+ }
+
// Setup the dynamic module mapper if needed.
//
// Note that it's plausible in the future we will use it even if
@@ -4140,6 +4149,15 @@ namespace build2
args.push_back ("-fPIC");
}
+ if (ctype == compiler_type::clang && tsys == "win32-msvc")
+ {
+ if (!find_options ({"-nostdlib", "-nostartfiles"}, args))
+ {
+ args.push_back ("-D_MT");
+ args.push_back ("-D_DLL");
+ }
+ }
+
args.push_back ("-E");
append_lang_options (args, md);
@@ -5805,6 +5823,61 @@ namespace build2
args.push_back ("-fPIC");
}
+ if (tsys == "win32-msvc")
+ {
+ switch (ctype)
+ {
+ case compiler_type::clang:
+ {
+ // Default to the multi-threaded DLL runtime (/MD), similar to
+ // the MSVC case above.
+ //
+ // Clang's MSVC.cpp will not link the default runtime if either
+ // -nostdlib or -nostartfiles is specified. Let's do the same.
+ //
+ if (!find_options ({"-nostdlib", "-nostartfiles"}, args))
+ {
+ args.push_back ("-D_MT");
+ args.push_back ("-D_DLL");
+
+ // All these -Xclang --dependent-lib=... add quite a bit of
+ // noise to the command line. The alternative is to use the
+ // /DEFAULTLIB option during linking. The drawback of that
+ // approach is that now we can theoretically build the object
+ // file for one runtime but try to link it with something
+ // else.
+ //
+ // For example, an installed static library was built for a
+ // non-debug runtime while a project that links it uses
+ // debug. With the --dependent-lib approach we will try to
+ // link multiple runtimes while with /DEFAULTLIB we may end up
+ // with unresolved symbols (but things might also work out
+ // fine, unless the runtimes have incompatible ABIs).
+ //
+ // Let's start with /DEFAULTLIB and see how it goes (see the
+ // link rule).
+ //
+#if 0
+ args.push_back ("-Xclang");
+ args.push_back ("--dependent-lib=msvcrt");
+
+ // This provides POSIX compatibility (map open() to _open(),
+ // etc).
+ //
+ args.push_back ("-Xclang");
+ args.push_back ("--dependent-lib=oldnames");
+#endif
+ }
+
+ break;
+ }
+ case compiler_type::gcc:
+ case compiler_type::msvc:
+ case compiler_type::icc:
+ assert (false);
+ }
+ }
+
append_headers (env, args, header_args, a, t, md, md.dd);
append_modules (env, args, module_args, a, t, md, md.dd);
diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx
index fb7588b..5341a2e 100644
--- a/libbuild2/cc/link-rule.cxx
+++ b/libbuild2/cc/link-rule.cxx
@@ -2471,13 +2471,15 @@ namespace build2
if (ctype == compiler_type::clang)
{
- // According to Clang's MSVC.cpp, we shall link libcmt.lib (static
- // multi-threaded runtime) unless -nostdlib or -nostartfiles is
- // specified.
+ // See the runtime selection code in the compile rule for details
+ // on what's going on here.
//
if (!find_options ({"-nostdlib", "-nostartfiles"}, t, c_coptions) &&
!find_options ({"-nostdlib", "-nostartfiles"}, t, x_coptions))
- args.push_back ("/DEFAULTLIB:libcmt.lib");
+ {
+ args.push_back ("/DEFAULTLIB:msvcrt");
+ args.push_back ("/DEFAULTLIB:oldnames");
+ }
}
// If you look at the list of libraries Visual Studio links by
@@ -2496,8 +2498,8 @@ namespace build2
// does). This way the user can override our actions with the
// /NODEFAULTLIB option.
//
- args.push_back ("/DEFAULTLIB:shell32.lib");
- args.push_back ("/DEFAULTLIB:user32.lib");
+ args.push_back ("/DEFAULTLIB:shell32");
+ args.push_back ("/DEFAULTLIB:user32");
// Take care of the manifest (will be empty for the DLL).
//