aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.conf7
-rw-r--r--src/build.l1
-rw-r--r--src/build.y5
-rw-r--r--src/builder.h4
-rw-r--r--src/filetarget.cpp63
-rw-r--r--src/filetarget.h9
-rw-r--r--src/main.cpp7
-rw-r--r--src/perform.cpp1
-rw-r--r--src/perform.h1
-rw-r--r--src/performcmd.cpp2
-rw-r--r--src/rule.cpp11
11 files changed, 100 insertions, 11 deletions
diff --git a/build.conf b/build.conf
index 1d7c6a2..b24d7d0 100644
--- a/build.conf
+++ b/build.conf
@@ -1,14 +1,13 @@
1# This is a build file for build 1# This is a build file for build
2 2
3default action: check build 3default action: check build
4"clean" action: clean build
4 5
5create file build from files in src using rule exe 6create file build from files in src using rule exe
6 7
7set CXXFLAGS += "-Ilibbu++/src" 8set CXXFLAGS += "-Ilibbu++/src"
8set LDFLAGS += "-Llibbu++ -lbu++" 9set LDFLAGS += "-Llibbu++ -lbu++"
9 10
10for build set LDFLAGS += -lreadline
11
12build requires src/libbu++/libbu++.a 11build requires src/libbu++/libbu++.a
13 12
14/(.*)\.o$/ requires from command "g++ {CXXFLAGS} -M {re:1}.c*" 13/(.*)\.o$/ requires from command "g++ {CXXFLAGS} -M {re:1}.c*"
@@ -19,8 +18,8 @@ rule exe matches all /(.*)\.o$/ perform command ...
19rule cpp matches one /(.*)\.c(pp)?$/ produces "{re:1}.o" perform command ... 18rule cpp matches one /(.*)\.c(pp)?$/ produces "{re:1}.o" perform command ...
20 "g++ {CXXFLAGS} -c -o {target} {match}" 19 "g++ {CXXFLAGS} -c -o {target} {match}"
21 20
22rule bison matches one /(.*)\.y$/ produces "{re:1}.tab.c", "{re:1}.tab.h" ... 21rule bison matches one /(.*)\.y$/ produces "{re:1}.tab.c", "{re:1}.tab.h", ...
23 perform command "bison -v -b{re:1} {match}" 22 "{re:1}.output" perform command "bison -v -b{re:1} {match}"
24 23
25rule flex matches one /(.*)\.l$/ produces "{re:1}.yy.c" perform ... 24rule flex matches one /(.*)\.l$/ produces "{re:1}.yy.c" perform ...
26 command "flex --bison-bridge --bison-locations -o {target} {match}" 25 command "flex --bison-bridge --bison-locations -o {target} {match}"
diff --git a/src/build.l b/src/build.l
index a88f90d..a18cbeb 100644
--- a/src/build.l
+++ b/src/build.l
@@ -40,6 +40,7 @@ std::string strbuf;
40"produces" return TOK_PRODUCES; 40"produces" return TOK_PRODUCES;
41"command" return TOK_COMMAND; 41"command" return TOK_COMMAND;
42"check" return TOK_CHECK; 42"check" return TOK_CHECK;
43"clean" return TOK_CLEAN;
43 44
44"..."\n /* elipsis line continuation */ 45"..."\n /* elipsis line continuation */
45\n+ return TOK_EOL; 46\n+ return TOK_EOL;
diff --git a/src/build.y b/src/build.y
index ecc5d59..4d87a86 100644
--- a/src/build.y
+++ b/src/build.y
@@ -49,6 +49,7 @@ void yyerror( YYLTYPE *locp, Builder &bld, char const *msg );
49%token TOK_PRODUCES "produces" 49%token TOK_PRODUCES "produces"
50%token TOK_COMMAND "command" 50%token TOK_COMMAND "command"
51%token TOK_CHECK "check" 51%token TOK_CHECK "check"
52%token TOK_CLEAN "clean"
52%token TOK_EOL "end of line" 53%token TOK_EOL "end of line"
53%token ',' ':' '=' 54%token ',' ':' '='
54 55
@@ -162,6 +163,10 @@ action: TOK_CHECK STRING
162 { 163 {
163 bld.add( new Command( Command::cmdCheck, $2 ) ); 164 bld.add( new Command( Command::cmdCheck, $2 ) );
164 } 165 }
166 | TOK_CLEAN STRING
167 {
168 bld.add( new Command( Command::cmdClean, $2 ) );
169 }
165 ; 170 ;
166 171
167setexpr: STRING '=' STRING 172setexpr: STRING '=' STRING
diff --git a/src/builder.h b/src/builder.h
index f21e411..f27a042 100644
--- a/src/builder.h
+++ b/src/builder.h
@@ -100,8 +100,10 @@ public:
100 return mTarget[sName]; 100 return mTarget[sName];
101 } 101 }
102 102
103 std::list<std::string> getRequires( const char *sReq ) 103 std::list<std::string> *getRequires( const char *sReq )
104 { 104 {
105 if( mRequires.find(sReq) == mRequires.end() )
106 return NULL;
105 return mRequires[sReq]; 107 return mRequires[sReq];
106 } 108 }
107 109
diff --git a/src/filetarget.cpp b/src/filetarget.cpp
index 1880c35..f9367a4 100644
--- a/src/filetarget.cpp
+++ b/src/filetarget.cpp
@@ -1,6 +1,7 @@
1#include <errno.h> 1#include <errno.h>
2#include <dirent.h> 2#include <dirent.h>
3 3
4#include "perform.h"
4#include "rule.h" 5#include "rule.h"
5#include "filetarget.h" 6#include "filetarget.h"
6#include "builder.h" // for BuildException 7#include "builder.h" // for BuildException
@@ -66,8 +67,11 @@ void FileTarget::addInputDir( const char *sDir )
66 closedir( dir ); 67 closedir( dir );
67} 68}
68 69
70int nNew, nCache;
71
69void FileTarget::check( Builder &bld ) 72void FileTarget::check( Builder &bld )
70{ 73{
74 nNew = nCache = 0;
71 Rule *pRule = bld.getRule( sRule ); 75 Rule *pRule = bld.getRule( sRule );
72 76
73 std::list<Perform *> perf; 77 std::list<Perform *> perf;
@@ -79,12 +83,67 @@ void FileTarget::check( Builder &bld )
79 for( std::list<Perform *>::iterator i = perf.begin(); 83 for( std::list<Perform *>::iterator i = perf.begin();
80 i != perf.end(); i++ ) 84 i != perf.end(); i++ )
81 { 85 {
82 std::list<std::string> lReqs = bld.getRequires( (*i)->getTarget() ); 86 time_t target = getTime( std::string((*i)->getTarget()) );
83 87 std::list<std::string> *lReqs = bld.getRequires( (*i)->getTarget() );
88 if( lReqs == NULL )
89 {
90 printf("No dependancies: %s\n", (*i)->getTarget() );
91 continue;
92 }
93 for( std::list<std::string>::iterator j = lReqs->begin();
94 j != lReqs->end(); j++ )
95 {
96 if( getTime( *j ) > target )
97 {
98 (*i)->execute( bld );
99 updateTime( (*i)->getTarget() );
100 break;
101 }
102 }
84 } 103 }
104
105 printf("Cache hits %d, %d new (%f%%)\n", nCache, nNew, nCache/ (double)(nNew+nCache)*100.0 );
85} 106}
86 107
87void FileTarget::clean( Builder &bld ) 108void FileTarget::clean( Builder &bld )
88{ 109{
110 Rule *pRule = bld.getRule( sRule );
111
112 std::list<Perform *> perf;
113 std::list<std::string> tmp = pRule->execute( bld, lInput, perf, getName() );
114 lOutput.insert( lOutput.end(), tmp.begin(), tmp.end() );
115
116 for( std::list<std::string>::iterator i = lOutput.begin();
117 i != lOutput.end(); i++ )
118 {
119 unlink( (*i).c_str() );
120 }
121}
122
123time_t FileTarget::getTime( std::string str )
124{
125 std::map<std::string, time_t>::iterator i = mTimes.find( str );
126 if( i != mTimes.end() )
127 {
128 nCache++;
129 return (*i).second;
130 }
131
132 struct stat st;
133 stat( str.c_str(), &st );
134
135 mTimes[str] = st.st_mtime;
136
137 nNew++;
138
139 return st.st_mtime;
140}
141
142void FileTarget::updateTime( std::string str )
143{
144 struct stat st;
145 stat( str.c_str(), &st );
146
147 mTimes[str] = st.st_mtime;
89} 148}
90 149
diff --git a/src/filetarget.h b/src/filetarget.h
index c872c0a..856e854 100644
--- a/src/filetarget.h
+++ b/src/filetarget.h
@@ -2,6 +2,10 @@
2#define FILE_TARGET_H 2#define FILE_TARGET_H
3 3
4#include <stdint.h> 4#include <stdint.h>
5#include <map>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <unistd.h>
5#include "target.h" 9#include "target.h"
6 10
7class FileTarget : public Target 11class FileTarget : public Target
@@ -16,9 +20,12 @@ public:
16 20
17 virtual void check( class Builder &bld ); 21 virtual void check( class Builder &bld );
18 virtual void clean( class Builder &bld ); 22 virtual void clean( class Builder &bld );
23
24 time_t getTime( std::string str );
25 void updateTime( std::string str );
19 26
20private: 27private:
21 // start here with the file time cache 28 std::map<std::string, time_t> mTimes;
22 29
23}; 30};
24 31
diff --git a/src/main.cpp b/src/main.cpp
index ebf0cfd..ebfb745 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,12 +1,15 @@
1#include "builder.h" 1#include "builder.h"
2 2
3int main() 3int main( int argc, char *argv[] )
4{ 4{
5 Builder bld; 5 Builder bld;
6 6
7 bld.load("build.conf"); 7 bld.load("build.conf");
8 8
9 bld.build(); 9 if( argc >= 2 )
10 bld.build( argv[1] );
11 else
12 bld.build();
10/* 13/*
11 printf("\n\n----------\nDebug dump\n----------\n"); 14 printf("\n\n----------\nDebug dump\n----------\n");
12 bld.debug();*/ 15 bld.debug();*/
diff --git a/src/perform.cpp b/src/perform.cpp
index d7082a0..c96d70f 100644
--- a/src/perform.cpp
+++ b/src/perform.cpp
@@ -8,3 +8,4 @@ Perform::Perform( const char *sTarget ) :
8Perform::~Perform() 8Perform::~Perform()
9{ 9{
10} 10}
11
diff --git a/src/perform.h b/src/perform.h
index 2eb8cb0..914f3b0 100644
--- a/src/perform.h
+++ b/src/perform.h
@@ -2,6 +2,7 @@
2#define PERFORM_H 2#define PERFORM_H
3 3
4#include <stdint.h> 4#include <stdint.h>
5#include "staticstring.h"
5 6
6class Perform 7class Perform
7{ 8{
diff --git a/src/performcmd.cpp b/src/performcmd.cpp
index 724f42b..d9b7977 100644
--- a/src/performcmd.cpp
+++ b/src/performcmd.cpp
@@ -3,7 +3,7 @@
3 3
4PerformCmd::PerformCmd( const char *sCmd, const char *sTarget ) : 4PerformCmd::PerformCmd( const char *sCmd, const char *sTarget ) :
5 Perform( sTarget ), 5 Perform( sTarget ),
6 sCommand( sCmd ), 6 sCommand( sCmd )
7{ 7{
8} 8}
9 9
diff --git a/src/rule.cpp b/src/rule.cpp
index 979075b..ce37e93 100644
--- a/src/rule.cpp
+++ b/src/rule.cpp
@@ -77,6 +77,7 @@ Perform *Rule::buildCommand( Builder &bld, const char *sCmd, Builder::varmap *va
77 77
78std::list<std::string> Rule::execute( Builder &bld, std::list<std::string> lInput, std::list<Perform *> &lPerf, const char *sTarget ) 78std::list<std::string> Rule::execute( Builder &bld, std::list<std::string> lInput, std::list<Perform *> &lPerf, const char *sTarget )
79{ 79{
80 bld.requiresRegexp( false );
80 std::list<Rule *> lRule = bld.findRuleChain( this ); 81 std::list<Rule *> lRule = bld.findRuleChain( this );
81 /* 82 /*
82 if( !lRule.empty() ) 83 if( !lRule.empty() )
@@ -134,11 +135,21 @@ std::list<std::string> Rule::execute( Builder &bld, std::list<std::string> lInpu
134 revars 135 revars
135 ); 136 );
136 lPerf.push_back( p ); 137 lPerf.push_back( p );
138
139 bld.requires(
140 (*revars)["target"].c_str(),
141 (*revars)["match"].c_str()
142 );
137 } 143 }
138 else if( mHow == matchAll ) 144 else if( mHow == matchAll )
139 { 145 {
140 sMatches += " "; 146 sMatches += " ";
141 sMatches += (*i); 147 sMatches += (*i);
148
149 bld.requires(
150 sTarget,
151 (*i).c_str()
152 );
142 } 153 }
143 } 154 }
144 delete revars; 155 delete revars;