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