{
dep_libs.push_back(lib);
- if(Install *inst = dynamic_cast<Install *>(lib))
- lib = &inst->get_source();
+ lib = lib->get_real_target();
if(StaticLibrary *stlib = dynamic_cast<StaticLibrary *>(lib))
queue.push_back(&stlib->get_component());
}
if(tgt)
{
- Target *real_tgt = tgt;
- if(Install *inst = dynamic_cast<Install *>(tgt))
- real_tgt = &inst->get_source();
+ Target *real_tgt = tgt->get_real_target();
/* Ignore dynamic libraries from local packages unless library mode is
DYNAMIC */
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#include "sharedlibrary.h"
#include "sourcepackage.h"
#include "staticlibrary.h"
+#include "symlink.h"
#include "tarball.h"
#include "target.h"
Target *inst_tgt = builder.get_target("install");
for(list<FileTarget *>::const_iterator i=inst_list.begin(); i!=inst_list.end(); ++i)
- inst_tgt->add_depend(new Install(builder, pkg, **i, inst_loc));
+ {
+ Install *inst = new Install(builder, pkg, **i, inst_loc);
+ inst_tgt->add_depend(inst);
+
+ if(type==LIBRARY)
+ if(SharedLibrary *shlib = dynamic_cast<SharedLibrary *>(*i))
+ inst_tgt->add_depend(new Symlink(builder, pkg, *inst, shlib->get_name()));
+ }
}
PathList Component::collect_source_files() const
/* $Id$
This file is part of builder
-Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
builder.add_target(this);
struct stat st;
- if(!FS::stat(path, st))
+ if(!FS::lstat(path, st))
{
mtime = Time::TimeStamp::from_unixtime(st.st_mtime);
size = st.st_size;
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
add_depend(&source);
}
+Target *Install::get_real_target()
+{
+ return source.get_real_target();
+}
+
void Install::check_rebuild()
{
if(!mtime)
{
const Component &comp = shlib->get_component();
if(comp.get_type()==Component::LIBRARY)
+ {
mid = "lib";
+ tgtname = shlib->get_soname();
+ }
else if(comp.get_type()==Component::MODULE)
mid = "lib/"+tgt.get_package()->get_name();
}
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
Install(Builder &, const SourcePackage &, FileTarget &, const std::string & =std::string());
virtual const char *get_type() const { return "Install"; }
FileTarget &get_source() const { return source; }
+ virtual Target *get_real_target();
private:
virtual void check_rebuild();
virtual Action *create_action();
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
else if(comp.get_package().get_library_mode()==ALL_STATIC)
argv.push_back("-static");
+ if(const SharedLibrary *lib = dynamic_cast<const SharedLibrary *>(&bin))
+ if(!lib->get_soname().empty())
+ argv.push_back("-Wl,-soname,"+lib->get_soname());
+
const BuildInfo &binfo = comp.get_build_info();
for(list<string>::const_iterator i=binfo.ldflags.begin(); i!=binfo.ldflags.end(); ++i)
argv.push_back(*i);
const TargetList &deps = bin.get_depends();
for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i)
{
- Target *tgt = *i;
- if(Install *inst = dynamic_cast<Install *>(tgt))
- tgt = &inst->get_source();
+ Target *tgt = (*i)->get_real_target();
if(ObjectFile *obj = dynamic_cast<ObjectFile *>(tgt))
argv.push_back(relative(obj->get_path(), work_dir).str());
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <unistd.h>
+#include <msp/fs/utils.h>
+#include <msp/io/print.h>
+#include "builder.h"
+#include "package.h"
+#include "makesymlink.h"
+#include "symlink.h"
+
+using namespace Msp;
+
+MakeSymlink::MakeSymlink(Builder &b, const Symlink &sl):
+ Action(b)
+{
+ FS::Path relpath = FS::relative(sl.get_target().get_path(), FS::dirname(sl.get_path()));
+
+ announce(sl.get_package()->get_name(), "LN", sl.get_path().str());
+ if(builder.get_verbose()>=2)
+ IO::print("%s -> %s\n", sl.get_name(), relpath.str());
+
+ if(!builder.get_dry_run())
+ symlink(relpath.str().c_str(), sl.get_path().str().c_str());
+}
+
+int MakeSymlink::check()
+{
+ signal_done.emit();
+ return 0;
+}
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MAKESYMLINK_H_
+#define MAKESYMLINK_H_
+
+#include "action.h"
+
+class Symlink;
+
+class MakeSymlink: public Action
+{
+public:
+ MakeSymlink(Builder &, const Symlink &);
+ virtual int check();
+};
+
+#endif
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
void ObjectFile::find_depends(Target *tgt)
{
- SourceFile *src = dynamic_cast<SourceFile *>(tgt);
- FileTarget *file = src;
- if(!src)
- {
- if(Install *inst = dynamic_cast<Install *>(tgt))
- {
- file = inst;
- src = dynamic_cast<SourceFile *>(&inst->get_source());
- }
- }
- if(!src)
+ SourceFile *src = dynamic_cast<SourceFile *>(tgt->get_real_target());
+ FileTarget *file = dynamic_cast<FileTarget *>(tgt);
+ if(!src || !file)
return;
FS::Path spath = FS::dirname(file->get_path());
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, spath, incpath);
- if(hdr2 && find(depends.begin(), depends.end(), hdr2)==depends.end())
- add_depend(hdr2);
+ Target *hdr = builder.get_header(*i, spath, incpath);
+ if(hdr && find(depends.begin(), depends.end(), hdr)==depends.end())
+ add_depend(hdr);
}
}
Distributed under the LGPL
*/
+#include <msp/strings/formatter.h>
#include "component.h"
#include "sharedlibrary.h"
#include "sourcepackage.h"
using namespace std;
+using namespace Msp;
SharedLibrary::SharedLibrary(Builder &b, const Component &c, const list<ObjectFile *> &objs):
FileTarget(b, &c.get_package(), generate_target_path(c)),
Binary(b, c, objs),
- Library(b, &c.get_package(), path, c.get_name())
+ Library(b, &c.get_package(), path, c.get_name()),
+ soname(create_soname(c))
{ }
+
+string SharedLibrary::create_soname(const Component &c)
+{
+ const string &ver = c.get_package().get_version();
+ if(ver.empty())
+ return string();
+
+ unsigned dots = 0;
+ unsigned i = 0;
+ for(; i<ver.size(); ++i)
+ if(ver[i]=='.')
+ {
+ ++dots;
+ if(dots>=2)
+ break;
+ }
+
+ return format("%s.%s", name, ver.substr(0, i));
+}
*/
class SharedLibrary: public Binary, public Library
{
+private:
+ std::string soname;
+
public:
SharedLibrary(Builder &, const Component &, const std::list<ObjectFile *> &);
virtual const char *get_type() const { return "SharedLibrary"; }
+ const std::string &get_soname() const { return soname; }
+
+private:
+ std::string create_soname(const Component &);
};
#endif
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/fs/utils.h>
+#include "makesymlink.h"
+#include "symlink.h"
+
+using namespace std;
+using namespace Msp;
+
+Symlink::Symlink(Builder &b, const Package &p, FileTarget &t, const string &n):
+ FileTarget(b, &p, FS::dirname(t.get_path())/n),
+ target(t)
+{
+ buildable = true;
+}
+
+Target *Symlink::get_real_target()
+{
+ return target.get_real_target();
+}
+
+void Symlink::check_rebuild()
+{
+ if(!mtime)
+ mark_rebuild("Does not exist");
+}
+
+Action *Symlink::create_action()
+{
+ return new MakeSymlink(builder, *this);
+}
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef SYMLINK_H_
+#define SYMLINK_H_
+
+#include "filetarget.h"
+
+/**
+Symbolic link.
+*/
+class Symlink: public FileTarget
+{
+private:
+ FileTarget ⌖
+ bool relative;
+
+public:
+ Symlink(Builder &, const Package &, FileTarget &, const std::string &);
+
+ virtual const char *get_type() const { return "Symlink";}
+ FileTarget &get_target() const { return target; }
+ virtual Target *get_real_target();
+private:
+ virtual void check_rebuild();
+ virtual Action *create_action();
+};
+
+#endif
/* $Id$
This file is part of builder
-Copyright © 2006-2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
*/
Target *get_buildable_target();
+ /**
+ If this target is a proxy for another (such as Install or Symlink), return
+ that target. Otherwise, return the target itself.
+
+ Implementors should call the function recursively to find the final target.
+ */
+ virtual Target *get_real_target() { return this; }
+
bool is_buildable() const { return buildable; }
bool get_rebuild() const { return rebuild; }
const std::string &get_rebuild_reason() const { return rebuild_reason; }