aboutsummaryrefslogtreecommitdiff
path: root/build2/cc/init.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/cc/init.cxx')
-rw-r--r--build2/cc/init.cxx233
1 files changed, 117 insertions, 116 deletions
diff --git a/build2/cc/init.cxx b/build2/cc/init.cxx
index 066367d..42412a7 100644
--- a/build2/cc/init.cxx
+++ b/build2/cc/init.cxx
@@ -74,8 +74,8 @@ namespace build2
}
bool
- core_config_init (scope& r,
- scope& b,
+ core_config_init (scope& rs,
+ scope&,
const location& loc,
unique_ptr<module_base>&,
bool first,
@@ -83,96 +83,93 @@ namespace build2
const variable_map& hints)
{
tracer trace ("cc::core_config_init");
- l5 ([&]{trace << "for " << b.out_path ();});
+ l5 ([&]{trace << "for " << rs.out_path ();});
+
+ assert (first);
// Load cc.core.vars.
//
- if (first)
- {
- if (!cast_false<bool> (b["cc.core.vars.loaded"]))
- load_module ("cc.core.vars", r, b, loc);
- }
+ if (!cast_false<bool> (rs["cc.core.vars.loaded"]))
+ load_module ("cc.core.vars", rs, rs, loc);
// Configure.
//
- if (first)
+
+ // Adjust module priority (compiler).
+ //
+ config::save_module (rs, "cc", 250);
+
+ // config.cc.id
+ //
{
- // Adjust module priority (compiler).
+ // This value must be hinted.
//
- config::save_module (r, "cc", 250);
+ rs.assign<string> ("cc.id") = cast<string> (hints["config.cc.id"]);
+ }
- // config.cc.id
+ // config.cc.target
+ //
+ {
+ // This value must be hinted and already canonicalized.
//
+ const string& s (cast<string> (hints["config.cc.target"]));
+
+ try
{
- // This value must be hinted.
+ //@@ We do it in the hinting module and here. Any way not to
+ // duplicate the effort? Maybe move the splitting here and
+ // simply duplicate the values there?
//
- r.assign<string> ("cc.id") = cast<string> (hints["config.cc.id"]);
- }
+ triplet t (s);
- // config.cc.target
- //
- {
- // This value must be hinted and already canonicalized.
+ // Enter as cc.target.{cpu,vendor,system,version,class}.
//
- const string& s (cast<string> (hints["config.cc.target"]));
-
- try
- {
- //@@ We do it in the hinting module and here. Any way not to
- // duplicate the effort? Maybe move the splitting here and
- // simply duplicate the values there?
- //
- triplet t (s);
-
- // Enter as cc.target.{cpu,vendor,system,version,class}.
- //
- r.assign<string> ("cc.target") = s;
- r.assign<string> ("cc.target.cpu") = move (t.cpu);
- r.assign<string> ("cc.target.vendor") = move (t.vendor);
- r.assign<string> ("cc.target.system") = move (t.system);
- r.assign<string> ("cc.target.version") = move (t.version);
- r.assign<string> ("cc.target.class") = move (t.class_);
- }
- catch (const invalid_argument& e)
- {
- assert (false); // Should have been caught by the hinting module.
- }
+ rs.assign<string> ("cc.target") = s;
+ rs.assign<string> ("cc.target.cpu") = move (t.cpu);
+ rs.assign<string> ("cc.target.vendor") = move (t.vendor);
+ rs.assign<string> ("cc.target.system") = move (t.system);
+ rs.assign<string> ("cc.target.version") = move (t.version);
+ rs.assign<string> ("cc.target.class") = move (t.class_);
}
-
- // config.cc.pattern
- //
+ catch (const invalid_argument& e)
{
- // This value could be hinted.
- //
- if (auto l = hints["config.cc.pattern"])
- r.assign<string> ("cc.pattern") = cast<string> (l);
+ assert (false); // Should have been caught by the hinting module.
}
+ }
- // Note that we are not having a config report since it will just
- // duplicate what has already been printed by the hinting module.
+ // config.cc.pattern
+ //
+ {
+ // This value could be hinted.
+ //
+ if (auto l = hints["config.cc.pattern"])
+ rs.assign<string> ("cc.pattern") = cast<string> (l);
}
+ // Note that we are not having a config report since it will just
+ // duplicate what has already been printed by the hinting module.
+
// config.cc.{p,c,l}options
// config.cc.libs
//
// @@ Same nonsense as in module.
//
//
- b.assign ("cc.poptions") += cast_null<strings> (
- config::optional (r, "config.cc.poptions"));
+ rs.assign ("cc.poptions") += cast_null<strings> (
+ config::optional (rs, "config.cc.poptions"));
- b.assign ("cc.coptions") += cast_null<strings> (
- config::optional (r, "config.cc.coptions"));
+ rs.assign ("cc.coptions") += cast_null<strings> (
+ config::optional (rs, "config.cc.coptions"));
- b.assign ("cc.loptions") += cast_null<strings> (
- config::optional (r, "config.cc.loptions"));
+ rs.assign ("cc.loptions") += cast_null<strings> (
+ config::optional (rs, "config.cc.loptions"));
- b.assign ("cc.libs") += cast_null<strings> (
- config::optional (r, "config.cc.libs"));
+ rs.assign ("cc.libs") += cast_null<strings> (
+ config::optional (rs, "config.cc.libs"));
// Load the bin.config module.
//
- if (!cast_false<bool> (b["bin.config.loaded"]))
+ if (!cast_false<bool> (rs["bin.config.loaded"]))
{
// Prepare configuration hints. They are only used on the first load
// of bin.config so we only populate them on our first load.
@@ -180,13 +177,13 @@ namespace build2
variable_map h;
if (first)
{
- h.assign ("config.bin.target") = cast<string> (r["cc.target"]);
+ h.assign ("config.bin.target") = cast<string> (rs["cc.target"]);
if (auto l = hints["config.bin.pattern"])
- h.assign ("config.bin.pattern") = cast<string> (l);
+ h.assign ("config.bin.pattern") = cast<string> (l);
}
- load_module ("bin.config", r, b, loc, false, h);
+ load_module ("bin.config", rs, rs, loc, false, h);
}
// Verify bin's target matches ours (we do it even if we loaded it
@@ -195,8 +192,8 @@ namespace build2
//
if (first)
{
- const string& ct (cast<string> (r["cc.target"]));
- const string& bt (cast<string> (r["bin.target"]));
+ const string& ct (cast<string> (rs["cc.target"]));
+ const string& bt (cast<string> (rs["bin.target"]));
if (bt != ct)
fail (loc) << "cc and bin module target mismatch" <<
@@ -204,31 +201,31 @@ namespace build2
info << "bin.target is " << bt;
}
- const string& cid (cast<string> (r["cc.id"]));
- const string& tsys (cast<string> (r["cc.target.system"]));
+ const string& cid (cast<string> (rs["cc.id"]));
+ const string& tsys (cast<string> (rs["cc.target.system"]));
// Load bin.*.config for bin.* modules we may need (see core_init()
// below).
//
- if (auto l = r["config.bin.lib"])
+ if (auto l = rs["config.bin.lib"])
{
if (cast<string> (l) != "shared")
{
- if (!cast_false<bool> (b["bin.ar.config.loaded"]))
- load_module ("bin.ar.config", r, b, loc);
+ if (!cast_false<bool> (rs["bin.ar.config.loaded"]))
+ load_module ("bin.ar.config", rs, rs, loc);
}
}
if (cid == "msvc")
{
- if (!cast_false<bool> (b["bin.ld.config.loaded"]))
- load_module ("bin.ld.config", r, b, loc);
+ if (!cast_false<bool> (rs["bin.ld.config.loaded"]))
+ load_module ("bin.ld.config", rs, rs, loc);
}
if (tsys == "mingw32")
{
- if (!cast_false<bool> (b["bin.rc.config.loaded"]))
- load_module ("bin.rc.config", r, b, loc);
+ if (!cast_false<bool> (rs["bin.rc.config.loaded"]))
+ load_module ("bin.rc.config", rs, rs, loc);
}
// Load (optionally) the pkgconfig.config module.
@@ -238,53 +235,55 @@ namespace build2
// doesn't set pkgconfig.target. Perhaps only set if it was used
// to derive the program name?
//
- if (first && !cast_false<bool> (b["pkgconfig.config.loaded"]))
+ if (!cast_false<bool> (rs["pkgconfig.config.loaded"]))
{
// Prepare configuration hints.
//
variable_map h;
- h.assign ("config.pkgconfig.target") = cast<string> (r["cc.target"]);
+ h.assign ("config.pkgconfig.target") = cast<string> (rs["cc.target"]);
- load_module ("pkgconfig.config", r, r, loc, true, h);
+ load_module ("pkgconfig.config", rs, rs, loc, true, h);
}
return true;
}
bool
- core_init (scope& r,
- scope& b,
+ core_init (scope& rs,
+ scope&,
const location& loc,
unique_ptr<module_base>&,
- bool,
+ bool first,
bool,
const variable_map& hints)
{
tracer trace ("cc::core_init");
- l5 ([&]{trace << "for " << b.out_path ();});
+ l5 ([&]{trace << "for " << rs.out_path ();});
+
+ assert (first);
// Load cc.core.config.
//
- if (!cast_false<bool> (b["cc.core.config.loaded"]))
- load_module ("cc.core.config", r, b, loc, false, hints);
+ if (!cast_false<bool> (rs["cc.core.config.loaded"]))
+ load_module ("cc.core.config", rs, rs, loc, false, hints);
// Load the bin module.
//
- if (!cast_false<bool> (b["bin.loaded"]))
- load_module ("bin", r, b, loc);
+ if (!cast_false<bool> (rs["bin.loaded"]))
+ load_module ("bin", rs, rs, loc);
- const string& cid (cast<string> (r["cc.id"]));
- const string& tsys (cast<string> (r["cc.target.system"]));
+ const string& cid (cast<string> (rs["cc.id"]));
+ const string& tsys (cast<string> (rs["cc.target.system"]));
// Load the bin.ar module unless we were asked to only build shared
// libraries.
//
- if (auto l = r["config.bin.lib"])
+ if (auto l = rs["config.bin.lib"])
{
if (cast<string> (l) != "shared")
{
- if (!cast_false<bool> (b["bin.ar.loaded"]))
- load_module ("bin.ar", r, b, loc);
+ if (!cast_false<bool> (rs["bin.ar.loaded"]))
+ load_module ("bin.ar", rs, rs, loc);
}
}
@@ -293,8 +292,8 @@ namespace build2
//
if (cid == "msvc")
{
- if (!cast_false<bool> (b["bin.ld.loaded"]))
- load_module ("bin.ld", r, b, loc);
+ if (!cast_false<bool> (rs["bin.ld.loaded"]))
+ load_module ("bin.ld", rs, rs, loc);
}
// If our target is MinGW, then we will need the resource compiler
@@ -302,8 +301,8 @@ namespace build2
//
if (tsys == "mingw32")
{
- if (!cast_false<bool> (b["bin.rc.loaded"]))
- load_module ("bin.rc", r, b, loc);
+ if (!cast_false<bool> (rs["bin.rc.loaded"]))
+ load_module ("bin.rc", rs, rs, loc);
}
return true;
@@ -315,45 +314,51 @@ namespace build2
//
static inline bool
init_alias (tracer& trace,
+ const char* m,
const char* c,
const char* c_loaded,
const char* cxx,
const char* cxx_loaded,
- scope& r,
- scope& b,
+ scope& rs,
+ scope& bs,
const location& loc,
const variable_map& hints)
{
- l5 ([&]{trace << "for " << b.out_path ();});
+ l5 ([&]{trace << "for " << bs.out_path ();});
+
+ // We only support root loading (which means there can only be one).
+ //
+ if (&rs != &bs)
+ fail (loc) << m << " module must be loaded in project root";
// We want to order the loading to match what user specified on the
// command line (config.c or config.cxx). This way the first loaded
// module (with user-specified config.*) will hint the compiler to the
// second.
//
- bool lc (!cast_false<bool> (b[c_loaded]));
- bool lp (!cast_false<bool> (b[cxx_loaded]));
+ bool lc (!cast_false<bool> (rs[c_loaded]));
+ bool lp (!cast_false<bool> (rs[cxx_loaded]));
// If none of them are already loaded, load c first only if config.c
// is specified.
//
- if (lc && lp && r["config.c"])
+ if (lc && lp && rs["config.c"])
{
- load_module (c, r, b, loc, false, hints);
- load_module (cxx, r, b, loc, false, hints);
+ load_module (c, rs, rs, loc, false, hints);
+ load_module (cxx, rs, rs, loc, false, hints);
}
else
{
- if (lp) load_module (cxx, r, b, loc, false, hints);
- if (lc) load_module (c, r, b, loc, false, hints);
+ if (lp) load_module (cxx, rs, rs, loc, false, hints);
+ if (lc) load_module (c, rs, rs, loc, false, hints);
}
return true;
}
bool
- config_init (scope& r,
- scope& b,
+ config_init (scope& rs,
+ scope& bs,
const location& loc,
unique_ptr<module_base>&,
bool,
@@ -361,17 +366,15 @@ namespace build2
const variable_map& hints)
{
tracer trace ("cc::config_init");
- return init_alias (trace,
+ return init_alias (trace, "cc.config",
"c.config", "c.config.loaded",
"cxx.config", "cxx.config.loaded",
- r, b,
- loc,
- hints);
+ rs, bs, loc, hints);
}
bool
- init (scope& r,
- scope& b,
+ init (scope& rs,
+ scope& bs,
const location& loc,
unique_ptr<module_base>&,
bool,
@@ -379,12 +382,10 @@ namespace build2
const variable_map& hints)
{
tracer trace ("cc::init");
- return init_alias (trace,
+ return init_alias (trace, "cc",
"c", "c.loaded",
"cxx", "cxx.loaded",
- r, b,
- loc,
- hints);
+ rs, bs, loc, hints);
}
}
}