2 #include <msp/fs/dir.h>
3 #include <msp/fs/stat.h>
4 #include <msp/fs/utils.h>
5 #include <msp/io/print.h>
6 #include <msp/strings/lexicalcast.h>
10 #include "executable.h"
14 #include "objectfile.h"
15 #include "sharedlibrary.h"
16 #include "sourcepackage.h"
17 #include "staticlibrary.h"
21 #include "toolchain.h"
26 Component::Component(SourcePackage &p, Type t, const string &n):
34 void Component::configure(const StringMap &opts, unsigned flag)
36 for(StringList::iterator i=sources.begin(); i!=sources.end(); ++i)
37 *i = (pkg.get_source()/pkg.expand_string(*i)).str();
39 for(PackageList::const_iterator i=requires.begin(); i!=requires.end(); ++i)
40 (*i)->configure(opts, flag&2);
43 void Component::create_build_info()
45 const PackageList &pkg_reqs = pkg.get_requires();
46 PackageList direct_reqs = requires;
47 direct_reqs.insert(direct_reqs.end(), pkg_reqs.begin(), pkg_reqs.end());
49 PackageList all_reqs = direct_reqs;
50 for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
52 if(find(direct_reqs.begin(), direct_reqs.end(), *i)!=direct_reqs.end())
53 build_info.add((*i)->get_exported_binfo());
56 const BuildInfo &ebi = (*i)->get_exported_binfo();
57 build_info.cflags.insert(build_info.cflags.end(), ebi.cflags.begin(), ebi.cflags.end());
58 build_info.incpath.insert(build_info.incpath.end(), ebi.incpath.begin(), ebi.incpath.end());
59 build_info.defines.insert(build_info.defines.end(), ebi.defines.begin(), ebi.defines.end());
62 const PackageList &reqs = (*i)->get_requires();
63 for(PackageList::const_iterator j=reqs.begin(); j!=reqs.end(); ++j)
64 if(find(all_reqs.begin(), all_reqs.end(), *j)==all_reqs.end())
65 all_reqs.push_back(*j);
68 build_info.add(pkg.get_build_info());
70 for(StringList::iterator i=build_info.incpath.begin(); i!=build_info.incpath.end(); ++i)
71 *i = (pkg.get_source() / *i).str();
72 for(StringList::iterator i=build_info.libpath.begin(); i!=build_info.libpath.end(); ++i)
73 *i = (pkg.get_source() / *i).str();
75 if(pkg.get_library_mode()!=DYNAMIC)
77 for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
79 const BuildInfo &ebi = (*i)->get_exported_binfo();
80 build_info.libpath.insert(build_info.libpath.end(), ebi.libpath.begin(), ebi.libpath.end());
86 string strip = pkg.get_config().get_option("strip").value;
87 if(lexical_cast<bool>(strip))
88 build_info.ldflags.push_back("-s");
90 else if(type==LIBRARY)
92 build_info.cflags.push_back("-fPIC");
98 void Component::create_targets() const
100 Builder &builder = pkg.get_builder();
101 const Toolchain &toolchain = builder.get_toolchain();
102 Target *world = builder.get_target("world");
103 Target *def_tgt = builder.get_target("default");
105 PathList source_filenames = collect_source_files();
106 list<Target *> inst_list;
111 //const Tool &tar = toolchain.get_tool("TAR");
113 string tarname = name;
116 tarname = pkg.get_name()+"-"+pkg.get_version();
117 source_filenames.push_back(pkg.get_source()/"Build");
120 list<Target *> files;
121 for(PathList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
123 FileTarget *file = builder.get_vfs().get_target(*i);
125 file = new File(builder, *i);
126 files.push_back(file);
131 const Builder::TargetMap &targets = builder.get_targets();
132 for(Builder::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i)
133 if(i->second->get_package()==&pkg && !i->second->is_buildable())
134 files.push_back(i->second);
137 /* XXX The source files don't have a package at the moment, so we can't
138 create the tarball target until things get fixed up a bit */
139 /*Target *result = tar.create_target(files, tarname);
141 Target *tarballs_tgt = builder.get_target("tarballs");
142 tarballs_tgt->add_depend(result);*/
146 else if(type==INSTALL)
149 for(PathList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
152 if(Target *tgt = builder.get_vfs().get_target(*i))
153 ft = dynamic_cast<FileTarget *>(tgt);
155 ft = new File(builder, pkg, *i);
156 inst_list.push_back(ft);
159 else if(type==DATAFILE)
161 const Tool &dcomp = toolchain.get_tool("DATA");
164 if(Target *tgt = builder.get_vfs().get_target(source_filenames.front()))
165 source = dynamic_cast<File *>(tgt);
167 source = new File(builder, pkg, source_filenames.front());
168 Target *result = dcomp.create_target(*source);
170 if(&pkg==builder.get_main_package() && deflt)
171 def_tgt->add_depend(result);
173 world->add_depend(result);
175 inst_list.push_back(result);
179 for(PathList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
181 string ext = FS::extpart(FS::basename(*i));
184 FileTarget *hdr = builder.get_vfs().get_target(*i);
186 hdr = new Header(builder, *this, i->str());
188 // Install headers if requested
189 if(type==HEADERS && install)
190 inst_list.push_back(hdr);
195 if(type==PROGRAM || type==LIBRARY || type==MODULE)
198 for(PathList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
200 string ext = FS::extpart(FS::basename(*i));
201 const Tool *tool = toolchain.get_tool_for_suffix(ext);
204 Target *src = tool->create_source(*this, *i);
205 Target *obj = tool->create_target(*src);
210 const Tool &linker = toolchain.get_tool("LINK");
212 list<Target *> results;
215 const Tool &archiver = toolchain.get_tool("AR");
216 results.push_back(linker.create_target(objs, "shared"));
217 results.push_back(archiver.create_target(objs));
219 else if(type==MODULE)
220 results.push_back(linker.create_target(objs, "shared"));
222 results.push_back(linker.create_target(objs));
224 for(list<Target *>::const_iterator i=results.begin(); i!=results.end(); ++i)
226 if(&pkg==builder.get_main_package() && deflt)
227 def_tgt->add_depend(*i);
229 world->add_depend(*i);
231 inst_list.push_back(*i);
235 Target *inst_tgt = builder.get_target("install");
236 const Tool © = toolchain.get_tool("CP");
237 for(list<Target *>::const_iterator i=inst_list.begin(); i!=inst_list.end(); ++i)
239 Target *inst = copy.create_target(**i, inst_loc);
240 inst_tgt->add_depend(inst);
244 PathList Component::collect_source_files() const
247 for(StringList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
252 list<string> sfiles = list_files(path);
253 for(list<string>::iterator j=sfiles.begin(); j!=sfiles.end(); ++j)
254 files.push_back(path / *j);
257 files.push_back(path);
264 Component::Loader::Loader(Component &c):
267 add("source", &Loader::source);
268 add("install", &Component::install);
269 add("install_headers", &Loader::install_headers);
270 add("build_info", &Loader::build_info);
271 add("require", &Loader::require);
272 add("modular", &Loader::modular);
273 add("host", &Loader::host);
274 add("default", &Component::deflt);
277 void Component::Loader::finish()
279 if(!inst_hdr.empty())
281 Component hdrcomp(comp.pkg, HEADERS, inst_hdr);
282 hdrcomp.sources = comp.sources;
283 hdrcomp.install = true;
284 const_cast<ComponentList &>(comp.pkg.get_components()).push_back(hdrcomp);
288 void Component::Loader::source(const string &s)
290 comp.sources.push_back(s);
293 void Component::Loader::require(const string &n)
295 Package *req = comp.pkg.get_builder().get_package(n);
297 comp.requires.push_back(req);
300 void Component::Loader::modular()
302 IO::print("%s: Note: modular is deprecated\n", get_source());
303 comp.build_info.ldflags.push_back("-rdynamic");
304 comp.build_info.libs.push_back("dl");
307 void Component::Loader::host(const string &)
309 IO::print("%s: Note: host is deprecated\n", get_source());
312 void Component::Loader::install_headers(const string &p)
314 IO::print("%s: Note: install_headers is deprecated\n", get_source());
315 if(comp.type==HEADERS)
324 void Component::Loader::build_info()
326 load_sub(comp.build_info);