aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/bin
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/bin')
-rw-r--r--libbuild2/bin/def-rule.cxx10
-rw-r--r--libbuild2/bin/init.cxx138
-rw-r--r--libbuild2/bin/init.hxx6
-rw-r--r--libbuild2/bin/target.cxx6
-rw-r--r--libbuild2/bin/target.hxx15
-rw-r--r--libbuild2/bin/utility.cxx4
6 files changed, 124 insertions, 55 deletions
diff --git a/libbuild2/bin/def-rule.cxx b/libbuild2/bin/def-rule.cxx
index 0998c89..143cc35 100644
--- a/libbuild2/bin/def-rule.cxx
+++ b/libbuild2/bin/def-rule.cxx
@@ -417,6 +417,8 @@ namespace build2
// we will try to recognize C/C++ identifiers plus the special symbols
// that we need to export (e.g., vtable).
//
+ // Note that it looks like rdata should not be declared DATA. It is
+ // known to break ??_7 (vtable) exporting (see GH issue 315).
//
for (const string& s: syms.r)
{
@@ -424,7 +426,7 @@ namespace build2
(s[0] == '?' && s[1] != '?') || // C++
s.compare (0, 4, "??_7") == 0) // vtable
{
- os << " " << strip (s) << " DATA\n";
+ os << " " << strip (s) << '\n';
}
}
}
@@ -496,6 +498,12 @@ namespace build2
// we will try to recognize C/C++ identifiers plus the special symbols
// that we need to export (e.g., vtable and typeinfo).
//
+ // For the description of GNU binutils .def format, see:
+ //
+ // https://sourceware.org/binutils/docs/binutils/def-file-format.html
+ //
+ // @@ Maybe CONSTANT is more appropriate than DATA?
+ //
for (const string& s: syms.r)
{
if (s.find_first_of (".") != string::npos) // Special (.refptr.*)
diff --git a/libbuild2/bin/init.cxx b/libbuild2/bin/init.cxx
index 78119cb..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.
//
@@ -79,6 +82,9 @@ namespace build2
// example, addition of rpaths for prerequisite libraries (see the cc
// module for an example). Default is true.
//
+ // Note also that a rule may need to make rpath relative if
+ // install.relocatable is true.
+ //
vp.insert<dir_paths> ("config.bin.rpath");
vp.insert<bool> ("config.bin.rpath.auto");
@@ -107,12 +113,12 @@ namespace build2
// Link whole archive. Note: with target visibility.
//
// The lookup semantics is as follows: we first look for a prerequisite-
- // specific value, then for a target-specific value in the library being
- // linked, and then for target type/pattern-specific value starting from
- // the scope of the target being linked-to. In that final lookup we do
- // not look in the target being linked-to itself since that is used to
- // indicate how this target should be linked to other targets. For
- // example:
+ // specific value, then for a target-specific value in the prerequisite
+ // library, and then for target type/pattern-specific value starting
+ // from the scope of the target being linked. In that final lookup we do
+ // not look in the target being linked itself since that is used to
+ // indicate how this target should be used as a prerequisite of other
+ // targets. For example:
//
// exe{test}: liba{foo}
// liba{foo}: libua{foo1 foo2}
@@ -153,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
@@ -447,53 +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)
- {
- 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)
@@ -543,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 {
@@ -553,7 +592,7 @@ namespace build2
nullptr, /* default_extension */
&target_pattern_fix<wasm_ext>,
&target_print_0_ext_verb, // Fixed extension, no use printing.
- &file_search,
+ &target_search, // Note: don't look for an existing file.
target_type::flag::none}));
if (install_loaded)
@@ -939,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 {
@@ -949,7 +990,7 @@ namespace build2
nullptr, /* default_extension */
&target_pattern_fix<pdb_ext>,
&target_print_0_ext_verb, // Fixed extension, no use printing.
- &file_search,
+ &target_search, // Note: don't look for an existing file.
target_type::flag::none}));
if (cast_false<bool> (rs["install.loaded"]))
@@ -1213,8 +1254,8 @@ namespace build2
// changing anything here.
{"bin.vars", nullptr, vars_init},
+ {"bin.types", nullptr, types_init},
{"bin.config", nullptr, config_init},
- {"bin", nullptr, init},
{"bin.ar.config", nullptr, ar_config_init},
{"bin.ar", nullptr, ar_init},
{"bin.ld.config", nullptr, ld_config_init},
@@ -1224,6 +1265,7 @@ namespace build2
{"bin.nm.config", nullptr, nm_config_init},
{"bin.nm", nullptr, nm_init},
{"bin.def", nullptr, def_init},
+ {"bin", nullptr, init},
{nullptr, nullptr, nullptr}
};
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/bin/target.cxx b/libbuild2/bin/target.cxx
index 38572ef..7e4875a 100644
--- a/libbuild2/bin/target.cxx
+++ b/libbuild2/bin/target.cxx
@@ -374,7 +374,7 @@ namespace build2
&target_extension_var<nullptr>,
&target_pattern_var<nullptr>,
nullptr,
- &file_search,
+ &target_search, // Note: not _file(); don't look for an existing file.
target_type::flag::none
};
@@ -387,7 +387,7 @@ namespace build2
&target_extension_var<nullptr>,
&target_pattern_var<nullptr>,
nullptr,
- &file_search,
+ &target_search, // Note: not _file(); don't look for an existing file.
target_type::flag::none
};
@@ -452,7 +452,7 @@ namespace build2
&target_extension_var<nullptr>,
&target_pattern_var<nullptr>,
nullptr,
- &file_search,
+ &target_search, // Note: not _file(); don't look for an existing file.
target_type::flag::none
};
diff --git a/libbuild2/bin/target.hxx b/libbuild2/bin/target.hxx
index 9685e39..8f2a92e 100644
--- a/libbuild2/bin/target.hxx
+++ b/libbuild2/bin/target.hxx
@@ -412,6 +412,21 @@ namespace build2
virtual group_view
group_members (action) const override;
+ // Match options for the install operation on the liba{}/libs{} and
+ // libua{}/libus{} target types (note: not lib{}/libul{} nor libue{}).
+ //
+ // If only install_runtime option is specified, then only install the
+ // runtime files omitting everything buildtime (headers, pkg-config
+ // files, shared library version-related symlinks, etc).
+ //
+ // Note that it's either runtime-only or runtime and buildtime (i.e.,
+ // everything), so match with install_all instead of install_buildtime
+ // (the latter is only useful in the rule implementations).
+ //
+ static constexpr uint64_t option_install_runtime = 0x01;
+ static constexpr uint64_t option_install_buildtime = 0x02;
+ static constexpr uint64_t option_install_all = match_extra::all_options;
+
public:
static const target_type static_type;
};
diff --git a/libbuild2/bin/utility.cxx b/libbuild2/bin/utility.cxx
index 2a87bbd..a03ea50 100644
--- a/libbuild2/bin/utility.cxx
+++ b/libbuild2/bin/utility.cxx
@@ -89,7 +89,9 @@ namespace build2
// Make sure group members are resolved.
//
group_view gv (resolve_members (a, l));
- assert (gv.members != nullptr);
+
+ if (gv.members == nullptr)
+ fail << "group " << l << " has no members";
pair<otype, bool> p (
link_member (lmembers {l.a != nullptr, l.s != nullptr}, li.order));