]> git.tdb.fi Git - builder.git/blob - source/binary.cpp
Inline simple constructors
[builder.git] / source / binary.cpp
1 #include <msp/core/algorithm.h>
2 #include <msp/fs/utils.h>
3 #include <msp/strings/format.h>
4 #include <msp/strings/utils.h>
5 #include "binary.h"
6 #include "builder.h"
7 #include "component.h"
8 #include "objectfile.h"
9 #include "sharedlibrary.h"
10 #include "sourcepackage.h"
11 #include "staticlibrary.h"
12 #include "tool.h"
13
14 using namespace std;
15 using namespace Msp;
16
17 Binary::Binary(Builder &b, const Component &c, const string &p, const vector<ObjectFile *> &objs):
18         FileTarget(b, c.get_package(), c.get_package().get_output_directory()/p),
19         objects(objs)
20 {
21         component = &c;
22         for(ObjectFile *o: objects)
23                 add_dependency(*o);
24
25         nested_build_sig = true;
26         arch_in_build_sig = true;
27 }
28
29 void Binary::collect_build_info(BuildInfo &binfo) const
30 {
31         for(ObjectFile *o: objects)
32                 if(const Tool *obj_tool = o->get_tool())
33                         binfo.update_from(obj_tool->get_build_info());
34
35         Target::collect_build_info(binfo);
36
37         binfo.update_from(static_binfo);
38 }
39
40 void Binary::find_dependencies()
41 {
42         if(!component)
43                 return;
44
45         vector<Target *> static_libs;
46         vector<Target *> shared_libs;
47         vector<string> missing_libs;
48         find_dependencies(this, static_libs, shared_libs, missing_libs);
49
50         for(Target *t: static_libs)
51                 add_dependency(*t);
52         for(Target *t: shared_libs)
53                 add_dependency(*t);
54         for(const string &m: missing_libs)
55                 problems.push_back(format("Required library %s not found", m));
56 }
57
58 void Binary::find_dependencies(Target *tgt, vector<Target *> &static_libs, vector<Target *> &shared_libs, vector<string> &missing_libs)
59 {
60         BuildInfo binfo;
61         tgt->collect_build_info(binfo);
62         if(tgt!=this)
63         {
64                 static_binfo.libpath.insert(static_binfo.libpath.end(), binfo.libpath.begin(), binfo.libpath.end());
65                 static_binfo.keep_symbols.insert(static_binfo.keep_symbols.end(), binfo.keep_symbols.begin(), binfo.keep_symbols.end());
66                 if(binfo.threads)
67                         static_binfo.threads = true;
68         }
69
70         for(const string &l: binfo.libs)
71         {
72                 if(l.size()>10 && !l.compare(l.size()-10, 10, ".framework"))
73                         continue;
74
75                 BuildInfo::LibraryMode libmode = component->get_build_info().get_libmode_for(l);
76                 Target *lib = builder.get_vfs().find_library(l, binfo.libpath, libmode);
77                 if(lib)
78                 {
79                         Target *real = lib->get_real_target();
80                         if(StaticLibrary *stlib = dynamic_cast<StaticLibrary *>(real))
81                         {
82                                 /* Keep only the last occurrence of each static library.  This
83                                 ensures the order is correct for linking. */
84                                 auto i = find(static_libs, stlib);
85                                 if(i!=static_libs.end())
86                                         static_libs.erase(i);
87                                 static_libs.push_back(stlib);
88                                 find_dependencies(stlib, static_libs, shared_libs, missing_libs);
89                         }
90                         else if(!any_equals(shared_libs, lib))
91                                 shared_libs.push_back(lib);
92                 }
93                 else if(!any_equals(missing_libs, l))
94                         missing_libs.push_back(l);
95         }
96 }