3 This file is part of builder
4 Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
9 #include <msp/strings/lexicalcast.h>
10 #include <msp/strings/utils.h>
11 #include "binarypackage.h"
14 #include "sourcepackage.h"
19 SourcePackage::SourcePackage(Builder &b, const string &n, const FS::Path &s):
25 tar_files.push_back(source/"Build");
28 Msp::FS::Path SourcePackage::get_temp_dir() const
30 return source/config.get_option("tempdir").value/builder.get_current_arch().get_name()/config.get_option("profile").value;
33 Msp::FS::Path SourcePackage::get_out_dir() const
35 const Architecture &arch=builder.get_current_arch();
37 return source/config.get_option("outdir").value;
39 return source/arch.get_name()/config.get_option("outdir").value;
42 unsigned SourcePackage::get_install_flags()
45 for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
49 if(i->get_type()==Component::PROGRAM)
51 else if(i->get_type()==Component::LIBRARY || i->get_type()==Component::MODULE)
54 if(!i->get_install_headers().empty())
61 LibMode SourcePackage::get_library_mode() const
63 const string &mode=config.get_option("staticlibs").value;
66 else if(mode=="local")
71 throw Exception("Unknown library mode");
74 void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
78 StringMap::const_iterator prof=opts.find("profile");
79 if(prof!=opts.end() && flag)
80 config.select_profile(prof->second);
82 config.select_last_profile();
84 if(flag && config.update(opts))
86 if(builder.get_verbose()>=2)
87 cout<<"Configuration of "<<name<<" changed\n";
88 if(!builder.get_dry_run())
94 for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
97 const StringList &reqs=i->get_requires();
98 for(StringList::const_iterator j=reqs.begin(); j!=reqs.end(); ++j)
99 if(Package *pkg=builder.get_package(*j))
100 requires.push_back(pkg);
105 for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
107 const PackageList &reqs=i->get_requires();
108 requires.insert(requires.end(), reqs.begin(), reqs.end());
111 for(PackageList::iterator i=requires.begin(); i!=requires.end(); ++i)
113 BinaryPackage *bpkg=dynamic_cast<BinaryPackage *>(*i);
114 if(bpkg && bpkg->get_need_path())
115 bpkg->set_path(config.get_option(bpkg->get_name()+"_path").value);
120 /*for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
121 (*i)->configure(opts, flag&2);*/
124 void SourcePackage::init_config()
126 config.add_option("profile", "default", "Configuration profile");
127 config.add_option("tempdir", "temp", "Directory for storing temporary files");
128 config.add_option("outdir", ".", "Directory to put build results in");
129 config.add_option("optimize", "0", "Apply compiler optimizations");
130 config.add_option("strip", "0", "Strip symbols from programs");
131 config.add_option("debug", "0", "Produce debugging symbols");
132 config.add_option("cpu", "auto", "CPU type to optimize for");
133 config.add_option("staticlibs", "local", "Use static libraries");
135 for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
136 config.add_option("with_"+i->name, "0", i->descr);
138 for(PackageList::const_iterator i=requires.begin(); i!=requires.end(); ++i)
140 BinaryPackage *bpkg=dynamic_cast<BinaryPackage *>(*i);
141 if(bpkg && bpkg->get_need_path())
142 config.add_option(bpkg->get_name()+"_path", "/usr", "Path for "+bpkg->get_name());
146 void SourcePackage::create_build_info()
148 for(PackageList::iterator i=base_reqs.begin(); i!=base_reqs.end(); ++i)
150 const BuildInfo &ebi=(*i)->get_exported_binfo();
153 export_binfo.cflags.insert(export_binfo.cflags.end(), ebi.cflags.begin(), ebi.cflags.end());
154 export_binfo.incpath.insert(export_binfo.incpath.end(), ebi.incpath.begin(), ebi.incpath.end());
155 export_binfo.defines.insert(export_binfo.defines.end(), ebi.defines.begin(), ebi.defines.end());
158 // XXX Currently, a package-specific settings will override cmdline. This might or might not be desirable.
159 const StringList &warnings=builder.get_warnings();
160 build_info.warnings.insert(build_info.warnings.begin(), warnings.begin(), warnings.end());
162 unsigned flags=get_install_flags();
164 build_info.incpath.push_back((builder.get_prefix()/"include").str());
165 build_info.libpath.push_back((builder.get_prefix()/"lib").str());
168 export_binfo.incpath.push_back((builder.get_prefix()/"include").str());
170 export_binfo.libpath.push_back((builder.get_prefix()/"lib").str());
172 string optimize=config.get_option("optimize").value;
173 if(lexical_cast<unsigned>(optimize))
175 build_info.cflags.push_back("-O"+optimize);
176 build_info.ldflags.push_back("-O"+optimize);
177 string cpu=config.get_option("cpu").value;
179 build_info.cflags.push_back("-march="+cpu);
182 if(lexical_cast<bool>(config.get_option("debug").value))
184 build_info.cflags.push_back("-ggdb");
185 build_info.defines.push_back("DEBUG");
188 for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
189 if(lexical_cast<bool>(config.get_option("with_"+i->name).value))
190 build_info.cflags.push_back("-DWITH_"+toupper(i->name));
192 for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
194 build_info.add(i->get_build_info());
198 for(list<Component>::iterator i=components.begin(); i!=components.end(); ++i)
200 i->create_build_info();
201 if(i->get_type()==Component::LIBRARY)
202 export_binfo.libs.push_back(i->get_name());
205 export_binfo.unique();
209 SourcePackage::Loader::Loader(Package &p):
212 add("version", &SourcePackage::version);
213 add("description", &SourcePackage::description);
214 add("build_info", &Loader::build_info);
215 add("feature", &Loader::feature);
216 add("if", &Loader::condition);
217 add("program", &Loader::program);
218 add("library", &Loader::library);
219 add("module", &Loader::module);
220 add("headers", &Loader::headers);
221 add("tar_file", &Loader::tar_file);
224 void SourcePackage::Loader::feature(const string &n, const string &d)
226 static_cast<SourcePackage &>(pkg).features.push_back(Feature(n, d));
229 void SourcePackage::Loader::condition(const string &c)
231 SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
232 Condition cond(spkg, c);
234 spkg.conditions.push_back(cond);
237 void SourcePackage::Loader::program(const string &n)
239 SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
240 Component prog(spkg, Component::PROGRAM, n);
242 spkg.components.push_back(prog);
245 void SourcePackage::Loader::library(const string &n)
247 SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
248 Component prog(spkg, Component::LIBRARY, n);
250 spkg.components.push_back(prog);
253 void SourcePackage::Loader::module(const string &n)
255 SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
256 Component prog(spkg, Component::MODULE, n);
258 spkg.components.push_back(prog);
261 void SourcePackage::Loader::headers(const string &n)
263 SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
264 Component prog(spkg, Component::HEADERS, n);
266 spkg.components.push_back(prog);
269 void SourcePackage::Loader::build_info()
271 load_sub(static_cast<SourcePackage &>(pkg).build_info);
274 void SourcePackage::Loader::tar_file(const string &f)
276 SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
277 spkg.tar_files.push_back(spkg.source/f);