aboutsummaryrefslogtreecommitdiff
path: root/build2/cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-03-28 15:59:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-03-28 16:03:35 +0200
commit96f2131e593e206f0e458409f22adfff8c1b5356 (patch)
treefdb71a7a435d631872e0413dbe13113a636932de /build2/cxx
parent69801c4e23f877359118e55ed291737f4fbece04 (diff)
Clean up variable usage
Diffstat (limited to 'build2/cxx')
-rw-r--r--build2/cxx/compile.cxx8
-rw-r--r--build2/cxx/guess28
-rw-r--r--build2/cxx/guess.cxx159
-rw-r--r--build2/cxx/link.cxx14
-rw-r--r--build2/cxx/module.cxx17
5 files changed, 128 insertions, 98 deletions
diff --git a/build2/cxx/compile.cxx b/build2/cxx/compile.cxx
index cf0c91c..c4e9cee 100644
--- a/build2/cxx/compile.cxx
+++ b/build2/cxx/compile.cxx
@@ -461,10 +461,10 @@ namespace build2
auto init_args = [&t, &s, &rs, &args, &cxx_std] ()
{
- const string& cxx (cast<string> (rs["config.cxx"]));
+ const path& cxx (cast<path> (rs["config.cxx"]));
const string& sys (cast<string> (rs["cxx.target.system"]));
- args.push_back (cxx.c_str ());
+ args.push_back (cxx.string ().c_str ());
// Add cxx.export.poptions from prerequisite libraries. Note
// that here we don't need to see group members (see apply()).
@@ -923,10 +923,10 @@ namespace build2
path rels (relative (s->path ()));
scope& rs (t.root_scope ());
- const string& cxx (cast<string> (rs["config.cxx"]));
+ const path& cxx (cast<path> (rs["config.cxx"]));
const string& sys (cast<string> (rs["cxx.target.system"]));
- cstrings args {cxx.c_str ()};
+ cstrings args {cxx.string ().c_str ()};
// Add cxx.export.poptions from prerequisite libraries. Note that
// here we don't need to see group members (see apply()).
diff --git a/build2/cxx/guess b/build2/cxx/guess
index cd9f740..0588523 100644
--- a/build2/cxx/guess
+++ b/build2/cxx/guess
@@ -8,8 +8,6 @@
#include <build2/types>
#include <build2/utility>
-#include <build2/variable>
-
namespace build2
{
namespace cxx
@@ -62,22 +60,18 @@ namespace build2
//
struct compiler_version
{
- std::string major;
- std::string minor;
- std::string patch;
- std::string build;
+ std::string string;
- // The format is always A.B[.C][-D].
+ // Currently all the compilers that we support have numeric MAJOR,
+ // MINOR, and PATCH components and it makes sense to represent them as
+ // integers for easy comparison. If we meet a compiler for which this
+ // doesn't hold, then we will probably just set these to 0 and let the
+ // user deal with the string representation.
//
- std::string
- string () const
- {
- std::string r (major);
- r += '.'; r += minor;
- if (!patch.empty ()) {r += '.'; r += patch;}
- if (!build.empty ()) {r += '-'; r += build;}
- return r;
- }
+ uint64_t major;
+ uint64_t minor;
+ uint64_t patch;
+ std::string build;
};
// C++ compiler information.
@@ -106,7 +100,7 @@ namespace build2
};
compiler_info
- guess (const path& cxx, lookup<const value> coptions); // @@ VAR
+ guess (const path& cxx, const strings* coptions);
}
}
diff --git a/build2/cxx/guess.cxx b/build2/cxx/guess.cxx
index d2f828d..ad52847 100644
--- a/build2/cxx/guess.cxx
+++ b/build2/cxx/guess.cxx
@@ -277,9 +277,7 @@ namespace build2
}
static compiler_info
- guess_gcc (const path& cxx,
- lookup<const value> coptions,
- guess_result&& gr)
+ guess_gcc (const path& cxx, const strings* coptions, guess_result&& gr)
{
tracer trace ("cxx::guess_gcc");
@@ -309,19 +307,27 @@ namespace build2
if (b == e)
fail << "unable to extract gcc version from '" << s << "'";
+ compiler_version v;
+ v.string.assign (s, b, string::npos);
+
// Split the version into components.
//
size_t vb (b), ve (b);
- auto next = [&s, b, e, &vb, &ve] (const char* m) -> string
+ auto next = [&s, b, e, &vb, &ve] (const char* m) -> uint64_t
{
- if (!next_word (s, e, vb, ve, '.'))
- fail << "unable to extract gcc " << m << " version from '"
- << string (s, b, e - b) << "'";
+ try
+ {
+ if (next_word (s, e, vb, ve, '.'))
+ return stoull (string (s, vb, ve - vb));
+ }
+ catch (const invalid_argument&) {}
+ catch (const out_of_range&) {}
- return string (s, vb, ve - vb);
+ error << "unable to extract gcc " << m << " version from '"
+ << string (s, b, e - b) << "'";
+ throw failed ();
};
- compiler_version v;
v.major = next ("major");
v.minor = next ("minor");
v.patch = next ("patch");
@@ -351,7 +357,8 @@ namespace build2
// -dumpmachine (older gcc or not multi-arch).
//
cstrings args {cxx.string ().c_str (), "-print-multiarch"};
- append_options (args, coptions);
+ if (coptions != nullptr)
+ append_options (args, *coptions);
args.push_back (nullptr);
// The output of both -print-multiarch and -dumpmachine is a single line
@@ -383,9 +390,7 @@ namespace build2
}
static compiler_info
- guess_clang (const path& cxx,
- lookup<const value> coptions,
- guess_result&& gr)
+ guess_clang (const path& cxx, const strings* coptions, guess_result&& gr)
{
// Extract the version. Here we will try to handle both vanilla and
// Apple clang since the signature lines are fairly similar. They have
@@ -425,25 +430,33 @@ namespace build2
if (b == e)
fail << "unable to extract clang version from '" << s << "'";
+ compiler_version v;
+ v.string.assign (s, b, string::npos);
+
// Split the version into components.
//
size_t vb (b), ve (b);
- auto next = [&s, b, e, &vb, &ve] (const char* m) -> string
+ auto next = [&s, b, e, &vb, &ve] (const char* m, bool opt) -> uint64_t
{
- if (next_word (s, e, vb, ve, '.'))
- return string (s, vb, ve - vb);
+ try
+ {
+ if (next_word (s, e, vb, ve, '.'))
+ return stoull (string (s, vb, ve - vb));
- if (m != nullptr)
- fail << "unable to extract clang " << m << " version from '"
- << string (s, b, e - b) << "'";
+ if (opt)
+ return 0;
+ }
+ catch (const invalid_argument&) {}
+ catch (const out_of_range&) {}
- return string ();
+ error << "unable to extract clang " << m << " version from '"
+ << string (s, b, e - b) << "'";
+ throw failed ();
};
- compiler_version v;
- v.major = next ("major");
- v.minor = next ("minor");
- v.patch = next (gr.id.variant == "apple" ? nullptr : "patch");
+ v.major = next ("major", false);
+ v.minor = next ("minor", false);
+ v.patch = next ("patch", gr.id.variant == "apple");
if (e != s.size ())
v.build.assign (s, e + 1, string::npos);
@@ -454,7 +467,8 @@ namespace build2
// however, respects the compile options (e.g., -m32).
//
cstrings args {cxx.string ().c_str (), "-dumpmachine"};
- append_options (args, coptions);
+ if (coptions != nullptr)
+ append_options (args, *coptions);
args.push_back (nullptr);
// The output of -dumpmachine is a single line containing just the
@@ -475,9 +489,7 @@ namespace build2
}
static compiler_info
- guess_icc (const path& cxx,
- lookup<const value> coptions,
- guess_result&& gr)
+ guess_icc (const path& cxx, const strings* coptions, guess_result&& gr)
{
// Extract the version. If the version has the fourth component, then
// the signature line (extracted with --version) won't include it. So we
@@ -513,7 +525,9 @@ namespace build2
: string ();
};
- s = run<string> (cxx, "-V", f);
+ // The -V output is sent to STDERR.
+ //
+ s = run<string> (cxx, "-V", f, false);
if (s.empty ())
fail << "unable to extract signature from " << cxx << " -V output";
@@ -553,27 +567,36 @@ namespace build2
if (b == e)
fail << "unable to extract icc version from '" << s << "'";
+ compiler_version v;
+ v.string.assign (s, b, string::npos);
+
// Split the version into components.
//
size_t vb (b), ve (b);
- auto next = [&s, b, e, &vb, &ve] (const char* m) -> string
+ auto next = [&s, b, e, &vb, &ve] (const char* m, bool opt) -> uint64_t
{
- if (next_word (s, e, vb, ve, '.'))
- return string (s, vb, ve - vb);
+ try
+ {
+ if (next_word (s, e, vb, ve, '.'))
+ return stoull (string (s, vb, ve - vb));
- if (m != nullptr)
- fail << "unable to extract icc " << m << " version from '"
- << string (s, b, e - b) << "'";
+ if (opt)
+ return 0;
+ }
+ catch (const invalid_argument&) {}
+ catch (const out_of_range&) {}
- return "";
+ error << "unable to extract icc " << m << " version from '"
+ << string (s, b, e - b) << "'";
+ throw failed ();
};
- compiler_version v;
- v.major = next ("major");
- v.minor = next ("minor");
- v.patch = next (nullptr);
- if (!v.patch.empty ())
- v.build = next (nullptr);
+ v.major = next ("major", false);
+ v.minor = next ("minor", false);
+ v.patch = next ("patch", true);
+
+ if (vb != ve && next_word (s, e, vb, ve, '.'))
+ v.build.assign (s, vb, ve - vb);
if (e != s.size ())
{
@@ -597,10 +620,13 @@ namespace build2
// "Intel(R)" "MIC" (-dumpmachine says: x86_64-k1om-linux)
//
cstrings args {cxx.string ().c_str (), "-V"};
- append_options (args, coptions);
+ if (coptions != nullptr)
+ append_options (args, *coptions);
args.push_back (nullptr);
- string t (run<string> (args.data (), f));
+ // The -V output is sent to STDERR.
+ //
+ string t (run<string> (args.data (), f, false));
if (t.empty ())
fail << "unable to extract target architecture from " << cxx
@@ -735,26 +761,33 @@ namespace build2
if (b == e)
fail << "unable to extract msvc version from '" << s << "'";
+ compiler_version v;
+ v.string.assign (s, b, e - b);
+
// Split the version into components.
//
size_t vb (b), ve (b);
- auto next = [&s, b, e, &vb, &ve] (const char* m) -> string
+ auto next = [&s, b, e, &vb, &ve] (const char* m) -> uint64_t
{
- if (next_word (s, e, vb, ve, '.'))
- return string (s, vb, ve - vb);
-
- if (m != nullptr)
- fail << "unable to extract msvc " << m << " version from '"
- << string (s, b, e - b) << "'";
+ try
+ {
+ if (next_word (s, e, vb, ve, '.'))
+ return stoull (string (s, vb, ve - vb));
+ }
+ catch (const invalid_argument&) {}
+ catch (const out_of_range&) {}
- return "";
+ error << "unable to extract msvc " << m << " version from '"
+ << string (s, b, e - b) << "'";
+ throw failed ();
};
- compiler_version v;
v.major = next ("major");
v.minor = next ("minor");
v.patch = next ("patch");
- v.build = next (nullptr);
+
+ if (next_word (s, e, vb, ve, '.'))
+ v.build.assign (s, vb, ve - vb);
// Continue scanning for the CPU.
//
@@ -837,14 +870,14 @@ namespace build2
// 14.00 80/8.0 VS2005
// 13.10 71/7.1 VS2003
//
- /**/ if (v.major == "19" && v.minor == "00") arch += "14.0";
- else if (v.major == "18" && v.minor == "00") arch += "12.0";
- else if (v.major == "17" && v.minor == "00") arch += "11.0";
- else if (v.major == "16" && v.minor == "00") arch += "10.0";
- else if (v.major == "15" && v.minor == "00") arch += "9.0";
- else if (v.major == "14" && v.minor == "00") arch += "8.0";
- else if (v.major == "13" && v.minor == "10") arch += "7.1";
- else fail << "unable to map msvc compiler version '" << v.string ()
+ /**/ if (v.major == 19 && v.minor == 0) arch += "14.0";
+ else if (v.major == 18 && v.minor == 0) arch += "12.0";
+ else if (v.major == 17 && v.minor == 0) arch += "11.0";
+ else if (v.major == 16 && v.minor == 0) arch += "10.0";
+ else if (v.major == 15 && v.minor == 0) arch += "9.0";
+ else if (v.major == 14 && v.minor == 0) arch += "8.0";
+ else if (v.major == 13 && v.minor == 10) arch += "7.1";
+ else fail << "unable to map msvc compiler version '" << v.string
<< "' to runtime version";
}
@@ -861,7 +894,7 @@ namespace build2
}
compiler_info
- guess (const path& cxx, lookup<const value> coptions)
+ guess (const path& cxx, const strings* coptions)
{
string pre (pre_guess (cxx));
guess_result gr;
diff --git a/build2/cxx/link.cxx b/build2/cxx/link.cxx
index c0ea6d3..aa60c7e 100644
--- a/build2/cxx/link.cxx
+++ b/build2/cxx/link.cxx
@@ -123,7 +123,7 @@ namespace build2
cstrings args;
string std_storage;
- args.push_back (cast<string> (rs["config.cxx"]).c_str ());
+ args.push_back (cast<path> (rs["config.cxx"]).string ().c_str ());
append_options (args, bs, "cxx.coptions");
append_std (args, bs, std_storage);
append_options (args, bs, "cxx.loptions");
@@ -877,8 +877,8 @@ namespace build2
// precedence.
//
if (auto l = t["bin.rpath"])
- for (const string& p: cast<strings> (l))
- sargs.push_back ("-Wl,-rpath," + p);
+ for (const dir_path& p: cast<dir_paths> (l))
+ sargs.push_back ("-Wl,-rpath," + p.string ());
// Then the paths of the shared libraries we are linking to. Unless
// this is update for install, in which case we have to do something
@@ -978,12 +978,12 @@ namespace build2
if (lt == type::a)
{
- args[0] = cast<string> (rs["config.bin.ar"]).c_str ();
+ args[0] = cast<path> (rs["config.bin.ar"]).string ().c_str ();
args.push_back (relt.string ().c_str ());
}
else
{
- args[0] = cast<string> (rs["config.cxx"]).c_str ();
+ args[0] = cast<path> (rs["config.cxx"]).string ().c_str ();
args.push_back ("-o");
args.push_back (relt.string ().c_str ());
}
@@ -1048,7 +1048,9 @@ namespace build2
if (ranlib)
{
const char* args[] = {
- cast<string> (ranlib).c_str (), relt.string ().c_str (), nullptr};
+ cast<path> (ranlib).string ().c_str (),
+ relt.string ().c_str (),
+ nullptr};
if (verb >= 2)
print_process (args);
diff --git a/build2/cxx/module.cxx b/build2/cxx/module.cxx
index 18f9e53..7b0f04e 100644
--- a/build2/cxx/module.cxx
+++ b/build2/cxx/module.cxx
@@ -62,7 +62,7 @@ namespace build2
{
auto& v (var_pool);
- v.find<string> ("config.cxx"); //@@ VAR type
+ v.find<path> ("config.cxx");
v.find<strings> ("config.cxx.poptions");
v.find<strings> ("config.cxx.coptions");
@@ -172,12 +172,12 @@ namespace build2
//
if (first)
{
- auto p (config::required (r, "config.cxx", "g++"));
+ auto p (config::required (r, "config.cxx", path ("g++")));
// Figure out which compiler we are dealing with, its target, etc.
//
- const path& cxx (path (cast<string> (p.first))); // @@ VAR
- compiler_info ci (guess (cxx, r["cxx.coptions"]));
+ const path& cxx (cast<path> (p.first));
+ compiler_info ci (guess (cxx, cast_null<strings> (r["cxx.coptions"])));
// If this is a new value (e.g., we are configuring), then print the
// report at verbosity level 2 and up (-v).
@@ -188,6 +188,7 @@ namespace build2
text << cxx << ":\n"
<< " id " << ci.id << "\n"
+ << " version " << ci.version.string << "\n"
<< " major " << ci.version.major << "\n"
<< " minor " << ci.version.minor << "\n"
<< " patch " << ci.version.patch << "\n"
@@ -201,10 +202,10 @@ namespace build2
r.assign<string> ("cxx.id.type") = move (ci.id.type);
r.assign<string> ("cxx.id.variant") = move (ci.id.variant);
- r.assign<string> ("cxx.version") = ci.version.string ();
- r.assign<string> ("cxx.version.major") = move (ci.version.major);
- r.assign<string> ("cxx.version.minor") = move (ci.version.minor);
- r.assign<string> ("cxx.version.patch") = move (ci.version.patch);
+ r.assign<string> ("cxx.version") = move (ci.version.string);
+ r.assign<uint64_t> ("cxx.version.major") = ci.version.major;
+ r.assign<uint64_t> ("cxx.version.minor") = ci.version.minor;
+ r.assign<uint64_t> ("cxx.version.patch") = ci.version.patch;
r.assign<string> ("cxx.version.build") = move (ci.version.build);
r.assign<string> ("cxx.signature") = move (ci.signature);