From 3d8f2b3779ae32a16627a0f09f1798224cdaf68f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 31 Aug 2016 10:48:51 +0200 Subject: Improve mixed source (e.g., C and C++) building support --- build2/cc/link.cxx | 7 ++++++- build2/cc/target | 19 +++++++++++++++++-- build2/cc/target.cxx | 13 ++++++++++++- build2/cxx/target | 4 ++-- build2/cxx/target.cxx | 2 +- 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 ()) + 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 ()) { 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, &target_extension_var, 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, &target_extension_var, nullptr, -- cgit v1.1