aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-01-09 13:09:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-01-09 13:09:18 +0200
commit8e904346350cff0453c8bcd524a40a631fc05485 (patch)
treef096ad1e87d8a814c6e00c179c8849ed646e0989
parentba8ce9226af026f873883b7d4e29079bbfece586 (diff)
Tighten cc rules matching
Specifically, make sure the rule does not match if there is a c-common prerequisites that it doesn't recognize.
-rw-r--r--build2/cc/common.hxx2
-rw-r--r--build2/cc/link-rule.cxx20
-rw-r--r--build2/cc/target.cxx2
-rw-r--r--build2/cc/target.hxx12
-rw-r--r--build2/cxx/target.cxx8
-rw-r--r--build2/cxx/target.hxx18
6 files changed, 34 insertions, 28 deletions
diff --git a/build2/cc/common.hxx b/build2/cc/common.hxx
index dccf62e..e1b04d7 100644
--- a/build2/cc/common.hxx
+++ b/build2/cc/common.hxx
@@ -148,7 +148,7 @@ namespace build2
const target_type* x_mod; // Module target type (mxx{}), if any.
// Array of target types that are considered headers. Keep them in the
- // most likely to appear order with the "header header" first and
+ // most likely to appear order with the "real header" first and
// terminated with NULL.
//
const target_type* const* x_hdr;
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index c24655a..b7ecd85 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -71,7 +71,8 @@ namespace build2
}
// Scan prerequisites and see if we can work with what we've got. Note
- // that X could be C. We handle this by always checking for X first.
+ // that X could be C (as in language). We handle this by always checking
+ // for X first.
//
// Note also that we treat bmi{} as obj{}.
//
@@ -84,9 +85,9 @@ namespace build2
if (include (a, t, p) != include_type::normal)
continue;
- if (p.is_a (x_src) ||
- (lt.library () && p.is_a (*x_hdr[0])) || // Header-only library.
- (x_mod != nullptr && p.is_a (*x_mod)))
+ if (p.is_a (x_src) ||
+ (x_mod != nullptr && p.is_a (*x_mod)) ||
+ (lt.library () && x_header (p))) // Header-only library.
{
seen_x = seen_x || true;
}
@@ -127,11 +128,16 @@ namespace build2
{
seen_lib = seen_lib || true;
}
- // If this is some other c-common source (say C++ in a C rule), then
- // it will most definitely need to be compiled but we can't do that.
+ // If this is some other c-common header/source (say C++ in a C rule),
+ // then we shouldn't try to handle that (it may need to be compiled,
+ // etc). But we assume everyone can handle a C header.
//
- else if (p.is_a<cc> ())
+ else if (p.is_a<cc> () && !p.is_a<h> ())
+ {
+ l4 ([&]{trace << "non-" << x_lang << " prerequisite " << p
+ << " for target " << t;});
return false;
+ }
}
if (!(seen_x || seen_c || seen_obj || seen_lib))
diff --git a/build2/cc/target.cxx b/build2/cc/target.cxx
index 7039728..981f4d7 100644
--- a/build2/cc/target.cxx
+++ b/build2/cc/target.cxx
@@ -30,7 +30,7 @@ namespace build2
const target_type h::static_type
{
"h",
- &file::static_type,
+ &cc::static_type,
&target_factory<h>,
nullptr, /* fixed_extension */
&target_extension_var<var_extension, h_ext_def>,
diff --git a/build2/cc/target.hxx b/build2/cc/target.hxx
index 4fb38cb..395c233 100644
--- a/build2/cc/target.hxx
+++ b/build2/cc/target.hxx
@@ -14,10 +14,10 @@ namespace build2
{
namespace cc
{
- // This is an abstract base target for all c-common source files. We use
- // this arrangement in rule matching to detect "unknown" (to this rule)
- // source files that it cannot handle but should not ignore either. For
- // example, a C link rule that sees a C++ source file.
+ // This is an abstract base target for all c-common header/source files.
+ // We use this arrangement during rule matching to detect "unknown" (to
+ // this rule) source/header files that it cannot handle but should not
+ // ignore either. For example, a C link rule that sees a C++ source file.
//
class cc: public file
{
@@ -32,10 +32,10 @@ namespace build2
// There is hardly a c-family compilation without a C header inclusion.
// As a result, this target type is registered for any c-family module.
//
- class h: public file
+ class h: public cc
{
public:
- using file::file;
+ using cc::cc;
public:
static const target_type static_type;
diff --git a/build2/cxx/target.cxx b/build2/cxx/target.cxx
index 3431bc4..bdfa609 100644
--- a/build2/cxx/target.cxx
+++ b/build2/cxx/target.cxx
@@ -16,7 +16,7 @@ namespace build2
const target_type hxx::static_type
{
"hxx",
- &file::static_type,
+ &cc::static_type,
&target_factory<hxx>,
nullptr, /* fixed_extension */
&target_extension_var<var_extension, hxx_ext_def>,
@@ -30,7 +30,7 @@ namespace build2
const target_type ixx::static_type
{
"ixx",
- &file::static_type,
+ &cc::static_type,
&target_factory<ixx>,
nullptr, /* fixed_extension */
&target_extension_var<var_extension, ixx_ext_def>,
@@ -44,7 +44,7 @@ namespace build2
const target_type txx::static_type
{
"txx",
- &file::static_type,
+ &cc::static_type,
&target_factory<txx>,
nullptr, /* fixed_extension */
&target_extension_var<var_extension, txx_ext_def>,
@@ -72,7 +72,7 @@ namespace build2
const target_type mxx::static_type
{
"mxx",
- &file::static_type,
+ &cc::static_type,
&target_factory<mxx>,
nullptr, /* fixed_extension */
&target_extension_var<var_extension, mxx_ext_def>,
diff --git a/build2/cxx/target.hxx b/build2/cxx/target.hxx
index e31d311..94295d1 100644
--- a/build2/cxx/target.hxx
+++ b/build2/cxx/target.hxx
@@ -18,30 +18,30 @@ namespace build2
using cc::h;
using cc::c;
- class hxx: public file
+ class hxx: public cc::cc
{
public:
- using file::file;
+ using cc::cc;
public:
static const target_type static_type;
virtual const target_type& dynamic_type () const {return static_type;}
};
- class ixx: public file
+ class ixx: public cc::cc
{
public:
- using file::file;
+ using cc::cc;
public:
static const target_type static_type;
virtual const target_type& dynamic_type () const {return static_type;}
};
- class txx: public file
+ class txx: public cc::cc
{
public:
- using file::file;
+ using cc::cc;
public:
static const target_type static_type;
@@ -61,12 +61,12 @@ namespace build2
// The module interface unit is both like a header (e.g., we need to
// install it) and like a source (we need to compile it). Plus, to
// support dual use (modules/headers) it could actually be #include'd
- // (and even in both cases).
+ // (and even in both cases e.g., by different codebases).
//
- class mxx: public file
+ class mxx: public cc::cc
{
public:
- using file::file;
+ using cc::cc;
public:
static const target_type static_type;