}
Architecture::Architecture(Builder &b, const string &spec):
- builder(b),
- bits(0),
- native(false)
+ builder(b)
{
if(spec.empty())
{
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");
}
}
-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), "-");
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;
}
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;
}
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;
}
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;
}