]> git.tdb.fi Git - builder.git/blob - source/binary.cpp
Move the Component reference to Target and make it a pointer
[builder.git] / source / binary.cpp
1 #include <msp/fs/utils.h>
2 #include <msp/strings/format.h>
3 #include "binary.h"
4 #include "builder.h"
5 #include "component.h"
6 #include "link.h"
7 #include "objectfile.h"
8 #include "sharedlibrary.h"
9 #include "sourcepackage.h"
10 #include "staticlibrary.h"
11
12 using namespace std;
13 using namespace Msp;
14
15 Binary::Binary(Builder &b, const Component &c, const list<ObjectFile *> &objs):
16         FileTarget(b, &c.get_package(), generate_target_path(c))
17 {
18         component = &c;
19         for(list<ObjectFile *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
20                 add_depend(*i);
21 }
22
23 void Binary::find_depends()
24 {
25         if(!component)
26                 return;
27
28         const SourcePackage &spkg = component->get_package();
29         LibMode libmode = spkg.get_library_mode();
30         if(dynamic_cast<SharedLibrary *>(this))
31                 libmode = DYNAMIC;
32
33         list<const Component *> queue;
34         list<Target *> dep_libs;
35         queue.push_back(component);
36         while(!queue.empty())
37         {
38                 const Component *c = queue.front();
39                 queue.erase(queue.begin());
40
41                 const StringList &libpath = c->get_build_info().libpath;
42
43                 const list<string> &libs = c->get_build_info().libs;
44                 for(StringList::const_iterator i=libs.begin(); i!=libs.end(); ++i)
45                 {
46                         Target *lib = builder.get_vfs().find_library(*i, libpath, libmode);
47                         if(lib)
48                         {
49                                 dep_libs.push_back(lib);
50
51                                 lib = lib->get_real_target();
52                                 if(StaticLibrary *stlib = dynamic_cast<StaticLibrary *>(lib))
53                                         queue.push_back(stlib->get_component());
54                         }
55                         else
56                                 builder.problem(spkg.get_name(), format("Couldn't find library %s for %s", *i, name));
57                 }
58         }
59
60         /* Add only the last occurrence of each library to the actual dependencies.
61         This ensures that static library ordering is correct. */
62         for(list<Target *>::iterator i=dep_libs.begin(); i!=dep_libs.end(); ++i)
63         {
64                 bool last = true;
65                 for(list<Target *>::iterator j=i; (last && j!=dep_libs.end()); ++j)
66                         last = (j==i || *j!=*i);
67                 if(last)
68                         add_depend(*i);
69         }
70
71         deps_ready = true;
72 }
73
74 FS::Path Binary::generate_target_path(const Component &c)
75 {
76         const SourcePackage &pkg = c.get_package();
77         string prefix, suffix;
78         const string &sys = pkg.get_builder().get_current_arch().get_system();
79
80         if(c.get_type()==Component::LIBRARY)
81         {
82                 prefix = "lib";
83                 if(sys=="windows")
84                         suffix = ".dll";
85                 else
86                         suffix = ".so";
87         }
88         else if(c.get_type()==Component::MODULE)
89                 suffix = ".m";
90         else if(c.get_type()==Component::PROGRAM)
91         {
92                 if(sys=="windows")
93                         suffix = ".exe";
94         }
95
96         return pkg.get_out_dir()/(prefix+c.get_name()+suffix);
97 }