aboutsummaryrefslogtreecommitdiff
path: root/build2/cc/link-rule.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-06-12 11:56:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-06-12 11:56:18 +0200
commit08f36d41ea69ca331715ac8d70b0bf8fd849f401 (patch)
treeb377f5459fdcdcbf9e8980394386b1305b7dd516 /build2/cc/link-rule.cxx
parente50b11ceb81089fc32eac7614b66daef7119f620 (diff)
Add built-in support for Windows module definition files (.def)
Diffstat (limited to 'build2/cc/link-rule.cxx')
-rw-r--r--build2/cc/link-rule.cxx52
1 files changed, 47 insertions, 5 deletions
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index ce1a9f6..e3516ac 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -679,6 +679,14 @@ namespace build2
if (p.is_a<obj> ()) pt = &search (t, tt.obj, p.key ());
else if (p.is_a<bmi> ()) pt = &search (t, tt.bmi, p.key ());
//
+ // Windows module definition (.def). For other platforms (and for
+ // static libraries) treat it as an ordinary prerequisite.
+ //
+ else if (p.is_a<def> () && tclass == "windows" && ot != otype::a)
+ {
+ pt = &p.search (t);
+ }
+ //
// Something else. This could be something unrelated that the user
// tacked on (e.g., a doc{}). Or it could be some ad hoc input to
// the linker (say a linker script or some such).
@@ -691,6 +699,9 @@ namespace build2
// for update. This allows operations like test and install to
// skip such tacked on stuff.
//
+ // @@ This is broken since, for example, update for install will
+ // ignore ad hoc inputs.
+ //
if (current_outer_oif != nullptr)
continue;
}
@@ -1624,11 +1635,12 @@ namespace build2
// Finally, hash and compare the list of input files.
//
- // Should we capture actual files or their checksum? The only good
- // reason for capturing actual files is diagnostics: we will be able
- // to pinpoint exactly what is causing the update. On the other hand,
- // the checksum is faster and simpler. And we like simple.
+ // Should we capture actual file names or their checksum? The only good
+ // reason for capturing actual files is diagnostics: we will be able to
+ // pinpoint exactly what is causing the update. On the other hand, the
+ // checksum is faster and simpler. And we like simple.
//
+ const file* def (nullptr); // Cache if present.
{
sha256 cs;
@@ -1673,6 +1685,21 @@ namespace build2
else
hash_path (cs, f->path (), rs.out_path ());
}
+ else if ((f = pt->is_a<bin::def> ()))
+ {
+ if (tclass == "windows" && !lt.static_library ())
+ {
+ // At least link.exe only allows a single .def file.
+ //
+ if (def != nullptr)
+ fail << "multiple module definition files specified for " << t;
+
+ hash_path (cs, f->path (), rs.out_path ());
+ def = f;
+ }
+ else
+ f = nullptr; // Not an input.
+ }
else
f = pt->is_a<exe> (); // Consider executable mtime (e.g., linker).
@@ -1736,7 +1763,7 @@ namespace build2
// Ok, so we are updating. Finish building the command line.
//
- string out, out1, out2, out3; // Storage.
+ string in, out, out1, out2, out3; // Storage.
// Translate paths to relative (to working directory) ones. This results
// in easier to read diagnostics.
@@ -1841,6 +1868,12 @@ namespace build2
args.push_back (out3.c_str ());
}
+ if (def != nullptr)
+ {
+ in = "/DEF:" + relative (def->path ()).string ();
+ args.push_back (in.c_str ());
+ }
+
if (ot == otype::s)
{
// On Windows libs{} is the DLL and its first ad hoc group member
@@ -1907,6 +1940,15 @@ namespace build2
args.push_back ("-o");
args.push_back (relt.string ().c_str ());
+
+ // For MinGW the .def file is just another input.
+ //
+ if (def != nullptr)
+ {
+ in = relative (def->path ()).string ();
+ args.push_back (in.c_str ());
+ }
+
break;
}
case compiler_class::msvc: assert (false);