#include <msp/strings/utils.h>
#include "architecture.h"
#include "builder.h"
+#include "executable.h"
+#include "objectfile.h"
+#include "sharedlibrary.h"
+#include "staticlibrary.h"
#include "sysutils.h"
using namespace std;
name += format("-%s", fpu);
name += format("-%d-%s-%s", bits, system, toolchain);
- object_patterns.push_back(Pattern("%.o"));
+ add_pattern<ObjectFile>("%.o");
if(system=="windows")
{
- sharedlib_patterns.push_back(Pattern("%.dll"));
- sharedlib_patterns.push_back(Pattern("lib%.dll"));
+ add_pattern<SharedLibrary>("%.dll");
+ add_pattern<SharedLibrary>("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>("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>("%");
}
}
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)
#ifndef ARCHITECTURE_H_
#define ARCHITECTURE_H_
+#include <typeinfo>
#include <msp/datafile/loader.h>
#include "buildinfo.h"
#include "pattern.h"
std::string name;
bool native;
std::string cross_prefix;
- PatternList object_patterns;
- PatternList sharedlib_patterns;
- PatternList staticlib_patterns;
- PatternList executable_patterns;
+ std::map<std::string, PatternList> filename_patterns;
public:
Architecture(Builder &b, const std::string &spec);
const std::string &get_cross_prefix() const { return cross_prefix; }
- const PatternList &get_object_patterns() const { return object_patterns; }
- const PatternList &get_shared_library_patterns() const { return sharedlib_patterns; }
- const PatternList &get_static_library_patterns() const { return staticlib_patterns; }
- const PatternList &get_executable_patterns() const { return executable_patterns; }
+ template<typename T>
+ const PatternList &get_patterns() const;
+
+ template<typename T>
+ std::string create_filename(const std::string &) const;
+
+private:
+ template<typename T>
+ void add_pattern(const std::string &);
private:
static void resolve_aliases(std::vector<std::string> &);
void parse_specification(const std::string &);
};
+template<typename T>
+inline const Architecture::PatternList &Architecture::get_patterns() const
+{
+ std::map<std::string, PatternList>::const_iterator i = filename_patterns.find(typeid(T).name());
+ if(i!=filename_patterns.end())
+ return i->second;
+
+ static PatternList empty;
+ return empty;
+}
+
+template<typename T>
+inline std::string Architecture::create_filename(const std::string &base) const
+{
+ const PatternList &patterns = get_patterns<T>();
+ return patterns.empty() ? base : patterns.front().apply(base);
+}
+
#endif
{ }
Executable::Executable(Builder &b, const Component &c, const list<ObjectFile *> &objs):
- Binary(b, c, generate_filename(c), objs)
+ Binary(b, c, b.get_current_arch().create_filename<Executable>(c.get_name()), objs)
{
install_location = "bin";
}
-
-string Executable::generate_filename(const Component &comp)
-{
- const Architecture &arch = comp.get_package().get_builder().get_current_arch();
- return arch.get_executable_patterns().front().apply(comp.get_name());
-}
public:
Executable(Builder &, const Msp::FS::Path &);
Executable(Builder &, const Component &, const std::list<ObjectFile *> &);
-private:
- static std::string generate_filename(const Component &);
-public:
virtual const char *get_type() const { return "Executable"; }
};
builder.get_build_graph().add_installed_target(*shlib->get_import_library());
else
{
- const Pattern &pattern = architecture->get_shared_library_patterns().front();
- string link_name = pattern.apply(shlib->get_libname());
+ string link_name = architecture->create_filename<SharedLibrary>(shlib->get_libname());
if(link_name!=FS::basename(inst_tgt->get_path()))
inst_tgt->set_symlink(link_name);
}
fn += *i;
}
const Architecture &arch = comp.get_package().get_builder().get_current_arch();
- return temp_dir/arch.get_object_patterns().front().apply(FS::basepart(fn));
+ return temp_dir/arch.create_filename<ObjectFile>(FS::basepart(fn));
}
void ObjectFile::set_used_in_shared_library(bool u)
if(!version.empty())
{
const Architecture &arch = builder.get_current_arch();
- const Pattern &pattern = arch.get_shared_library_patterns().front();
if(arch.get_system()=="windows")
- soname = pattern.apply(format("%s-%s", component->get_name(), version));
+ soname = arch.create_filename<SharedLibrary>(format("%s-%s", libname, version));
else if(arch.get_system()=="darwin")
- {
- string filename = pattern.apply(component->get_name());
- string base = FS::basepart(filename);
- string ext = FS::extpart(filename);
- soname = format("%s.%s%s", base, version, ext);
- }
+ soname = arch.create_filename<SharedLibrary>(format("%s.%s", libname, version));
else
- soname = format("%s.%s", pattern.apply(component->get_name()), version);
+ soname = format("%s.%s", arch.create_filename<SharedLibrary>(libname), version);
install_filename = soname;
}
else
{
const Architecture &arch = comp.get_package().get_builder().get_current_arch();
- return arch.get_shared_library_patterns().front().apply(comp.get_name());
+ return arch.create_filename<SharedLibrary>(comp.get_name());
}
}
string StaticLibrary::generate_filename(const Component &comp)
{
const Architecture &arch = comp.get_package().get_builder().get_current_arch();
- return arch.get_static_library_patterns().front().apply(comp.get_name());
+ return arch.create_filename<StaticLibrary>(comp.get_name());
}
void StaticLibrary::add_required_library(const string &lib)
list<string> shared_names;
if(mode!=BuildInfo::FORCE_STATIC)
- shared_names = Pattern::apply_list(arch.get_shared_library_patterns(), lib);
+ shared_names = Pattern::apply_list(arch.get_patterns<SharedLibrary>(), lib);
list<string> static_names;
if(mode!=BuildInfo::FORCE_DYNAMIC)
- static_names = Pattern::apply_list(arch.get_static_library_patterns(), lib);
+ static_names = Pattern::apply_list(arch.get_patterns<StaticLibrary>(), lib);
for(list<FS::Path>::const_iterator i=combined_path.begin(); i!=combined_path.end(); ++i)
{