#include "binarypackage.h"
#include "builder.h"
#include "copy.h"
+#include "datatool.h"
#include "gnuarchiver.h"
#include "gnuccompiler.h"
#include "gnucxxcompiler.h"
toolchain.add_tool(new PkgConfigGenerator(*this));
if(current_arch->get_system()=="windows")
toolchain.add_tool(new MingwDllTool(*this, *current_arch));
+ toolchain.add_tool(new DataTool(*this));
}
Builder::~Builder()
#include "builder.h"
#include "component.h"
#include "csourcefile.h"
-#include "datafile.h"
+#include "datapack.h"
#include "executable.h"
#include "file.h"
#include "objectfile.h"
inst->add_dependency(*copy.create_target(*ft, name));
}
}
- else if(type==DATAFILE)
+ else if(type==DATAPACK)
{
const Tool &dcomp = toolchain.get_tool("DATA");
- File *source;
- if(Target *tgt = builder.get_vfs().get_target(source_filenames.front()))
- source = dynamic_cast<File *>(tgt);
- else
- source = new File(builder, package, source_filenames.front());
- Target *result = dcomp.create_target(*source);
+ list<Target *> files;
+ for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
+ {
+ string ext = FS::extpart(FS::basename(*i));
+ if(ext==".mdt")
+ {
+ Target *src = dcomp.create_source(*this, *i);
+ files.push_back(dcomp.create_target(*src, "collection"));
+ }
+ else if(Target *tgt = builder.get_vfs().get_target(*i))
+ files.push_back(tgt);
+ else
+ files.push_back(new File(builder, package, *i));
+ }
+
+ Target *result = dcomp.create_target(files, "pack");
build_graph.add_primary_target(*result);
if(install)
LIBRARY,
PROGRAM,
MODULE,
- DATAFILE,
+ DATAPACK,
INSTALL,
TARBALL
};
--- /dev/null
+#include <msp/fs/utils.h>
+#include "component.h"
+#include "datacollection.h"
+#include "datatransform.h"
+#include "sourcepackage.h"
+
+using namespace Msp;
+
+DataCollection::DataCollection(Builder &b, const Component &c, DataTransform &s):
+ FileTarget(b, c.get_package(), generate_target_path(c, s.get_path())),
+ source(s)
+{
+ component = &c;
+ add_dependency(source);
+}
+
+Msp::FS::Path DataCollection::generate_target_path(const Component &comp, const Msp::FS::Path &src)
+{
+ return comp.get_package().get_temp_directory()/comp.get_name()/(FS::basepart(FS::basename(src))+".mdc");
+}
--- /dev/null
+#ifndef DATACOLLECTION_H_
+#define DATACOLLECTION_H_
+
+#include "filetarget.h"
+
+class DataTransform;
+
+class DataCollection: public FileTarget
+{
+private:
+ DataTransform &source;
+
+public:
+ DataCollection(Builder &, const Component &, DataTransform &);
+private:
+ static Msp::FS::Path generate_target_path(const Component &, const Msp::FS::Path &);
+
+public:
+ virtual const char *get_type() const { return "DataCollection"; }
+ DataTransform &get_source() const { return source; }
+};
+
+#endif
+++ /dev/null
-#include <stdexcept>
-#include "datacompiler.h"
-
-using namespace std;
-
-DataCompiler::DataCompiler(Builder &b):
- Tool(b, "DATA")
-{
-}
-
-Target *DataCompiler::create_target(const list<Target *> &sources, const string &) const
-{
- if(sources.size()!=1)
- throw invalid_argument("DataCompiler::create_target");
- throw runtime_error("Not implemented");
- //File &source = dynamic_cast<File &>(sources.front());
- //return new ::DataFile(
-}
-
-Task *DataCompiler::run(const Target &) const
-{
- throw runtime_error("Not implemented");
-}
+++ /dev/null
-#ifndef DATACOMPILER_H_
-#define DATACOMPILER_H_
-
-#include "tool.h"
-
-class DataCompiler: public Tool
-{
-public:
- DataCompiler(Builder &);
-
- virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
- virtual Task *run(const Target &) const;
-};
-
-#endif
+++ /dev/null
-#include "component.h"
-#include "datafile.h"
-#include "file.h"
-#include "sourcepackage.h"
-
-DataFile::DataFile(Builder &b, const Component &c, File &s):
- FileTarget(b, c.get_package(), generate_target_path(c)),
- component(c),
- source(s)
-{
- add_dependency(source);
-
- install_location = Msp::FS::Path("share")/package->get_name();
-}
-
-Msp::FS::Path DataFile::generate_target_path(const Component &comp)
-{
- return comp.get_package().get_output_directory()/(comp.get_name()+".dat");
-}
+++ /dev/null
-#ifndef DATAFILE_H_
-#define DATAFILE_H_
-
-#include "filetarget.h"
-
-class Component;
-class File;
-
-class DataFile: public FileTarget
-{
-private:
- const Component &component;
- File &source;
-
-public:
- DataFile(Builder &, const Component &, File &);
-private:
- static Msp::FS::Path generate_target_path(const Component &);
-
-public:
- virtual const char *get_type() const { return "DataFile"; }
- const Component &get_component() const { return component; }
- File &get_source() const { return source; }
-};
-
-#endif
--- /dev/null
+#include "component.h"
+#include "datapack.h"
+#include "sourcepackage.h"
+
+using namespace std;
+
+DataPack::DataPack(Builder &b, const Component &c, const list<FileTarget *> &f):
+ FileTarget(b, c.get_package(), generate_target_path(c)),
+ files(f)
+{
+ component = &c;
+ for(list<FileTarget *>::const_iterator i=files.begin(); i!=files.end(); ++i)
+ add_dependency(**i);
+
+ install_location = Msp::FS::Path("share")/package->get_name();
+}
+
+Msp::FS::Path DataPack::generate_target_path(const Component &comp)
+{
+ return comp.get_package().get_output_directory()/(comp.get_name()+".mdp");
+}
--- /dev/null
+#ifndef DATAPACK_H_
+#define DATAPACK_H_
+
+#include "filetarget.h"
+
+class DataPack: public FileTarget
+{
+public:
+ typedef std::list<FileTarget *> FileList;
+private:
+ FileList files;
+
+public:
+ DataPack(Builder &, const Component &, const std::list<FileTarget *> &);
+private:
+ static Msp::FS::Path generate_target_path(const Component &);
+
+public:
+ virtual const char *get_type() const { return "DataPack"; }
+
+ const FileList &get_files() const { return files; }
+};
+
+#endif
--- /dev/null
+#include <stdexcept>
+#include <msp/fs/utils.h>
+#include <msp/strings/format.h>
+#include "builder.h"
+#include "component.h"
+#include "datacollection.h"
+#include "datapack.h"
+#include "datatool.h"
+#include "datatransform.h"
+#include "externaltask.h"
+#include "sourcepackage.h"
+
+using namespace std;
+using namespace Msp;
+
+DataTool::DataTool(Builder &b):
+ Tool(b, "DATA")
+{
+ executable = builder.get_vfs().find_binary("mspdatatool");
+ if(!executable)
+ builder.problem(string(), format("Can't find executable mspdatatool for tool %s", tag));
+
+ input_suffixes.push_back(".mdt");
+}
+
+Target *DataTool::create_source(const Component &comp, const FS::Path &path) const
+{
+ return new DataTransform(builder, comp, path);
+}
+
+Target *DataTool::create_target(const list<Target *> &sources, const string &arg) const
+{
+ if(arg=="collection")
+ {
+ if(sources.size()!=1)
+ throw invalid_argument("DataTool::create_target");
+ DataTransform &source = dynamic_cast<DataTransform &>(*sources.front());
+ DataCollection *coll = new DataCollection(builder, *source.get_component(), source);
+ coll->set_tool(*this);
+ return coll;
+ }
+ else if(arg=="pack")
+ {
+ list<FileTarget *> files;
+ for(list<Target *>::const_iterator i=sources.begin(); i!=sources.end(); ++i)
+ files.push_back(&dynamic_cast<FileTarget &>(**i));
+ DataPack *pack = new DataPack(builder, *files.front()->get_component(), files);
+ pack->set_tool(*this);
+ return pack;
+ }
+ else
+ throw invalid_argument("DataTool::create_target");
+}
+
+Task *DataTool::run(const Target &tgt) const
+{
+ const Component &comp = *tgt.get_component();
+ FS::Path work_dir = comp.get_package().get_source_directory();
+
+ vector<string> argv;
+ argv.push_back(executable->get_path().str());
+
+ argv.push_back("-o");
+ argv.push_back(FS::relative(dynamic_cast<const FileTarget &>(tgt).get_path(), work_dir).str());
+
+ const BuildInfo &binfo = comp.get_build_info();
+ if(binfo.debug)
+ argv.push_back("-g");
+ if(binfo.optimize>0)
+ {
+ argv.push_back("-b");
+ if(binfo.optimize>1)
+ argv.push_back("-z");
+ }
+
+ if(const DataCollection *coll = dynamic_cast<const DataCollection *>(&tgt))
+ {
+ argv.push_back("-c");
+ argv.push_back(FS::relative(coll->get_source().get_path(), work_dir).str());
+ }
+ else if(const DataPack *pack = dynamic_cast<const DataPack *>(&tgt))
+ {
+ argv.push_back("-p");
+ const DataPack::FileList &files = pack->get_files();
+ for(DataPack::FileList::const_iterator i=files.begin(); i!=files.end(); ++i)
+ argv.push_back(FS::relative((*i)->get_path(), work_dir).str());
+ }
+
+ return new ExternalTask(argv, work_dir);
+}
--- /dev/null
+#ifndef DATACOMPILER_H_
+#define DATACOMPILER_H_
+
+#include "tool.h"
+
+class DataTool: public Tool
+{
+public:
+ DataTool(Builder &);
+
+ virtual Target *create_source(const Component &, const Msp::FS::Path &) const;
+ virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+ virtual Task *run(const Target &) const;
+};
+
+#endif
--- /dev/null
+#include <msp/fs/dir.h>
+#include <msp/fs/utils.h>
+#include <msp/strings/format.h>
+#include <msp/strings/regex.h>
+#include "builder.h"
+#include "cache.h"
+#include "component.h"
+#include "datatransform.h"
+#include "file.h"
+#include "sourcepackage.h"
+
+using namespace std;
+using namespace Msp;
+
+DataTransform::DataTransform(Builder &b, const Component &c, const FS::Path &p):
+ FileTarget(b, c.get_package(), p)
+{
+ component = &c;
+}
+
+void DataTransform::find_dependencies()
+{
+ list<string> files;
+ Cache &cache = component->get_package().get_cache();
+ // XXX Should check directory mtime as well
+ if(mtime<cache.get_mtime() && cache.has_key(this, "files"))
+ files = cache.get_values(this, "files");
+ else
+ {
+ builder.get_logger().log("files", format("Reading imports from %s", path.str()));
+
+ list<string> dir_files = list_files(FS::dirname(path));
+ IO::File in(path.str());
+ DataFile::Parser parser(in, path.str());
+ while(!in.eof())
+ {
+ DataFile::Statement st = parser.parse();
+ if(st.keyword=="for_each")
+ {
+ for(DataFile::Statement::Arguments::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
+ {
+ Regex re(i->get<string>());
+ for(list<string>::const_iterator j=dir_files.begin(); j!=dir_files.end(); ++j)
+ if(re.match(*j))
+ files.push_back(*j);
+ }
+ }
+ else if(st.keyword=="file" && st.args.size()==1)
+ files.push_back(st.args.front().get<string>());
+ }
+
+ cache.set_values(this, "files", files);
+ }
+
+ for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
+ {
+ FS::Path file_path = FS::dirname(path)/ *i;
+ if(Target *tgt = builder.get_vfs().get_target(file_path))
+ add_dependency(*tgt);
+ else
+ add_dependency(*new File(builder, *package, file_path));
+ }
+}
--- /dev/null
+#ifndef DATATRANSFORM_H_
+#define DATATRANSFORM_H_
+
+#include "filetarget.h"
+
+class DataTransform: public FileTarget
+{
+public:
+ DataTransform(Builder &, const Component &, const Msp::FS::Path &);
+
+ virtual const char *get_type() const { return "DataTransform"; }
+
+private:
+ virtual void find_dependencies();
+};
+
+#endif
{
public:
File(Builder &b, const Msp::FS::Path &t): FileTarget(b, t) { }
- File(Builder &b, SourcePackage &p, const Msp::FS::Path &t): FileTarget(b, p, t) { }
+ File(Builder &b, const SourcePackage &p, const Msp::FS::Path &t): FileTarget(b, p, t) { }
virtual const char *get_type() const { return "File"; }
};
add("headers", &Loader::headers);
add("install", &Loader::component<Component::INSTALL>);
add("interface_version", &Loader::interface_version);
- add("datafile", &Loader::component<Component::DATAFILE>);
+ add("datapack", &Loader::component<Component::DATAPACK>);
add("source_tarball", &Loader::source_tarball);
add("tarball", &Loader::tarball);
add("tar_file", &Loader::tar_file);