aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-01-07 12:12:19 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-01-08 08:13:59 +0200
commit9d5a9628d22bae7c6a4f9688e8efdfc2cbb5c4fb (patch)
tree7800123198e26ed929343f2a5bc5cb39b80ef650
parent34a44bf3733e5cfda0265c10b11caec3cb2ba3d8 (diff)
Add {bin,c,cxx}.types submodules that only register target types
-rw-r--r--libbuild2/bin/init.cxx120
-rw-r--r--libbuild2/bin/init.hxx6
-rw-r--r--libbuild2/c/init.cxx162
-rw-r--r--libbuild2/c/init.hxx25
-rw-r--r--libbuild2/cc/module.cxx43
-rw-r--r--libbuild2/cxx/init.cxx161
-rw-r--r--libbuild2/cxx/init.hxx20
7 files changed, 371 insertions, 166 deletions
diff --git a/libbuild2/bin/init.cxx b/libbuild2/bin/init.cxx
index 1b3039f..610082e 100644
--- a/libbuild2/bin/init.cxx
+++ b/libbuild2/bin/init.cxx
@@ -41,16 +41,19 @@ namespace build2
bool
vars_init (scope& rs,
- scope&,
- const location&,
- bool first,
+ scope& bs,
+ const location& loc,
+ bool,
bool,
module_init_extra&)
{
tracer trace ("bin::vars_init");
l5 ([&]{trace << "for " << rs;});
- assert (first);
+ // We only support root loading (which means there can only be one).
+ //
+ if (rs != bs)
+ fail (loc) << "bin.vars module must be loaded in project root";
// Enter variables.
//
@@ -156,6 +159,68 @@ namespace build2
return true;
}
+ bool
+ types_init (scope& rs,
+ scope& bs,
+ const location& loc,
+ bool,
+ bool,
+ module_init_extra&)
+ {
+ tracer trace ("bin::types_init");
+ l5 ([&]{trace << "for " << rs;});
+
+ // We only support root loading (which means there can only be one).
+ //
+ if (rs != bs)
+ fail (loc) << "bin.types module must be loaded in project root";
+
+ // Register target types.
+ //
+ // Note that certain platform-specific and toolchain-specific types are
+ // registered in bin and bin.ld.
+ //
+ // Note also that it would make sense to configure their default
+ // "installability" here but that requires the knowledge of the platform
+ // in some cases. So we do it all in bin for now. One way to support
+ // both use-cases would be to detect if we are loaded after bin.guess
+ // and then decide whether to do it here or delay to bin.
+ //
+ // NOTE: remember to update the documentation if changing anything here!
+ //
+ rs.insert_target_type<obj> ();
+ rs.insert_target_type<obje> ();
+ rs.insert_target_type<obja> ();
+ rs.insert_target_type<objs> ();
+
+ rs.insert_target_type<bmi> ();
+ rs.insert_target_type<bmie> ();
+ rs.insert_target_type<bmia> ();
+ rs.insert_target_type<bmis> ();
+
+ rs.insert_target_type<hbmi> ();
+ rs.insert_target_type<hbmie> ();
+ rs.insert_target_type<hbmia> ();
+ rs.insert_target_type<hbmis> ();
+
+ rs.insert_target_type<libul> ();
+ rs.insert_target_type<libue> ();
+ rs.insert_target_type<libua> ();
+ rs.insert_target_type<libus> ();
+
+ rs.insert_target_type<lib> ();
+ rs.insert_target_type<liba> ();
+ rs.insert_target_type<libs> ();
+
+ // Register the def{} target type. Note that we do it here since it is
+ // input and can be specified unconditionally (i.e., not only when
+ // building for Windows).
+ //
+ rs.insert_target_type<def> ();
+
+ return true;
+ }
+
void
functions (function_map&); // functions.cxx
@@ -450,56 +515,22 @@ namespace build2
tracer trace ("bin::init");
l5 ([&]{trace << "for " << bs;});
- // Load bin.config.
+ // Load bin.{config,types}.
//
load_module (rs, rs, "bin.config", loc, extra.hints);
+ load_module (rs, rs, "bin.types", loc);
// Cache some config values we will be needing below.
//
const target_triplet& tgt (cast<target_triplet> (rs["bin.target"]));
- // Register target types and configure their default "installability".
+ // Configure target type default "installability". Also register
+ // additional platform-specific types.
//
bool install_loaded (cast_false<bool> (rs["install.loaded"]));
{
using namespace install;
- if (first)
- {
- // NOTE: remember to update the documentation if changing anything
- // here!
- //
- rs.insert_target_type<obj> ();
- rs.insert_target_type<obje> ();
- rs.insert_target_type<obja> ();
- rs.insert_target_type<objs> ();
-
- rs.insert_target_type<bmi> ();
- rs.insert_target_type<bmie> ();
- rs.insert_target_type<bmia> ();
- rs.insert_target_type<bmis> ();
-
- rs.insert_target_type<hbmi> ();
- rs.insert_target_type<hbmie> ();
- rs.insert_target_type<hbmia> ();
- rs.insert_target_type<hbmis> ();
-
- rs.insert_target_type<libul> ();
- rs.insert_target_type<libue> ();
- rs.insert_target_type<libua> ();
- rs.insert_target_type<libus> ();
-
- rs.insert_target_type<lib> ();
- rs.insert_target_type<liba> ();
- rs.insert_target_type<libs> ();
-
- // Register the def{} target type. Note that we do it here since it
- // is input and can be specified unconditionally (i.e., not only
- // when building for Windows).
- //
- rs.insert_target_type<def> ();
- }
-
// Note: libu*{} members are not installable.
//
if (install_loaded)
@@ -549,6 +580,8 @@ namespace build2
if (tgt.cpu == "wasm32" || tgt.cpu == "wasm64")
{
+ // @@ TODO: shouldn't this be wrapped in if(first) somehow?
+
const target_type& wasm (
rs.derive_target_type(
target_type {
@@ -945,6 +978,8 @@ namespace build2
if (lid == "msvc")
{
+ // @@ TODO: shouldn't this be wrapped in if(first) somehow?
+
const target_type& pdb (
rs.derive_target_type(
target_type {
@@ -1219,6 +1254,7 @@ namespace build2
// changing anything here.
{"bin.vars", nullptr, vars_init},
+ {"bin.types", nullptr, types_init},
{"bin.config", nullptr, config_init},
{"bin.ar.config", nullptr, ar_config_init},
{"bin.ar", nullptr, ar_init},
diff --git a/libbuild2/bin/init.hxx b/libbuild2/bin/init.hxx
index 4eb0f10..b163bf5 100644
--- a/libbuild2/bin/init.hxx
+++ b/libbuild2/bin/init.hxx
@@ -20,9 +20,11 @@ namespace build2
// Submodules:
//
// `bin.vars` -- registers some variables.
+ // `bin.types` -- registers target types.
// `bin.config` -- loads bin.vars and sets some variables.
- // `bin` -- loads bin.config and registers target types and
- // rules.
+ // `bin` -- loads bin.{types,config} and registers rules and
+ // functions.
+ //
// `bin.ar.config` -- loads bin.config and registers/sets more variables.
// `bin.ar` -- loads bin and bin.ar.config.
//
diff --git a/libbuild2/c/init.cxx b/libbuild2/c/init.cxx
index d8d7488..3c03c9c 100644
--- a/libbuild2/c/init.cxx
+++ b/libbuild2/c/init.cxx
@@ -6,9 +6,12 @@
#include <libbuild2/scope.hxx>
#include <libbuild2/diagnostics.hxx>
+#include <libbuild2/install/utility.hxx>
+
#include <libbuild2/cc/guess.hxx>
#include <libbuild2/cc/module.hxx>
+#include <libbuild2/cc/target.hxx> // pc*
#include <libbuild2/c/target.hxx>
#ifndef BUILD2_DEFAULT_C
@@ -154,6 +157,79 @@ namespace build2
}
}
+ // See cc::data::x_{hdr,inc} for background.
+ //
+ static const target_type* const hdr[] =
+ {
+ &h::static_type,
+ nullptr
+ };
+
+ // Note that we include S{} here because .S files can include each other.
+ // (And maybe from inline assembler instructions?)
+ //
+ static const target_type* const inc[] =
+ {
+ &h::static_type,
+ &c::static_type,
+ &m::static_type,
+ &S::static_type,
+ &c_inc::static_type,
+ nullptr
+ };
+
+ bool
+ types_init (scope& rs,
+ scope& bs,
+ const location& loc,
+ bool,
+ bool,
+ module_init_extra&)
+ {
+ tracer trace ("c::types_init");
+ l5 ([&]{trace << "for " << bs;});
+
+ // We only support root loading (which means there can only be one).
+ //
+ if (rs != bs)
+ fail (loc) << "c.types module must be loaded in project root";
+
+ // Register target types and configure their "installability".
+ //
+ using namespace install;
+
+ bool install_loaded (cast_false<bool> (rs["install.loaded"]));
+
+ // Note: not registering m{} or S{} (they are registered seperately
+ // by the respective optional .types submodules).
+ //
+ rs.insert_target_type<c> ();
+
+ auto insert_hdr = [&rs, install_loaded] (const target_type& tt)
+ {
+ rs.insert_target_type (tt);
+
+ // Install headers into install.include.
+ //
+ if (install_loaded)
+ install_path (rs, tt, dir_path ("include"));
+ };
+
+ for (const target_type* const* ht (hdr); *ht != nullptr; ++ht)
+ insert_hdr (**ht);
+
+ // @@ PERF: maybe factor this to cc.types?
+ //
+ rs.insert_target_type<cc::pc> ();
+ rs.insert_target_type<cc::pca> ();
+ rs.insert_target_type<cc::pcs> ();
+
+ if (install_loaded)
+ install_path<cc::pc> (rs, dir_path ("pkgconfig"));
+
+ return true;
+ }
+
static const char* const hinters[] = {"cxx", nullptr};
// See cc::module for details on guess_init vs config_init.
@@ -343,25 +419,6 @@ namespace build2
return true;
}
- static const target_type* const hdr[] =
- {
- &h::static_type,
- nullptr
- };
-
- // Note that we include S{} here because .S files can include each other.
- // (And maybe from inline assembler instructions?)
- //
- static const target_type* const inc[] =
- {
- &h::static_type,
- &c::static_type,
- &m::static_type,
- &S::static_type,
- &c_inc::static_type,
- nullptr
- };
-
bool
init (scope& rs,
scope& bs,
@@ -435,6 +492,29 @@ namespace build2
}
bool
+ objc_types_init (scope& rs,
+ scope& bs,
+ const location& loc,
+ bool,
+ bool,
+ module_init_extra&)
+ {
+ tracer trace ("c::objc_types_init");
+ l5 ([&]{trace << "for " << bs;});
+
+ // We only support root loading (which means there can only be one).
+ //
+ if (rs != bs)
+ fail (loc) << "c.objc.types module must be loaded in project root";
+
+ // Register the m{} target type.
+ //
+ rs.insert_target_type<m> ();
+
+ return true;
+ }
+
+ bool
objc_init (scope& rs,
scope& bs,
const location& loc,
@@ -463,7 +543,7 @@ namespace build2
//
// Note: see similar code in the cxx module.
//
- rs.insert_target_type<m> ();
+ load_module (rs, rs, "c.objc.types", loc);
// Note that while Objective-C is supported by MinGW GCC, it's unlikely
// Clang supports it when targeting MSVC or Emscripten. But let's keep
@@ -477,6 +557,29 @@ namespace build2
}
bool
+ as_cpp_types_init (scope& rs,
+ scope& bs,
+ const location& loc,
+ bool,
+ bool,
+ module_init_extra&)
+ {
+ tracer trace ("c::as_cpp_types_init");
+ l5 ([&]{trace << "for " << bs;});
+
+ // We only support root loading (which means there can only be one).
+ //
+ if (rs != bs)
+ fail (loc) << "c.as-cpp.types module must be loaded in project root";
+
+ // Register the S{} target type.
+ //
+ rs.insert_target_type<S> ();
+
+ return true;
+ }
+
+ bool
as_cpp_init (scope& rs,
scope& bs,
const location& loc,
@@ -503,7 +606,7 @@ namespace build2
// C compiler is capable of compiling Assember with C preprocessor. But
// we enable only if it is.
//
- rs.insert_target_type<S> ();
+ load_module (rs, rs, "c.as-cpp.types", loc);
if (mod->ctype == compiler_type::gcc ||
mod->ctype == compiler_type::clang)
@@ -553,13 +656,16 @@ namespace build2
// NOTE: don't forget to also update the documentation in init.hxx if
// changing anything here.
- {"c.guess", nullptr, guess_init},
- {"c.config", nullptr, config_init},
- {"c.objc", nullptr, objc_init},
- {"c.as-cpp", nullptr, as_cpp_init},
- {"c.predefs", nullptr, predefs_init},
- {"c", nullptr, init},
- {nullptr, nullptr, nullptr}
+ {"c.types", nullptr, types_init},
+ {"c.guess", nullptr, guess_init},
+ {"c.config", nullptr, config_init},
+ {"c.objc.types", nullptr, objc_types_init},
+ {"c.objc", nullptr, objc_init},
+ {"c.as-cpp.types", nullptr, as_cpp_types_init},
+ {"c.as-cpp", nullptr, as_cpp_init},
+ {"c.predefs", nullptr, predefs_init},
+ {"c", nullptr, init},
+ {nullptr, nullptr, nullptr}
};
const module_functions*
diff --git a/libbuild2/c/init.hxx b/libbuild2/c/init.hxx
index 713a78a..38515c1 100644
--- a/libbuild2/c/init.hxx
+++ b/libbuild2/c/init.hxx
@@ -19,15 +19,22 @@ namespace build2
//
// Submodules:
//
- // `c.guess` -- registers and sets some variables.
- // `c.config` -- loads c.guess and sets more variables.
- // `c` -- loads c.config and registers target types and rules.
- // `c.objc` -- registers m{} target type and enables Objective-C
- // compilation. Must be loaded after c.
- // `c.as-cpp` -- registers S{} target type and enables Assembler with
- // C preprocessor compilation. Must be loaded after c.
- // `c.predefs` -- registers rule for generating a C header with
- // predefined compiler macros. Must be loaded after c.
+ // `c.types` -- registers target types.
+ // `c.guess` -- registers and sets some variables.
+ // `c.config` -- loads c.guess and sets more variables.
+ // `c` -- loads c.{types,config} and registers rules and
+ // functions.
+ //
+ // `c.objc.types` -- registers m{} target type.
+ // `c.objc` -- loads c.objc.types and enables Objective-C
+ // compilation. Must be loaded after c.
+ //
+ // `c.as-cpp.types` -- registers S{} target type.
+ // `c.as-cpp` -- loads c.as-cpp.types and enables Assembler with C
+ // preprocessor compilation. Must be loaded after c.
+ //
+ // `c.predefs` -- registers rule for generating a C header with
+ // predefined compiler macros. Must be loaded after c.
//
extern "C" LIBBUILD2_C_SYMEXPORT const module_functions*
build2_c_load ();
diff --git a/libbuild2/cc/module.cxx b/libbuild2/cc/module.cxx
index eed7db1..70624a2 100644
--- a/libbuild2/cc/module.cxx
+++ b/libbuild2/cc/module.cxx
@@ -11,10 +11,7 @@
#include <libbuild2/bin/target.hxx>
-#include <libbuild2/cc/target.hxx> // pc*
-
#include <libbuild2/config/utility.hxx>
-#include <libbuild2/install/utility.hxx>
#include <libbuild2/cc/guess.hxx>
@@ -989,43 +986,7 @@ namespace build2
// Register target types and configure their "installability".
//
- bool install_loaded (cast_false<bool> (rs["install.loaded"]));
-
- {
- using namespace install;
-
- // Note: not registering x_obj or x_asp (they are registered
- // seperately by the respective optional submodules).
- //
- rs.insert_target_type (x_src);
-
- auto insert_hdr = [&rs, install_loaded] (const target_type& tt)
- {
- rs.insert_target_type (tt);
-
- // Install headers into install.include.
- //
- if (install_loaded)
- install_path (rs, tt, dir_path ("include"));
- };
-
- // Note: module (x_mod) is in x_hdrs.
- //
- for (const target_type* const* ht (x_hdrs); *ht != nullptr; ++ht)
- insert_hdr (**ht);
-
- // Also register the C header for C-derived languages.
- //
- if (*x_hdrs != &h::static_type)
- insert_hdr (h::static_type);
-
- rs.insert_target_type<pc> ();
- rs.insert_target_type<pca> ();
- rs.insert_target_type<pcs> ();
-
- if (install_loaded)
- install_path<pc> (rs, dir_path ("pkgconfig"));
- }
+ load_module (rs, rs, (string (x) += ".types"), loc);
// Register rules.
//
@@ -1123,7 +1084,7 @@ namespace build2
// them in case they depend on stuff that we need to install (see the
// install rule implementations for details).
//
- if (install_loaded)
+ if (cast_false<bool> (rs["install.loaded"]))
{
// Note: we rely quite heavily in these rule implementations that
// these are the only target types they are registered for.
diff --git a/libbuild2/cxx/init.cxx b/libbuild2/cxx/init.cxx
index 7dadce8..941593e 100644
--- a/libbuild2/cxx/init.cxx
+++ b/libbuild2/cxx/init.cxx
@@ -7,10 +7,12 @@
#include <libbuild2/diagnostics.hxx>
#include <libbuild2/config/utility.hxx>
+#include <libbuild2/install/utility.hxx>
#include <libbuild2/cc/guess.hxx>
#include <libbuild2/cc/module.hxx>
+#include <libbuild2/cc/target.hxx> // pc*
#include <libbuild2/cxx/target.hxx>
#ifndef BUILD2_DEFAULT_CXX
@@ -617,6 +619,95 @@ namespace build2
//set_feature (concepts);
}
+ // See cc::data::x_{hdr,inc} for background.
+ //
+ static const target_type* const hdr[] =
+ {
+ &hxx::static_type,
+ &ixx::static_type,
+ &txx::static_type,
+ &mxx::static_type,
+ nullptr
+ };
+
+ // Note that we don't include S{} here because none of the files we
+ // compile can plausibly want to include .S. (Maybe in inline assembler
+ // instructions?)
+ //
+ static const target_type* const inc[] =
+ {
+ &hxx::static_type,
+ &h::static_type,
+ &ixx::static_type,
+ &txx::static_type,
+ &mxx::static_type,
+ &cxx::static_type,
+ &c::static_type,
+ &mm::static_type,
+ &m::static_type,
+ &cxx_inc::static_type,
+ &cc::c_inc::static_type,
+ nullptr
+ };
+
+ bool
+ types_init (scope& rs,
+ scope& bs,
+ const location& loc,
+ bool,
+ bool,
+ module_init_extra&)
+ {
+ tracer trace ("cxx::types_init");
+ l5 ([&]{trace << "for " << bs;});
+
+ // We only support root loading (which means there can only be one).
+ //
+ if (rs != bs)
+ fail (loc) << "cxx.types module must be loaded in project root";
+
+ // Register target types and configure their "installability".
+ //
+ using namespace install;
+
+ bool install_loaded (cast_false<bool> (rs["install.loaded"]));
+
+ // Note: not registering mm{} (it is registered seperately by the
+ // respective optional .types submodule).
+ //
+ // Note: mxx{} is in hdr. @@ But maybe it shouldn't be...
+ //
+ rs.insert_target_type<cxx> ();
+
+ auto insert_hdr = [&rs, install_loaded] (const target_type& tt)
+ {
+ rs.insert_target_type (tt);
+
+ // Install headers into install.include.
+ //
+ if (install_loaded)
+ install_path (rs, tt, dir_path ("include"));
+ };
+
+ for (const target_type* const* ht (hdr); *ht != nullptr; ++ht)
+ insert_hdr (**ht);
+
+ // Also register the C header for C-derived languages.
+ //
+ insert_hdr (h::static_type);
+
+ // @@ PERF: maybe factor this to cc.types?
+ //
+ rs.insert_target_type<cc::pc> ();
+ rs.insert_target_type<cc::pca> ();
+ rs.insert_target_type<cc::pcs> ();
+
+ if (install_loaded)
+ install_path<cc::pc> (rs, dir_path ("pkgconfig"));
+
+ return true;
+ }
+
static const char* const hinters[] = {"c", nullptr};
// See cc::module for details on guess_init vs config_init.
@@ -948,35 +1039,6 @@ namespace build2
return true;
}
- static const target_type* const hdr[] =
- {
- &hxx::static_type,
- &ixx::static_type,
- &txx::static_type,
- &mxx::static_type,
- nullptr
- };
-
- // Note that we don't include S{} here because none of the files we
- // compile can plausibly want to include .S. (Maybe in inline assembler
- // instructions?)
- //
- static const target_type* const inc[] =
- {
- &hxx::static_type,
- &h::static_type,
- &ixx::static_type,
- &txx::static_type,
- &mxx::static_type,
- &cxx::static_type,
- &c::static_type,
- &mm::static_type,
- &m::static_type,
- &cxx_inc::static_type,
- &cc::c_inc::static_type,
- nullptr
- };
-
bool
init (scope& rs,
scope& bs,
@@ -1062,12 +1124,35 @@ namespace build2
}
bool
+ objcxx_types_init (scope& rs,
+ scope& bs,
+ const location& loc,
+ bool,
+ bool,
+ module_init_extra&)
+ {
+ tracer trace ("cxx::objcxx_types_init");
+ l5 ([&]{trace << "for " << bs;});
+
+ // We only support root loading (which means there can only be one).
+ //
+ if (rs != bs)
+ fail (loc) << "cxx.objcxx.types module must be loaded in project root";
+
+ // Register the mm{} target type.
+ //
+ rs.insert_target_type<mm> ();
+
+ return true;
+ }
+
+ bool
objcxx_init (scope& rs,
scope& bs,
const location& loc,
bool,
bool,
- module_init_extra&)
+ module_init_extra&)
{
tracer trace ("cxx::objcxx_init");
l5 ([&]{trace << "for " << bs;});
@@ -1090,7 +1175,7 @@ namespace build2
//
// Note: see similar code in the c module.
//
- rs.insert_target_type<mm> ();
+ load_module (rs, rs, "cxx.objcxx.types", loc);
// Note that while Objective-C++ is supported by MinGW GCC, it's
// unlikely Clang supports it when targeting MSVC or Emscripten. But
@@ -1144,12 +1229,14 @@ namespace build2
// NOTE: don't forget to also update the documentation in init.hxx if
// changing anything here.
- {"cxx.guess", nullptr, guess_init},
- {"cxx.config", nullptr, config_init},
- {"cxx.objcxx", nullptr, objcxx_init},
- {"cxx.predefs", nullptr, predefs_init},
- {"cxx", nullptr, init},
- {nullptr, nullptr, nullptr}
+ {"cxx.types", nullptr, types_init},
+ {"cxx.guess", nullptr, guess_init},
+ {"cxx.config", nullptr, config_init},
+ {"cxx.objcxx.types", nullptr, objcxx_types_init},
+ {"cxx.objcxx", nullptr, objcxx_init},
+ {"cxx.predefs", nullptr, predefs_init},
+ {"cxx", nullptr, init},
+ {nullptr, nullptr, nullptr}
};
const module_functions*
diff --git a/libbuild2/cxx/init.hxx b/libbuild2/cxx/init.hxx
index 5b80fdc..a193e74 100644
--- a/libbuild2/cxx/init.hxx
+++ b/libbuild2/cxx/init.hxx
@@ -19,13 +19,19 @@ namespace build2
//
// Submodules:
//
- // `cxx.guess` -- registers and sets some variables.
- // `cxx.config` -- loads cxx.guess and sets more variables.
- // `cxx` -- loads cxx.config and registers target types and rules.
- // `cxx.objcxx` -- registers mm{} target type and enables Objective-C++
- // compilation.
- // `cxx.predefs` -- registers rule for generating a C++ header with
- // predefined compiler macros. Must be loaded after cxx.
+ // `cxx.types` -- registers target types.
+ // `cxx.guess` -- registers and sets some variables.
+ // `cxx.config` -- loads cxx.guess and sets more variables.
+ // `cxx` -- loads cxx.{types,config} and registers rules
+ // and functions.
+ //
+ // `cxx.objcxx.types` -- registers mm{} target type.
+ // `cxx.objcxx` -- loads cxx.objcxx and enables Objective-C++
+ // compilation.
+ //
+ // `cxx.predefs` -- registers rule for generating a C++ header with
+ // predefined compiler macros. Must be loaded after
+ // cxx.
//
extern "C" LIBBUILD2_CXX_SYMEXPORT const module_functions*
build2_cxx_load ();