aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-31 10:48:51 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-31 10:48:51 +0200
commit3d8f2b3779ae32a16627a0f09f1798224cdaf68f (patch)
treefab60da301c5e686514b8cedfedf541548ec912b
parent02f294ade6ba3c7c33fd4fb4dccb7901eaa7ae5c (diff)
Improve mixed source (e.g., C and C++) building support
-rw-r--r--build2/cc/link.cxx7
-rw-r--r--build2/cc/target19
-rw-r--r--build2/cc/target.cxx13
-rw-r--r--build2/cxx/target4
-rw-r--r--build2/cxx/target.cxx2
5 files changed, 38 insertions, 7 deletions
diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx
index a1ecac3..29a46b4 100644
--- a/build2/cc/link.cxx
+++ b/build2/cc/link.cxx
@@ -104,6 +104,11 @@ 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.
+ //
+ else if (p.is_a<cc> ())
+ return nullptr;
}
if (!(seen_x || seen_c || seen_obj || seen_lib))
@@ -563,7 +568,7 @@ namespace build2
// Most of the time we will have just a single source so fast-path
// that case.
//
- if (p1.is_a (x_src))
+ if (p1.is_a (x_src) || p1.is_a<c> ())
{
if (!found)
{
diff --git a/build2/cc/target b/build2/cc/target
index 2d8125b..465ea61 100644
--- a/build2/cc/target
+++ b/build2/cc/target
@@ -14,6 +14,21 @@ 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.
+ //
+ class cc: public file
+ {
+ public:
+ using file::file;
+
+ public:
+ static const target_type static_type;
+ virtual const target_type& dynamic_type () const = 0;
+ };
+
// 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.
//
@@ -33,10 +48,10 @@ namespace build2
// also without relaxing things too much (i.e., the user still won't be
// able to refer to c{} without loading the c module).
//
- class c: public file
+ class c: public cc
{
public:
- using file::file;
+ using cc::cc;
public:
static const target_type static_type;
diff --git a/build2/cc/target.cxx b/build2/cc/target.cxx
index 7c2bb24..4961b35 100644
--- a/build2/cc/target.cxx
+++ b/build2/cc/target.cxx
@@ -10,6 +10,17 @@ namespace build2
{
namespace cc
{
+ const target_type cc::static_type
+ {
+ "cc",
+ &file::static_type,
+ nullptr,
+ nullptr,
+ nullptr,
+ &search_target,
+ false
+ };
+
extern const char ext_var[] = "extension"; // VC 19 rejects constexpr.
extern const char h_ext_def[] = "h";
@@ -28,7 +39,7 @@ namespace build2
const target_type c::static_type
{
"c",
- &file::static_type,
+ &cc::static_type,
&target_factory<c>,
&target_extension_var<ext_var, c_ext_def>,
nullptr,
diff --git a/build2/cxx/target b/build2/cxx/target
index 0239c25..d581caf 100644
--- a/build2/cxx/target
+++ b/build2/cxx/target
@@ -48,10 +48,10 @@ namespace build2
virtual const target_type& dynamic_type () const {return static_type;}
};
- class cxx: public file
+ class cxx: public cc::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 30afd89..e9733a8 100644
--- a/build2/cxx/target.cxx
+++ b/build2/cxx/target.cxx
@@ -52,7 +52,7 @@ namespace build2
const target_type cxx::static_type
{
"cxx",
- &file::static_type,
+ &cc::static_type,
&target_factory<cxx>,
&target_extension_var<ext_var, cxx_ext_def>,
nullptr,