const Architecture &native_arch = builder.get_native_arch();
- list<string> tc_archs = list_files(toolchains_dir/use_toolchain/"prebuilt");
- string use_arch;
- for(list<string>::const_iterator i=tc_archs.begin(); i!=tc_archs.end(); ++i)
- if(native_arch.match_name(*i))
- {
- use_arch = *i;
- break;
- }
+ FS::Path tc_archs_dir = toolchains_dir/use_toolchain/"prebuilt";
+ string use_arch = native_arch.best_match(list_files(tc_archs_dir));
if(use_arch.empty())
throw runtime_error("No matching toolchain found");
if(use_platform.empty())
throw runtime_error("No applicable platforms found");
- list<string> platform_archs = list_files(platforms_dir/use_platform);
- string use_arch;
- for(list<string>::const_iterator i=platform_archs.begin(); i!=platform_archs.end(); ++i)
- if(!i->compare(0, 5, "arch-") && architecture.match_name(i->substr(5)))
- {
- use_arch = *i;
- break;
- }
+ list<string> platform_archs = list_filtered(platforms_dir/use_platform, "^arch-");
+ for(list<string>::iterator i=platform_archs.begin(); i!=platform_archs.end(); ++i)
+ i->erase(0, 5);
+ string use_arch = architecture.best_match(platform_archs);
if(use_arch.empty())
throw runtime_error("No matching platform found");
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)
unsigned get_bits() const { return bits; }
const std::string &get_cpu() const { return cpu; }
bool match_name(const std::string &) const;
+ std::string best_match(const std::list<std::string> &) const;
bool is_native() const { return native; }
bool is_cross() const { return !cross_prefix.empty(); }