diff options
-rw-r--r-- | libbuild2/cc/compile-rule.cxx | 77 | ||||
-rw-r--r-- | libbuild2/cc/link-rule.cxx | 14 |
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). // |