aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc/guess.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/cc/guess.hxx')
-rw-r--r--libbuild2/cc/guess.hxx246
1 files changed, 246 insertions, 0 deletions
diff --git a/libbuild2/cc/guess.hxx b/libbuild2/cc/guess.hxx
new file mode 100644
index 0000000..3677cc7
--- /dev/null
+++ b/libbuild2/cc/guess.hxx
@@ -0,0 +1,246 @@
+// file : libbuild2/cc/guess.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef LIBBUILD2_CC_GUESS_HXX
+#define LIBBUILD2_CC_GUESS_HXX
+
+#include <libbuild2/types.hxx>
+#include <libbuild2/utility.hxx>
+
+#include <libbuild2/cc/types.hxx>
+
+namespace build2
+{
+ namespace cc
+ {
+ // Compiler id consisting of a type and optional variant. If the variant
+ // is not empty, then the id is spelled out as 'type-variant', similar to
+ // target triplets (this also means that the type cannot contain '-').
+ //
+ // Currently recognized compilers and their ids:
+ //
+ // gcc GCC gcc/g++
+ // clang Vanilla Clang clang/clang++
+ // clang-apple Apple Clang clang/clang++ and the gcc/g++ "alias"
+ // msvc Microsoft cl.exe
+ // icc Intel icc/icpc
+ //
+ // Note that the user can provide a custom id with one of the predefined
+ // types and a custom variant (say 'gcc-tasking').
+ //
+ enum class compiler_type
+ {
+ gcc = 1, // 0 value represents invalid type.
+ clang,
+ msvc,
+ icc
+ // Update compiler_id(string) and to_string() if adding a new type.
+ };
+
+ const compiler_type invalid_compiler_type = static_cast<compiler_type> (0);
+
+ string
+ to_string (compiler_type);
+
+ inline ostream&
+ operator<< (ostream& o, const compiler_type& t)
+ {
+ return o << to_string (t);
+ }
+
+ struct compiler_id
+ {
+ compiler_type type = invalid_compiler_type;
+ std::string variant;
+
+ bool
+ empty () const {return type == invalid_compiler_type;}
+
+ std::string
+ string () const;
+
+ compiler_id ()
+ : type (invalid_compiler_type) {}
+
+ compiler_id (compiler_type t, std::string v)
+ : type (t), variant (move (v)) {}
+
+ explicit
+ compiler_id (const std::string&);
+ };
+
+ inline ostream&
+ operator<< (ostream& o, const compiler_id& id)
+ {
+ return o << id.string ();
+ }
+
+ // Compiler class describes a set of compilers that follow more or less
+ // the same command line interface. Compilers that don't belong to any of
+ // the existing classes are in classes of their own (say, Sun CC would be
+ // on its own if we were to support it).
+ //
+ // Currently defined compiler classes:
+ //
+ // gcc gcc, clang, clang-apple, icc (on non-Windows)
+ // msvc msvc, clang-cl, icc (Windows)
+ //
+ enum class compiler_class
+ {
+ gcc,
+ msvc
+ };
+
+ string
+ to_string (compiler_class);
+
+ inline ostream&
+ operator<< (ostream& o, compiler_class c)
+ {
+ return o << to_string (c);
+ }
+
+ // Compiler version. Here we map the various compiler version formats to
+ // something that resembles the MAJOR.MINOR.PATCH-BUILD form of the
+ // Semantic Versioning. While the MAJOR.MINOR part is relatively
+ // straightforward, PATCH may be empty and BUILD can contain pretty much
+ // anything (including spaces).
+ //
+ // gcc A.B.C[ ...] {A, B, C, ...}
+ // clang A.B.C[( |-)...] {A, B, C, ...}
+ // clang-apple A.B[.C] ... {A, B, C, ...}
+ // icc A.B[.C.D] ... {A, B, C, D ...}
+ // msvc A.B.C[.D] {A, B, C, D}
+ //
+ // Note that the clang-apple version is a custom Apple version and does
+ // not correspond to the vanilla clang version.
+ //
+ struct compiler_version
+ {
+ std::string string;
+
+ // 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.
+ //
+ uint64_t major;
+ uint64_t minor;
+ uint64_t patch;
+ std::string build;
+ };
+
+ // Compiler information.
+ //
+ // The signature is normally the -v/--version line that was used to guess
+ // the compiler id and its version.
+ //
+ // The checksum is used to detect compiler changes. It is calculated in a
+ // compiler-specific manner (usually the output of -v/--version) and is
+ // not bulletproof (e.g., it most likely won't detect that the underlying
+ // assembler or linker has changed). However, it should detect most
+ // common cases, such as an upgrade to a new version or a configuration
+ // change.
+ //
+ // Note that we assume the checksum incorporates the (default) target so
+ // that if the compiler changes but only in what it targets, then the
+ // checksum will still change. This is currently the case for all the
+ // compilers that we support.
+ //
+ // The target is the compiler's traget architecture triplet. Note that
+ // unlike all the preceding fields, this one takes into account the
+ // compile options (e.g., -m32).
+ //
+ // The pattern is the toolchain program pattern that could sometimes be
+ // derived for some toolchains. For example, i686-w64-mingw32-*-4.9.
+ //
+ // The bin_pattern is the binutils program pattern that could sometimes be
+ // derived for some toolchains. For example, i686-w64-mingw32-*. If the
+ // pattern could not be derived, then it could contain a fallback search
+ // directory, in which case it will end with a directory separator but
+ // will not contain '*'.
+ //
+ struct compiler_info
+ {
+ process_path path;
+ compiler_id id;
+ compiler_class class_;
+ compiler_version version;
+ string signature;
+ string checksum;
+ string target;
+ string original_target; // As reported by the compiler.
+ string pattern;
+ string bin_pattern;
+
+ // Compiler runtime, C standard library, and language (e.g., C++)
+ // standard library.
+ //
+ // The runtime is the low-level compiler runtime library and its name is
+ // the library/project name. Current values are (but can also be some
+ // custom name specified with Clang's --rtlib):
+ //
+ // libgcc
+ // compiler-rt (clang)
+ // msvc
+ //
+ // The C standard library is normally the library/project name (e.g,
+ // glibc, klibc, newlib, etc) but if there is none, then we fallback to
+ // the vendor name (e.g., freebsd, apple). Current values are:
+ //
+ // glibc
+ // msvc (msvcrt.lib/msvcrNNN.dll)
+ // freebsd
+ // apple
+ // newlib (also used by Cygwin)
+ // klibc
+ // bionic
+ // uclibc
+ // musl
+ // dietlibc
+ // other
+ // none
+ //
+ // The C++ standard library is normally the library/project name.
+ // Current values are:
+ //
+ // libstdc++
+ // libc++
+ // msvcp (msvcprt.lib/msvcpNNN.dll)
+ // other
+ // none
+ //
+ string runtime;
+ string c_stdlib;
+ string x_stdlib;
+ };
+
+ // In a sense this is analagous to the language standard which we handle
+ // via a virtual function in common. However, duplicating this hairy ball
+ // of fur in multiple places doesn't seem wise, especially considering
+ // that most of it will be the same, at least for C and C++.
+ //
+ const compiler_info&
+ guess (const char* xm, // Module (for variable names in diagnostics).
+ lang xl, // Language.
+ const path& xc, // Compiler path.
+ const string* xi, // Compiler id (optional).
+ const string* xv, // Compiler version (optional).
+ const string* xt, // Compiler target (optional).
+ const strings* c_poptions, const strings* x_poptions,
+ const strings* c_coptions, const strings* x_coptions,
+ const strings* c_loptions, const strings* x_loptions);
+
+ // Given a language, compiler id, and optionally an (empty) pattern,
+ // return an appropriate default compiler path.
+ //
+ // For example, for (lang::cxx, gcc, *-4.9) we will get g++-4.9.
+ //
+ path
+ guess_default (lang, const string& cid, const string& pattern);
+ }
+}
+
+#endif // LIBBUILD2_CC_GUESS_HXX