2 #include <msp/fs/utils.h>
3 #include <msp/io/print.h>
4 #include <msp/strings/lexicalcast.h>
5 #include <msp/strings/utils.h>
6 #include "binarypackage.h"
7 #include "booleanevaluator.h"
10 #include "pkgconfigfile.h"
12 #include "sourcegenerator.h"
13 #include "sourcepackage.h"
20 bool component_sort(const Component &c1, const Component &c2)
21 { return c1.get_type()<c2.get_type(); }
26 SourcePackage::SourcePackage(Builder &b, const string &n, const FS::Path &f):
28 source_dir(FS::dirname(f)),
35 build_file = builder.get_vfs().get_target(f);
37 build_file = new File(builder, *this, f);
38 components.push_back(Component(*this, Component::TARBALL, "@src"));
39 source_tarball = &components.back();
42 FS::Path SourcePackage::get_temp_directory() const
44 string subdir = builder.get_current_arch().get_name();
48 subdir += build_type->get_name();
51 const FS::Path &temp = builder.get_temp_directory();
52 if(temp.is_absolute())
53 return temp/name/subdir;
55 return source_dir/temp/subdir;
58 FS::Path SourcePackage::get_output_directory() const
60 const Architecture &arch = builder.get_current_arch();
64 return source_dir/arch.get_name();
67 bool SourcePackage::match_feature(const string &feat, const string *comp) const
69 string value = config.get_option("with_"+feat).value;
73 return lexical_cast<bool>(value);
76 void SourcePackage::set_build_type(const BuildType &t)
81 void SourcePackage::do_prepare()
83 BuildInfo final_build_info;
86 final_build_info.update_from(build_type->get_build_info());
88 final_build_info.update_from(build_info);
89 build_info = final_build_info;
91 build_info.incpath.push_back((builder.get_prefix()/"include").str());
92 build_info.libpath.push_back((builder.get_prefix()/"lib").str());
94 for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
96 string ident = "WITH_"+toupper(i->name);
97 string value = config.get_option("with_"+i->name).value;
98 if(!i->choices.empty())
99 build_info.defines[ident] = value;
100 else if(lexical_cast<bool>(value))
101 build_info.defines[ident] = "1";
104 bool export_paths = false;
105 for(list<Component>::iterator i=components.begin(); i!=components.end(); ++i)
108 i->create_build_info();
110 if(i->get_type()==Component::LIBRARY)
112 export_binfo.libs.push_back(i->get_name());
119 export_binfo.incpath.push_back((builder.get_prefix()/"include").str());
120 export_binfo.libpath.push_back((builder.get_prefix()/"lib").str());
125 bool pc_needed = false;
126 for(ComponentList::const_iterator i=components.begin(); i!=components.end(); ++i)
129 if(i->get_type()==Component::LIBRARY)
135 PkgConfigFile *pc = new PkgConfigFile(builder, *this);
136 builder.get_build_graph().get_target("install")->add_dependency(*builder.get_toolchain().get_tool("CP").create_target(*pc));
140 void SourcePackage::save_caches()
147 SourcePackage::Loader::Loader(SourcePackage &p):
148 DataFile::DerivedObjectLoader<SourcePackage, Package::Loader>(p)
153 SourcePackage::Loader::Loader(SourcePackage &p, const Config::InputOptions &o):
154 DataFile::DerivedObjectLoader<SourcePackage, Package::Loader>(p)
159 void SourcePackage::Loader::init(const Config::InputOptions *o)
162 add("description", &SourcePackage::description);
163 add("build_info", &Loader::build_info);
164 add("feature", &Loader::feature);
165 add("generate", &Loader::generate);
166 add("if_feature", &Loader::if_feature);
167 add("program", &Loader::component<Component::PROGRAM>);
168 add("library", &Loader::component<Component::LIBRARY>);
169 add("module", &Loader::component<Component::MODULE>);
170 add("install", &Loader::component<Component::INSTALL>);
171 add("interface_version", &Loader::interface_version);
172 add("datapack", &Loader::component<Component::DATAPACK>);
173 add("source_tarball", &Loader::source_tarball);
174 add("tarball", &Loader::tarball);
175 add("version", &Loader::version);
178 void SourcePackage::Loader::finish()
180 obj.components.sort(component_sort);
183 void SourcePackage::Loader::feature(const string &n, const string &d)
186 feat.description = d;
188 obj.features.push_back(feat);
190 const Config::Option &opt = obj.config.add_option(feat);
193 Config::InputOptions::const_iterator i = options->find(opt.name);
194 if(i!=options->end())
195 obj.config.set_option(opt.name, i->second);
199 template<Component::Type t>
200 void SourcePackage::Loader::component(const string &n)
202 Component comp(obj, t, n);
204 obj.components.push_back(comp);
207 void SourcePackage::Loader::build_info()
209 load_sub(obj.build_info);
212 void SourcePackage::Loader::generate(const string &tag)
214 SourceGenerator *gen = new SourceGenerator(obj.builder, obj, tag);
216 obj.local_tools.add_tool(gen);
219 void SourcePackage::Loader::if_feature(const string &cond)
221 BooleanEvaluator eval(sigc::mem_fun(&obj, &SourcePackage::match_feature));
222 bool match = eval.evaluate(cond);
223 obj.builder.get_logger().log("configure", format("%s: feature %s %smatched", obj.name, cond, (match ? "" : "not ")));
225 load_sub_with(*this);
228 void SourcePackage::Loader::interface_version(const string &v)
230 obj.interface_version = v;
231 if(obj.version.empty())
235 void SourcePackage::Loader::source_tarball()
237 load_sub(*obj.source_tarball);
240 void SourcePackage::Loader::tarball(const string &n)
242 Component trbl(obj, Component::TARBALL, n);
246 void SourcePackage::Loader::version(const string &v)
250 string::size_type i = 0;
251 for(unsigned dots=0; i<obj.version.size(); ++i)
252 if(obj.version[i]=='.' && ++dots>=2)
254 obj.interface_version = obj.version.substr(0, i);