]> git.tdb.fi Git - builder.git/blobdiff - source/architecture.cpp
Add gcc's private library directory to ClangLinker's system path
[builder.git] / source / architecture.cpp
index 2efcd5e3e4ee23dc9294cfb04f261ab06ce8f1c8..54ffcf0f872cf7d5e1483190e9156cded9012402 100644 (file)
@@ -96,9 +96,7 @@ const char *aliases[] =
 }
 
 Architecture::Architecture(Builder &b, const string &spec):
-       builder(b),
-       bits(0),
-       native(false)
+       builder(b)
 {
        if(spec.empty())
        {
@@ -130,23 +128,27 @@ Architecture::Architecture(Builder &b, const string &spec):
                        native = true;
        }
 
-       if(toolchain.empty())
-       {
-               if((system=="darwin" || system=="freebsd") && builder.get_vfs().find_binary("clang"))
-                       toolchain = "clang";
-               else if(system=="windows" && native)
-                       toolchain = "msvc";
-               else
-                       toolchain = "gnu";
-       }
+       update();
+}
 
+void Architecture::refine(const string &spec)
+{
+       parse_specification(spec);
+       update();
+}
+
+void Architecture::update()
+{
        name = type;
        if(!cpu.empty())
                name += format("-%s", cpu);
        if(!fpu.empty())
                name += format("-%s", fpu);
-       name += format("-%d-%s-%s", bits, system, toolchain);
+       name += format("-%d-%s", bits, system);
+       if(!toolchain.empty())
+               name += format("-%s", toolchain);
 
+       filename_patterns.clear();
        if(system=="windows")
        {
                add_pattern<SharedLibrary>("%.dll");
@@ -177,7 +179,7 @@ Architecture::Architecture(Builder &b, const string &spec):
        }
 }
 
-bool Architecture::match_name(const string &pattern) const
+bool Architecture::match_name(const string &pattern, unsigned *quality) const
 {
        bool negate = (pattern[0]=='!');
        vector<string> parts = split(pattern.substr(negate), "-");
@@ -187,31 +189,32 @@ bool Architecture::match_name(const string &pattern) const
                if((p=="32" && bits==32) || (p=="64" && bits==64))
                        ;
                else if(p!=type && p!=cpu && p!=fpu && p!=system && p!=toolchain)
+               {
+                       if(quality)
+                               *quality = 0;
                        return negate;
+               }
        }
+
+       if(quality)
+               *quality = parts.size();
        return !negate;
 }
 
 string Architecture::best_match(const vector<string> &names) const
 {
        string best;
-       unsigned best_size = 0;
+       unsigned best_quality = 0;
        for(const string &n: names)
-               if(match_name(n))
-               {
-                       /* TODO Do full parse and alias resolution here?  Otherwise x86 and
-                       x86_64 are treated as equally good, even though the latter is more
-                       specific. */
-                       unsigned size = 1;
-                       for(char c: n)
-                               size += (c=='-');
-
-                       if(size>best_size)
+       {
+               unsigned quality;
+               if(match_name(n, &quality))
+                       if(quality>best_quality)
                        {
                                best = n;
-                               best_size = size;
+                               best_quality = quality;
                        }
-               }
+       }
 
        return best;
 }
@@ -291,6 +294,8 @@ void Architecture::parse_specification(const string &spec)
                for(unsigned j=0; (!ok && systems[j]); ++j)
                        if(p==systems[j])
                        {
+                               if(!system.empty() && p!=system)
+                                       throw invalid_argument("Conflicting system specification");
                                system = p;
                                ok = true;
                        }
@@ -298,13 +303,18 @@ void Architecture::parse_specification(const string &spec)
                for(unsigned j=0; (!ok && toolchains[j]); ++j)
                        if(p==toolchains[j])
                        {
+                               if(!toolchain.empty() && p!=toolchain)
+                                       throw invalid_argument("Conflicting toolchain specification");
                                toolchain = p;
                                ok = true;
                        }
 
                if(!ok && (p=="32" || p=="64"))
                {
-                       bits = lexical_cast<unsigned>(p);
+                       unsigned b = lexical_cast<unsigned>(p);
+                       if(bits && b!=bits)
+                               throw invalid_argument("Conflicting bits specification");
+                       bits = b;
                        ok = true;
                }
 
@@ -317,5 +327,11 @@ void Architecture::parse_specification(const string &spec)
 Architecture::Loader::Loader(Architecture &a):
        DataFile::ObjectLoader<Architecture>(a)
 {
-       add("prefix", &Architecture::cross_prefix);
+       add("prefix", &Loader::cross_prefix);
+}
+
+void Architecture::Loader::cross_prefix(const string &p)
+{
+       if(!obj.native)
+               obj.cross_prefix = p;
 }