From 774bfb559ecaef2aac1dcb7a0414bc6895a9b9d5 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 17 Jun 2016 16:42:38 +0200 Subject: Initial take on DLL support for MinGW toolchain --- build2/cxx/link.cxx | 98 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 23 deletions(-) (limited to 'build2/cxx/link.cxx') diff --git a/build2/cxx/link.cxx b/build2/cxx/link.cxx index 3d0255e..5792615 100644 --- a/build2/cxx/link.cxx +++ b/build2/cxx/link.cxx @@ -255,7 +255,7 @@ namespace build2 scope& rs (*p.scope.root_scope ()); const string& cid (cast (rs["cxx.id"])); - const string& sys (cast (rs["cxx.target.system"])); + const string& tsys (cast (rs["cxx.target.system"])); bool l (p.is_a ()); const string* ext (l ? nullptr : p.ext); // Only for liba/libso. @@ -306,23 +306,31 @@ namespace build2 if (l || p.is_a ()) { - // @@ VC TODO - // - - sn = path ("lib" + p.name); + const char* e (""); - if (ext == nullptr) + if (cid == "msvc") { - const char* e; - if (sys == "darwin") - e = "dylib"; - else - e = "so"; + // @@ VC TODO: still .lib, right? + // + } + else + { + sn = path ("lib" + p.name); - ext = &extension_pool.find (e); + if (tsys == "darwin") e = "dylib"; + // + // @@ Here we are searching for the import library but if it's not + // found, then we could also search for the DLL since we can link + // directly to it. Of course, we would also need some way to mark + // this libso{} as "import-less". + // + else if (tsys == "mingw32") e = "dll.a"; + else e = "so"; } - se = ext; + se = ext == nullptr + ? &extension_pool.find (e) + : ext; if (!se->empty ()) { @@ -594,9 +602,11 @@ namespace build2 { //@@ VC: DLL name. - if (tclass == "macosx") e = "dylib"; - else e = "so"; - if (p == nullptr) p = "lib"; + if (tclass == "macosx") e = "dylib"; + if (tclass == "windows") e = "dll"; + else e = "so"; + + if (p == nullptr) p = "lib"; } t.derive_path (e, p); @@ -817,7 +827,7 @@ namespace build2 switch (a) { case perform_update_id: return &perform_update; - case perform_clean_id: return &perform_clean_depdb; + case perform_clean_id: return &perform_clean; default: return noop_recipe; // Configure update. } } @@ -885,6 +895,7 @@ namespace build2 scope& rs (t.root_scope ()); const string& cid (cast (rs["cxx.id"])); + const string& tsys (cast (rs["cxx.target.system"])); const string& tclass (cast (rs["cxx.target.class"])); const string& aid (lt == type::a @@ -979,7 +990,7 @@ namespace build2 // Set soname. // - if (so && cid != "msvc") + if (so && tclass != "windows") { const string& leaf (t.path ().leaf ().string ()); @@ -1016,9 +1027,11 @@ namespace build2 // rpath of the imported libraries (i.e., we assume the are also // installed). // - // @@ VC TODO: emulate own rpath somehow and complain on user's. - // - if (cid != "msvc") + if (tclass == "windows") + { + // @@ VC TODO: emulate own rpath somehow and complain on user's. + } + else { for (target* pt: t.prerequisite_targets) { @@ -1185,6 +1198,17 @@ namespace build2 args.push_back ("-o"); args.push_back (relt.string ().c_str ()); + + // Add any additional options (import library name, etc). + // + if (so) + { + if (tsys == "mingw32") + { + out = "-Wl,--out-implib=" + relt.string () + ".a"; + args.push_back (out.c_str ()); + } + } } } @@ -1194,14 +1218,23 @@ namespace build2 { path_target* ppt; liba* a (nullptr); + libso* so (nullptr); if ((ppt = pt->is_a ()) || (ppt = pt->is_a ()) || (lt != type::a && ((ppt = a = pt->is_a ()) || - (ppt = pt->is_a ())))) + (ppt = so = pt->is_a ())))) { - sargs.push_back (relative (ppt->path ()).string ()); // string()&& + string p (relative (ppt->path ()).string ()); // string()&& + + if (so != nullptr) + { + if (tsys == "mingw32") + p += ".a"; // Link to the import library (*.dll -> *.dll.a). + } + + sargs.push_back (move (p)); // If this is a static library, link all the libraries it depends // on, recursively. @@ -1305,6 +1338,25 @@ namespace build2 return target_state::changed; } + target_state link:: + perform_clean (action a, target& xt) + { + file& t (static_cast (xt)); + + scope& rs (t.root_scope ()); + const string& tsys (cast (rs["cxx.target.system"])); + + const char* e (nullptr); + + if (link_type (t) == type::so) + { + if (tsys == "mingw32") + e = "+.a"; // Import library (*.dll.a). + } + + return clean_extra (a, t, {"+.d", e}); + } + link link::instance; } } -- cgit v1.1