]> git.tdb.fi Git - builder.git/blob - source/gnucompiler.cpp
Store a target representing the executable in each tool
[builder.git] / source / gnucompiler.cpp
1 #include <msp/fs/dir.h>
2 #include <msp/fs/utils.h>
3 #include <msp/strings/format.h>
4 #include "architecture.h"
5 #include "builder.h"
6 #include "component.h"
7 #include "externaltask.h"
8 #include "gnucompiler.h"
9 #include "objectfile.h"
10 #include "sourcefile.h"
11 #include "sourcepackage.h"
12
13 using namespace std;
14 using namespace Msp;
15
16 GnuCompiler::GnuCompiler(Builder &b, const string &t, const string &n):
17         Tool(b, t),
18         name(n)
19 {
20         executable = builder.get_vfs().find_binary(name);
21
22         const Architecture &arch = builder.get_current_arch();
23         if(arch.is_native())
24                 system_path.push_back("/usr/include");
25         else
26                 system_path.push_back("/usr/"+arch.get_cross_prefix()+"/include");
27 }
28
29 Target *GnuCompiler::create_target(const list<Target *> &sources, const std::string &) const
30 {
31         if(sources.size()!=1)
32                 throw invalid_argument("GnuCCompiler::create_target");
33         SourceFile &source = dynamic_cast<SourceFile &>(*sources.front());
34         ObjectFile *obj = new ObjectFile(builder, *source.get_component(), source);
35         obj->set_tool(*this);
36         return obj;
37 }
38
39 Task *GnuCompiler::run(const Target &target) const
40 {
41         const ObjectFile &object = dynamic_cast<const ObjectFile &>(target);
42         const Component &comp = object.get_component();
43
44         ExternalTask::Arguments argv;
45         argv.push_back(executable->get_path().str());
46         argv.push_back("-c");
47
48         const BuildInfo &binfo = comp.get_build_info();
49         for(BuildInfo::WordList::const_iterator i=binfo.warnings.begin(); i!=binfo.warnings.end(); ++i)
50                 argv.push_back("-W"+*i);
51         for(BuildInfo::PathList::const_iterator i=binfo.incpath.begin(); i!=binfo.incpath.end(); ++i)
52                 argv.push_back("-I"+i->str());
53         for(BuildInfo::DefineMap::const_iterator i=binfo.defines.begin(); i!=binfo.defines.end(); ++i)
54         {
55                 if(i->second.empty())
56                         argv.push_back(format("-D%s", i->first));
57                 else
58                         argv.push_back(format("-D%s=%s", i->first, i->second));
59         }
60         if(binfo.debug)
61                 argv.push_back("-ggdb");
62         if(binfo.optimize)
63         {
64                 if(binfo.optimize<0)
65                         argv.push_back("-Os");
66                 else
67                         argv.push_back(format("-O%d", binfo.optimize));
68         }
69         if(binfo.threads)
70                 argv.push_back("-pthread");
71         if(comp.get_type()==Component::LIBRARY)
72                 argv.push_back("-fPIC");
73
74         const Architecture &arch = builder.get_current_arch();
75         const Architecture &native_arch = builder.get_native_arch();
76         if(arch.get_bits()!=native_arch.get_bits())
77                 argv.push_back(format("-m%d", arch.get_bits()));
78
79         const string &cpu = arch.get_cpu();
80         if(!cpu.empty())
81                 argv.push_back("-march="+cpu);
82
83         FS::Path obj_path = object.get_path();
84         FS::Path src_path = object.get_source().get_path();
85         FS::Path work_dir = comp.get_package().get_source();
86
87         argv.push_back("-o");
88         argv.push_back(relative(obj_path, work_dir).str());
89         argv.push_back(relative(src_path, work_dir).str());
90
91         if(!builder.get_dry_run())
92                 FS::mkpath(FS::dirname(obj_path), 0755);
93
94         return new ExternalTask(argv, work_dir);
95 }