diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-06-17 16:42:38 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-06-17 16:42:38 +0200 |
commit | 774bfb559ecaef2aac1dcb7a0414bc6895a9b9d5 (patch) | |
tree | ef218a78b2122c6bdc1c13f376d1bcf83fe23e84 /build2/cxx | |
parent | 9ae6fd626ed2ca0b7eff64bda68ca84463e66b84 (diff) |
Initial take on DLL support for MinGW toolchain
Diffstat (limited to 'build2/cxx')
-rw-r--r-- | build2/cxx/compile.cxx | 6 | ||||
-rw-r--r-- | build2/cxx/link | 3 | ||||
-rw-r--r-- | build2/cxx/link.cxx | 98 |
3 files changed, 81 insertions, 26 deletions
diff --git a/build2/cxx/compile.cxx b/build2/cxx/compile.cxx index bfeaeb9..b11a919 100644 --- a/build2/cxx/compile.cxx +++ b/build2/cxx/compile.cxx @@ -194,7 +194,7 @@ namespace build2 if (t.is_a<objso> ()) { - // On Darwin -fPIC is the default. + // On Darwin, Win32 -fPIC is the default. // if (tclass == "linux" || tclass == "freebsd") cs.append ("-fPIC"); @@ -610,7 +610,7 @@ namespace build2 if (t.is_a<objso> ()) { - // On Darwin -fPIC is the default. + // On Darwin, Win32 -fPIC is the default. // if (tclass == "linux" || tclass == "freebsd") args.push_back ("-fPIC"); @@ -1217,7 +1217,7 @@ namespace build2 { if (t.is_a<objso> ()) { - // On Darwin -fPIC is the default. + // On Darwin, Win32 -fPIC is the default. // if (tclass == "linux" || tclass == "freebsd") args.push_back ("-fPIC"); diff --git a/build2/cxx/link b/build2/cxx/link index d0584de..ca45e17 100644 --- a/build2/cxx/link +++ b/build2/cxx/link @@ -28,6 +28,9 @@ namespace build2 static target_state perform_update (action, target&); + static target_state + perform_clean (action, target&); + static link instance; public: 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<string> (rs["cxx.id"])); - const string& sys (cast<string> (rs["cxx.target.system"])); + const string& tsys (cast<string> (rs["cxx.target.system"])); bool l (p.is_a<lib> ()); const string* ext (l ? nullptr : p.ext); // Only for liba/libso. @@ -306,23 +306,31 @@ namespace build2 if (l || p.is_a<libso> ()) { - // @@ 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<string> (rs["cxx.id"])); + const string& tsys (cast<string> (rs["cxx.target.system"])); const string& tclass (cast<string> (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<obja> ()) || (ppt = pt->is_a<objso> ()) || (lt != type::a && ((ppt = a = pt->is_a<liba> ()) || - (ppt = pt->is_a<libso> ())))) + (ppt = so = pt->is_a<libso> ())))) { - 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<file&> (xt)); + + scope& rs (t.root_scope ()); + const string& tsys (cast<string> (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; } } |