diff options
Diffstat (limited to 'libbuild2/bin')
-rw-r--r-- | libbuild2/bin/def-rule.cxx | 10 | ||||
-rw-r--r-- | libbuild2/bin/init.cxx | 138 | ||||
-rw-r--r-- | libbuild2/bin/init.hxx | 6 | ||||
-rw-r--r-- | libbuild2/bin/target.cxx | 6 | ||||
-rw-r--r-- | libbuild2/bin/target.hxx | 15 | ||||
-rw-r--r-- | libbuild2/bin/utility.cxx | 4 |
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)); |