]> git.tdb.fi Git - builder.git/blobdiff - source/architecture.cpp
Add FPU specification to Architecture and GnuCompiler
[builder.git] / source / architecture.cpp
index a9434986a91170a3de3ef4c7e6462b7b2ee1c911..627ba66ccf6ab6defbcaa960c09fbca775845b14 100644 (file)
@@ -42,6 +42,15 @@ const char *cpus[] =
        0
 };
 
+const char *fpus[] =
+{
+       "387",   "x86",
+       "sse",   "x86",
+       "vfpv3", "arm",
+       "neon",  "arm",
+       0
+};
+
 const char *systems[] =
 {
        "linux",
@@ -116,6 +125,8 @@ Architecture::Architecture(Builder &b, const string &spec):
        name = type;
        if(!cpu.empty())
                name += format("-%s", cpu);
+       if(!fpu.empty())
+               name += format("-%s", fpu);
        name += format("-%d-%s", bits, system);
 
        if(system=="windows")
@@ -126,6 +137,7 @@ Architecture::Architecture(Builder &b, const string &spec):
                even though technically they are linked statically. */
                sharedlib_patterns.push_back(Pattern("lib%.dll.a"));
                staticlib_patterns.push_back(Pattern("lib%.a"));
+               staticlib_patterns.push_back(Pattern("%.lib"));
                executable_patterns.push_back(Pattern("%.exe"));
        }
        else
@@ -148,12 +160,36 @@ bool Architecture::match_name(const string &pattern) const
        {
                if((*i=="32" && bits==32) || (*i=="64" && bits==64))
                        ;
-               else if(*i!=type && *i!=cpu && *i!=system)
+               else if(*i!=type && *i!=cpu && *i!=fpu && *i!=system)
                        return negate;
        }
        return !negate;
 }
 
+string Architecture::best_match(const list<string> &names) const
+{
+       string best;
+       unsigned best_size = 0;
+       for(list<string>::const_iterator i=names.begin(); i!=names.end(); ++i)
+               if(match_name(*i))
+               {
+                       /* 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(string::const_iterator j=i->begin(); j!=i->end(); ++j)
+                               size += (*j=='-');
+
+                       if(size>best_size)
+                       {
+                               best = *i;
+                               best_size = size;
+                       }
+               }
+
+       return best;
+}
+
 void Architecture::resolve_aliases(vector<string> &parts)
 {
        for(unsigned i=0; i<parts.size(); ++i)
@@ -211,6 +247,15 @@ void Architecture::parse_specification(const string &spec)
                                ok = true;
                        }
 
+               for(unsigned j=0; (!ok && fpus[j]); j+=2)
+                       if(*i==fpus[j])
+                       {
+                               if(fpus[j+1]!=type)
+                                       throw invalid_argument("Conflicting FPU specification");
+                               fpu = *i;
+                               ok = true;
+                       }
+
                for(unsigned j=0; (!ok && systems[j]); ++j)
                        if(*i==systems[j])
                        {