]> git.tdb.fi Git - builder.git/blobdiff - source/architecture.cpp
Use a separate category for import library filename patterns
[builder.git] / source / architecture.cpp
index fe0033891feb903867bc7eb037b8ca9d480c0943..75a64607a395f7726357d52887fb06e65953277c 100644 (file)
@@ -1,11 +1,14 @@
 #include <limits>
-#ifndef WIN32
-#include <sys/utsname.h>
-#endif
 #include <msp/strings/format.h>
 #include <msp/strings/utils.h>
 #include "architecture.h"
 #include "builder.h"
+#include "executable.h"
+#include "importlibrary.h"
+#include "objectfile.h"
+#include "sharedlibrary.h"
+#include "staticlibrary.h"
+#include "sysutils.h"
 
 using namespace std;
 using namespace Msp;
@@ -42,6 +45,15 @@ const char *cpus[] =
        0
 };
 
+const char *fpus[] =
+{
+       "387",   "x86",
+       "sse",   "x86",
+       "vfpv3", "arm",
+       "neon",  "arm",
+       0
+};
+
 const char *systems[] =
 {
        "linux",
@@ -52,10 +64,18 @@ const char *systems[] =
        0
 };
 
+const char *toolchains[] =
+{
+       "gnu",
+       "clang",
+       0
+};
+
 const char *aliases[] =
 {
        "pc",              "x86",
        "x86_64",          "x86-64",
+       "x64",             "x86-64",
        "amd64",           "x86-64",
        "i586",            "pentium",
        "i686",            "pentiumpro",
@@ -65,6 +85,8 @@ const char *aliases[] =
        "power macintosh", "ppc",
        "armeabi",         "arm",
        "v7a",             "armv7a",
+       "gcc",             "gnu",
+       "mingw",           "windows-gnu",
        0
 };
 
@@ -77,18 +99,9 @@ Architecture::Architecture(Builder &b, const string &spec):
 {
        if(spec.empty())
        {
-#ifdef WIN32
-               system = "windows";
-#else
-               utsname un;
-               if(uname(&un)==0)
-               {
-                       system = tolower(un.sysname);
-                       parse_specification(tolower(un.machine));
-                       // We really only want to set type for the default arch
-                       cpu.clear();
-               }
-#endif
+               parse_specification(get_system_type());
+               // We really only want to set type for the default arch
+               cpu.clear();
                bits = sizeof(void *)*numeric_limits<unsigned char>::digits;
                native = true;
        }
@@ -113,30 +126,40 @@ Architecture::Architecture(Builder &b, const string &spec):
                else if(bits==native_arch.bits)
                        native = true;
        }
+
+       if(toolchain.empty())
+       {
+               if((system=="darwin" || system=="freebsd") && builder.get_vfs().find_binary("clang"))
+                       toolchain = "clang";
+               else
+                       toolchain = "gnu";
+       }
+
        name = type;
        if(!cpu.empty())
                name += format("-%s", cpu);
-       name += format("-%d-%s", bits, system);
+       if(!fpu.empty())
+               name += format("-%s", fpu);
+       name += format("-%d-%s-%s", bits, system, toolchain);
 
+       add_pattern<ObjectFile>("%.o");
        if(system=="windows")
        {
-               sharedlib_patterns.push_back(Pattern("%.dll"));
-               sharedlib_patterns.push_back(Pattern("lib%.dll"));
-               /* XXX Hack: Consider import libraries (*.dll.a) as dynamic libraries,
-               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"));
+               add_pattern<SharedLibrary>("%.dll");
+               add_pattern<SharedLibrary>("lib%.dll");
+               add_pattern<ImportLibrary>("lib%.dll.a");
+               add_pattern<StaticLibrary>("lib%.a");
+               add_pattern<StaticLibrary>("%.lib");
+               add_pattern<Executable>("%.exe");
        }
        else
        {
                if(system=="darwin")
-                       sharedlib_patterns.push_back(Pattern("lib%.dylib"));
+                       add_pattern<SharedLibrary>("lib%.dylib");
                else
-                       sharedlib_patterns.push_back(Pattern("lib%.so"));
-               staticlib_patterns.push_back(Pattern("lib%.a"));
-               executable_patterns.push_back(Pattern("%"));
+                       add_pattern<SharedLibrary>("lib%.so");
+               add_pattern<StaticLibrary>("lib%.a");
+               add_pattern<Executable>("%");
        }
 }
 
@@ -149,17 +172,17 @@ 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 && *i!=toolchain)
                        return negate;
        }
        return !negate;
 }
 
-string Architecture::best_match(const list<string> &names) const
+string Architecture::best_match(const vector<string> &names) const
 {
        string best;
        unsigned best_size = 0;
-       for(list<string>::const_iterator i=names.begin(); i!=names.end(); ++i)
+       for(vector<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
@@ -179,6 +202,12 @@ string Architecture::best_match(const list<string> &names) const
        return best;
 }
 
+template<typename T>
+void Architecture::add_pattern(const string &pat)
+{
+       filename_patterns[typeid(T).name()].push_back(Pattern(pat));
+}
+
 void Architecture::resolve_aliases(vector<string> &parts)
 {
        for(unsigned i=0; i<parts.size(); ++i)
@@ -236,6 +265,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])
                        {
@@ -243,6 +281,13 @@ void Architecture::parse_specification(const string &spec)
                                ok = true;
                        }
 
+               for(unsigned j=0; (!ok && toolchains[j]); ++j)
+                       if(*i==toolchains[j])
+                       {
+                               toolchain = *i;
+                               ok = true;
+                       }
+
                if(!ok && (*i=="32" || *i=="64"))
                {
                        bits = lexical_cast<unsigned>(*i);