aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-08-26 12:06:03 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-08-28 15:01:48 +0300
commitac87e3827b214c0ba1bd1c17a2d8a18026637d3f (patch)
tree8a750721a2537f9762b9dda4e00951b61ee1354f
parentf7adb1ce7a13753a6acf5c9eeb9577ecdada630c (diff)
Move cxx build system module to separate library
-rw-r--r--bootstrap-mingw.bat2
-rw-r--r--bootstrap-msvc.bat2
-rw-r--r--bootstrap.gmake7
-rwxr-xr-xbootstrap.sh2
-rw-r--r--build2/b.cxx8
-rw-r--r--build2/buildfile11
-rw-r--r--build2/cli/init.cxx2
-rw-r--r--build2/cli/target.hxx2
-rw-r--r--build2/cxx/init.hxx46
-rw-r--r--libbuild2/buildfile8
-rw-r--r--libbuild2/cxx/buildfile90
-rw-r--r--libbuild2/cxx/export.hxx38
-rw-r--r--libbuild2/cxx/init.cxx (renamed from build2/cxx/init.cxx)23
-rw-r--r--libbuild2/cxx/init.hxx32
-rw-r--r--libbuild2/cxx/target.cxx (renamed from build2/cxx/target.cxx)4
-rw-r--r--libbuild2/cxx/target.hxx (renamed from build2/cxx/target.hxx)20
-rw-r--r--libbuild2/module.cxx1
-rw-r--r--tests/libbuild2/buildfile2
-rw-r--r--tests/libbuild2/driver.cxx2
19 files changed, 211 insertions, 91 deletions
diff --git a/bootstrap-mingw.bat b/bootstrap-mingw.bat
index 43cc84f..128bf58 100644
--- a/bootstrap-mingw.bat
+++ b/bootstrap-mingw.bat
@@ -61,7 +61,6 @@ if "_%libbutl%_" == "__" (
rem All the source directories.
rem
set "src=build2"
-set "src=%src% build2\cxx"
set "src=%src% libbuild2"
set "src=%src% libbuild2\config"
@@ -72,6 +71,7 @@ set "src=%src% libbuild2\install"
set "src=%src% libbuild2\bin"
set "src=%src% libbuild2\c"
set "src=%src% libbuild2\cc"
+set "src=%src% libbuild2\cxx"
set "src=%src% libbuild2\version"
set "src=%src% libbuild2\in"
diff --git a/bootstrap-msvc.bat b/bootstrap-msvc.bat
index 8da8769..1c860a2 100644
--- a/bootstrap-msvc.bat
+++ b/bootstrap-msvc.bat
@@ -92,7 +92,6 @@ if "_%libbutl%_" == "__" (
rem All the source directories.
rem
set "src=build2"
-set "src=%src% build2\cxx"
set "src=%src% libbuild2"
set "src=%src% libbuild2\config"
@@ -103,6 +102,7 @@ set "src=%src% libbuild2\install"
set "src=%src% libbuild2\bin"
set "src=%src% libbuild2\c"
set "src=%src% libbuild2\cc"
+set "src=%src% libbuild2\cxx"
set "src=%src% libbuild2\version"
set "src=%src% libbuild2\in"
diff --git a/bootstrap.gmake b/bootstrap.gmake
index 0e3126e..0587004 100644
--- a/bootstrap.gmake
+++ b/bootstrap.gmake
@@ -129,9 +129,6 @@ endif
#
# Note: list nested subdirectories first (used in clean).
#
-build2_sub := \
-cxx
-
libbuild2_sub := \
config \
dist \
@@ -141,11 +138,11 @@ install \
bin \
c \
cc \
+cxx \
version \
in
build2_src := $(wildcard $(src_root)/build2/*.cxx)
-build2_src += $(foreach d,$(build2_sub),$(wildcard $(src_root)/build2/$d/*.cxx))
libbuild2_src := $(wildcard $(src_root)/libbuild2/*.cxx)
libbuild2_src += $(foreach d,$(libbuild2_sub),$(wildcard $(src_root)/libbuild2/$d/*.cxx))
libbutl_src := $(wildcard $(libbutl)/libbutl/*.cxx)
@@ -196,5 +193,5 @@ cleano:
clean: cleano
rm -f $(out_root)/build2/b-boot$(exe)
ifeq ($(in_tree),false)
- rm -fd $(foreach d,$(build2_sub),$(out_root)/build2/$d) $(out_root)/build2 $(foreach d,$(libbuild2_sub),$(out_root)/libbuild2/$d) $(out_root)/libbuild2 $(libbutl_out)
+ rm -fd $(out_root)/build2 $(foreach d,$(libbuild2_sub),$(out_root)/libbuild2/$d) $(out_root)/libbuild2 $(libbutl_out)
endif
diff --git a/bootstrap.sh b/bootstrap.sh
index 368a549..753f538 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -117,7 +117,6 @@ if test -z "$libbutl"; then
fi
src="build2/*.cxx"
-src="$src build2/cxx/*.cxx"
src="$src libbuild2/*.cxx"
src="$src libbuild2/config/*.cxx"
@@ -128,6 +127,7 @@ src="$src libbuild2/install/*.cxx"
src="$src libbuild2/bin/*.cxx"
src="$src libbuild2/c/*.cxx"
src="$src libbuild2/cc/*.cxx"
+src="$src libbuild2/cxx/*.cxx"
src="$src libbuild2/version/*.cxx"
src="$src libbuild2/in/*.cxx"
diff --git a/build2/b.cxx b/build2/b.cxx
index 1fd6b5a..a4e799c 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -56,6 +56,7 @@
#include <libbuild2/bin/init.hxx>
#include <libbuild2/c/init.hxx>
#include <libbuild2/cc/init.hxx>
+#include <libbuild2/cxx/init.hxx>
#include <libbuild2/version/init.hxx>
#ifndef BUILD2_BOOTSTRAP
@@ -64,8 +65,6 @@
# include <build2/cli/init.hxx>
#endif
-#include <build2/cxx/init.hxx>
-
using namespace butl;
using namespace std;
@@ -522,13 +521,10 @@ main (int argc, char* argv[])
load (&bin::build2_bin_load);
load (&cc::build2_cc_load);
load (&c::build2_c_load);
+ load (&cxx::build2_cxx_load);
load (&version::build2_version_load);
load (&in::build2_in_load);
- TMP_LOAD (cxx_guess, "cxx.guess", cxx::guess_init);
- TMP_LOAD (cxx_config, "cxx.config", cxx::config_init);
- TMP_LOAD (cxx, "cxx", cxx::init);
-
#ifndef BUILD2_BOOTSTRAP
TMP_LOAD (cli_config, "cli.config", cli::config_init);
TMP_LOAD (cli, "cli", cli::init);
diff --git a/build2/buildfile b/build2/buildfile
index 7f4187e..fd9cec6 100644
--- a/build2/buildfile
+++ b/build2/buildfile
@@ -7,7 +7,7 @@ import libs = libbutl%lib{butl}
include ../libbuild2/
libs += ../libbuild2/lib{build2}
-for m: bash bin c cc in version
+for m: bash bin c cc cxx in version
{
include ../libbuild2/$m/
libs += ../libbuild2/$m/lib{build2-$m}
@@ -43,15 +43,6 @@ for t: cxx{**.test...}
#
obj{b}: cxx.poptions += -DBUILD2_HOST_TRIPLET=\"$cxx.target\"
-# Pass native C and C++ compiler paths (not forgetting to escape backslashes
-# on Windows). These are used as defaults for BUILD2_DEFAULT_*.
-#
-if ($cxx.target == $build.host)
-{
- cxx/obj{init}: cxx.poptions += \
- -DBUILD2_NATIVE_CXX=\"$regex.replace($recall($cxx.path), '\\', '\\\\')\"
-}
-
if ($cxx.target.class != 'windows')
{
if ($cxx.target.class == 'linux')
diff --git a/build2/cli/init.cxx b/build2/cli/init.cxx
index 3aebe8e..7b7a519 100644
--- a/build2/cli/init.cxx
+++ b/build2/cli/init.cxx
@@ -11,7 +11,7 @@
#include <libbuild2/config/utility.hxx>
-#include <build2/cxx/target.hxx>
+#include <libbuild2/cxx/target.hxx>
#include <build2/cli/target.hxx>
#include <build2/cli/rule.hxx>
diff --git a/build2/cli/target.hxx b/build2/cli/target.hxx
index c6aa266..cf66a44 100644
--- a/build2/cli/target.hxx
+++ b/build2/cli/target.hxx
@@ -10,7 +10,7 @@
#include <libbuild2/target.hxx>
-#include <build2/cxx/target.hxx>
+#include <libbuild2/cxx/target.hxx>
namespace build2
{
diff --git a/build2/cxx/init.hxx b/build2/cxx/init.hxx
deleted file mode 100644
index 83553e6..0000000
--- a/build2/cxx/init.hxx
+++ /dev/null
@@ -1,46 +0,0 @@
-// file : build2/cxx/init.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_CXX_INIT_HXX
-#define BUILD2_CXX_INIT_HXX
-
-#include <libbuild2/types.hxx>
-#include <libbuild2/utility.hxx>
-
-#include <libbuild2/module.hxx>
-
-namespace build2
-{
- namespace cxx
- {
- bool
- guess_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&);
- }
-}
-
-#endif // BUILD2_CXX_INIT_HXX
diff --git a/libbuild2/buildfile b/libbuild2/buildfile
index 75731fc..8d40c28 100644
--- a/libbuild2/buildfile
+++ b/libbuild2/buildfile
@@ -2,10 +2,10 @@
# copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-# NOTE: remember to update bundled_modules in libbuild2/modules.cxx if adding
-# a new module.
+# NOTE: remember to update bundled_modules in libbuild2/module.cxx if adding a
+# new module.
#
-./: lib{build2} bash/ bin/ c/ cc/ in/ version/
+./: lib{build2} bash/ bin/ c/ cc/ cxx/ in/ version/
import int_libs = libbutl%lib{butl}
@@ -88,7 +88,7 @@ cross = ($cxx.target.cpu != $build.host.cpu || \
if! $cross
obj{context}: cxx.poptions += \
- "-DBUILD2_IMPORT_PATH=\"$regex.replace($out_root, '\\', '\\\\')\""
+ -DBUILD2_IMPORT_PATH=\"$regex.replace($out_root, '\\', '\\\\')\"
obja{context}: cxx.poptions += -DLIBBUILD2_STATIC_BUILD
objs{context}: cxx.poptions += -DLIBBUILD2_SHARED_BUILD
diff --git a/libbuild2/cxx/buildfile b/libbuild2/cxx/buildfile
new file mode 100644
index 0000000..debb574
--- /dev/null
+++ b/libbuild2/cxx/buildfile
@@ -0,0 +1,90 @@
+# file : libbuild2/cxx/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}
+
+include ../cc/
+int_libs += ../cc/lib{build2-cc}
+
+./: lib{build2-cxx}: libul{build2-cxx}: {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-cxx}: bin.whole = false
+}
+
+# Build options.
+#
+obja{*}: cxx.poptions += -DLIBBUILD2_CXX_STATIC_BUILD
+objs{*}: cxx.poptions += -DLIBBUILD2_CXX_SHARED_BUILD
+
+# Note that we used to compare complete target triplets but that proved too
+# strict (see libbuild2/buildfile for details).
+#
+cross = ($cxx.target.cpu != $build.host.cpu || \
+ $cxx.target.system != $build.host.system)
+
+# Pass native C++ compiler path (not forgetting to escape backslashes on
+# Windows). It is used as defaults for BUILD2_DEFAULT_CXX.
+#
+if! $cross
+{
+ obj{init}: cxx.poptions += \
+ -DBUILD2_NATIVE_CXX=\"$regex.replace($recall($cxx.path), '\\', '\\\\')\"
+
+ obja{init}: cxx.poptions += -DLIBBUILD2_CXX_STATIC_BUILD
+ objs{init}: cxx.poptions += -DLIBBUILD2_CXX_SHARED_BUILD
+}
+
+# Export options.
+#
+lib{build2-cxx}:
+{
+ cxx.export.poptions = "-I$out_root" "-I$src_root"
+ cxx.export.libs = $int_libs
+}
+
+liba{build2-cxx}: cxx.export.poptions += -DLIBBUILD2_CXX_STATIC
+libs{build2-cxx}: cxx.export.poptions += -DLIBBUILD2_CXX_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.
+#
+# And because this is a build system module, we also embed the same value as
+# the interface version (note that we cannot use build.version.interface for
+# bundled modules because we could be built with a different version of the
+# build system).
+#
+ver = ($version.pre_release \
+ ? "$version.project_id" \
+ : "$version.major.$version.minor")
+
+lib{build2-cxx}: bin.lib.version = @"-$ver"
+libs{build2-cxx}: bin.lib.load_suffix = "-$ver"
+
+# Install into the libbuild2/cxx/ subdirectory of, say, /usr/include/
+# recreating subdirectories.
+#
+{hxx ixx txx}{*}:
+{
+ install = include/libbuild2/cxx/
+ install.subdirs = true
+}
diff --git a/libbuild2/cxx/export.hxx b/libbuild2/cxx/export.hxx
new file mode 100644
index 0000000..64df2f7
--- /dev/null
+++ b/libbuild2/cxx/export.hxx
@@ -0,0 +1,38 @@
+// file : libbuild2/cxx/export.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#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_CXX_STATIC) // Using static.
+# define LIBBUILD2_CXX_SYMEXPORT
+#elif defined(LIBBUILD2_CXX_STATIC_BUILD) // Building static.
+# define LIBBUILD2_CXX_SYMEXPORT
+#elif defined(LIBBUILD2_CXX_SHARED) // Using shared.
+# ifdef _WIN32
+# define LIBBUILD2_CXX_SYMEXPORT __declspec(dllimport)
+# else
+# define LIBBUILD2_CXX_SYMEXPORT
+# endif
+#elif defined(LIBBUILD2_CXX_SHARED_BUILD) // Building shared.
+# ifdef _WIN32
+# define LIBBUILD2_CXX_SYMEXPORT __declspec(dllexport)
+# else
+# define LIBBUILD2_CXX_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_CXX_SYMEXPORT // Using static or shared.
+#endif
diff --git a/build2/cxx/init.cxx b/libbuild2/cxx/init.cxx
index fefa7b9..24d2cb9 100644
--- a/build2/cxx/init.cxx
+++ b/libbuild2/cxx/init.cxx
@@ -1,8 +1,8 @@
-// file : build2/cxx/init.cxx -*- C++ -*-
+// file : libbuild2/cxx/init.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <build2/cxx/init.hxx>
+#include <libbuild2/cxx/init.hxx>
#include <libbuild2/scope.hxx>
#include <libbuild2/diagnostics.hxx>
@@ -10,7 +10,7 @@
#include <libbuild2/cc/guess.hxx>
#include <libbuild2/cc/module.hxx>
-#include <build2/cxx/target.hxx>
+#include <libbuild2/cxx/target.hxx>
#ifndef BUILD2_DEFAULT_CXX
# ifdef BUILD2_NATIVE_CXX
@@ -625,5 +625,22 @@ namespace build2
m->init (rs, loc, hints);
return true;
}
+
+ static const module_functions mod_functions[] =
+ {
+ // NOTE: don't forget to also update the documentation in init.hxx if
+ // changing anything here.
+
+ {"cxx.guess", nullptr, guess_init},
+ {"cxx.config", nullptr, config_init},
+ {"cxx", nullptr, init},
+ {nullptr, nullptr, nullptr}
+ };
+
+ const module_functions*
+ build2_cxx_load ()
+ {
+ return mod_functions;
+ }
}
}
diff --git a/libbuild2/cxx/init.hxx b/libbuild2/cxx/init.hxx
new file mode 100644
index 0000000..a6398de
--- /dev/null
+++ b/libbuild2/cxx/init.hxx
@@ -0,0 +1,32 @@
+// file : libbuild2/cxx/init.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef LIBBUILD2_CXX_INIT_HXX
+#define LIBBUILD2_CXX_INIT_HXX
+
+#include <libbuild2/types.hxx>
+#include <libbuild2/utility.hxx>
+
+#include <libbuild2/module.hxx>
+
+#include <libbuild2/cxx/export.hxx>
+
+namespace build2
+{
+ namespace cxx
+ {
+ // Module `cxx` does not require bootstrapping.
+ //
+ // Submodules:
+ //
+ // `cxx.guess` -- registers and sets some variables.
+ // `cxx.config` -- loads cxx.guess and sets more variables.
+ // `cxx` -- loads cxx.config and registers target types and rules.
+ //
+ extern "C" LIBBUILD2_CXX_SYMEXPORT const module_functions*
+ build2_cxx_load ();
+ }
+}
+
+#endif // LIBBUILD2_CXX_INIT_HXX
diff --git a/build2/cxx/target.cxx b/libbuild2/cxx/target.cxx
index 45463f3..25dfa3a 100644
--- a/build2/cxx/target.cxx
+++ b/libbuild2/cxx/target.cxx
@@ -1,8 +1,8 @@
-// file : build2/cxx/target.cxx -*- C++ -*-
+// file : libbuild2/cxx/target.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <build2/cxx/target.hxx>
+#include <libbuild2/cxx/target.hxx>
#include <libbuild2/context.hxx>
diff --git a/build2/cxx/target.hxx b/libbuild2/cxx/target.hxx
index 40dd810..3cf2882 100644
--- a/build2/cxx/target.hxx
+++ b/libbuild2/cxx/target.hxx
@@ -1,9 +1,9 @@
-// file : build2/cxx/target.hxx -*- C++ -*-
+// file : libbuild2/cxx/target.hxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef BUILD2_CXX_TARGET_HXX
-#define BUILD2_CXX_TARGET_HXX
+#ifndef LIBBUILD2_CXX_TARGET_HXX
+#define LIBBUILD2_CXX_TARGET_HXX
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
@@ -11,6 +11,8 @@
#include <libbuild2/target.hxx>
#include <libbuild2/cc/target.hxx>
+#include <libbuild2/cxx/export.hxx>
+
namespace build2
{
namespace cxx
@@ -18,7 +20,7 @@ namespace build2
using cc::h;
using cc::c;
- class hxx: public cc::cc
+ class LIBBUILD2_CXX_SYMEXPORT hxx: public cc::cc
{
public:
using cc::cc;
@@ -28,7 +30,7 @@ namespace build2
virtual const target_type& dynamic_type () const {return static_type;}
};
- class ixx: public cc::cc
+ class LIBBUILD2_CXX_SYMEXPORT ixx: public cc::cc
{
public:
using cc::cc;
@@ -38,7 +40,7 @@ namespace build2
virtual const target_type& dynamic_type () const {return static_type;}
};
- class txx: public cc::cc
+ class LIBBUILD2_CXX_SYMEXPORT txx: public cc::cc
{
public:
using cc::cc;
@@ -48,7 +50,7 @@ namespace build2
virtual const target_type& dynamic_type () const {return static_type;}
};
- class cxx: public cc::cc
+ class LIBBUILD2_CXX_SYMEXPORT cxx: public cc::cc
{
public:
using cc::cc;
@@ -63,7 +65,7 @@ namespace build2
// support dual use (modules/headers) it could actually be #include'd
// (and even in both cases e.g., by different codebases).
//
- class mxx: public cc::cc
+ class LIBBUILD2_CXX_SYMEXPORT mxx: public cc::cc
{
public:
using cc::cc;
@@ -75,4 +77,4 @@ namespace build2
}
}
-#endif // BUILD2_CXX_TARGET_HXX
+#endif // LIBBUILD2_CXX_TARGET_HXX
diff --git a/libbuild2/module.cxx b/libbuild2/module.cxx
index 37bc817..5cfb1ec 100644
--- a/libbuild2/module.cxx
+++ b/libbuild2/module.cxx
@@ -41,6 +41,7 @@ namespace build2
"bin",
"c",
"cc",
+ "cxx",
"in",
"version"
};
diff --git a/tests/libbuild2/buildfile b/tests/libbuild2/buildfile
index 1d7faf7..f1104d2 100644
--- a/tests/libbuild2/buildfile
+++ b/tests/libbuild2/buildfile
@@ -4,7 +4,7 @@
import libs = build2%lib{build2}
-for m: bash bin c cc in version
+for m: bash bin c cc cxx in version
import libs += build2%lib{build2-$m}
exe{driver}: {hxx cxx}{*} $libs testscript
diff --git a/tests/libbuild2/driver.cxx b/tests/libbuild2/driver.cxx
index e17cdc5..a14d145 100644
--- a/tests/libbuild2/driver.cxx
+++ b/tests/libbuild2/driver.cxx
@@ -12,6 +12,7 @@
#include <libbuild2/bin/init.hxx>
#include <libbuild2/c/init.hxx>
#include <libbuild2/cc/init.hxx>
+#include <libbuild2/cxx/init.hxx>
#include <libbuild2/bash/init.hxx>
#include <libbuild2/version/init.hxx>
@@ -28,6 +29,7 @@ main (int, char* argv[])
bin::build2_bin_load ();
cc::build2_cc_load ();
c::build2_c_load ();
+ cxx::build2_cxx_load ();
version::build2_version_load ();
in::build2_in_load ();
bash::build2_bash_load ();