]> git.tdb.fi Git - builder.git/blob - source/executable.cpp
db8bd11db0b3c832790d3cbdbef4d2f717ad80fd
[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         LibMode libmode=package->get_library_mode();
30         
31         list<const Component *> queue;
32         list<Target *> dep_libs;
33         queue.push_back(&comp);
34         while(!queue.empty())
35         {
36                 const Component *c=queue.front();
37                 queue.erase(queue.begin());
38                 
39                 const list<string> &libs=c->get_build_info().libs;
40                 for(StringList::const_iterator i=libs.begin(); i!=libs.end(); ++i)
41                 {
42                         Target *lib=builder.get_library(*i, c->get_build_info().libpath, libmode);
43                         if(lib)
44                         {
45                                 if(contains(depends, lib))
46                                         continue;
47
48                                 dep_libs.push_front(lib);
49
50                                 if(dynamic_cast<Install *>(lib))
51                                         lib=lib->get_depends().front();
52                                 if(StaticLibrary *stlib=dynamic_cast<StaticLibrary *>(lib))
53                                         queue.push_back(&stlib->get_component());
54                         }
55                         else
56                                 cout<<"Couldn't find library "<<*i<<" for "<<name<<'\n';
57                                 //XXX Throw an exception here or something
58                 }
59         }
60
61         for(list<Target *>::iterator i=dep_libs.begin(); i!=dep_libs.end(); ++i)
62                 add_depend(*i);
63
64         deps_ready=true;
65 }
66
67 Action *Executable::build()
68 {
69         return Target::build(new Link(builder, *this));;
70 }
71
72 /**
73 Returns the name for the executable.  We can't do this in the constructor since
74 we need to pass the value to the Target c'tor.
75 */
76 string Executable::generate_target_name(const Component &c)
77 {
78         string prefix,suffix;
79         const string &arch=c.get_package().get_arch();
80
81         if(c.get_type()==Component::LIBRARY)
82         {
83                 prefix="lib";
84                 if(arch=="win32")
85                         suffix=".dll";
86                 else
87                         suffix=".so";
88         }
89         else if(c.get_type()==Component::MODULE)
90                 suffix=".m";
91         else if(c.get_type()==Component::PROGRAM)
92         {
93                 if(arch=="win32")
94                         suffix=".exe";
95         }
96
97         return (c.get_package().get_out_dir()/(prefix+c.get_name()+suffix)).str();
98 }