]> git.tdb.fi Git - builder.git/blob - source/buildinfo.cpp
0e06a5908ff984d1e67def75d64e643106e47ace
[builder.git] / source / buildinfo.cpp
1 #include <algorithm>
2 #include <set>
3 #include <msp/strings/format.h>
4 #include "buildinfo.h"
5
6 using namespace std;
7 using namespace Msp;
8
9 namespace {
10
11 /** Removes any duplicate entries from a list, leaving only the first one.  The
12 order of other elements is preserved.  O(nlogn) efficiency. */
13 template<typename T>
14 void unique(list<T> &l)
15 {
16         set<T> seen;
17         for(typename list<T>::iterator i=l.begin(); i!=l.end(); )
18         {
19                 if(seen.count(*i))
20                         l.erase(i++);
21                 else
22                         seen.insert(*i++);
23         }
24 }
25
26 }
27
28
29 BuildInfo::BuildInfo():
30         libmode(DYNAMIC),
31         threads(false),
32         debug(false),
33         optimize(0),
34         strip(false),
35         warning_level(0),
36         fatal_warnings(false)
37 { }
38
39 BuildInfo::LibraryMode BuildInfo::get_libmode_for(const string &lib) const
40 {
41         LibModeMap::const_iterator i = libmodes.find(lib);
42         if(i!=libmodes.end())
43                 return i->second;
44         return libmode;
45 }
46
47 void BuildInfo::update_from(const BuildInfo &bi, UpdateLevel level)
48 {
49         for(DefineMap::const_iterator i=bi.defines.begin(); i!=bi.defines.end(); ++i)
50                 defines[i->first] = i->second;
51         incpath.insert(incpath.begin(), bi.incpath.begin(), bi.incpath.end());
52         if(level!=CHAINED)
53         {
54                 libpath.insert(libpath.begin(), bi.libpath.begin(), bi.libpath.end());
55                 libs.insert(libs.begin(), bi.libs.begin(), bi.libs.end());
56         }
57         threads = bi.threads;
58         if(level==LOCAL)
59         {
60                 sysroot = bi.sysroot;
61                 local_incpath.insert(local_incpath.begin(), bi.local_incpath.begin(), bi.local_incpath.end());
62                 libmode = bi.libmode;
63                 for(LibModeMap::const_iterator i=bi.libmodes.begin(); i!=bi.libmodes.end(); ++i)
64                         libmodes[i->first] = i->second;
65                 for(StandardMap::const_iterator i=bi.standards.begin(); i!=bi.standards.end(); ++i)
66                         standards[i->first] = i->second;
67                 debug = bi.debug;
68                 optimize = bi.optimize;
69                 strip = bi.strip;
70                 warning_level = bi.warning_level;
71                 fatal_warnings = bi.fatal_warnings;
72         }
73
74         unique(incpath);
75         unique(libpath);
76         unique(libs);
77 }
78
79
80 BuildInfo::Loader::Loader(BuildInfo &bi):
81         DataFile::ObjectLoader<BuildInfo>(bi)
82 {
83         add("debug",    &BuildInfo::debug);
84         add("define",   &Loader::define);
85         add("incpath",  &Loader::incpath);
86         add("libpath",  &Loader::libpath);
87         add("library",  &Loader::library);
88         add("libmode",  &BuildInfo::libmode);
89         add("libmode",  &Loader::libmode_for_lib);
90         add("local_incpath", &Loader::local_incpath);
91         add("optimize", &BuildInfo::optimize);
92         add("standard", &Loader::standard);
93         add("strip",    &BuildInfo::strip);
94         add("sysroot",  &Loader::sysroot);
95         add("threads",  &BuildInfo::threads);
96         add("warning_level", &BuildInfo::warning_level);
97         add("fatal_warnings", &BuildInfo::fatal_warnings);
98 }
99
100 void BuildInfo::Loader::incpath(const string &s)
101 {
102         obj.incpath.push_back(s);
103 }
104
105 void BuildInfo::Loader::define(const string &d, const string &v)
106 {
107         obj.defines[d] = v;
108 }
109
110 void BuildInfo::Loader::libmode_for_lib(const string &l, LibraryMode m)
111 {
112         obj.libmodes[l] = m;
113 }
114
115 void BuildInfo::Loader::libpath(const string &s)
116 {
117         obj.libpath.push_back(s);
118 }
119
120 void BuildInfo::Loader::library(const string &s)
121 {
122         obj.libs.push_back(s);
123 }
124
125 void BuildInfo::Loader::local_incpath(const string &s)
126 {
127         obj.local_incpath.push_back(s);
128 }
129
130 void BuildInfo::Loader::standard(DataFile::Symbol tag, const string &std)
131 {
132         obj.standards[tag.name] = std;
133 }
134
135 void BuildInfo::Loader::sysroot(const string &s)
136 {
137         obj.sysroot = s;
138 }
139
140
141 void operator>>(const LexicalConverter &conv, BuildInfo::LibraryMode &libmode)
142 {
143         if(conv.get()=="FORCE_STATIC")
144                 libmode = BuildInfo::FORCE_STATIC;
145         else if(conv.get()=="STATIC")
146                 libmode = BuildInfo::STATIC;
147         else if(conv.get()=="DYNAMIC")
148                 libmode = BuildInfo::DYNAMIC;
149         else if(conv.get()=="FORCE_DYNAMIC")
150                 libmode = BuildInfo::FORCE_DYNAMIC;
151         else
152                 throw lexical_error(format("Conversion of '%s' to LibraryMode", conv.get()));
153 }