diff options
-rw-r--r-- | build2/c/init.cxx | 2 | ||||
-rw-r--r-- | build2/cc/common | 2 | ||||
-rw-r--r-- | build2/cc/init.cxx | 7 | ||||
-rw-r--r-- | build2/cc/link.cxx | 42 | ||||
-rw-r--r-- | build2/cxx/init.cxx | 2 |
5 files changed, 46 insertions, 9 deletions
diff --git a/build2/c/init.cxx b/build2/c/init.cxx index 4eab8a6..be72655 100644 --- a/build2/c/init.cxx +++ b/build2/c/init.cxx @@ -148,6 +148,8 @@ namespace build2 v["cc.export.loptions"], v["cc.export.libs"], + v["cc.type"], + v.insert<string> ("c.std", true), v.insert<string> ("c.id"), diff --git a/build2/cc/common b/build2/cc/common index 987fe7b..ff6841f 100644 --- a/build2/cc/common +++ b/build2/cc/common @@ -57,6 +57,8 @@ namespace build2 const variable& c_export_loptions; const variable& c_export_libs; + const variable& c_type; // cc.type + const variable& x_std; const variable& x_id; diff --git a/build2/cc/init.cxx b/build2/cc/init.cxx index 0c82169..0f1fda7 100644 --- a/build2/cc/init.cxx +++ b/build2/cc/init.cxx @@ -60,6 +60,13 @@ namespace build2 v.insert<string> ("config.cc.target"); v.insert<string> ("config.cc.pattern"); + // Target type, for example, "C library" or "C++ library". Should be set + // on the target by the matching rule to the name of the module (e.g., + // "c", "cxx"). Currenly only set for libraries and is used to decide + // which *.libs to use during static linking. + // + v.insert<string> ("cc.type"); + return true; } diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx index ffa088f..b608817 100644 --- a/build2/cc/link.cxx +++ b/build2/cc/link.cxx @@ -575,6 +575,9 @@ namespace build2 } } + if (!(seen_x || seen_c || seen_obj || seen_lib)) + return nullptr; + // We will only chain a C source if there is also an X source or we were // explicitly told to. // @@ -584,10 +587,14 @@ namespace build2 return nullptr; } - // If we have any prerequisite libraries (which also means that - // we match), search/import and pre-match them to implement the - // "library meta-information protocol". Don't do this if we are - // called from the install rule just to check if we would match. + // Set the library type. + // + t.vars.assign (c_type) = string (x); + + // If we have any prerequisite libraries, search/import and pre-match + // them to implement the "library meta-information protocol". Don't do + // this if we are called from the install rule just to check if we would + // match. // auto op (a.operation ()); auto oop (a.outer_operation ()); @@ -629,7 +636,7 @@ namespace build2 } } - return seen_x || seen_c || seen_obj || seen_lib ? &t : nullptr; + return &t; } recipe link:: @@ -1046,8 +1053,15 @@ namespace build2 if (la) { - append_options (args, l, c_libs); - append_options (args, l, x_libs); + // See what type of library this is (C, C++, etc). Use it do decide + // which x.libs variable name. If it is not a C-common library, then + // it probably doesn't have cc.libs either. + // + if (const string* t = cast_null<string> (l.vars[c_type])) + { + append_options (args, l, c_libs); + append_options (args, l, *t == x ? x_libs : var_pool[*t + ".libs"]); + } } else { @@ -1092,6 +1106,9 @@ namespace build2 } }; + // @@ Should we also pick one based on cc.type? And also *.poptions in + // compile? Feels right. + // append (c_export_libs); append (x_export_libs); } @@ -1117,8 +1134,15 @@ namespace build2 if (la) { - hash_options (cs, l, c_libs); - hash_options (cs, l, x_libs); + // See what type of library this is (C, C++, etc). Use it do decide + // which x.libs variable name. If it is not a C-common library, then + // it probably doesn't have cc.libs either. + // + if (const string* t = cast_null<string> (l.vars[c_type])) + { + hash_options (cs, l, c_libs); + hash_options (cs, l, *t == x ? x_libs : var_pool[*t + ".libs"]); + } } else { diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx index 3dd6b1f..8202139 100644 --- a/build2/cxx/init.cxx +++ b/build2/cxx/init.cxx @@ -148,6 +148,8 @@ namespace build2 v["cc.export.loptions"], v["cc.export.libs"], + v["cc.type"], + v.insert<string> ("cxx.std", true), v.insert<string> ("cxx.id"), |