#include "install.h"
#include "objectfile.h"
#include "package.h"
+#include "sourcefile.h"
#include "target.h"
using namespace std;
if(mode!=REBUILD && mode!=ALLDEPS)
{
// Skip trivial targets
- if(dynamic_cast<ObjectFile *>(&tgt))
- return build_depend_table(*tgt.get_depends().front(), depth);
- else if(dynamic_cast<Install *>(&tgt))
- return build_depend_table(*tgt.get_depends().front(), depth);
+ if(ObjectFile *obj=dynamic_cast<ObjectFile *>(&tgt))
+ return build_depend_table(obj->get_source(), depth);
+ else if(Install *inst=dynamic_cast<Install *>(&tgt))
+ return build_depend_table(inst->get_source(), depth);
}
else if(mode==REBUILD && !tgt.get_rebuild())
/* All targets that depend on to-be-built targets will be rebuilt
argv.push_back(builder.get_current_arch().get_tool(tool));
argv.push_back("rc");
- argv.push_back(relative(lib.get_name(), work_dir).str());
+ argv.push_back(relative(lib.get_path(), work_dir).str());
const TargetList &deps=lib.get_depends();
for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i)
- if(dynamic_cast<ObjectFile *>(*i))
- argv.push_back(relative((*i)->get_name(), work_dir).str());
+ if(ObjectFile *obj=dynamic_cast<ObjectFile *>(*i))
+ argv.push_back(relative(obj->get_path(), work_dir).str());
- FS::Path lpath=lib.get_name();
+ FS::Path lpath=lib.get_path();
if(!builder.get_dry_run())
FS::mkpath(FS::dirname(lpath), 0755);
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/fs/utils.h>
+#include <msp/strings/formatter.h>
+#include "binary.h"
+#include "builder.h"
+#include "component.h"
+#include "install.h"
+#include "link.h"
+#include "objectfile.h"
+#include "package.h"
+#include "sharedlibrary.h"
+#include "staticlibrary.h"
+
+using namespace std;
+using namespace Msp;
+
+Binary::Binary(Builder &b, const Component &c, const list<ObjectFile *> &objs):
+ FileTarget(b, &c.get_package(), generate_target_path(c)),
+ comp(c)
+{
+ buildable=true;
+ for(list<ObjectFile *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
+ add_depend(*i);
+}
+
+void Binary::find_depends()
+{
+ LibMode libmode=comp.get_package().get_library_mode();
+ if(dynamic_cast<SharedLibrary *>(this))
+ libmode=DYNAMIC;
+
+ list<const Component *> queue;
+ list<Target *> dep_libs;
+ queue.push_back(&comp);
+ while(!queue.empty())
+ {
+ const Component *c=queue.front();
+ queue.erase(queue.begin());
+
+ const StringList &libpath=c->get_build_info().libpath;
+
+ const list<string> &libs=c->get_build_info().libs;
+ for(StringList::const_iterator i=libs.begin(); i!=libs.end(); ++i)
+ {
+ Target *lib=builder.get_library(*i, libpath, libmode);
+ if(lib)
+ {
+ dep_libs.push_back(lib);
+
+ if(Install *inst=dynamic_cast<Install *>(lib))
+ lib=&inst->get_source();
+ if(StaticLibrary *stlib=dynamic_cast<StaticLibrary *>(lib))
+ queue.push_back(&stlib->get_component());
+ }
+ else
+ builder.problem(comp.get_package().get_name(), format("Couldn't find library %s for %s", *i, FS::basename(name)));
+ }
+ }
+
+ /* Add only the last occurrence of each library to the actual dependencies.
+ This ensures that static library ordering is correct. */
+ for(list<Target *>::iterator i=dep_libs.begin(); i!=dep_libs.end(); ++i)
+ {
+ bool last=true;
+ for(list<Target *>::iterator j=i; (last && j!=dep_libs.end()); ++j)
+ last=(j==i || *j!=*i);
+ if(last)
+ add_depend(*i);
+ }
+
+ deps_ready=true;
+}
+
+Action *Binary::create_action()
+{
+ return new Link(builder, *this);
+}
+
+FS::Path Binary::generate_target_path(const Component &c)
+{
+ const SourcePackage &pkg=c.get_package();
+ string prefix, suffix;
+ const string &arch=pkg.get_builder().get_current_arch().get_name();
+
+ if(c.get_type()==Component::LIBRARY)
+ {
+ prefix="lib";
+ if(arch=="win32")
+ suffix=".dll";
+ else
+ suffix=".so";
+ }
+ else if(c.get_type()==Component::MODULE)
+ suffix=".m";
+ else if(c.get_type()==Component::PROGRAM)
+ {
+ if(arch=="win32")
+ suffix=".exe";
+ }
+
+ return pkg.get_out_dir()/(prefix+c.get_name()+suffix);
+}
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef BINARY_H_
+#define BINARY_H_
+
+#include "filetarget.h"
+
+class Component;
+class ObjectFile;
+
+/**
+Produces a binary file, which may be either a standalone executable or a shared
+library.
+*/
+class Binary: public virtual FileTarget
+{
+protected:
+ const Component ∁
+
+ Binary(Builder &, const Component &, const std::list<ObjectFile *> &);
+public:
+ const Component &get_component() const { return comp; }
+ virtual void find_depends();
+protected:
+ virtual Action *create_action();
+
+ /** Returns the path for the binary. We can't do this in the constructor
+ since we need to pass the value to the Target c'tor. */
+ static Msp::FS::Path generate_target_path(const Component &);
+};
+
+#endif
cmdline_targets.push_back("default");
if(!work_dir.empty())
- chdir(work_dir.c_str());
+ FS::chdir(work_dir);
cwd=FS::getcwd();
Target *Builder::get_target(const string &n) const
{
+ // XXX Used for getting targets by path. get_target(const FS::Path &)?
TargetMap::const_iterator i=targets.find(n);
if(i!=targets.end())
return i->second;
return 0;
}
-Target *Builder::get_header(const string &include, const string &from, const list<string> &path)
+Target *Builder::get_header(const string &include, const FS::Path &from, const list<string> &path)
{
string hash(8, 0);
if(include[0]=='\"')
- update_hash(hash, from);
+ update_hash(hash, from.str());
for(list<string>::const_iterator i=path.begin(); i!=path.end(); ++i)
update_hash(hash, *i);
if(tgt)
{
Target *real_tgt=tgt;
- if(dynamic_cast<Install *>(tgt))
- real_tgt=real_tgt->get_depends().front();
+ if(Install *inst=dynamic_cast<Install *>(tgt))
+ real_tgt=&inst->get_source();
/* Ignore dynamic libraries from local packages unless library mode is
DYNAMIC */
}
for(set<Target *>::iterator i=clean_tgts.begin(); i!=clean_tgts.end(); ++i)
- {
- Action *action=new Unlink(*this, **i);
- while(action->check()<0) ;
- delete action;
- }
+ if(FileTarget *ft=dynamic_cast<FileTarget *>(*i))
+ {
+ Action *action=new Unlink(*this, *ft);
+ while(action->check()<0) ;
+ delete action;
+ }
return 0;
}
path. Considers known targets as well as existing files. If a matching
target is not found but a file exists, a new SystemHeader target will be
created and returned. */
- Target *get_header(const std::string &, const std::string &, const StringList &);
+ Target *get_header(const std::string &, const Msp::FS::Path &, const StringList &);
/** Tries to locate a library in a library path. The library name should be
the same as would be given to the linker with -l, i.e. without the "lib"
#include "compile.h"
#include "component.h"
#include "objectfile.h"
+#include "sourcefile.h"
#include "sourcepackage.h"
using namespace std;
work_dir=comp.get_package().get_source();
- const TargetList &deps=obj.get_depends();
- FS::Path spath=deps.front()->get_name();
+ FS::Path spath=obj.get_source().get_path();
string ext=FS::extpart(spath.str());
const char *tool=0;
for(list<string>::const_iterator i=binfo.defines.begin(); i!=binfo.defines.end(); ++i)
argv.push_back("-D"+*i);
- FS::Path opath=obj.get_name();
+ FS::Path opath=obj.get_path();
argv.push_back("-o");
argv.push_back(relative(opath, work_dir).str());
argv.push_back(relative(spath, work_dir).str());
#include <msp/strings/lexicalcast.h>
#include "builder.h"
#include "component.h"
+#include "executable.h"
#include "header.h"
#include "install.h"
#include "objectfile.h"
bool build_exe=(type!=HEADERS);
list<ObjectFile *> objs;
- list<Target *> inst_tgts;
+ list<FileTarget *> inst_tgts;
for(PathList::const_iterator i=files.begin(); i!=files.end(); ++i)
{
string ext=FS::extpart(FS::basename(*i));
}
else if(ext==".h")
{
- Target *hdr=builder.get_target(i->str());
+ FileTarget *hdr=dynamic_cast<FileTarget *>(builder.get_target(i->str()));
if(!hdr)
hdr=new Header(builder, this, i->str());
if(build_exe)
{
- Executable *exe=0;
+ Binary *bin=0;
StaticLibrary *slib=0;
if(type==LIBRARY)
{
- exe=new SharedLibrary(builder, *this, objs);
+ bin=new SharedLibrary(builder, *this, objs);
slib=new StaticLibrary(builder, *this, objs);
}
else
- exe=new Executable(builder, *this, objs);
+ bin=new Executable(builder, *this, objs);
if(&pkg==builder.get_main_package() && deflt)
{
- def_tgt->add_depend(exe);
+ def_tgt->add_depend(bin);
if(slib) def_tgt->add_depend(slib);
}
else
{
- world->add_depend(exe);
+ world->add_depend(bin);
if(slib) world->add_depend(slib);
}
if(install)
{
- inst_tgts.push_back(exe);
+ inst_tgts.push_back(bin);
if(slib)
inst_tgts.push_back(slib);
}
}
Target *inst_tgt=builder.get_target("install");
- for(TargetList::const_iterator i=inst_tgts.begin(); i!=inst_tgts.end(); ++i)
+ for(list<FileTarget *>::const_iterator i=inst_tgts.begin(); i!=inst_tgts.end(); ++i)
inst_tgt->add_depend(new Install(builder, pkg, **i));
}
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
-#include <msp/fs/utils.h>
-#include <msp/strings/formatter.h>
-#include "builder.h"
#include "component.h"
#include "executable.h"
-#include "install.h"
-#include "link.h"
-#include "objectfile.h"
-#include "package.h"
-#include "sharedlibrary.h"
-#include "staticlibrary.h"
+#include "sourcepackage.h"
-using namespace std;
-using namespace Msp;
-
-Executable::Executable(Builder &b, const Component &c, const list<ObjectFile *> &objs):
- Target(b, &c.get_package(), generate_target_name(c)),
- comp(c)
-{
- buildable=true;
- for(list<ObjectFile *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
- add_depend(*i);
-}
-
-void Executable::find_depends()
-{
- LibMode libmode=comp.get_package().get_library_mode();
- if(dynamic_cast<SharedLibrary *>(this))
- libmode=DYNAMIC;
-
- list<const Component *> queue;
- list<Target *> dep_libs;
- queue.push_back(&comp);
- while(!queue.empty())
- {
- const Component *c=queue.front();
- queue.erase(queue.begin());
-
- const StringList &libpath=c->get_build_info().libpath;
-
- const list<string> &libs=c->get_build_info().libs;
- for(StringList::const_iterator i=libs.begin(); i!=libs.end(); ++i)
- {
- Target *lib=builder.get_library(*i, libpath, libmode);
- if(lib)
- {
- dep_libs.push_back(lib);
-
- if(dynamic_cast<Install *>(lib))
- lib=lib->get_depends().front();
- if(StaticLibrary *stlib=dynamic_cast<StaticLibrary *>(lib))
- queue.push_back(&stlib->get_component());
- }
- else
- builder.problem(comp.get_package().get_name(), format("Couldn't find library %s for %s", *i, FS::basename(name)));
- }
- }
-
- /* Add only the last occurrence of each library to the actual dependencies.
- This ensures that static library ordering is correct. */
- for(list<Target *>::iterator i=dep_libs.begin(); i!=dep_libs.end(); ++i)
- {
- bool last=true;
- for(list<Target *>::iterator j=i; (last && j!=dep_libs.end()); ++j)
- last=(j==i || *j!=*i);
- if(last)
- add_depend(*i);
- }
-
- deps_ready=true;
-}
-
-Action *Executable::create_action()
-{
- return new Link(builder, *this);
-}
-
-string Executable::generate_target_name(const Component &c)
-{
- const SourcePackage &pkg=c.get_package();
- string prefix, suffix;
- const string &arch=pkg.get_builder().get_current_arch().get_name();
-
- if(c.get_type()==Component::LIBRARY)
- {
- prefix="lib";
- if(arch=="win32")
- suffix=".dll";
- else
- suffix=".so";
- }
- else if(c.get_type()==Component::MODULE)
- suffix=".m";
- else if(c.get_type()==Component::PROGRAM)
- {
- if(arch=="win32")
- suffix=".exe";
- }
-
- return (pkg.get_out_dir()/(prefix+c.get_name()+suffix)).str();
-}
+Executable::Executable(Builder &b, const Component &c, const std::list<ObjectFile *> &objs):
+ FileTarget(b, &c.get_package(), generate_target_path(c)),
+ Binary(b, c, objs)
+{ }
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#ifndef EXECUTABLE_H_
#define EXECUTABLE_H_
-#include "target.h"
+#include "binary.h"
-class Component;
-class ObjectFile;
-
-/**
-Produces a binary file, which may be either a standalone executable or a shared
-library.
-*/
-class Executable: public Target
+class Executable: public Binary
{
-private:
- const Component ∁
-
public:
Executable(Builder &, const Component &, const std::list<ObjectFile *> &);
virtual const char *get_type() const { return "Executable"; }
- const Component &get_component() const { return comp; }
- virtual void find_depends();
-private:
- virtual Action *create_action();
-
- /** Returns the name for the executable. We can't do this in the
- constructor since we need to pass the value to the Target c'tor. */
- static std::string generate_target_name(const Component &);
};
#endif
/* $Id$
This file is part of builder
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2009 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
using namespace std;
File::File(Builder &b, const string &n):
- Target(b, 0, n)
+ FileTarget(b, 0, n)
{ }
#ifndef FILE_H_
#define FILE_H_
-#include "target.h"
+#include "filetarget.h"
-class File: public Target
+/**
+Just a file. Any file, not attached to a package.
+*/
+class File: public FileTarget
{
public:
File(Builder &, const std::string &);
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/fs/stat.h>
+#include <msp/fs/utils.h>
+#include "file.h"
+
+using namespace std;
+using namespace Msp;
+
+FileTarget::FileTarget(Builder &b, const Package *p, const FS::Path &a):
+ // XXX Builder depends on target name being its path for locating file targets
+ Target(b, p, /*FS::basename*/(a.str())),
+ path(a)
+{
+ struct stat st;
+ if(!FS::stat(path, st))
+ mtime=Time::TimeStamp::from_unixtime(st.st_mtime);
+}
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef FILETARGET_H_
+#define FILETARGET_H_
+
+#include <msp/fs/path.h>
+#include "target.h"
+
+/**
+An intermediate base class for targets that represent files. Almost all target
+classes are derived from this.
+*/
+class FileTarget: public Target
+{
+protected:
+ Msp::FS::Path path;
+
+ FileTarget(Builder &, const Package *, const Msp::FS::Path &);
+public:
+ const Msp::FS::Path &get_path() const { return path; }
+};
+
+#endif
#include "install.h"
#include "package.h"
#include "pkgconfig.h"
+#include "sharedlibrary.h"
#include "staticlibrary.h"
using namespace std;
using namespace Msp;
-Install::Install(Builder &b, const SourcePackage &p, Target &tgt):
- Target(b, &p, generate_target_name(tgt))
+Install::Install(Builder &b, const SourcePackage &p, FileTarget &s):
+ FileTarget(b, &p, generate_target_path(s)),
+ source(s)
{
buildable=true;
- add_depend(&tgt);
+ add_depend(&source);
}
void Install::check_rebuild()
{
if(!mtime)
mark_rebuild("Does not exist");
- else
- {
- Target *dep=depends.front();
- if(dep->get_mtime()>mtime)
- mark_rebuild(FS::basename(dep->get_name())+" has changed");
- else if(dep->get_rebuild())
- mark_rebuild(FS::basename(dep->get_name())+" needs rebuilding");
- }
+ else if(source.get_mtime()>mtime)
+ mark_rebuild(FS::basename(source.get_name())+" has changed");
+ else if(source.get_rebuild())
+ mark_rebuild(FS::basename(source.get_name())+" needs rebuilding");
}
Action *Install::create_action()
{
- return new Copy(builder, *package, depends.front()->get_name(), name);
+ return new Copy(builder, *package, source.get_path(), path);
}
-string Install::generate_target_name(const Target &tgt)
+FS::Path Install::generate_target_path(const FileTarget &tgt)
{
const SourcePackage *spkg=dynamic_cast<const SourcePackage *>(tgt.get_package());
FS::Path base=spkg->get_builder().get_prefix();
- string tgtname=tgt.get_name().substr(tgt.get_name().rfind('/')+1);
+ string tgtname=FS::basename(tgt.get_path());
string mid;
if(const Header *hdr=dynamic_cast<const Header *>(&tgt))
mid="include/"+hdr->get_component()->get_install_headers();
- else if(const Executable *exe=dynamic_cast<const Executable *>(&tgt))
+ else if(dynamic_cast<const Executable *>(&tgt))
+ mid="bin";
+ else if(const SharedLibrary *shlib=dynamic_cast<const SharedLibrary *>(&tgt))
{
- const Component &comp=exe->get_component();
+ const Component &comp=shlib->get_component();
if(comp.get_type()==Component::LIBRARY)
mid="lib";
- else if(comp.get_type()==Component::PROGRAM)
- mid="bin";
else if(comp.get_type()==Component::MODULE)
mid="lib/"+tgt.get_package()->get_name();
}
#define INSTALL_H_
#include "sourcepackage.h"
-#include "target.h"
+#include "filetarget.h"
/**
Represents the installation of a file.
*/
-class Install: public Target
+class Install: public FileTarget
{
+private:
+ FileTarget &source;
+
public:
- Install(Builder &, const SourcePackage &, Target &);
+ Install(Builder &, const SourcePackage &, FileTarget &);
virtual const char *get_type() const { return "Install"; }
+ FileTarget &get_source() const { return source; }
private:
virtual void check_rebuild();
virtual Action *create_action();
- static std::string generate_target_name(const Target &);
+ static Msp::FS::Path generate_target_path(const FileTarget &);
};
#endif
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "library.h"
+
+Library::Library(Builder &b, const Package *p, const Msp::FS::Path &a, const std::string &l):
+ FileTarget(b, p, a),
+ libname(l)
+{ }
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef LIBRARY_H_
+#define LIBRARY_H_
+
+#include "filetarget.h"
+
+class Library: public virtual FileTarget
+{
+protected:
+ std::string libname;
+
+ Library(Builder &, const Package *, const Msp::FS::Path &, const std::string &);
+public:
+ const std::string &get_libname() const { return libname; }
+};
+
+#endif
using namespace std;
using namespace Msp;
-Link::Link(Builder &b, const Executable &exe):
+Link::Link(Builder &b, const Binary &bin):
ExternalAction(b)
{
- const Component &comp=exe.get_component();
+ const Component &comp=bin.get_component();
work_dir=comp.get_package().get_source();
argv.push_back("-L"+*i);
argv.push_back("-o");
- argv.push_back(relative(exe.get_name(), work_dir).str());
- const TargetList &deps=exe.get_depends();
+ argv.push_back(relative(bin.get_path(), work_dir).str());
+ const TargetList &deps=bin.get_depends();
for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i)
{
Target *tgt=*i;
- if(dynamic_cast<Install *>(tgt))
- tgt=tgt->get_depends().front();
+ if(Install *inst=dynamic_cast<Install *>(tgt))
+ tgt=&inst->get_source();
- if(dynamic_cast<ObjectFile *>(tgt))
- argv.push_back(relative((*i)->get_name(), work_dir).str());
- else if(SharedLibrary *shlib=dynamic_cast<SharedLibrary *>(tgt))
- argv.push_back("-l"+shlib->get_libname());
- else if(dynamic_cast<StaticLibrary *>(tgt))
- argv.push_back((*i)->get_name());
- else if(SystemLibrary *syslib=dynamic_cast<SystemLibrary *>(tgt))
- argv.push_back("-l"+syslib->get_libname());
+ if(ObjectFile *obj=dynamic_cast<ObjectFile *>(tgt))
+ argv.push_back(relative(obj->get_path(), work_dir).str());
+ else if(StaticLibrary *stlib=dynamic_cast<StaticLibrary *>(tgt))
+ argv.push_back(stlib->get_path().str());
+ else if(Library *lib=dynamic_cast<Library *>(tgt))
+ argv.push_back("-l"+lib->get_libname());
}
- FS::Path epath=exe.get_name();
+ FS::Path binpath=bin.get_path();
if(!builder.get_dry_run())
- FS::mkpath(FS::dirname(epath), 0755);
+ FS::mkpath(FS::dirname(binpath), 0755);
- announce(comp.get_package().get_name(), tool, relative(epath, work_dir).str());
+ announce(comp.get_package().get_name(), tool, relative(binpath, work_dir).str());
launch();
}
class Link: public ExternalAction
{
public:
- Link(Builder &, const Executable &);
+ Link(Builder &, const Binary &);
};
#endif
using namespace std;
using namespace Msp;
-ObjectFile::ObjectFile(Builder &b, const Component &c, SourceFile &src):
- Target(b, &c.get_package(), generate_target_name(c, src.get_name())),
- comp(c)
+ObjectFile::ObjectFile(Builder &b, const Component &c, SourceFile &s):
+ FileTarget(b, &c.get_package(), generate_target_path(c, FS::basename(s.get_path()))),
+ comp(c),
+ source(s)
{
buildable=true;
- add_depend(&src);
+ add_depend(&source);
}
void ObjectFile::find_depends()
void ObjectFile::find_depends(Target *tgt)
{
- const string &tname=tgt->get_name();
- string path=tname.substr(0, tname.rfind('/'));
-
SourceFile *src=dynamic_cast<SourceFile *>(tgt);
if(!src)
{
- Install *inst=dynamic_cast<Install *>(tgt);
- if(inst)
- src=dynamic_cast<SourceFile *>(inst->get_depends().front());
+ if(Install *inst=dynamic_cast<Install *>(tgt))
+ src=dynamic_cast<SourceFile *>(&inst->get_source());
}
if(!src)
return;
+ FS::Path spath=src->get_path();
const StringList &incpath=comp.get_build_info().incpath;
const list<string> &includes=src->get_includes();
for(list<string>::const_iterator i=includes.begin(); i!=includes.end(); ++i)
{
- Target *hdr2=builder.get_header(*i, path, incpath);
+ Target *hdr2=builder.get_header(*i, spath, incpath);
if(hdr2 && find(depends.begin(), depends.end(), hdr2)==depends.end())
add_depend(hdr2);
}
return new Compile(builder, *this);
}
-string ObjectFile::generate_target_name(const Component &comp, const string &src)
+FS::Path ObjectFile::generate_target_path(const Component &comp, const string &src)
{
const SourcePackage &pkg=comp.get_package();
- return (pkg.get_temp_dir()/comp.get_name()/(FS::basepart(FS::basename(src))+".o")).str();
+ return pkg.get_temp_dir()/comp.get_name()/(FS::basepart(src)+".o");
}
#ifndef OBJECTFILE_H_
#define OBJECTFILE_H_
-#include "target.h"
+#include "filetarget.h"
class Component;
class SourceFile;
/**
Object files are compiled from source files.
*/
-class ObjectFile: public Target
+class ObjectFile: public FileTarget
{
private:
const Component ∁
+ SourceFile &source;
TargetList new_deps;
public:
ObjectFile(Builder &, const Component &, SourceFile &);
virtual const char *get_type() const { return "ObjectFile"; }
const Component &get_component() const { return comp; }
+ SourceFile &get_source() const { return source; }
/** Processes as many new dependences as possible. Some may be created on
the fly and can't be processed until their own dependencies are ready. In
void add_depend(Target *);
virtual Action *create_action();
- static std::string generate_target_name(const Component &, const std::string &);
+ static Msp::FS::Path generate_target_path(const Component &, const std::string &);
};
#endif
#include "pkgconfigaction.h"
PkgConfig::PkgConfig(Builder &b, const SourcePackage &p):
- Target(b, &p, (p.get_source()/(p.get_name()+".pc")).str()),
- pkg(p)
+ FileTarget(b, &p, p.get_source()/(p.get_name()+".pc"))
{
buildable=true;
}
#define PKGCONFIG_H_
#include "sourcepackage.h"
-#include "target.h"
+#include "filetarget.h"
/**
Creates a .pc file to enable other packages fetch build options with pkg-config.
*/
-class PkgConfig: public Target
+class PkgConfig: public FileTarget
{
-private:
- const Package &pkg;
-
public:
PkgConfig(Builder &, const SourcePackage &);
virtual const char *get_type() const { return "PkgConfig"; }
{
const SourcePackage &spkg=*static_cast<const SourcePackage *>(p.get_package());
- announce(spkg.get_name(), "PC", relative(p.get_name(), spkg.get_source()).str());
+ announce(spkg.get_name(), "PC", relative(p.get_path(), spkg.get_source()).str());
- IO::BufferedFile out(p.get_name(), IO::M_WRITE);
+ IO::BufferedFile out(p.get_path().str(), IO::M_WRITE);
// Prefix is already included in the various paths
//IO::print(out, "prefix=%s\n", pkg.get_prefix());
IO::print(out, "source=%s\n\n", spkg.get_source());
*/
#include "component.h"
-#include "package.h"
#include "sharedlibrary.h"
+#include "sourcepackage.h"
using namespace std;
SharedLibrary::SharedLibrary(Builder &b, const Component &c, const list<ObjectFile *> &objs):
- Executable(b, c, objs),
- libname(c.get_name())
+ FileTarget(b, &c.get_package(), generate_target_path(c)),
+ Binary(b, c, objs),
+ Library(b, &c.get_package(), path, c.get_name())
{ }
-
#ifndef SHAREDLIB_H_
#define SHAREDLIB_H_
-#include "executable.h"
+#include "binary.h"
+#include "library.h"
/**
Represents a shared library. Mainly exists to give extra information to the
user.
*/
-class SharedLibrary: public Executable
+class SharedLibrary: public Binary, public Library
{
-private:
- std::string libname;
-
public:
SharedLibrary(Builder &, const Component &, const std::list<ObjectFile *> &);
virtual const char *get_type() const { return "SharedLibrary"; }
- const std::string &get_libname() const { return libname; }
};
#endif
using namespace std;
using namespace Msp;
-SourceFile::SourceFile(Builder &b, const Component *c, const string &n):
- Target(b, c?&c->get_package():0, n),
+SourceFile::SourceFile(Builder &b, const Component *c, const FS::Path &p):
+ FileTarget(b, (c ? &c->get_package() : 0), p),
comp(c)
{ }
const StringList &incpath=comp->get_build_info().incpath;
- string path=name.substr(0, name.rfind('/'));
+ FS::Path dir=FS::dirname(path);
for(list<string>::iterator i=includes.begin(); i!=includes.end(); ++i)
{
Target *hdr=builder.get_header(*i, path, incpath);
#ifndef SOURCEFILE_H_
#define SOURCEFILE_H_
-#include "target.h"
+#include "filetarget.h"
class Component;
/**
Represents a C or C++ source file.
*/
-class SourceFile: public Target
+class SourceFile: public FileTarget
{
private:
const Component *comp;
StringList includes;
public:
- SourceFile(Builder &, const Component *, const std::string &);
+ SourceFile(Builder &, const Component *, const Msp::FS::Path &);
virtual const char *get_type() const { return "SourceFile"; }
const StringList &get_includes() const { return includes; }
const Component *get_component() const { return comp; }
using namespace std;
-StaticLibrary::StaticLibrary(Builder &b, const Component &c, const std::list<ObjectFile *> &objs):
- Target(b, &c.get_package(), generate_target_name(c)),
+StaticLibrary::StaticLibrary(Builder &b, const Component &c, const list<ObjectFile *> &objs):
+ FileTarget(b, &c.get_package(), generate_target_path(c)),
+ Library(b, package, path, c.get_name()),
comp(c)
{
buildable=true;
return new Archive(builder, *this);
}
-string StaticLibrary::generate_target_name(const Component &c)
+Msp::FS::Path StaticLibrary::generate_target_path(const Component &c)
{
- return (c.get_package().get_out_dir()/("lib"+c.get_name()+".a")).str();
+ return c.get_package().get_out_dir()/("lib"+c.get_name()+".a");
}
#ifndef STATICLIB_H_
#define STATICLIB_H_
-#include "target.h"
+#include "library.h"
class Component;
class ObjectFile;
/**
A static library target.
*/
-class StaticLibrary: public Target
+class StaticLibrary: public Library
{
private:
const Component ∁
private:
virtual Action *create_action();
- static std::string generate_target_name(const Component &);
+ static Msp::FS::Path generate_target_path(const Component &);
};
#endif
using namespace std;
using namespace Msp;
-SystemLibrary::SystemLibrary(Builder &b, const string &n):
- Target(b, 0, n)
+SystemLibrary::SystemLibrary(Builder &b, const Msp::FS::Path &p):
+ FileTarget(b, 0, p),
+ Library(b, 0, p, extract_libname(p))
+{ }
+
+string SystemLibrary::extract_libname(const Msp::FS::Path &p)
{
- libname=FS::basepart(FS::basename(n));
- if(!libname.compare(0, 3, "lib"))
- libname.erase(0, 3);
+ string result=FS::basepart(FS::basename(p));
+ if(!result.compare(0, 3, "lib"))
+ result.erase(0, 3);
+ return result;
}
#ifndef SYSTEMLIBRARY_H_
#define SYSTEMLIBRARY_H_
-#include "target.h"
+#include "library.h"
/**
A library that doesn't belong to any known package.
*/
-class SystemLibrary: public Target
+class SystemLibrary: public Library
{
-private:
- std::string libname;
-
public:
- SystemLibrary(Builder &, const std::string &);
+ SystemLibrary(Builder &, const Msp::FS::Path &);
virtual const char *get_type() const { return "SystemLibrary"; }
- const std::string &get_libname() const { return libname; }
private:
virtual Action *create_action() { return 0; }
+
+ static std::string extract_libname(const Msp::FS::Path &);
};
#endif
InternalAction(b),
tarball(t)
{
- string basename=tarball.get_name().substr(tarball.get_name().rfind('/')+1);
+ string basename=FS::basename(tarball.get_path());
announce(tarball.get_package()->get_name(), "TAR ", basename);
if(builder.get_verbose()>=2)
cout<<"Create "<<basename<<'\n';
void Tar::Worker::main()
{
const FS::Path &pkg_src=tar.tarball.get_package()->get_source();
- FS::Path basedir=FS::basepart(FS::basename(tar.tarball.get_name()));
+ FS::Path basedir=FS::basepart(FS::basename(tar.tarball.get_path()));
- IO::File out(tar.tarball.get_name(), IO::M_WRITE);
+ IO::File out(tar.tarball.get_path().str(), IO::M_WRITE);
const TargetList &deps=tar.tarball.get_depends();
for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i)
{
+ FileTarget *ft=dynamic_cast<FileTarget *>(*i);
+ if(!ft)
+ continue;
+
char buf[4096];
memset(buf, 0, 512);
- string rel_path=(basedir/relative((*i)->get_name(), pkg_src)).str();
+ string rel_path=(basedir/relative(ft->get_path(), pkg_src)).str();
if(rel_path.size()>99)
{
cout<<"Can't store "<<rel_path<<" in tar archive - too long name\n";
memcpy(buf, rel_path.data(), rel_path.size());
- struct stat st=FS::stat((*i)->get_name());
+ struct stat st=FS::stat(ft->get_path());
store_number(buf+100, st.st_mode, 7);
store_number(buf+108, st.st_uid, 7);
store_number(buf+116, st.st_gid, 7);
buf[155]=0;
out.write(buf, 512);
- IO::File in((*i)->get_name());
+ IO::File in(ft->get_path().str());
for(int j=0; j<st.st_size; j+=4096)
{
unsigned len=in.read(buf, 4096);
using namespace std;
TarBall::TarBall(Builder &b, const SourcePackage &p, const string &ev):
- Target(b, &p, create_target_name(p, ev))
+ FileTarget(b, &p, create_target_name(p, ev))
{
buildable=true;
}
#ifndef TARBALL_H_
#define TARBALL_H_
-#include "target.h"
+#include "filetarget.h"
-class TarBall: public Target
+class TarBall: public FileTarget
{
-private:
- std::string tarname;
-
public:
TarBall(Builder &, const SourcePackage &, const std::string & =std::string());
virtual const char *get_type() const { return "TarBall"; }
#include <msp/time/utils.h>
#include "action.h"
#include "builder.h"
+#include "filetarget.h"
#include "package.h"
#include "sourcepackage.h"
#include "target.h"
counted(false)
{
builder.add_target(this);
-
- struct stat st;
- if(!FS::stat(name, st))
- mtime=Time::TimeStamp::from_unixtime(st.st_mtime);
}
Target *Target::get_buildable_target()
return 0;
}
- if(!builder.get_dry_run() && FS::exists(name))
- FS::unlink(name);
+ if(FileTarget *ft=dynamic_cast<FileTarget *>(this))
+ if(!builder.get_dry_run() && FS::exists(ft->get_path()))
+ FS::unlink(ft->get_path());
Action *action=create_action();
if(action)
*/
#include <msp/fs/utils.h>
+#include "filetarget.h"
#include "sourcepackage.h"
-#include "target.h"
#include "unlink.h"
-Unlink::Unlink(Builder &b, const Target &t):
+Unlink::Unlink(Builder &b, const FileTarget &t):
Action(b)
{
const SourcePackage &spkg=*static_cast<const SourcePackage *>(t.get_package());
- announce(spkg.get_name(), "RM", relative(t.get_name(), spkg.get_source()).str());
+ announce(spkg.get_name(), "RM", relative(t.get_path(), spkg.get_source()).str());
- unlink(t.get_name().c_str());
+ unlink(t.get_path());
}
int Unlink::check()
#include "action.h"
-class Target;
+class FileTarget;
class Unlink: public Action
{
public:
- Unlink(Builder &, const Target &);
+ Unlink(Builder &, const FileTarget &);
virtual int check();
};