aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstrap-mingw.bat2
-rw-r--r--bootstrap-msvc.bat2
-rw-r--r--bootstrap.gmake6
-rwxr-xr-xbootstrap.sh2
-rw-r--r--build/export.build12
-rw-r--r--build2/b.cxx94
-rw-r--r--build2/bash/rule.cxx2
-rw-r--r--build2/bash/rule.hxx2
-rw-r--r--build2/buildfile9
-rw-r--r--build2/in/init.hxx37
-rw-r--r--build2/version/rule.cxx2
-rw-r--r--build2/version/rule.hxx2
-rw-r--r--libbuild2/buildfile26
-rw-r--r--libbuild2/config/init.cxx14
-rw-r--r--libbuild2/config/init.hxx2
-rw-r--r--libbuild2/dist/init.cxx10
-rw-r--r--libbuild2/dist/init.hxx2
-rw-r--r--libbuild2/in/buildfile62
-rw-r--r--libbuild2/in/export.hxx34
-rw-r--r--libbuild2/in/init.cxx (renamed from build2/in/init.cxx)24
-rw-r--r--libbuild2/in/init.hxx30
-rw-r--r--libbuild2/in/rule.cxx (renamed from build2/in/rule.cxx)6
-rw-r--r--libbuild2/in/rule.hxx (renamed from build2/in/rule.hxx)12
-rw-r--r--libbuild2/in/target.cxx (renamed from build2/in/target.cxx)4
-rw-r--r--libbuild2/in/target.hxx (renamed from build2/in/target.hxx)12
-rw-r--r--libbuild2/install/init.cxx10
-rw-r--r--libbuild2/install/init.hxx2
-rw-r--r--libbuild2/module.hxx28
-rw-r--r--libbuild2/test/init.cxx10
-rw-r--r--libbuild2/test/init.hxx2
-rw-r--r--tests/libbuild2/buildfile3
-rw-r--r--tests/libbuild2/driver.cxx5
32 files changed, 324 insertions, 146 deletions
diff --git a/bootstrap-mingw.bat b/bootstrap-mingw.bat
index 73b76f3..5061753 100644
--- a/bootstrap-mingw.bat
+++ b/bootstrap-mingw.bat
@@ -66,7 +66,6 @@ set "src=%src% build2\c"
set "src=%src% build2\cc"
set "src=%src% build2\cxx"
set "src=%src% build2\version"
-set "src=%src% build2\in"
set "src=%src% libbuild2"
set "src=%src% libbuild2\config"
@@ -74,6 +73,7 @@ set "src=%src% libbuild2\dist"
set "src=%src% libbuild2\test"
set "src=%src% libbuild2\test\script"
set "src=%src% libbuild2\install"
+set "src=%src% libbuild2\in"
set "src=%src% %libbutl%\libbutl"
diff --git a/bootstrap-msvc.bat b/bootstrap-msvc.bat
index a011162..e4e2a66 100644
--- a/bootstrap-msvc.bat
+++ b/bootstrap-msvc.bat
@@ -97,7 +97,6 @@ set "src=%src% build2\c"
set "src=%src% build2\cc"
set "src=%src% build2\cxx"
set "src=%src% build2\version"
-set "src=%src% build2\in"
set "src=%src% libbuild2"
set "src=%src% libbuild2\config"
@@ -105,6 +104,7 @@ set "src=%src% libbuild2\dist"
set "src=%src% libbuild2\test"
set "src=%src% libbuild2\test\script"
set "src=%src% libbuild2\install"
+set "src=%src% libbuild2\in"
set "src=%src% %libbutl%\libbutl"
diff --git a/bootstrap.gmake b/bootstrap.gmake
index 04716be..793f3d0 100644
--- a/bootstrap.gmake
+++ b/bootstrap.gmake
@@ -134,15 +134,15 @@ bin \
c \
cc \
cxx \
-version \
-in
+version
libbuild2_sub := \
config \
dist \
test/script \
test \
-install
+install \
+in
build2_src := $(wildcard $(src_root)/build2/*.cxx)
build2_src += $(foreach d,$(build2_sub),$(wildcard $(src_root)/build2/$d/*.cxx))
diff --git a/bootstrap.sh b/bootstrap.sh
index 51e5e9d..7e754b0 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -123,7 +123,6 @@ src="$src build2/cc/*.cxx"
src="$src build2/cxx/*.cxx"
src="$src build2/cli/*.cxx"
src="$src build2/version/*.cxx"
-src="$src build2/in/*.cxx"
src="$src build2/bash/*.cxx"
src="$src libbuild2/*.cxx"
@@ -132,6 +131,7 @@ src="$src libbuild2/dist/*.cxx"
src="$src libbuild2/test/*.cxx"
src="$src libbuild2/test/script/*.cxx"
src="$src libbuild2/install/*.cxx"
+src="$src libbuild2/in/*.cxx"
src="$src $libbutl/libbutl/*.cxx"
diff --git a/build/export.build b/build/export.build
index 4847950..345baf0 100644
--- a/build/export.build
+++ b/build/export.build
@@ -11,12 +11,20 @@ if ($import.target == exe{b})
export $out_root/build2/exe{b}
}
-elif ($import.target == lib{build2})
+else
{
$out_root/
{
include libbuild2/
}
- export $out_root/libbuild2/lib{build2}
+ d = [dir_path] $out_root/libbuild2/
+ if ($import.target != lib{build2})
+ {
+ # Assume one of the modules.
+ #
+ d += $regex.replace($name($import.target), '^build2-(.+)', '\1')
+ }
+
+ export $d/$import.target
}
diff --git a/build2/b.cxx b/build2/b.cxx
index a76a8e4..907784b 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -42,20 +42,18 @@
#include <libbuild2/parser.hxx>
+#include <build2/b-options.hxx>
+
+// Build system modules.
+//
#include <libbuild2/dist/init.hxx>
#include <libbuild2/test/init.hxx>
#include <libbuild2/config/init.hxx>
#include <libbuild2/install/init.hxx>
-#include <build2/b-options.hxx>
-
-using namespace butl;
-using namespace std;
-
+#include <libbuild2/in/init.hxx>
#include <build2/version/init.hxx>
-#include <build2/in/init.hxx>
-
#include <build2/bin/init.hxx>
#include <build2/c/init.hxx>
#include <build2/cc/init.hxx>
@@ -66,6 +64,9 @@ using namespace std;
# include <build2/bash/init.hxx>
#endif
+using namespace butl;
+using namespace std;
+
namespace build2
{
static options ops;
@@ -437,46 +438,51 @@ main (int argc, char* argv[])
using mf = module_functions;
auto& bm (builtin_modules);
- bm["config"] = config::build2_config_load ();
- bm["dist"] = dist::build2_dist_load ();
- bm["test"] = test::build2_test_load ();
- bm["install"] = install::build2_install_load ();
-
- bm["version"] = mf {&version::boot, &version::init};
-
- bm["in.base"] = mf {nullptr, &in::base_init};
- bm["in"] = mf {nullptr, &in::init};
-
- bm["bin.vars"] = mf {nullptr, &bin::vars_init};
- bm["bin.config"] = mf {nullptr, &bin::config_init};
- bm["bin"] = mf {nullptr, &bin::init};
- bm["bin.ar.config"] = mf {nullptr, &bin::ar_config_init};
- bm["bin.ar"] = mf {nullptr, &bin::ar_init};
- bm["bin.ld.config"] = mf {nullptr, &bin::ld_config_init};
- bm["bin.ld"] = mf {nullptr, &bin::ld_init};
- bm["bin.rc.config"] = mf {nullptr, &bin::rc_config_init};
- bm["bin.rc"] = mf {nullptr, &bin::rc_init};
-
- bm["cc.core.vars"] = mf {nullptr, &cc::core_vars_init};
- bm["cc.core.guess"] = mf {nullptr, &cc::core_guess_init};
- bm["cc.core.config"] = mf {nullptr, &cc::core_config_init};
- bm["cc.core"] = mf {nullptr, &cc::core_init};
- bm["cc.config"] = mf {nullptr, &cc::config_init};
- bm["cc"] = mf {nullptr, &cc::init};
-
- bm["c.guess"] = mf {nullptr, &c::guess_init};
- bm["c.config"] = mf {nullptr, &c::config_init};
- bm["c"] = mf {nullptr, &c::init};
-
- bm["cxx.guess"] = mf {nullptr, &cxx::guess_init};
- bm["cxx.config"] = mf {nullptr, &cxx::config_init};
- bm["cxx"] = mf {nullptr, &cxx::init};
+ auto reg = [] (module_load_function* lf)
+ {
+ for (const module_functions* i (lf ()); i->name != nullptr; ++i)
+ builtin_modules[i->name] = *i;
+ };
+
+ reg (&config::build2_config_load);
+ reg (&dist::build2_dist_load);
+ reg (&test::build2_test_load);
+ reg (&install::build2_install_load);
+
+ bm["version"] = mf {"version", &version::boot, &version::init};
+
+ reg (&in::build2_in_load);
+
+ bm["bin.vars"] = mf {"bin.vars", nullptr, &bin::vars_init};
+ bm["bin.config"] = mf {"bin.config", nullptr, &bin::config_init};
+ bm["bin"] = mf {"bin", nullptr, &bin::init};
+ bm["bin.ar.config"] = mf {"bin.ar.config", nullptr, &bin::ar_config_init};
+ bm["bin.ar"] = mf {"bin.ar", nullptr, &bin::ar_init};
+ bm["bin.ld.config"] = mf {"bin.ld.config", nullptr, &bin::ld_config_init};
+ bm["bin.ld"] = mf {"bin.ld", nullptr, &bin::ld_init};
+ bm["bin.rc.config"] = mf {"bin.rc.config", nullptr, &bin::rc_config_init};
+ bm["bin.rc"] = mf {"bin.rc", nullptr, &bin::rc_init};
+
+ bm["cc.core.vars"] = mf {"cc.core.vars", nullptr, &cc::core_vars_init};
+ bm["cc.core.guess"] = mf {"cc.core.guess", nullptr, &cc::core_guess_init};
+ bm["cc.core.config"] = mf {"cc.core.config", nullptr, &cc::core_config_init};
+ bm["cc.core"] = mf {"cc.core", nullptr, &cc::core_init};
+ bm["cc.config"] = mf {"cc.config", nullptr, &cc::config_init};
+ bm["cc"] = mf {"cc", nullptr, &cc::init};
+
+ bm["c.guess"] = mf {"c.guess", nullptr, &c::guess_init};
+ bm["c.config"] = mf {"c.config", nullptr, &c::config_init};
+ bm["c"] = mf {"c", nullptr, &c::init};
+
+ bm["cxx.guess"] = mf {"cxx.guess", nullptr, &cxx::guess_init};
+ bm["cxx.config"] = mf {"cxx.config", nullptr, &cxx::config_init};
+ bm["cxx"] = mf {"cxx", nullptr, &cxx::init};
#ifndef BUILD2_BOOTSTRAP
- bm["cli.config"] = mf {nullptr, &cli::config_init};
- bm["cli"] = mf {nullptr, &cli::init};
+ bm["cli.config"] = mf {"cli.config", nullptr, &cli::config_init};
+ bm["cli"] = mf {"cli", nullptr, &cli::init};
- bm["bash"] = mf {nullptr, &bash::init};
+ bm["bash"] = mf {"bash", nullptr, &bash::init};
#endif
}
diff --git a/build2/bash/rule.cxx b/build2/bash/rule.cxx
index 72e3219..a612d23 100644
--- a/build2/bash/rule.cxx
+++ b/build2/bash/rule.cxx
@@ -11,7 +11,7 @@
#include <libbuild2/algorithm.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/in/target.hxx>
+#include <libbuild2/in/target.hxx>
#include <build2/bash/target.hxx>
#include <build2/bash/utility.hxx>
diff --git a/build2/bash/rule.hxx b/build2/bash/rule.hxx
index a6ec235..c160bb7 100644
--- a/build2/bash/rule.hxx
+++ b/build2/bash/rule.hxx
@@ -10,7 +10,7 @@
#include <libbuild2/install/rule.hxx>
-#include <build2/in/rule.hxx>
+#include <libbuild2/in/rule.hxx>
namespace build2
{
diff --git a/build2/buildfile b/build2/buildfile
index eb22266..a940793 100644
--- a/build2/buildfile
+++ b/build2/buildfile
@@ -6,12 +6,19 @@ import libs = libbutl%lib{butl}
import libs += libpkgconf%lib{pkgconf}
include ../libbuild2/
+libs += ../libbuild2/lib{build2}
+
+for m: in
+{
+ include ../libbuild2/in/
+ libs += ../libbuild2/$m/lib{build2-$m}
+}
./: exe{b}: {hxx ixx txx cxx}{+b} libue{b}
libue{b}: {hxx ixx txx cxx}{** -b -b-options -**.test...} \
{hxx ixx cxx}{b-options} \
- ../libbuild2/lib{build2} $libs
+ $libs
# Unit tests.
#
diff --git a/build2/in/init.hxx b/build2/in/init.hxx
deleted file mode 100644
index 3cf8ebf..0000000
--- a/build2/in/init.hxx
+++ /dev/null
@@ -1,37 +0,0 @@
-// file : build2/in/init.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_IN_INIT_HXX
-#define BUILD2_IN_INIT_HXX
-
-#include <libbuild2/types.hxx>
-#include <libbuild2/utility.hxx>
-
-#include <libbuild2/module.hxx>
-
-namespace build2
-{
- namespace in
- {
- bool
- base_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&);
- }
-}
-
-#endif // BUILD2_IN_INIT_HXX
diff --git a/build2/version/rule.cxx b/build2/version/rule.cxx
index 912efe3..f110e3e 100644
--- a/build2/version/rule.cxx
+++ b/build2/version/rule.cxx
@@ -8,7 +8,7 @@
#include <libbuild2/target.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/in/target.hxx>
+#include <libbuild2/in/target.hxx>
#include <build2/version/module.hxx>
#include <build2/version/utility.hxx>
diff --git a/build2/version/rule.hxx b/build2/version/rule.hxx
index 6d841df..7bfb783 100644
--- a/build2/version/rule.hxx
+++ b/build2/version/rule.hxx
@@ -10,7 +10,7 @@
#include <libbuild2/install/rule.hxx>
-#include <build2/in/rule.hxx>
+#include <libbuild2/in/rule.hxx>
namespace build2
{
diff --git a/libbuild2/buildfile b/libbuild2/buildfile
index f23f023..edabfc3 100644
--- a/libbuild2/buildfile
+++ b/libbuild2/buildfile
@@ -2,17 +2,21 @@
# copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
+./: lib{build2} in/
+
import int_libs = libbutl%lib{butl}
-# The config, test, install, and dist are "core modules" that come bundled
-# with libbuild2. Note that the core can still function without them or with
-# their alternative implementations.
+lib{build2}: libul{build2}: {hxx ixx txx cxx}{* -config -version -*.test...} \
+ {hxx}{config version}
+
+# These are "core modules" that come bundled with libbuild2 (see also unit
+# tests loop below). Note that the build system core can still function
+# without them or with their alternative implementations.
#
-./: lib{build2}: libul{build2}: {hxx ixx txx cxx}{** -config \
- -version \
- -**.test...} \
- {hxx}{config version} \
- $int_libs
+for m: config dist install test
+ libul{build2}: $m/{hxx ixx txx cxx}{** -**.test...}
+
+libul{build2}: $int_libs
# Include the generated config and version headers into the distribution (so
# that we don't pick up installed ones) and don't remove them when cleaning in
@@ -35,7 +39,11 @@ exe{*.test}:
install = false
}
-for t: cxx{**.test...}
+for t: cxx{ *.test...} \
+ config/cxx{**.test...} \
+ dist/cxx{**.test...} \
+ install/cxx{**.test...} \
+ test/cxx{**.test...}
{
d = $directory($t)
n = $name($t)...
diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx
index 73275c6..b790569 100644
--- a/libbuild2/config/init.cxx
+++ b/libbuild2/config/init.cxx
@@ -145,15 +145,21 @@ namespace build2
return true;
}
- module_functions
+ static const module_functions mod_functions[] =
+ {
+ {"config", &boot, &init},
+ {nullptr, nullptr, nullptr}
+ };
+
+ const module_functions*
build2_config_load ()
{
// Initialize the config entry points in the build system core.
//
- config_save_variable = &config::save_variable;
- config_preprocess_create = &config::preprocess_create;
+ config_save_variable = &save_variable;
+ config_preprocess_create = &preprocess_create;
- return module_functions {&boot, &init};
+ return mod_functions;
}
}
}
diff --git a/libbuild2/config/init.hxx b/libbuild2/config/init.hxx
index ff5e923..f900801 100644
--- a/libbuild2/config/init.hxx
+++ b/libbuild2/config/init.hxx
@@ -28,7 +28,7 @@ namespace build2
bool,
const variable_map&);
- extern "C" LIBBUILD2_SYMEXPORT module_functions
+ extern "C" LIBBUILD2_SYMEXPORT const module_functions*
build2_config_load ();
}
}
diff --git a/libbuild2/dist/init.cxx b/libbuild2/dist/init.cxx
index 959b2dd..4729938 100644
--- a/libbuild2/dist/init.cxx
+++ b/libbuild2/dist/init.cxx
@@ -183,10 +183,16 @@ namespace build2
return true;
}
- module_functions
+ static const module_functions mod_functions[] =
+ {
+ {"dist", &boot, &init},
+ {nullptr, nullptr, nullptr}
+ };
+
+ const module_functions*
build2_dist_load ()
{
- return module_functions {&boot, &init};
+ return mod_functions;
}
}
}
diff --git a/libbuild2/dist/init.hxx b/libbuild2/dist/init.hxx
index 41c82a7..cfcb3af 100644
--- a/libbuild2/dist/init.hxx
+++ b/libbuild2/dist/init.hxx
@@ -28,7 +28,7 @@ namespace build2
bool,
const variable_map&);
- extern "C" LIBBUILD2_SYMEXPORT module_functions
+ extern "C" LIBBUILD2_SYMEXPORT const module_functions*
build2_dist_load ();
}
}
diff --git a/libbuild2/in/buildfile b/libbuild2/in/buildfile
new file mode 100644
index 0000000..ae07e27
--- /dev/null
+++ b/libbuild2/in/buildfile
@@ -0,0 +1,62 @@
+# file : libbuild2/in/buildfile
+# copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+import int_libs = libbutl%lib{butl}
+
+include ../
+int_libs += ../lib{build2}
+
+./: lib{build2-in}: libul{build2-in}: {hxx ixx txx cxx}{** -**.test...} \
+ $int_libs
+
+# Unit tests.
+#
+exe{*.test}:
+{
+ test = true
+ install = false
+}
+
+for t: cxx{**.test...}
+{
+ d = $directory($t)
+ n = $name($t)...
+
+ ./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n}
+ $d/exe{$n}: libul{build2-in}: bin.whole = false
+}
+
+# Build options.
+#
+obja{*}: cxx.poptions += -DLIBBUILD2_IN_STATIC_BUILD
+objs{*}: cxx.poptions += -DLIBBUILD2_IN_SHARED_BUILD
+
+# Export options.
+#
+lib{build2-in}:
+{
+ cxx.export.poptions = "-I$out_root" "-I$src_root"
+ cxx.export.libs = $int_libs
+}
+
+liba{build2-in}: cxx.export.poptions += -DLIBBUILD2_IN_STATIC
+libs{build2-in}: cxx.export.poptions += -DLIBBUILD2_IN_SHARED
+
+# For pre-releases use the complete version to make sure they cannot be used
+# in place of another pre-release or the final version. See the version module
+# for details on the version.* variable values.
+#
+if $version.pre_release
+ lib{build2-in}: bin.lib.version = @"-$version.project_id"
+else
+ lib{build2-in}: bin.lib.version = @"-$version.major.$version.minor"
+
+# Install into the libbuild2/in/ subdirectory of, say, /usr/include/
+# recreating subdirectories.
+#
+{hxx ixx txx}{*}:
+{
+ install = include/libbuild2/in/
+ install.subdirs = true
+}
diff --git a/libbuild2/in/export.hxx b/libbuild2/in/export.hxx
new file mode 100644
index 0000000..47909e7
--- /dev/null
+++ b/libbuild2/in/export.hxx
@@ -0,0 +1,34 @@
+#pragma once
+
+// Normally we don't export class templates (but do complete specializations),
+// inline functions, and classes with only inline member functions. Exporting
+// classes that inherit from non-exported/imported bases (e.g., std::string)
+// will end up badly. The only known workarounds are to not inherit or to not
+// export. Also, MinGW GCC doesn't like seeing non-exported functions being
+// used before their inline definition. The workaround is to reorder code. In
+// the end it's all trial and error.
+
+#if defined(LIBBUILD2_IN_STATIC) // Using static.
+# define LIBBUILD2_IN_SYMEXPORT
+#elif defined(LIBBUILD2_IN_STATIC_BUILD) // Building static.
+# define LIBBUILD2_IN_SYMEXPORT
+#elif defined(LIBBUILD2_IN_SHARED) // Using shared.
+# ifdef _WIN32
+# define LIBBUILD2_IN_SYMEXPORT __declspec(dllimport)
+# else
+# define LIBBUILD2_IN_SYMEXPORT
+# endif
+#elif defined(LIBBUILD2_IN_SHARED_BUILD) // Building shared.
+# ifdef _WIN32
+# define LIBBUILD2_IN_SYMEXPORT __declspec(dllexport)
+# else
+# define LIBBUILD2_IN_SYMEXPORT
+# endif
+#else
+// If none of the above macros are defined, then we assume we are being used
+// by some third-party build system that cannot/doesn't signal the library
+// type. Note that this fallback works for both static and shared but in case
+// of shared will be sub-optimal compared to having dllimport.
+//
+# define LIBBUILD2_IN_SYMEXPORT // Using static or shared.
+#endif
diff --git a/build2/in/init.cxx b/libbuild2/in/init.cxx
index f01fe20..6ef996b 100644
--- a/build2/in/init.cxx
+++ b/libbuild2/in/init.cxx
@@ -1,16 +1,16 @@
-// file : build2/in/init.cxx -*- C++ -*-
+// file : libbuild2/in/init.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <build2/in/init.hxx>
+#include <libbuild2/in/init.hxx>
#include <libbuild2/scope.hxx>
#include <libbuild2/context.hxx>
#include <libbuild2/variable.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/in/rule.hxx>
-#include <build2/in/target.hxx>
+#include <libbuild2/in/rule.hxx>
+#include <libbuild2/in/target.hxx>
using namespace std;
@@ -106,5 +106,21 @@ namespace build2
return true;
}
+
+ static const module_functions mod_functions[] =
+ {
+ // NOTE: don't forget to also update the documentation in init.hxx if
+ // changing anything here.
+
+ {"in.base", nullptr, base_init},
+ {"in", nullptr, init},
+ {nullptr, nullptr, nullptr}
+ };
+
+ const module_functions*
+ build2_in_load ()
+ {
+ return mod_functions;
+ }
}
}
diff --git a/libbuild2/in/init.hxx b/libbuild2/in/init.hxx
new file mode 100644
index 0000000..b82c77e
--- /dev/null
+++ b/libbuild2/in/init.hxx
@@ -0,0 +1,30 @@
+// file : libbuild2/in/init.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef LIBBUILD2_IN_INIT_HXX
+#define LIBBUILD2_IN_INIT_HXX
+
+#include <libbuild2/types.hxx>
+#include <libbuild2/utility.hxx>
+
+#include <libbuild2/module.hxx>
+
+#include <libbuild2/in/export.hxx>
+
+namespace build2
+{
+ namespace in
+ {
+ // Module `in` does not require bootstrapping.
+ //
+ // Submodules:
+ //
+ // `in.base` -- only variables and target types.
+ //
+ extern "C" LIBBUILD2_IN_SYMEXPORT const module_functions*
+ build2_in_load ();
+ }
+}
+
+#endif // LIBBUILD2_IN_INIT_HXX
diff --git a/build2/in/rule.cxx b/libbuild2/in/rule.cxx
index 8a3244d..bdc9b24 100644
--- a/build2/in/rule.cxx
+++ b/libbuild2/in/rule.cxx
@@ -1,8 +1,8 @@
-// file : build2/in/rule.cxx -*- C++ -*-
+// file : libbuild2/in/rule.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <build2/in/rule.hxx>
+#include <libbuild2/in/rule.hxx>
#include <cstdlib> // strtoull()
@@ -14,7 +14,7 @@
#include <libbuild2/filesystem.hxx>
#include <libbuild2/diagnostics.hxx>
-#include <build2/in/target.hxx>
+#include <libbuild2/in/target.hxx>
using namespace std;
using namespace butl;
diff --git a/build2/in/rule.hxx b/libbuild2/in/rule.hxx
index 71dc032..0daf6c0 100644
--- a/build2/in/rule.hxx
+++ b/libbuild2/in/rule.hxx
@@ -1,15 +1,17 @@
-// file : build2/in/rule.hxx -*- C++ -*-
+// file : libbuild2/in/rule.hxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef BUILD2_IN_RULE_HXX
-#define BUILD2_IN_RULE_HXX
+#ifndef LIBBUILD2_IN_RULE_HXX
+#define LIBBUILD2_IN_RULE_HXX
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
#include <libbuild2/rule.hxx>
+#include <libbuild2/in/export.hxx>
+
namespace build2
{
namespace in
@@ -22,7 +24,7 @@ namespace build2
// Note also that currently this rule ignores the dry-run mode (see
// perform_update() for the rationale).
//
- class rule: public build2::rule
+ class LIBBUILD2_IN_SYMEXPORT rule: public build2::rule
{
public:
// The rule id is used to form the rule name/version entry in depdb. The
@@ -85,4 +87,4 @@ namespace build2
}
}
-#endif // BUILD2_IN_RULE_HXX
+#endif // LIBBUILD2_IN_RULE_HXX
diff --git a/build2/in/target.cxx b/libbuild2/in/target.cxx
index 8dc520b..490ab10 100644
--- a/build2/in/target.cxx
+++ b/libbuild2/in/target.cxx
@@ -1,8 +1,8 @@
-// file : build2/in/target.cxx -*- C++ -*-
+// file : libbuild2/in/target.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <build2/in/target.hxx>
+#include <libbuild2/in/target.hxx>
using namespace std;
diff --git a/build2/in/target.hxx b/libbuild2/in/target.hxx
index 47b0eed..5e3438d 100644
--- a/build2/in/target.hxx
+++ b/libbuild2/in/target.hxx
@@ -1,15 +1,17 @@
-// file : build2/in/target.hxx -*- C++ -*-
+// file : libbuild2/in/target.hxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef BUILD2_IN_TARGET_HXX
-#define BUILD2_IN_TARGET_HXX
+#ifndef LIBBUILD2_IN_TARGET_HXX
+#define LIBBUILD2_IN_TARGET_HXX
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
#include <libbuild2/target.hxx>
+#include <libbuild2/in/export.hxx>
+
namespace build2
{
namespace in
@@ -31,7 +33,7 @@ namespace build2
// the target-dependent search comes in: we take into account the target
// we are a prerequisite of.
//
- class in: public file
+ class LIBBUILD2_IN_SYMEXPORT in: public file
{
public:
using file::file;
@@ -43,4 +45,4 @@ namespace build2
}
}
-#endif // BUILD2_IN_TARGET_HXX
+#endif // LIBBUILD2_IN_TARGET_HXX
diff --git a/libbuild2/install/init.cxx b/libbuild2/install/init.cxx
index fb3d9ea..060007b 100644
--- a/libbuild2/install/init.cxx
+++ b/libbuild2/install/init.cxx
@@ -300,10 +300,16 @@ namespace build2
return true;
}
- module_functions
+ static const module_functions mod_functions[] =
+ {
+ {"install", &boot, &init},
+ {nullptr, nullptr, nullptr}
+ };
+
+ const module_functions*
build2_install_load ()
{
- return module_functions {&boot, &init};
+ return mod_functions;
}
}
}
diff --git a/libbuild2/install/init.hxx b/libbuild2/install/init.hxx
index fa0a1e1..b2daea0 100644
--- a/libbuild2/install/init.hxx
+++ b/libbuild2/install/init.hxx
@@ -28,7 +28,7 @@ namespace build2
bool,
const variable_map&);
- extern "C" LIBBUILD2_SYMEXPORT module_functions
+ extern "C" LIBBUILD2_SYMEXPORT const module_functions*
build2_install_load ();
}
}
diff --git a/libbuild2/module.hxx b/libbuild2/module.hxx
index 7d94837..c32fc9a 100644
--- a/libbuild2/module.hxx
+++ b/libbuild2/module.hxx
@@ -50,24 +50,31 @@ namespace build2
bool optional, // Loaded with using? (optional module).
const variable_map& hints); // Configuration hints (see below).
+ // If the boot function is not NULL, then such a module is said to require
+ // bootstrapping and must be loaded in bootstrap.build.
+ //
struct module_functions
{
- module_boot_function* boot;
- module_init_function* init;
+ const char* name = nullptr; // Module/submodule name.
+ module_boot_function* boot = nullptr;
+ module_init_function* init = nullptr;
};
- // The build2_<modname>_load() function will be written in C++ and will be
+ // The build2_<name>_load() function will be written in C++ and will be
// called from C++ but we need to suppress name mangling to be able to use
- // dlsym() or equivalent.
+ // dlsym() or equivalent, thus extern "C".
//
- // Note that the load() function is guaranteed to be called during serial
- // execution (either from main() or during the load phase).
+ // The <name> part in the function name is the main module name without
+ // submodule components (for example, `c` in `c.config`) and the load
+ // function is expected to return boot/init functions for all its submodules
+ // (if any) as well as for the module itself as an array of module_functions
+ // terminated with an all-NULL entry.
//
- // @@ I wonder if returning a "C++ struct" (it contains pointer to functions
- // with signatures containing C++ type) is kosher.
+ // Note that the load function is guaranteed to be called during serial
+ // execution (either from main() or during the load phase).
//
extern "C"
- using module_load_function = module_functions ();
+ using module_load_function = const module_functions* ();
// Loaded modules state.
//
@@ -119,6 +126,9 @@ namespace build2
// Builtin modules.
//
+ // @@ Maybe this should be renamed to loaded modules?
+ // @@ We can also change it to std::map<const char*, const module_functions*>
+ //
using available_module_map = std::map<string, module_functions>;
LIBBUILD2_SYMEXPORT extern available_module_map builtin_modules;
}
diff --git a/libbuild2/test/init.cxx b/libbuild2/test/init.cxx
index 3d13acc..a5afea0 100644
--- a/libbuild2/test/init.cxx
+++ b/libbuild2/test/init.cxx
@@ -220,12 +220,18 @@ namespace build2
return true;
}
- module_functions
+ static const module_functions mod_functions[] =
+ {
+ {"test", &boot, &init},
+ {nullptr, nullptr, nullptr}
+ };
+
+ const module_functions*
build2_test_load ()
{
script::regex::init ();
- return module_functions {&boot, &init};
+ return mod_functions;
}
}
}
diff --git a/libbuild2/test/init.hxx b/libbuild2/test/init.hxx
index a76b720..57f6bfa 100644
--- a/libbuild2/test/init.hxx
+++ b/libbuild2/test/init.hxx
@@ -28,7 +28,7 @@ namespace build2
bool,
const variable_map&);
- extern "C" LIBBUILD2_SYMEXPORT module_functions
+ extern "C" LIBBUILD2_SYMEXPORT const module_functions*
build2_test_load ();
}
}
diff --git a/tests/libbuild2/buildfile b/tests/libbuild2/buildfile
index 4d3a42f..51b2f5b 100644
--- a/tests/libbuild2/buildfile
+++ b/tests/libbuild2/buildfile
@@ -2,7 +2,8 @@
# copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-import libs = build2%lib{build2}
+import libs = build2%lib{build2}
+import libs += build2%lib{build2-in}
exe{driver}: {hxx cxx}{*} $libs testscript
diff --git a/tests/libbuild2/driver.cxx b/tests/libbuild2/driver.cxx
index 3df2fbe..d9c086a 100644
--- a/tests/libbuild2/driver.cxx
+++ b/tests/libbuild2/driver.cxx
@@ -8,6 +8,8 @@
#include <libbuild2/context.hxx> // sched, reset()
#include <libbuild2/scheduler.hxx>
+#include <libbuild2/in/init.hxx>
+
using namespace build2;
int
@@ -17,6 +19,9 @@ main (int, char* argv[])
//
init_diag (1);
init (argv[0]);
+
+ in::build2_in_load ();
+
sched.startup (1); // Serial execution.
reset (strings ()); // No command line variables.