]> git.tdb.fi Git - builder.git/blob - source/sourcefile.cpp
d95ea5edc5f3678d1f1c0eb1926a50866ab22311
[builder.git] / source / sourcefile.cpp
1 /* $Id$
2
3 This file is part of builder
4 Copyright © 2006-2009  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/fs/utils.h>
9 #include <msp/io/except.h>
10 #include <msp/io/print.h>
11 #include <msp/strings/regex.h>
12 #include "builder.h"
13 #include "component.h"
14 #include "sourcefile.h"
15 #include "sourcepackage.h"
16
17 using namespace std;
18 using namespace Msp;
19
20 SourceFile::SourceFile(Builder &b, const FS::Path &p):
21         FileTarget(b, 0, p),
22         comp(0)
23 { }
24
25 SourceFile::SourceFile(Builder &b, const Component &c, const FS::Path &p):
26         FileTarget(b, &c.get_package(), p),
27         comp(&c)
28 { }
29
30 void SourceFile::find_depends()
31 {
32         if(!comp)
33         {
34                 deps_ready = true;
35                 return;
36         }
37
38         const SourcePackage &spkg = comp->get_package();
39         string relname = FS::relative(path, spkg.get_source()).str();
40         DependencyCache &deps_cache = spkg.get_deps_cache();
41         bool deps_found = false;
42         if(mtime<deps_cache.get_mtime())
43         {
44                 try
45                 {
46                         includes = deps_cache.get_deps(relname);
47                         deps_found = true;
48                 }
49                 catch(const KeyError &)
50                 { }
51         }
52
53         if(!deps_found)
54         {
55                 try
56                 {
57                         IO::BufferedFile in(path.str());
58
59                         if(builder.get_verbose()>=4)
60                                 IO::print("Reading includes from %s\n", path.str());
61
62                         Regex r_include("^[ \t]*#include[ \t]+([\"<].*)[\">]");
63
64                         string line;
65                         while(in.getline(line))
66                                 if(RegMatch match = r_include.match(line))
67                                         includes.push_back(match[1].str);
68
69                         deps_cache.set_deps(relname, includes);
70                 }
71                 catch(const IO::FileNotFound &)
72                 {
73                         if(builder.get_verbose()>=4)
74                                 IO::print("Failed to read includes from %s\n", path.str());
75                         deps_ready = true;
76                         return;
77                 }
78         }
79
80         const StringList &incpath = comp->get_build_info().incpath;
81
82         FS::Path dir = FS::dirname(path);
83         for(list<string>::iterator i=includes.begin(); i!=includes.end(); ++i)
84         {
85                 Target *hdr = builder.get_header(*i, dir, incpath);
86                 if(hdr)
87                         add_depend(hdr);
88         }
89
90         deps_ready = true;
91 }