X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Farchitecture.cpp;h=a9434986a91170a3de3ef4c7e6462b7b2ee1c911;hb=081e13e6f146d1685bdcb1ec1c82752f4c6d264d;hp=65a7577bc2bb36e6f3c26df03c17a3cad4f4462a;hpb=04c316da6d5d90e43cba262f54d90ca231f703bf;p=builder.git diff --git a/source/architecture.cpp b/source/architecture.cpp index 65a7577..a943498 100644 --- a/source/architecture.cpp +++ b/source/architecture.cpp @@ -1,56 +1,237 @@ -/* $Id$ - -This file is part of builder -Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - +#include +#ifndef WIN32 +#include +#endif +#include +#include #include "architecture.h" #include "builder.h" using namespace std; using namespace Msp; -Architecture::Architecture(Builder &b, const string &n, bool a): - builder(b), - name(n), - native(a) -{ } +namespace { -void Architecture::set_tool(const string &t, const string &p) +const char *types[] = { - tools[t] = p; + "x86", + "arm", + "ppc", + 0 +}; + +const char *cpus[] = +{ + "i386", "x86", + "i486", "x86", + "pentium", "x86", + "pentiumpro", "x86", + "pentium2", "x86", + "pentium3", "x86", + "pentium4", "x86", + "core2", "x86", + "nehalem", "x86", + "k6", "x86", + "athlon", "x86", + "athlonxp", "x86", + "athlon64", "x86", + "armv5", "arm", + "armv6", "arm", + "armv7", "arm", + "armv7a", "arm", + 0 +}; + +const char *systems[] = +{ + "linux", + "freebsd", + "darwin", + "windows", + "android", + 0 +}; + +const char *aliases[] = +{ + "pc", "x86", + "x86_64", "x86-64", + "amd64", "x86-64", + "i586", "pentium", + "i686", "pentiumpro", + "corei7", "nehalem", + "win32", "windows-32", + "win64", "windows-64", + "power macintosh", "ppc", + "armeabi", "arm", + "v7a", "armv7a", + 0 +}; + } -std::string Architecture::get_tool(const string &t) const +Architecture::Architecture(Builder &b, const string &spec): + builder(b), + bits(0), + native(false) { - StringMap::const_iterator i = tools.find(t); - if(i!=tools.end()) + if(spec.empty()) { - if(i->second[0]=='-') - return prefix+i->second; - else - return i->second; +#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 + bits = sizeof(void *)*numeric_limits::digits; + native = true; } - - if(!native) + else { + parse_specification(spec); const Architecture &native_arch = builder.get_native_arch(); - return prefix+"-"+native_arch.get_tool(t); + if(type.empty()) + type = native_arch.type; + if(system.empty()) + system = native_arch.system; + if(!bits) + { + if(type==native_arch.type) + bits = native_arch.bits; + else + bits = 32; + } + + if(type!=native_arch.type || system!=native_arch.system) + cross_prefix = format("%s-%s", type, system); + else if(bits==native_arch.bits) + native = true; + } + name = type; + if(!cpu.empty()) + name += format("-%s", cpu); + name += format("-%d-%s", bits, system); + + 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")); + executable_patterns.push_back(Pattern("%.exe")); } else - throw KeyError("Unknown tool"); + { + if(system=="darwin") + sharedlib_patterns.push_back(Pattern("lib%.dylib")); + else + sharedlib_patterns.push_back(Pattern("lib%.so")); + staticlib_patterns.push_back(Pattern("lib%.a")); + executable_patterns.push_back(Pattern("%")); + } } +bool Architecture::match_name(const string &pattern) const +{ + bool negate = (pattern[0]=='!'); + vector parts = split(pattern.substr(negate), "-"); + resolve_aliases(parts); + for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) + { + if((*i=="32" && bits==32) || (*i=="64" && bits==64)) + ; + else if(*i!=type && *i!=cpu && *i!=system) + return negate; + } + return !negate; +} -Architecture::Loader::Loader(Architecture &a): - arch(a) +void Architecture::resolve_aliases(vector &parts) { - add("prefix", &Architecture::prefix); - add("tool", &Loader::tool); + for(unsigned i=0; i rparts = split(replace, "-"); + parts[i] = rparts[0]; + parts.insert(parts.begin()+i+1, rparts.begin()+1, rparts.end()); + i += rparts.size()-1; + } + else + parts[i] = replace; + } + } } -void Architecture::Loader::tool(const string &t, const string &p) +void Architecture::parse_specification(const string &spec) +{ + vector parts = split(spec, "-"); + resolve_aliases(parts); + for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) + { + bool ok = false; + + for(unsigned j=0; (!ok && types[j]); ++j) + if(*i==types[j]) + { + if(!type.empty() && *i!=type) + throw invalid_argument("Conflicting type specification"); + type = *i; + ok = true; + } + + for(unsigned j=0; (!ok && cpus[j]); j+=2) + if(*i==cpus[j]) + { + if(type.empty()) + type = cpus[j+1]; + else if(cpus[j+1]!=type) + throw invalid_argument("Conflicting CPU specification"); + cpu = *i; + ok = true; + } + + for(unsigned j=0; (!ok && systems[j]); ++j) + if(*i==systems[j]) + { + system = *i; + ok = true; + } + + if(!ok && (*i=="32" || *i=="64")) + { + bits = lexical_cast(*i); + ok = true; + } + + if(!ok) + throw invalid_argument("Unrecognized part in arch specification: "+*i); + } +} + + +Architecture::Loader::Loader(Architecture &a): + DataFile::ObjectLoader(a) { - arch.tools[t] = p; + add("prefix", &Architecture::cross_prefix); }