]> git.tdb.fi Git - builder.git/blob - source/executable.cpp
Refactor package configuration
[builder.git] / source / executable.cpp
1 #include <iostream>
2 #include <msp/algo.h>
3 #include "builder.h"
4 #include "component.h"
5 #include "executable.h"
6 #include "install.h"
7 #include "link.h"
8 #include "objectfile.h"
9 #include "package.h"
10 #include "staticlibrary.h"
11
12 using namespace std;
13 using namespace Msp;
14
15 Executable::Executable(Builder &b, const Component &c, const list<ObjectFile *> &objs):
16         Target(b, &c.get_package(), generate_target_name(c)),
17         comp(c)
18 {
19         buildable=true;
20         for(list<ObjectFile *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
21                 add_depend(*i);
22 }
23
24 /**
25 Finds and adds any required libraries to the dependencies.
26 */
27 void Executable::find_depends()
28 {
29         const string &staticlibs=package->get_config().get_option("staticlibs").value;
30         unsigned libmode=0;
31         if(staticlibs=="all")
32                 libmode=2;
33         else if(staticlibs=="local")
34                 libmode=1;
35         
36         //XXX Duplicate libraries?
37         list<const Component *> queue;
38         queue.push_back(&comp);
39         while(!queue.empty())
40         {
41                 const Component *c=queue.front();
42                 queue.erase(queue.begin());
43                 
44                 const list<string> &libs=c->get_build_info().libs;
45                 for(StringList::const_iterator i=libs.begin(); i!=libs.end(); ++i)
46                 {
47                         Target *lib=builder.get_library(*i, c->get_build_info().libpath, libmode);
48                         if(lib)
49                         {
50                                 if(contains(depends, lib))
51                                         continue;
52                                 add_depend(lib);
53
54                                 if(dynamic_cast<Install *>(lib))
55                                         lib=lib->get_depends().front();
56                                 if(StaticLibrary *stlib=dynamic_cast<StaticLibrary *>(lib))
57                                         queue.push_back(&stlib->get_component());
58                         }
59                         else
60                                 cout<<"Couldn't find library "<<*i<<" for "<<name<<'\n';
61                                 //XXX Throw an exception here or something
62                 }
63         }
64
65         deps_ready=true;
66 }
67
68 Action *Executable::build()
69 {
70         return Target::build(new Link(builder, *this));;
71 }
72
73 /**
74 Returns the name for the executable.  We can't do this in the constructor since
75 we need to pass the value to the Target c'tor.
76 */
77 string Executable::generate_target_name(const Component &c)
78 {
79         string prefix,suffix;
80
81         if(c.get_type()==Component::LIBRARY)
82         {
83                 prefix="lib";
84                 suffix=".so";
85         }
86
87         return (c.get_package().get_source()/(prefix+c.get_name()+suffix)).str();
88 }