aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-08-24 16:37:29 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-08-28 15:01:48 +0300
commitea24f530048cbce0c5335ca3fd3632c8ce34315a (patch)
tree3f7153cad1c3e34da5e992fe53db104512d7af71 /build2
parentd07521c67db21aa02dddf9615dce9f9f3dfe784c (diff)
Move bin build system module to separate library
Diffstat (limited to 'build2')
-rw-r--r--build2/b.cxx13
-rw-r--r--build2/bin/guess.cxx464
-rw-r--r--build2/bin/guess.hxx108
-rw-r--r--build2/bin/init.cxx940
-rw-r--r--build2/bin/init.hxx100
-rw-r--r--build2/bin/rule.cxx89
-rw-r--r--build2/bin/rule.hxx63
-rw-r--r--build2/bin/target.cxx474
-rw-r--r--build2/bin/target.hxx353
-rw-r--r--build2/buildfile2
-rw-r--r--build2/cc/common.hxx2
-rw-r--r--build2/cc/compile-rule.cxx2
-rw-r--r--build2/cc/gcc.cxx2
-rw-r--r--build2/cc/install-rule.cxx2
-rw-r--r--build2/cc/link-rule.cxx2
-rw-r--r--build2/cc/module.cxx2
-rw-r--r--build2/cc/msvc.cxx2
-rw-r--r--build2/cc/pkgconfig.cxx2
-rw-r--r--build2/cc/utility.cxx4
-rw-r--r--build2/cc/utility.hxx2
-rw-r--r--build2/cc/windows-rpath.cxx2
21 files changed, 15 insertions, 2615 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 27a9cd0..78f6248 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -53,6 +53,7 @@
#include <libbuild2/install/init.hxx>
#include <libbuild2/in/init.hxx>
+#include <libbuild2/bin/init.hxx>
#include <libbuild2/version/init.hxx>
#ifndef BUILD2_BOOTSTRAP
@@ -61,7 +62,6 @@
# include <build2/cli/init.hxx>
#endif
-#include <build2/bin/init.hxx>
#include <build2/c/init.hxx>
#include <build2/cc/init.hxx>
#include <build2/cxx/init.hxx>
@@ -519,19 +519,10 @@ main (int argc, char* argv[])
load (&test::build2_test_load);
load (&install::build2_install_load);
+ load (&bin::build2_bin_load);
load (&version::build2_version_load);
load (&in::build2_in_load);
- TMP_LOAD (bin_vars, "bin.vars", bin::vars_init);
- TMP_LOAD (bin_config, "bin.config", bin::config_init);
- TMP_LOAD (bin, "bin", bin::init);
- TMP_LOAD (bin_ar_config, "bin.ar.config", bin::ar_config_init);
- TMP_LOAD (bin_ar, "bin.ar", bin::ar_init);
- TMP_LOAD (bin_ld_config, "bin.ld.config", bin::ld_config_init);
- TMP_LOAD (bin_ld, "bin.ld", bin::ld_init);
- TMP_LOAD (bin_rc_config, "bin.rc.config", bin::rc_config_init);
- TMP_LOAD (bin_rc, "bin.rc", bin::rc_init);
-
TMP_LOAD (cc_core_vars, "cc.core.vars", cc::core_vars_init);
TMP_LOAD (cc_core_guess, "cc.core.guess", cc::core_guess_init);
TMP_LOAD (cc_core_config, "cc.core.config", cc::core_config_init);
diff --git a/build2/bin/guess.cxx b/build2/bin/guess.cxx
deleted file mode 100644
index d1b1545..0000000
--- a/build2/bin/guess.cxx
+++ /dev/null
@@ -1,464 +0,0 @@
-// file : build2/bin/guess.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <build2/bin/guess.hxx>
-
-#include <libbuild2/diagnostics.hxx>
-
-using namespace std;
-
-namespace build2
-{
- namespace bin
- {
- struct guess_result
- {
- string id;
- string signature;
- string checksum;
- semantic_version version;
-
- guess_result () = default;
- guess_result (string&& i, string&& s, semantic_version&& v)
- : id (move (i)), signature (move (s)), version (move (v)) {}
-
- bool
- empty () const {return id.empty ();}
- };
-
- // Try to parse a semantic-like version from the specified position.
- // Return 0-version if the version is invalid.
- //
- static inline semantic_version
- parse_version (const string& s, size_t p = 0, const char* bs = ".-+~ ")
- {
- optional<semantic_version> v (parse_semantic_version (s, p, bs));
- return v ? *v : semantic_version ();
- }
-
- ar_info
- guess_ar (const path& ar, const path* rl, const dir_path& fallback)
- {
- tracer trace ("bin::guess_ar");
-
- process_path arp, rlp;
- guess_result arr, rlr;
-
- {
- auto df = make_diag_frame (
- [](const diag_record& dr)
- {
- dr << info << "use config.bin.ar to override";
- });
-
- // Only search in PATH (specifically, omitting the current
- // executable's directory on Windows).
- //
- arp = run_search (ar, true, fallback, true /* path_only */);
- }
-
- if (rl != nullptr)
- {
- auto df = make_diag_frame (
- [](const diag_record& dr)
- {
- dr << info << "use config.bin.ranlib to override";
- });
-
- rlp = run_search (*rl, true, fallback, true /* path_only */);
- }
-
- // Binutils, LLVM, and FreeBSD ar/ranlib all recognize the --version
- // option. While Microsoft's lib.exe doesn't support --version, it only
- // issues a warning and exits with zero status, printing its usual
- // banner before that (running lib.exe without any options result in
- // non-zero exit status -- go figure). So we are going to start with
- // that.
- //
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- // Normally GNU binutils ar --version output has a line that starts
- // with "GNU ar" and ends with the version. For example:
- //
- // "GNU ar (GNU Binutils) 2.26"
- // "GNU ar (GNU Binutils for Ubuntu) 2.26.1"
- //
- // However, some embedded toolchain makers customize this stuff in
- // all kinds of ways. For example:
- //
- // "ppc-vle-ar (HighTec Release HDP-v4.6.6.1-bosch-1.3-3c1e3bc) build on 2017-03-23 (GNU Binutils) 2.20"
- // "GNU ar version 2.13 (tricore) using BFD version 2.13 (2008-12-10)"
- //
- // So let's look for "GNU " and be prepared to find junk instead of
- // the version.
- //
- if (l.find ("GNU ") != string::npos)
- {
- semantic_version v (parse_version (l, l.rfind (' ') + 1));
- return guess_result ("gnu", move (l), move (v));
- }
-
- // LLVM ar --version output has a line that starts with
- // "LLVM version " and ends with the version, for example:
- //
- // "LLVM version 3.5.2"
- // "LLVM version 5.0.0"
- //
- if (l.compare (0, 13, "LLVM version ") == 0)
- {
- semantic_version v (parse_version (l, l.rfind (' ') + 1));
- return guess_result ("llvm", move (l), move (v));
- }
-
- // FreeBSD ar --verison output starts with "BSD ar " followed by
- // the version and some extra information, for example:
- //
- // "BSD ar 1.1.0 - libarchive 3.1.2"
- //
- // We will treat the extra information as the build component.
- //
- if (l.compare (0, 7, "BSD ar ") == 0)
- {
- semantic_version v (parse_version (l, 7));
- return guess_result ("bsd", move (l), move (v));
- }
-
- // Microsoft lib.exe output starts with "Microsoft (R) " and ends
- // with a four-component version, for example:
- //
- // "Microsoft (R) Library Manager Version 14.00.24215.1"
- // "Microsoft (R) Library Manager Version 14.14.26428.1"
- //
- if (l.compare (0, 14, "Microsoft (R) ") == 0)
- {
- semantic_version v (parse_version (l, l.rfind (' ') + 1));
- return guess_result ("msvc", move (l), move (v));
- }
-
- return guess_result ();
- };
-
- // Suppress all the errors because we may be trying an unsupported
- // option. Note that in case of lib.exe we will hash the warning
- // (yes, it goes to stdout) but that seems harmless.
- //
- sha256 cs;
- arr = run<guess_result> (3, arp, "--version", f, false, false, &cs);
-
- if (!arr.empty ())
- arr.checksum = cs.string ();
- }
-
- // On Mac OS X (and probably also older BSDs) ar/ranlib doesn't have an
- // option to display version or help. If we run it without any arguments
- // it dumps usage and exist with an error status. So we will have to use
- // that.
- //
- if (arr.empty ())
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- return l.find (" ar ") != string::npos
- ? guess_result ("generic", move (l), semantic_version ())
- : guess_result ();
- };
-
- // Redirect STDERR to STDOUT and ignore exit status.
- //
- sha256 cs;
- arr = run<guess_result> (3, arp, f, false, true, &cs);
-
- if (!arr.empty ())
- {
- l4 ([&]{trace << "generic ar '" << arr.signature << "'";});
- arr.checksum = cs.string ();
- }
- }
-
- if (arr.empty ())
- fail << "unable to guess " << ar << " signature";
-
- // Now repeat pretty much the same steps for ranlib if requested. We
- // don't bother with the version assuming it is the same as for ar.
- //
- if (rl != nullptr)
- {
- // Binutils, LLVM, and FreeBSD.
- //
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- // The same story as with ar: normally starts with "GNU ranlib "
- // but can vary.
- //
- if (l.find ("GNU ") != string::npos)
- return guess_result ("gnu", move (l), semantic_version ());
-
- // "LLVM version ".
- //
- if (l.compare (0, 13, "LLVM version ") == 0)
- return guess_result ("llvm", move (l), semantic_version ());
-
- // On FreeBSD we get "ranlib" rather than "BSD ranlib" for some
- // reason. Which means we can't really call it 'bsd' for sure.
- //
- //if (l.compare (0, 7, "ranlib ") == 0)
- // return guess_result ("bsd", move (l), semantic_version ());
-
- return guess_result ();
- };
-
- sha256 cs;
- rlr = run<guess_result> (3, rlp, "--version", f, false, false, &cs);
-
- if (!rlr.empty ())
- rlr.checksum = cs.string ();
- }
-
- // Mac OS X (and probably also older BSDs).
- //
- if (rlr.empty ())
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- return l.find ("ranlib") != string::npos
- ? guess_result ("generic", move (l), semantic_version ())
- : guess_result ();
- };
-
- // Redirect STDERR to STDOUT and ignore exit status.
- //
- sha256 cs;
- rlr = run<guess_result> (3, rlp, f, false, true, &cs);
-
- if (!rlr.empty ())
- {
- l4 ([&]{trace << "generic ranlib '" << rlr.signature << "'";});
- rlr.checksum = cs.string ();
- }
- }
-
- if (rlr.empty ())
- fail << "unable to guess " << *rl << " signature";
- }
-
- return ar_info {
- move (arp),
- move (arr.id),
- move (arr.signature),
- move (arr.checksum),
- move (arr.version),
-
- move (rlp),
- move (rlr.id),
- move (rlr.signature),
- move (rlr.checksum)};
- }
-
- ld_info
- guess_ld (const path& ld, const dir_path& fallback)
- {
- tracer trace ("bin::guess_ld");
-
- guess_result r;
-
- process_path pp;
- {
- auto df = make_diag_frame (
- [](const diag_record& dr)
- {
- dr << info << "use config.bin.ld to override";
- });
-
- // Only search in PATH (specifically, omitting the current
- // executable's directory on Windows).
- //
- pp = run_search (ld, true, fallback, true /* path_only */);
- }
-
- // Binutils ld recognizes the --version option. Microsoft's link.exe
- // doesn't support --version (nor any other way to get the version
- // without the error exit status) but it will still print its banner.
- // We also want to recognize link.exe as fast as possible since it will
- // be the most commonly configured linker (for other platoforms the
- // linker will normally be used indirectly via the compiler and the
- // bin.ld module won't be loaded). So we are going to ignore the error
- // exit status. Our signatures are fairly specific to avoid any kind
- // of false positives.
- //
- // Version extraction is a @@ TODO.
- //
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- // Microsoft link.exe output starts with "Microsoft (R) ".
- //
- if (l.compare (0, 14, "Microsoft (R) ") == 0)
- return guess_result ("msvc", move (l), semantic_version ());
-
- // Binutils ld.bfd --version output has a line that starts with
- // "GNU ld " while ld.gold -- "GNU gold". Again, fortify it against
- // embedded toolchain customizations by search for "GNU " in the
- // former case.
- //
- if (l.compare (0, 9, "GNU gold ") == 0)
- return guess_result ("gold", move (l), semantic_version ());
-
- if (l.find ("GNU ") != string::npos)
- return guess_result ("gnu", move (l), semantic_version ());
-
- return guess_result ();
- };
-
- // Redirect STDERR to STDOUT and ignore exit status. Note that in case
- // of link.exe we will hash the diagnostics (yes, it goes to stdout)
- // but that seems harmless.
- //
- sha256 cs;
- r = run<guess_result> (3, pp, "--version", f, false, true, &cs);
-
- if (!r.empty ())
- r.checksum = cs.string ();
- }
-
- // Next try -v which will cover Apple's linkers.
- //
- if (r.empty ())
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- // New ld64 has "PROJECT:ld64" in the first line (output to stderr),
- // for example:
- //
- // @(#)PROGRAM:ld PROJECT:ld64-242.2
- //
- if (l.find ("PROJECT:ld64") != string::npos)
- return guess_result ("ld64", move (l), semantic_version ());
-
- // Old ld has "cctools" in the first line, for example:
- //
- // Apple Computer, Inc. version cctools-622.9~2
- //
- if (l.find ("cctools") != string::npos)
- return guess_result ("cctools", move (l), semantic_version ());
-
- return guess_result ();
- };
-
- sha256 cs;
- r = run<guess_result> (3, pp, "-v", f, false, false, &cs);
-
- if (!r.empty ())
- r.checksum = cs.string ();
- }
-
- // Finally try -version which will take care of LLVM's lld.
- //
- if (r.empty ())
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- // Unlike other LLVM tools (e.g., ar), the lld's version is printed
- // (to stderr) as:
- //
- // LLVM Linker Version: 3.7
- //
- if (l.compare (0, 19, "LLVM Linker Version") == 0)
- return guess_result ("llvm", move (l), semantic_version ());
-
- return guess_result ();
- };
-
- // Suppress all the errors because we may be trying an unsupported
- // option.
- //
- sha256 cs;
- r = run<guess_result> (3, pp, "-version", f, false, false, &cs);
-
- if (!r.empty ())
- r.checksum = cs.string ();
- }
-
- if (r.empty ())
- fail << "unable to guess " << ld << " signature";
-
- return ld_info {
- move (pp), move (r.id), move (r.signature), move (r.checksum)};
- }
-
- rc_info
- guess_rc (const path& rc, const dir_path& fallback)
- {
- tracer trace ("bin::guess_rc");
-
- guess_result r;
-
- process_path pp;
- {
- auto df = make_diag_frame (
- [](const diag_record& dr)
- {
- dr << info << "use config.bin.rc to override";
- });
-
- // Only search in PATH (specifically, omitting the current
- // executable's directory on Windows).
- //
- pp = run_search (rc, true, fallback, true /* path_only */);
- }
-
- // Binutils windres recognizes the --version option.
- //
- // Version extraction is a @@ TODO.
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- // Binutils windres --version output has a line that starts with
- // "GNU windres " but search for "GNU ", similar to other tools.
- //
- if (l.find ("GNU ") != string::npos)
- return guess_result ("gnu", move (l), semantic_version ());
-
- return guess_result ();
- };
-
- // Suppress all the errors because we may be trying an unsupported
- // option.
- //
- sha256 cs;
- r = run<guess_result> (3, pp, "--version", f, false, false, &cs);
-
- if (!r.empty ())
- r.checksum = cs.string ();
- }
-
- // Microsoft rc.exe /? prints its standard banner and exits with zero
- // status.
- //
- if (r.empty ())
- {
- auto f = [] (string& l, bool) -> guess_result
- {
- if (l.compare (0, 14, "Microsoft (R) ") == 0)
- return guess_result ("msvc", move (l), semantic_version ());
-
- return guess_result ();
- };
-
- sha256 cs;
- r = run<guess_result> (3, pp, "/?", f, false, false, &cs);
-
- if (!r.empty ())
- r.checksum = cs.string ();
- }
-
- if (r.empty ())
- fail << "unable to guess " << rc << " signature";
-
- return rc_info {
- move (pp), move (r.id), move (r.signature), move (r.checksum)};
- }
- }
-}
diff --git a/build2/bin/guess.hxx b/build2/bin/guess.hxx
deleted file mode 100644
index a3b2b34..0000000
--- a/build2/bin/guess.hxx
+++ /dev/null
@@ -1,108 +0,0 @@
-// file : build2/bin/guess.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_BIN_GUESS_HXX
-#define BUILD2_BIN_GUESS_HXX
-
-#include <libbuild2/types.hxx>
-#include <libbuild2/utility.hxx>
-
-namespace build2
-{
- namespace bin
- {
- // ar/ranlib information.
- //
- // Currently recognized ar/ranlib and their ids:
- //
- // gnu GNU binutils
- // llvm LLVM
- // bsd FreeBSD (and maybe other BSDs)
- // msvc Microsoft's lib.exe
- // generic Generic/unrecognized
- //
- // The signature is normally the --version/-V line.
- //
- // The checksum is used to detect ar/ranlib changes. It is calculated in
- // a toolchain-specific manner (usually the output of --version/-V) and
- // is not bulletproof.
- //
- struct ar_info
- {
- process_path ar_path;
- string ar_id;
- string ar_signature;
- string ar_checksum;
- semantic_version ar_version;
-
- process_path ranlib_path;
- string ranlib_id;
- string ranlib_signature;
- string ranlib_checksum;
- };
-
- // The ranlib path can be NULL, in which case no ranlib guessing will be
- // attemplated and the returned ranlib_* members will be left empty.
- //
- ar_info
- guess_ar (const path& ar, const path* ranlib, const dir_path& fallback);
-
- // ld information.
- //
- // Currently recognized linkers and their ids:
- //
- // gnu GNU binutils ld.bfd
- // gold GNU binutils ld.gold
- // llvm LLVM lld (note: not llvm-ld or llvm-link)
- // ld64 Apple's new linker
- // cctools Apple's old/classic linker
- // msvc Microsoft's link.exe
- //
- // Note that BSDs are currently using GNU ld but some of them (e.g.,
- // FreeBSD) are hoping to migrate to lld.
- //
- // The signature is normally the --version/-version/-v line.
- //
- // The checksum is used to detect ld changes. It is calculated in a
- // toolchain-specific manner (usually the output of --version/-version/-v)
- // and is not bulletproof.
- //
- struct ld_info
- {
- process_path path;
- string id;
- string signature;
- string checksum;
- };
-
- ld_info
- guess_ld (const path& ld, const dir_path& fallback);
-
- // rc information.
- //
- // Currently recognized resource compilers and their ids:
- //
- // gnu GNU binutils windres
- // msvc Microsoft's rc.exe
- //
- // The signature is normally the --version line.
- //
- // The checksum is used to detect rc changes. It is calculated in a
- // toolchain-specific manner (usually the output of --version) and is not
- // bulletproof.
- //
- struct rc_info
- {
- process_path path;
- string id;
- string signature;
- string checksum;
- };
-
- rc_info
- guess_rc (const path& rc, const dir_path& fallback);
- }
-}
-
-#endif // BUILD2_BIN_GUESS_HXX
diff --git a/build2/bin/init.cxx b/build2/bin/init.cxx
deleted file mode 100644
index 54bd84a..0000000
--- a/build2/bin/init.cxx
+++ /dev/null
@@ -1,940 +0,0 @@
-// file : build2/bin/init.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <build2/bin/init.hxx>
-
-#include <map>
-
-#include <libbuild2/scope.hxx>
-#include <libbuild2/variable.hxx>
-#include <libbuild2/diagnostics.hxx>
-
-#include <libbuild2/config/utility.hxx>
-
-#include <libbuild2/test/module.hxx>
-
-#include <libbuild2/install/rule.hxx>
-#include <libbuild2/install/utility.hxx>
-
-#include <build2/bin/rule.hxx>
-#include <build2/bin/guess.hxx>
-#include <build2/bin/target.hxx>
-
-using namespace std;
-using namespace butl;
-
-namespace build2
-{
- namespace bin
- {
- static const fail_rule fail_;
- static const lib_rule lib_;
-
- // Default config.bin.*.lib values.
- //
- static const strings exe_lib {"shared", "static"};
- static const strings liba_lib {"static", "shared"};
- static const strings libs_lib {"shared", "static"};
-
- bool
- vars_init (scope& rs,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool first,
- bool,
- const variable_map&)
- {
- tracer trace ("bin::vars_init");
- l5 ([&]{trace << "for " << rs;});
-
- assert (first);
-
- // Enter variables. Note: some overridable, some not.
- //
- // Target is a string and not target_triplet because it can be
- // specified by the user.
- //
- auto& vp (rs.ctx.var_pool.rw (rs));
-
- vp.insert<string> ("config.bin.target", true);
- vp.insert<string> ("config.bin.pattern", true);
-
- // Library types to build.
- //
- vp.insert<string> ("config.bin.lib", true);
-
- // Library types to use (in priority order).
- //
- vp.insert<strings> ("config.bin.exe.lib", true);
- vp.insert<strings> ("config.bin.liba.lib", true);
- vp.insert<strings> ("config.bin.libs.lib", true);
-
- // The rpath[_link].auto flag controls automatic rpath behavior, for
- // example, addition of rpaths for prerequisite libraries (see the cc
- // module for an example). Default is true.
- //
- vp.insert<dir_paths> ("config.bin.rpath", true);
- vp.insert<bool> ("config.bin.rpath.auto", true);
-
- vp.insert<dir_paths> ("config.bin.rpath_link", true);
- vp.insert<bool> ("config.bin.rpath_link.auto", true);
-
- vp.insert<string> ("config.bin.prefix", true);
- vp.insert<string> ("config.bin.suffix", true);
- vp.insert<string> ("config.bin.lib.prefix", true);
- vp.insert<string> ("config.bin.lib.suffix", true);
- vp.insert<string> ("config.bin.exe.prefix", true);
- vp.insert<string> ("config.bin.exe.suffix", true);
-
- vp.insert<string> ("bin.lib");
-
- vp.insert<strings> ("bin.exe.lib");
- vp.insert<strings> ("bin.liba.lib");
- vp.insert<strings> ("bin.libs.lib");
-
- vp.insert<dir_paths> ("bin.rpath");
- vp.insert<bool> ("bin.rpath.auto");
-
- vp.insert<dir_paths> ("bin.rpath_link");
- vp.insert<bool> ("bin.rpath_link.auto");
-
- // Link whole archive. Note: non-overridable 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:
- //
- // exe{test}: liba{foo}
- // liba{foo}: libua{foo1 foo2}
- // liba{foo}: bin.whole = false # Affects test but not foo1 and foo2.
- //
- // If unspecified, defaults to false for liba{} and to true for libu*{}.
- //
- vp.insert<bool> ("bin.whole", false, variable_visibility::target);
-
- vp.insert<string> ("bin.exe.prefix");
- vp.insert<string> ("bin.exe.suffix");
- vp.insert<string> ("bin.lib.prefix");
- vp.insert<string> ("bin.lib.suffix");
-
- vp.insert<string> ("bin.lib.load_suffix",
- variable_visibility::project);
-
- vp.insert<map<string, string>> ("bin.lib.version",
- variable_visibility::project);
-
- return true;
- }
-
- bool
- config_init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool first,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::config_init");
- l5 ([&]{trace << "for " << bs;});
-
- // We only support root loading (which means there can only be one).
- //
- if (&rs != &bs)
- fail (loc) << "bin.config module must be loaded in project root";
-
- // Load bin.vars.
- //
- if (!cast_false<bool> (rs["bin.vars.loaded"]))
- load_module (rs, rs, "bin.vars", loc);
-
- // Configure.
- //
- using config::required;
- using config::optional;
- using config::omitted;
-
- // Adjust module priority (binutils).
- //
- config::save_module (rs, "bin", 350);
-
- // The idea here is as follows: if we already have one of
- // the bin.* variables set, then we assume this is static
- // project configuration and don't bother setting the
- // corresponding config.bin.* variable.
- //
- //@@ Need to validate the values. Would be more efficient
- // to do it once on assignment than every time on query.
- // Custom var type?
- //
-
- // config.bin.lib
- //
- {
- value& v (rs.assign ("bin.lib"));
- if (!v)
- v = *required (rs, "config.bin.lib", "both").first;
- }
-
- // config.bin.exe.lib
- //
- {
- value& v (rs.assign ("bin.exe.lib"));
- if (!v)
- v = *required (rs, "config.bin.exe.lib", exe_lib).first;
- }
-
- // config.bin.liba.lib
- //
- {
- value& v (rs.assign ("bin.liba.lib"));
- if (!v)
- v = *required (rs, "config.bin.liba.lib", liba_lib).first;
- }
-
- // config.bin.libs.lib
- //
- {
- value& v (rs.assign ("bin.libs.lib"));
- if (!v)
- v = *required (rs, "config.bin.libs.lib", libs_lib).first;
- }
-
- // config.bin.rpath[_link]
- //
- // These ones are optional and we merge them into bin.rpath[_link], if
- // any.
- //
- rs.assign ("bin.rpath") += cast_null<dir_paths> (
- optional (rs, "config.bin.rpath"));
-
- rs.assign ("bin.rpath_link") += cast_null<dir_paths> (
- optional (rs, "config.bin.rpath_link"));
-
- // config.bin.rpath[_link].auto
- //
- {
- lookup l;
-
- rs.assign ("bin.rpath.auto") =
- (l = omitted (rs, "config.bin.rpath.auto").first)
- ? cast<bool> (l)
- : true;
-
- rs.assign ("bin.rpath_link.auto") =
- (l = omitted (rs, "config.bin.rpath_link.auto").first)
- ? cast<bool> (l)
- : true;
- }
-
- // config.bin.{lib,exe}.{prefix,suffix}
- //
- // These ones are not used very often so we will omit them from the
- // config.build if not specified. We also override any existing value
- // that might have been specified before loading the module.
- //
- {
- lookup p (omitted (rs, "config.bin.prefix").first);
- lookup s (omitted (rs, "config.bin.suffix").first);
-
- auto set = [&rs] (const char* bv, const char* cv, lookup l)
- {
- if (lookup o = omitted (rs, cv).first)
- l = o;
-
- if (l)
- rs.assign (bv) = *l;
- };
-
- set ("bin.lib.prefix", "config.bin.lib.prefix", p);
- set ("bin.lib.suffix", "config.bin.lib.suffix", s);
-
- set ("bin.exe.prefix", "config.bin.exe.prefix", p);
- set ("bin.exe.suffix", "config.bin.exe.suffix", s);
- }
-
- if (first)
- {
- bool new_val (false); // Set any new values?
-
- // config.bin.target
- //
- {
- const variable& var (rs.ctx.var_pool["config.bin.target"]);
-
- // We first see if the value was specified via the configuration
- // mechanism.
- //
- auto p (omitted (rs, var));
- lookup l (p.first);
-
- // Then see if there is a config hint (e.g., from the cc module).
- //
- bool hint (false);
- if (!l)
- {
- if (auto hl = hints[var])
- {
- l = hl;
- hint = true;
- }
- }
-
- if (!l)
- fail (loc) << "unable to determine binutils target" <<
- info << "consider specifying it with " << var <<
- info << "or first load a module that can provide it as a hint, "
- << "such as c or cxx";
-
- // Split/canonicalize the target.
- //
- string s (cast<string> (l));
-
- // Did the user ask us to use config.sub? If this is a hinted value,
- // then we assume it has already been passed through config.sub.
- //
- if (!hint && config_sub)
- {
- s = run<string> (3,
- *config_sub,
- s.c_str (),
- [] (string& l, bool) {return move (l);});
- l5 ([&]{trace << "config.sub target: '" << s << "'";});
- }
-
- try
- {
- target_triplet t (s);
-
- l5 ([&]{trace << "canonical target: '" << t.string () << "'; "
- << "class: " << t.class_;});
-
- assert (!hint || s == t.string ());
-
- // Also enter as bin.target.{cpu,vendor,system,version,class}
- // for convenience of access.
- //
- rs.assign<string> ("bin.target.cpu") = t.cpu;
- rs.assign<string> ("bin.target.vendor") = t.vendor;
- rs.assign<string> ("bin.target.system") = t.system;
- rs.assign<string> ("bin.target.version") = t.version;
- rs.assign<string> ("bin.target.class") = t.class_;
-
- rs.assign<target_triplet> ("bin.target") = move (t);
- }
- catch (const invalid_argument& e)
- {
- // This is where we suggest that the user specifies --config-sub
- // to help us out.
- //
- fail << "unable to parse binutils target '" << s << "': " << e <<
- info << "consider using the --config-sub option";
- }
-
- new_val = new_val || p.second; // False for a hinted value.
- }
-
- // config.bin.pattern
- //
- {
- const variable& var (rs.ctx.var_pool["config.bin.pattern"]);
-
- // We first see if the value was specified via the configuration
- // mechanism.
- //
- auto p (omitted (rs, var));
- lookup l (p.first);
-
- // Then see if there is a config hint (e.g., from the C++ module).
- //
- if (!l)
- {
- if (auto hl = hints[var])
- l = hl;
- }
-
- // For ease of use enter it as bin.pattern (since it can come from
- // different places).
- //
- if (l)
- {
- const string& s (cast<string> (l));
-
- if (s.empty () ||
- (!path::traits_type::is_separator (s.back ()) &&
- s.find ('*') == string::npos))
- {
- fail << "missing '*' in binutils pattern '" << s << "'";
- }
-
- rs.assign<string> ("bin.pattern") = s;
- new_val = new_val || p.second; // False for a hinted value.
- }
- }
-
- // If we set any new values (e.g., we are configuring), then print the
- // report at verbosity level 2 and up (-v).
- //
- if (verb >= (new_val ? 2 : 3))
- {
- diag_record dr (text);
-
- dr << "bin " << project (rs) << '@' << rs << '\n'
- << " target " << cast<target_triplet> (rs["bin.target"]);
-
- if (auto l = rs["bin.pattern"])
- dr << '\n'
- << " pattern " << cast<string> (l);
- }
- }
-
- return true;
- }
-
- bool
- init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool first,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::init");
- l5 ([&]{trace << "for " << bs;});
-
- // Load bin.config.
- //
- if (!cast_false<bool> (rs["bin.config.loaded"]))
- load_module (rs, rs, "bin.config", loc, false, hints);
-
- // Cache some config values we will be needing below.
- //
- const string& tclass (cast<string> (rs["bin.target.class"]));
-
- // Register target types and configure their default "installability".
- //
- 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)
- {
- install_path<liba> (bs, dir_path ("lib")); // Install in install.lib.
- install_mode<liba> (bs, "644");
- }
-
- // Should shared libraries have the executable bit? That depends on
- // who you ask. In Debian, for example, it should not unless, it
- // really is executable (i.e., has main()). On the other hand, on
- // some systems, this may be required in order for the dynamic
- // linker to be able to load the library. So, by default, we will
- // keep it executable, especially seeing that this is also the
- // behavior of autotools. At the same time, it is easy to override
- // this, for example:
- //
- // config.install.lib.mode=644
- //
- // And a library that wants to override any such overrides (e.g.,
- // because it does have main()) can do:
- //
- // libs{foo}: install.mode=755
- //
- // Everyone is happy then? On Windows libs{} is the DLL and goes to
- // bin/, not lib/.
- //
- if (install_loaded)
- install_path<libs> (bs,
- dir_path (tclass == "windows" ? "bin" : "lib"));
-
- // Create additional target types for certain targets.
- //
- if (tclass == "windows")
- {
- // Import library.
- //
- if (first)
- rs.insert_target_type<libi> ();
-
- if (install_loaded)
- {
- install_path<libi> (bs, dir_path ("lib"));
- install_mode<libi> (bs, "644");
- }
- }
- }
-
- // Register rules.
- //
- {
- auto& r (bs.rules);
-
- r.insert<obj> (perform_update_id, "bin.obj", fail_);
- r.insert<obj> (perform_clean_id, "bin.obj", fail_);
-
- r.insert<bmi> (perform_update_id, "bin.bmi", fail_);
- r.insert<bmi> (perform_clean_id, "bin.bmi", fail_);
-
- r.insert<hbmi> (perform_update_id, "bin.hbmi", fail_);
- r.insert<hbmi> (perform_clean_id, "bin.hbmi", fail_);
-
- r.insert<libul> (perform_update_id, "bin.libul", fail_);
- r.insert<libul> (perform_clean_id, "bin.libul", fail_);
-
- // Similar to alias.
- //
-
- //@@ outer
- r.insert<lib> (perform_id, 0, "bin.lib", lib_);
- r.insert<lib> (configure_id, 0, "bin.lib", lib_);
-
- // Treat as a see through group for install and test.
- //
- if (install_loaded)
- {
- auto& gr (install::group_rule::instance);
-
- r.insert<lib> (perform_install_id, "bin.lib", gr);
- r.insert<lib> (perform_uninstall_id, "bin.lib", gr);
- }
-
- if (const test::module* m = rs.lookup_module<test::module> ("test"))
- {
- r.insert<lib> (perform_test_id, "bin.lib", m->group_rule ());
- }
- }
-
- return true;
- }
-
- bool
- ar_config_init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool first,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::ar_config_init");
- l5 ([&]{trace << "for " << bs;});
-
- // Make sure bin.config is loaded.
- //
- if (!cast_false<bool> (rs["bin.config.loaded"]))
- load_module (rs, bs, "bin.config", loc, false, hints);
-
- // Enter configuration variables.
- //
- if (first)
- {
- auto& v (rs.ctx.var_pool.rw (rs));
-
- v.insert<process_path> ("bin.ar.path");
- v.insert<process_path> ("bin.ranlib.path");
-
- v.insert<path> ("config.bin.ar", true);
- v.insert<path> ("config.bin.ranlib", true);
- }
-
- // Configure.
- //
- if (first)
- {
- // config.bin.ar
- // config.bin.ranlib
- //
- // For config.bin.ar we have the default (plus the pattern) while
- // ranlib should be explicitly specified by the user in order for us
- // to use it (all targets that we currently care to support have the
- // ar -s option but if that changes we can always force the use of
- // ranlib for certain targets).
- //
- // Another idea is to refuse to use default 'ar' (without the pattern)
- // if the host/build targets don't match. On the other hand, a cross-
- // toolchain can be target-unprefixed. Also, without canonicalization,
- // comparing targets will be unreliable.
- //
-
- // Use the target to decide on the default binutils program names.
- //
- const string& tsys (cast<string> (rs["bin.target.system"]));
- const char* ar_d (tsys == "win32-msvc" ? "lib" : "ar");
-
- // This can be either a pattern or a fallback search directory.
- //
- const string* pat (cast_null<string> (rs["bin.pattern"]));
-
- bool fb (pat != nullptr &&
- path::traits_type::is_separator (pat->back ()));
-
- // Don't save the default value to config.build so that if the user
- // changes, say, the C++ compiler (which hinted the pattern), then
- // ar will automatically change as well.
- //
- auto ap (
- config::required (
- rs,
- "config.bin.ar",
- path (apply_pattern (ar_d, fb ? nullptr : pat)),
- false,
- config::save_commented));
-
- auto rp (
- config::required (
- rs,
- "config.bin.ranlib",
- nullptr,
- false,
- config::save_commented));
-
- const path& ar (cast<path> (ap.first));
- const path* ranlib (cast_null<path> (rp.first));
-
- ar_info ari (
- guess_ar (ar, ranlib, fb ? dir_path (*pat) : dir_path ()));
-
- // If this is a new value (e.g., we are configuring), then print the
- // report at verbosity level 2 and up (-v).
- //
- if (verb >= (ap.second || rp.second ? 2 : 3))
- {
- diag_record dr (text);
-
- {
- dr << "bin.ar " << project (rs) << '@' << rs << '\n'
- << " ar " << ari.ar_path << '\n'
- << " id " << ari.ar_id << '\n'
- << " version " << ari.ar_version.string () << '\n'
- << " major " << ari.ar_version.major << '\n'
- << " minor " << ari.ar_version.minor << '\n'
- << " patch " << ari.ar_version.patch << '\n';
- }
-
- if (!ari.ar_version.build.empty ())
- {
- dr << " build " << ari.ar_version.build << '\n';
- }
-
- {
- dr << " signature " << ari.ar_signature << '\n'
- << " checksum " << ari.ar_checksum;
- }
-
- if (ranlib != nullptr)
- {
- dr << '\n'
- << " ranlib " << ari.ranlib_path << '\n'
- << " id " << ari.ranlib_id << '\n'
- << " signature " << ari.ranlib_signature << '\n'
- << " checksum " << ari.ranlib_checksum;
- }
- }
-
- rs.assign<process_path> ("bin.ar.path") = move (ari.ar_path);
- rs.assign<string> ("bin.ar.id") = move (ari.ar_id);
- rs.assign<string> ("bin.ar.signature") = move (ari.ar_signature);
- rs.assign<string> ("bin.ar.checksum") = move (ari.ar_checksum);
-
- {
- semantic_version& v (ari.ar_version);
-
- rs.assign<string> ("bin.ar.version") = v.string ();
- rs.assign<uint64_t> ("bin.ar.version.major") = v.major;
- rs.assign<uint64_t> ("bin.ar.version.minor") = v.minor;
- rs.assign<uint64_t> ("bin.ar.version.patch") = v.patch;
- rs.assign<string> ("bin.ar.version.build") = move (v.build);
- }
-
- if (ranlib != nullptr)
- {
- rs.assign<process_path> ("bin.ranlib.path") = move (ari.ranlib_path);
- rs.assign<string> ("bin.ranlib.id") = move (ari.ranlib_id);
- rs.assign<string> ("bin.ranlib.signature") =
- move (ari.ranlib_signature);
- rs.assign<string> ("bin.ranlib.checksum") =
- move (ari.ranlib_checksum);
- }
- }
-
- return true;
- }
-
- bool
- ar_init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::ar_init");
- l5 ([&]{trace << "for " << bs;});
-
- // Make sure the bin core and ar.config are loaded.
- //
- if (!cast_false<bool> (bs["bin.loaded"]))
- load_module (rs, bs, "bin", loc, false, hints);
-
- if (!cast_false<bool> (bs["bin.ar.config.loaded"]))
- load_module (rs, bs, "bin.ar.config", loc, false, hints);
-
- return true;
- }
-
- bool
- ld_config_init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool first,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::ld_config_init");
- l5 ([&]{trace << "for " << bs;});
-
- // Make sure bin.config is loaded.
- //
- if (!cast_false<bool> (rs["bin.config.loaded"]))
- load_module (rs, rs, "bin.config", loc, false, hints);
-
- // Enter configuration variables.
- //
- if (first)
- {
- auto& v (rs.ctx.var_pool.rw (rs));
-
- v.insert<process_path> ("bin.ld.path");
- v.insert<path> ("config.bin.ld", true);
- }
-
- // Configure.
- //
- if (first)
- {
- // config.bin.ld
- //
- // Use the target to decide on the default ld name.
- //
- const string& tsys (cast<string> (rs["bin.target.system"]));
- const char* ld_d (tsys == "win32-msvc" ? "link" : "ld");
-
- // This can be either a pattern or a fallback search directory.
- //
- const string* pat (cast_null<string> (rs["bin.pattern"]));
-
- bool fb (pat != nullptr &&
- path::traits_type::is_separator (pat->back ()));
-
- auto p (
- config::required (
- rs,
- "config.bin.ld",
- path (apply_pattern (ld_d, fb ? nullptr : pat)),
- false,
- config::save_commented));
-
- const path& ld (cast<path> (p.first));
- ld_info ldi (guess_ld (ld, fb ? dir_path (*pat) : dir_path ()));
-
- // If this is a new value (e.g., we are configuring), then print the
- // report at verbosity level 2 and up (-v).
- //
- if (verb >= (p.second ? 2 : 3))
- {
- text << "bin.ld " << project (rs) << '@' << rs << '\n'
- << " ld " << ldi.path << '\n'
- << " id " << ldi.id << '\n'
- << " signature " << ldi.signature << '\n'
- << " checksum " << ldi.checksum;
- }
-
- rs.assign<process_path> ("bin.ld.path") = move (ldi.path);
- rs.assign<string> ("bin.ld.id") = move (ldi.id);
- rs.assign<string> ("bin.ld.signature") = move (ldi.signature);
- rs.assign<string> ("bin.ld.checksum") = move (ldi.checksum);
- }
-
- return true;
- }
-
- bool
- ld_init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::ld_init");
- l5 ([&]{trace << "for " << bs;});
-
- // Make sure the bin core and ld.config are loaded.
- //
- if (!cast_false<bool> (bs["bin.loaded"]))
- load_module (rs, bs, "bin", loc, false, hints);
-
- if (!cast_false<bool> (bs["bin.ld.config.loaded"]))
- load_module (rs, bs, "bin.ld.config", loc, false, hints);
-
- const string& lid (cast<string> (rs["bin.ld.id"]));
-
- // Register the pdb{} target if using the VC toolchain.
- //
- using namespace install;
-
- if (lid == "msvc")
- {
- const target_type& pdb (bs.derive_target_type<file> ("pdb").first);
- install_path (bs, pdb, dir_path ("bin")); // Goes to install.bin
- install_mode (bs, pdb, "644"); // But not executable.
- }
-
- return true;
- }
-
- bool
- rc_config_init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool first,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::rc_config_init");
- l5 ([&]{trace << "for " << bs;});
-
- // Make sure bin.config is loaded.
- //
- if (!cast_false<bool> (bs["bin.config.loaded"]))
- load_module (rs, bs, "bin.config", loc, false, hints);
-
- // Enter configuration variables.
- //
- if (first)
- {
- auto& v (rs.ctx.var_pool.rw (rs));
-
- v.insert<process_path> ("bin.rc.path");
- v.insert<path> ("config.bin.rc", true);
- }
-
- // Configure.
- //
- if (first)
- {
- // config.bin.rc
- //
- // Use the target to decide on the default rc name.
- //
- const string& tsys (cast<string> (rs["bin.target.system"]));
- const char* rc_d (tsys == "win32-msvc" ? "rc" : "windres");
-
- // This can be either a pattern or a fallback search directory.
- //
- const string* pat (cast_null<string> (rs["bin.pattern"]));
-
- bool fb (pat != nullptr &&
- path::traits_type::is_separator (pat->back ()));
-
- auto p (
- config::required (
- rs,
- "config.bin.rc",
- path (apply_pattern (rc_d, fb ? nullptr : pat)),
- false,
- config::save_commented));
-
- const path& rc (cast<path> (p.first));
- rc_info rci (guess_rc (rc, fb ? dir_path (*pat) : dir_path ()));
-
- // If this is a new value (e.g., we are configuring), then print the
- // report at verbosity level 2 and up (-v).
- //
- if (verb >= (p.second ? 2 : 3))
- {
- text << "bin.rc " << project (rs) << '@' << rs << '\n'
- << " rc " << rci.path << '\n'
- << " id " << rci.id << '\n'
- << " signature " << rci.signature << '\n'
- << " checksum " << rci.checksum;
- }
-
- rs.assign<process_path> ("bin.rc.path") = move (rci.path);
- rs.assign<string> ("bin.rc.id") = move (rci.id);
- rs.assign<string> ("bin.rc.signature") = move (rci.signature);
- rs.assign<string> ("bin.rc.checksum") = move (rci.checksum);
- }
-
- return true;
- }
-
- bool
- rc_init (scope& rs,
- scope& bs,
- const location& loc,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map& hints)
- {
- tracer trace ("bin::rc_init");
- l5 ([&]{trace << "for " << bs;});
-
- // Make sure the bin core and rc.config are loaded.
- //
- if (!cast_false<bool> (bs["bin.loaded"]))
- load_module (rs, bs, "bin", loc, false, hints);
-
- if (!cast_false<bool> (bs["bin.rc.config.loaded"]))
- load_module (rs, bs, "bin.rc.config", loc, false, hints);
-
- return true;
- }
- }
-}
diff --git a/build2/bin/init.hxx b/build2/bin/init.hxx
deleted file mode 100644
index 989dcaf..0000000
--- a/build2/bin/init.hxx
+++ /dev/null
@@ -1,100 +0,0 @@
-// file : build2/bin/init.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_BIN_INIT_HXX
-#define BUILD2_BIN_INIT_HXX
-
-#include <libbuild2/types.hxx>
-#include <libbuild2/utility.hxx>
-
-#include <libbuild2/module.hxx>
-
-namespace build2
-{
- namespace bin
- {
- bool
- vars_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- config_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- ar_config_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- ar_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- ld_config_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- ld_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- rc_config_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
-
- bool
- rc_init (scope&,
- scope&,
- const location&,
- unique_ptr<module_base>&,
- bool,
- bool,
- const variable_map&);
- }
-}
-
-#endif // BUILD2_BIN_INIT_HXX
diff --git a/build2/bin/rule.cxx b/build2/bin/rule.cxx
deleted file mode 100644
index 42ba86a..0000000
--- a/build2/bin/rule.cxx
+++ /dev/null
@@ -1,89 +0,0 @@
-// file : build2/bin/rule.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <build2/bin/rule.hxx>
-
-#include <libbuild2/scope.hxx>
-#include <libbuild2/target.hxx>
-#include <libbuild2/algorithm.hxx>
-#include <libbuild2/diagnostics.hxx>
-
-#include <build2/bin/target.hxx>
-
-using namespace std;
-
-namespace build2
-{
- namespace bin
- {
- // fail_rule
- //
- bool fail_rule::
- match (action a, target& t, const string&) const
- {
- const char* n (t.dynamic_type ().name); // Ignore derived type.
-
- fail << diag_doing (a, t) << " target group" <<
- info << "explicitly select " << n << "e{}, " << n << "a{}, or "
- << n << "s{} member" << endf;
- }
-
- recipe fail_rule::
- apply (action, target&) const {return empty_recipe;}
-
- // lib_rule
- //
- // The whole logic is pretty much as if we had our two group members as
- // our prerequisites.
- //
- lib_rule::members lib_rule::
- build_members (const scope& rs)
- {
- const string& type (cast<string> (rs["bin.lib"]));
-
- bool a (type == "static" || type == "both");
- bool s (type == "shared" || type == "both");
-
- if (!a && !s)
- fail << "unknown library type: " << type <<
- info << "'static', 'shared', or 'both' expected";
-
- return members {a, s};
- }
-
- bool lib_rule::
- match (action, target& xt, const string&) const
- {
- lib& t (xt.as<lib> ());
-
- members bm (build_members (t.root_scope ()));
- t.a = bm.a ? &search<liba> (t, t.dir, t.out, t.name) : nullptr;
- t.s = bm.s ? &search<libs> (t, t.dir, t.out, t.name) : nullptr;
-
- return true;
- }
-
- recipe lib_rule::
- apply (action a, target& xt) const
- {
- lib& t (xt.as<lib> ());
-
- //@@ outer: also prerequisites (if outer) or not?
-
- const target* m[] = {t.a, t.s};
- match_members (a, t, m);
-
- return &perform;
- }
-
- target_state lib_rule::
- perform (action a, const target& xt)
- {
- const lib& t (xt.as<lib> ());
-
- const target* m[] = {t.a, t.s};
- return execute_members (a, t, m);
- }
- }
-}
diff --git a/build2/bin/rule.hxx b/build2/bin/rule.hxx
deleted file mode 100644
index 4230933..0000000
--- a/build2/bin/rule.hxx
+++ /dev/null
@@ -1,63 +0,0 @@
-// file : build2/bin/rule.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_BIN_RULE_HXX
-#define BUILD2_BIN_RULE_HXX
-
-#include <libbuild2/types.hxx>
-#include <libbuild2/utility.hxx>
-
-#include <libbuild2/rule.hxx>
-
-namespace build2
-{
- namespace bin
- {
- // "Fail rule" for obj{}, [h]bmi{}, and libu{} that issues diagnostics if
- // someone tries to build any of these groups directly.
- //
- class fail_rule: public rule
- {
- public:
- fail_rule () {}
-
- virtual bool
- match (action, target&, const string&) const override;
-
- virtual recipe
- apply (action, target&) const override;
- };
-
- // Pass-through to group members rule, similar to alias.
- //
- class lib_rule: public rule
- {
- public:
- lib_rule () {}
-
- virtual bool
- match (action, target&, const string&) const override;
-
- virtual recipe
- apply (action, target&) const override;
-
- static target_state
- perform (action, const target&);
-
- // Return library types to build according to the bin.lib value (set
- // on project's root scope by init()).
- //
- struct members
- {
- bool a; // static
- bool s; // shared
- };
-
- static members
- build_members (const scope&);
- };
- }
-}
-
-#endif // BUILD2_BIN_RULE_HXX
diff --git a/build2/bin/target.cxx b/build2/bin/target.cxx
deleted file mode 100644
index 9074317..0000000
--- a/build2/bin/target.cxx
+++ /dev/null
@@ -1,474 +0,0 @@
-// file : build2/bin/target.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <build2/bin/target.hxx>
-
-#include <libbuild2/context.hxx>
-
-using namespace std;
-
-namespace build2
-{
- namespace bin
- {
- const target_type objx::static_type
- {
- "objx",
- &file::static_type,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- const target_type bmix::static_type
- {
- "bmix",
- &file::static_type,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- const target_type hbmix::static_type
- {
- "hbmix",
- &bmix::static_type,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- const target_type libx::static_type
- {
- "libx",
- &mtime_target::static_type,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- const target_type libux::static_type
- {
- "libux",
- &file::static_type,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- // Note that we link groups during the load phase since this is often
- // relied upon when setting target-specific variables (e.g., we may set a
- // common value for lib{} and then append liba/libs-specific values to
- // it). While sure inelegant, this is MT-safe since during load we are
- // running serial. For the members it is also safe to set the group during
- // creation.
-
- // obj*{} and [h]bmi*{} member factory.
- //
- template <typename M, typename G>
- static target*
- m_factory (context& ctx,
- const target_type&, dir_path dir, dir_path out, string n)
- {
- const G* g (ctx.targets.find<G> (dir, out, n));
-
- M* m (new M (ctx, move (dir), move (out), move (n)));
- m->group = g;
-
- return m;
- }
-
- const target_type obje::static_type
- {
- "obje",
- &objx::static_type,
- &m_factory<obje, obj>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type bmie::static_type
- {
- "bmie",
- &bmix::static_type,
- &m_factory<bmie, bmi>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type hbmie::static_type
- {
- "hbmie",
- &hbmix::static_type,
- &m_factory<hbmie, hbmi>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type obja::static_type
- {
- "obja",
- &objx::static_type,
- &m_factory<obja, obj>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type bmia::static_type
- {
- "bmia",
- &bmix::static_type,
- &m_factory<bmia, bmi>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type hbmia::static_type
- {
- "hbmia",
- &hbmix::static_type,
- &m_factory<hbmia, hbmi>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type objs::static_type
- {
- "objs",
- &objx::static_type,
- &m_factory<objs, obj>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type bmis::static_type
- {
- "bmis",
- &bmix::static_type,
- &m_factory<bmis, bmi>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type hbmis::static_type
- {
- "hbmis",
- &hbmix::static_type,
- &m_factory<hbmis, hbmi>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type libue::static_type
- {
- "libue",
- &libux::static_type,
- &target_factory<libue>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type libua::static_type
- {
- "libua",
- &libux::static_type,
- &m_factory<libua, libul>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- const target_type libus::static_type
- {
- "libus",
- &libux::static_type,
- &m_factory<libus, libul>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &target_search, // Note: not _file(); don't look for an existing file.
- false
- };
-
- // obj{}, [h]bmi{}, and libu{} group factory.
- //
- template <typename G, typename E, typename A, typename S>
- static target*
- g_factory (context& ctx,
- const target_type&, dir_path dir, dir_path out, string n)
- {
- // Casts are MT-aware (during serial load).
- //
- E* e (ctx.phase == run_phase::load
- ? const_cast<E*> (ctx.targets.find<E> (dir, out, n))
- : nullptr);
- A* a (ctx.phase == run_phase::load
- ? const_cast<A*> (ctx.targets.find<A> (dir, out, n))
- : nullptr);
- S* s (ctx.phase == run_phase::load
- ? const_cast<S*> (ctx.targets.find<S> (dir, out, n))
- : nullptr);
-
- G* g (new G (ctx, move (dir), move (out), move (n)));
-
- if (e != nullptr) e->group = g;
- if (a != nullptr) a->group = g;
- if (s != nullptr) s->group = g;
-
- return g;
- }
-
- const target_type obj::static_type
- {
- "obj",
- &target::static_type,
- &g_factory<obj, obje, obja, objs>,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- const target_type bmi::static_type
- {
- "bmi",
- &target::static_type,
- &g_factory<bmi, bmie, bmia, bmis>,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- const target_type hbmi::static_type
- {
- "hbmi",
- &target::static_type,
- &g_factory<hbmi, hbmie, hbmia, hbmis>,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- // The same as g_factory() but without E.
- //
- static target*
- libul_factory (context& ctx,
- const target_type&, dir_path dir, dir_path out, string n)
- {
- libua* a (ctx.phase == run_phase::load
- ? const_cast<libua*> (ctx.targets.find<libua> (dir, out, n))
- : nullptr);
- libus* s (ctx.phase == run_phase::load
- ? const_cast<libus*> (ctx.targets.find<libus> (dir, out, n))
- : nullptr);
-
- libul* g (new libul (ctx, move (dir), move (out), move (n)));
-
- if (a != nullptr) a->group = g;
- if (s != nullptr) s->group = g;
-
- return g;
- }
-
- const target_type libul::static_type
- {
- "libul",
- &libx::static_type,
- &libul_factory,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false
- };
-
- // What extensions should we use? At the outset, this is platform-
- // dependent. And if we consider cross-compilation, is it build or
- // host-dependent? Feels like it should be host-dependent so that
- // we can copy things between cross and native environments. So
- // these will have to be determined based on what we are building.
- // As if this is not complicated enough, the bin module doesn't
- // know anything about building. So perhaps the extension should
- // come from a variable that is set not by bin but by the module
- // whose rule matched the target (e.g., cxx::link).
- //
- const target_type liba::static_type
- {
- "liba",
- &file::static_type,
- &m_factory<liba, lib>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &file_search,
- false
- };
-
- const target_type libs::static_type
- {
- "libs",
- &file::static_type,
- &m_factory<libs, lib>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &file_search,
- false
- };
-
- // lib
- //
- group_view lib::
- group_members (action) const
- {
- static_assert (sizeof (lib_members) == sizeof (const target*) * 2,
- "member layout incompatible with array");
-
- return a != nullptr || s != nullptr
- ? group_view {reinterpret_cast<const target* const*> (&a), 2}
- : group_view {nullptr, 0};
- }
-
- static target*
- lib_factory (context& ctx,
- const target_type&, dir_path dir, dir_path out, string n)
- {
- // Casts are MT-aware (during serial load).
- //
- liba* a (ctx.phase == run_phase::load
- ? const_cast<liba*> (ctx.targets.find<liba> (dir, out, n))
- : nullptr);
- libs* s (ctx.phase == run_phase::load
- ? const_cast<libs*> (ctx.targets.find<libs> (dir, out, n))
- : nullptr);
-
- lib* l (new lib (ctx, move (dir), move (out), move (n)));
-
- if (a != nullptr) a->group = l;
- if (s != nullptr) s->group = l;
-
- return l;
- }
-
- const target_type lib::static_type
- {
- "lib",
- &libx::static_type,
- &lib_factory,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- &target_search,
- false // Note: not see-through ("alternatives" group).
- };
-
- // libi
- //
- const target_type libi::static_type
- {
- "libi",
- &file::static_type,
- &target_factory<libi>,
- nullptr, /* fixed_extension */
- &target_extension_var<nullptr>,
- &target_pattern_var<nullptr>,
- nullptr,
- &file_search,
- false
- };
-
- // def
- //
- extern const char def_ext[] = "def"; // VC14 rejects constexpr.
-
- const target_type def::static_type
- {
- "def",
- &file::static_type,
- &target_factory<def>,
- &target_extension_fix<def_ext>,
- nullptr, /* default_extension */
- &target_pattern_fix<def_ext>,
- nullptr,
- &file_search,
- false
- };
- }
-}
diff --git a/build2/bin/target.hxx b/build2/bin/target.hxx
deleted file mode 100644
index 45229ce..0000000
--- a/build2/bin/target.hxx
+++ /dev/null
@@ -1,353 +0,0 @@
-// file : build2/bin/target.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_BIN_TARGET_HXX
-#define BUILD2_BIN_TARGET_HXX
-
-#include <libbuild2/types.hxx>
-#include <libbuild2/utility.hxx>
-
-#include <libbuild2/target.hxx>
-
-namespace build2
-{
- namespace bin
- {
- // The obj{} target group.
- //
- class objx: public file // Common base of all objX{} object files.
- {
- public:
- using file::file;
-
- public:
- static const target_type static_type;
- };
-
- class obje: public objx
- {
- public:
- using objx::objx;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class obja: public objx
- {
- public:
- using objx::objx;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class objs: public objx
- {
- public:
- using objx::objx;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class obj: public target
- {
- public:
- using target::target;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- // Binary module interface (BMI).
- //
- // While currently there are only C++ modules, if things pan out, chances
- // are we will have C (or Obj-C) modules. And in that case it is plausible
- // we will also have some binutils to examine BMIs, similar to objdump,
- // etc. So that's why this target type is in bin and not cxx.
- //
- // bmi*{} is similar to obj*{} though the semantics is a bit different:
- // the idea is that we should try hard to re-use a single bmiX{} file for
- // an entire "build" but if that's not possible (because the compilation
- // options are too different), then compile a private version for
- // ourselves (the definition of "too different" is, of course, compiler-
- // specific).
- //
- // When we compile a module interface unit, we end up with bmi*{} and
- // obj*{}. How that obj*{} is produced is compiler-dependent. While it
- // makes sense to decouple the production of the two in order to increase
- // parallelism, doing so will further complicate the already hairy
- // organization. So, at least for now, we produce the two at the same time
- // and make obj*{} an ad hoc member of bmi*{}.
- //
- // There are also header units for which we define a parallel hbmi*{}
- // hierarchy. Note that hbmix{} is-a bmix{} (we think of header BMIs as a
- // more specialized kind of BMI) so where you need to distinguish between
- // header and module BMIs, you should check for headers first. Note also
- // that in case of a header unit there may be no obj*{}.
- //
- class bmix: public file // Common base of all bmiX{} interface files.
- {
- public:
- using file::file;
-
- public:
- static const target_type static_type;
- };
-
- class hbmix: public bmix // Common base of all hbmiX{} interface files.
- {
- public:
- using bmix::bmix;
-
- public:
- static const target_type static_type;
- };
-
- class bmie: public bmix
- {
- public:
- using bmix::bmix;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class hbmie: public hbmix
- {
- public:
- using hbmix::hbmix;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class bmia: public bmix
- {
- public:
- using bmix::bmix;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class hbmia: public hbmix
- {
- public:
- using hbmix::hbmix;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class bmis: public bmix
- {
- public:
- using bmix::bmix;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class hbmis: public hbmix
- {
- public:
- using hbmix::hbmix;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class bmi: public target
- {
- public:
- using target::target;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class hbmi: public target
- {
- public:
- using target::target;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
-
- // Common base for lib{} and libul{} groups.
- //
- // We use mtime_target as a base for the "trust me it exists" functionality
- // which we use, for example, to have installed lib{} prerequisites that
- // are matched by the fallback file rule.
- //
- class libx: public mtime_target
- {
- public:
- using mtime_target::mtime_target;
-
- public:
- static const target_type static_type;
- };
-
- // The libue{} target, libul{} group and libua{} and libus{} members
- // (utility library).
- //
- // Utility libraries are static libraries that differ based on the kind of
- // object files they contains. Note that the libul{} group is more like
- // obj{} rather than lib{} in that one does not build the group directly
- // rather picking a suitable member.
- //
- // libul{} is a "library utility library" in that the choice of members is
- // libua{} or libus{}, even when linking an executable (normally a unit
- // test).
- //
- // Note that there is no "general utility library" with all three types of
- // members (that would cause member uplink ambiguity). If you need to
- // build both a library from libua{}/libus{} and an executable from
- // libue{} then you will need to arrange this explicitly, for example:
- //
- // exe{foo}: libue{foo}
- // lib{foo}: libul{foo}
- //
- // {libue libul}{foo}: cxx{*}
- //
- class libux: public file // Common base of all libuX{} static libraries.
- {
- public:
- using file::file;
-
- public:
- static const target_type static_type;
- };
-
- class libue: public libux
- {
- public:
- using libux::libux;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class libua: public libux
- {
- public:
- using libux::libux;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class libus: public libux
- {
- public:
- using libux::libux;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class libul: public libx
- {
- public:
- using libx::libx;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- // The lib{} target group.
- //
- class liba: public file
- {
- public:
- using file::file;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- class libs: public file
- {
- public:
- using file::file;
-
- public:
- static const target_type static_type;
-
- virtual const target_type&
- dynamic_type () const override {return static_type;}
- };
-
- // Standard layout type compatible with group_view's const target*[2].
- //
- struct lib_members
- {
- const liba* a = nullptr;
- const libs* s = nullptr;
- };
-
- class lib: public libx, public lib_members
- {
- public:
- using libx::libx;
-
- virtual group_view
- group_members (action) const override;
-
- public:
- static const target_type static_type;
-
- virtual const target_type&
- dynamic_type () const override {return static_type;}
- };
-
- // Windows import library.
- //
- class libi: public file
- {
- public:
- using file::file;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
-
- // Windows module definition (.def).
- //
- class def: public file
- {
- public:
- using file::file;
-
- public:
- static const target_type static_type;
- virtual const target_type& dynamic_type () const {return static_type;}
- };
- }
-}
-
-#endif // BUILD2_BIN_TARGET_HXX
diff --git a/build2/buildfile b/build2/buildfile
index 196c485..1f956a3 100644
--- a/build2/buildfile
+++ b/build2/buildfile
@@ -8,7 +8,7 @@ import libs += libpkgconf%lib{pkgconf}
include ../libbuild2/
libs += ../libbuild2/lib{build2}
-for m: bash in version
+for m: bash bin in version
{
include ../libbuild2/$m/
libs += ../libbuild2/$m/lib{build2-$m}
diff --git a/build2/cc/common.hxx b/build2/cc/common.hxx
index b24eb7d..527c31a 100644
--- a/build2/cc/common.hxx
+++ b/build2/cc/common.hxx
@@ -11,7 +11,7 @@
#include <libbuild2/context.hxx>
#include <libbuild2/variable.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/types.hxx>
#include <build2/cc/guess.hxx> // compiler_id
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx
index fa43533..5d4c838 100644
--- a/build2/cc/compile-rule.cxx
+++ b/build2/cc/compile-rule.cxx
@@ -18,7 +18,7 @@
#include <libbuild2/config/utility.hxx> // create_project()
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/parser.hxx>
#include <build2/cc/target.hxx> // h
diff --git a/build2/cc/gcc.cxx b/build2/cc/gcc.cxx
index e6d7101..a979b2d 100644
--- a/build2/cc/gcc.cxx
+++ b/build2/cc/gcc.cxx
@@ -8,7 +8,7 @@
#include <libbuild2/filesystem.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/types.hxx>
diff --git a/build2/cc/install-rule.cxx b/build2/cc/install-rule.cxx
index 9e52501..876e780 100644
--- a/build2/cc/install-rule.cxx
+++ b/build2/cc/install-rule.cxx
@@ -6,7 +6,7 @@
#include <libbuild2/algorithm.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/utility.hxx>
#include <build2/cc/link-rule.hxx> // match()
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index ce5fce9..adf76d1 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -18,7 +18,7 @@
#include <libbuild2/filesystem.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/target.hxx> // c, pc*
#include <build2/cc/utility.hxx>
diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx
index bd853cc..478cabe 100644
--- a/build2/cc/module.cxx
+++ b/build2/cc/module.cxx
@@ -9,7 +9,7 @@
#include <libbuild2/scope.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/target.hxx> // pc*
diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx
index 7d8c3f5..886975a 100644
--- a/build2/cc/msvc.cxx
+++ b/build2/cc/msvc.cxx
@@ -11,7 +11,7 @@
#include <libbuild2/filesystem.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/types.hxx>
diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx
index 3b4c711..0ebf818 100644
--- a/build2/cc/pkgconfig.cxx
+++ b/build2/cc/pkgconfig.cxx
@@ -19,7 +19,7 @@
#include <libbuild2/install/utility.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/types.hxx>
#include <build2/cc/target.hxx> // pc
diff --git a/build2/cc/utility.cxx b/build2/cc/utility.cxx
index e9d4ce3..f17d1b0 100644
--- a/build2/cc/utility.cxx
+++ b/build2/cc/utility.cxx
@@ -8,8 +8,8 @@
#include <libbuild2/variable.hxx>
#include <libbuild2/algorithm.hxx> // search()
-#include <build2/bin/rule.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/rule.hxx>
+#include <libbuild2/bin/target.hxx>
using namespace std;
diff --git a/build2/cc/utility.hxx b/build2/cc/utility.hxx
index 6222b5f..002dea7 100644
--- a/build2/cc/utility.hxx
+++ b/build2/cc/utility.hxx
@@ -9,7 +9,7 @@
#include <libbuild2/utility.hxx>
#include <libbuild2/target.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/types.hxx>
diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx
index 4478f7d..c4ef358 100644
--- a/build2/cc/windows-rpath.cxx
+++ b/build2/cc/windows-rpath.cxx
@@ -11,7 +11,7 @@
#include <libbuild2/filesystem.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/bin/target.hxx>
+#include <libbuild2/bin/target.hxx>
#include <build2/cc/link-rule.hxx>