aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/cc/common.hxx13
-rw-r--r--build2/cc/link-rule.cxx8
-rw-r--r--build2/cc/module.cxx28
-rw-r--r--build2/cxx/init.cxx1
4 files changed, 30 insertions, 20 deletions
diff --git a/build2/cc/common.hxx b/build2/cc/common.hxx
index 19733cf..3f0f9fb 100644
--- a/build2/cc/common.hxx
+++ b/build2/cc/common.hxx
@@ -13,7 +13,8 @@
#include <build2/bin/target.hxx>
#include <build2/cc/types.hxx>
-#include <build2/cc/guess.hxx> // compiler_id
+#include <build2/cc/guess.hxx> // compiler_id
+#include <build2/cc/target.hxx> // h{}
namespace build2
{
@@ -151,21 +152,21 @@ namespace build2
const target_type& x_src; // Source target type (c{}, cxx{}).
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 "real header" first and
- // terminated with NULL.
+ // Array of target types that are considered the X-language headers
+ // (excluding h{} except for C). Keep them in the most likely to appear
+ // order with the "real header" first and terminated with NULL.
//
const target_type* const* x_hdr;
template <typename T>
bool
- x_header (const T& t) const
+ x_header (const T& t, bool c_hdr = true) const
{
for (const target_type* const* ht (x_hdr); *ht != nullptr; ++ht)
if (t.is_a (**ht))
return true;
- return false;
+ return c_hdr && t.is_a (h::static_type);
}
// Array of target types that can be #include'd. Used to reverse-lookup
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index 372d077..3b58ab7 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -87,12 +87,14 @@ namespace build2
if (p.is_a (x_src) ||
(x_mod != nullptr && p.is_a (*x_mod)) ||
- (lt.library () && x_header (p))) // Header-only library.
+ // Header-only X library (or library with C source and X header).
+ (lt.library () && x_header (p, false /* c_hdr */)))
{
seen_x = seen_x || true;
}
else if (p.is_a<c> () ||
- (lt.library () && p.is_a<h> ())) // Header-only library.
+ // Header-only C library.
+ (lt.library () && p.is_a<h> ()))
{
seen_c = seen_c || true;
}
@@ -132,7 +134,7 @@ namespace build2
// 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> () && !(x_header (p) || p.is_a<h> ()))
+ else if (p.is_a<cc> () && !(x_header (p, true /* c_hdr */)))
{
l4 ([&]{trace << "non-" << x_lang << " prerequisite " << p
<< " for target " << t;});
diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx
index 7527da2..14d3ceb 100644
--- a/build2/cc/module.cxx
+++ b/build2/cc/module.cxx
@@ -578,24 +578,32 @@ namespace build2
{
using namespace install;
- auto& t (rs.target_types);
+ auto& tts (rs.target_types);
- t.insert (x_src);
+ tts.insert (x_src);
- // Note: module (x_mod) is in x_hdr.
-
- for (const target_type* const* ht (x_hdr); *ht != nullptr; ++ht)
+ auto insert_hdr = [&rs, &tts, install_loaded] (const target_type& tt)
{
- t.insert (**ht);
+ tts.insert (tt);
// Install headers into install.include.
//
if (install_loaded)
- install_path (rs, **ht, dir_path ("include"));
- }
+ install_path (rs, tt, dir_path ("include"));
+ };
+
+ // Note: module (x_mod) is in x_hdr.
+ //
+ for (const target_type* const* ht (x_hdr); *ht != nullptr; ++ht)
+ insert_hdr (**ht);
+
+ // Also register the C header for C-derived languages.
+ //
+ if (*x_hdr != &h::static_type)
+ insert_hdr (h::static_type);
- t.insert<pca> ();
- t.insert<pcs> ();
+ tts.insert<pca> ();
+ tts.insert<pcs> ();
if (install_loaded)
install_path<pc> (rs, dir_path ("pkgconfig"));
diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx
index ff104d3..92d5da8 100644
--- a/build2/cxx/init.cxx
+++ b/build2/cxx/init.cxx
@@ -526,7 +526,6 @@ namespace build2
static const target_type* const hdr[] =
{
&hxx::static_type,
- &h::static_type,
&ixx::static_type,
&txx::static_type,
&mxx::static_type,