rake-builder 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +7 -0
- data/Rakefile +12 -32
- data/lib/rake/builder.rb +219 -42
- data/lib/rake/builder/version.rb +7 -5
- data/lib/rake/local_config.rb +19 -16
- data/lib/rake/microsecond.rb +70 -0
- data/lib/rake/once_task.rb +36 -0
- data/lib/rake/path.rb +12 -2
- data/spec/c_project_spec.rb +12 -5
- data/spec/cpp_project_spec.rb +8 -6
- data/spec/dependencies_spec.rb +138 -16
- data/spec/generated_files_spec.rb +7 -5
- data/spec/libraries_spec.rb +7 -5
- data/spec/local_config_spec.rb +51 -3
- data/spec/logger_spec.rb +2 -1
- data/spec/microsecond_task_spec.rb +32 -0
- data/spec/objective_c_project_spec.rb +9 -3
- data/spec/paths_spec.rb +1 -1
- data/spec/spec_helper.rb +8 -8
- data/spec/target_spec.rb +2 -2
- metadata +145 -74
data/lib/rake/builder/version.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
|
1
|
+
require 'rake/tasklib'
|
2
2
|
|
3
|
-
|
3
|
+
module Rake
|
4
|
+
class Builder < TaskLib
|
4
5
|
|
5
6
|
module VERSION #:nodoc:
|
6
|
-
MAJOR =
|
7
|
-
MINOR =
|
8
|
-
TINY =
|
7
|
+
MAJOR = 0
|
8
|
+
MINOR = 0
|
9
|
+
TINY = 15
|
9
10
|
|
10
11
|
STRING = [ MAJOR, MINOR, TINY ].join('.')
|
11
12
|
end
|
@@ -13,3 +14,4 @@ module Rake
|
|
13
14
|
end
|
14
15
|
|
15
16
|
end
|
17
|
+
|
data/lib/rake/local_config.rb
CHANGED
@@ -4,35 +4,38 @@ module Rake
|
|
4
4
|
|
5
5
|
class LocalConfig
|
6
6
|
|
7
|
-
|
7
|
+
VERSIONS = ['1.0', '1.1']
|
8
|
+
|
9
|
+
attr_accessor :include_paths
|
10
|
+
attr_accessor :compilation_options
|
8
11
|
|
9
12
|
def initialize( file_name )
|
10
|
-
@file_name
|
11
|
-
@
|
12
|
-
|
13
|
+
@file_name = file_name
|
14
|
+
@include_paths = []
|
15
|
+
@compilation_options = []
|
13
16
|
end
|
14
17
|
|
15
18
|
def load
|
16
|
-
|
17
|
-
|
18
|
-
version = @config[ :rake_builder ][ :config_file ][ :version ]
|
19
|
-
raise Rake::Builder::BuilderError.new( 'Config file version missing' ) if version.nil?
|
19
|
+
config = YAML.load_file( @file_name )
|
20
20
|
|
21
|
-
|
21
|
+
version = config[:rake_builder][:config_file][:version]
|
22
|
+
@include_paths = config[:include_paths]
|
23
|
+
@compilation_options = config[:compilation_options]
|
24
|
+
if not VERSIONS.find_index(version)
|
25
|
+
raise Rake::Builder::BuilderError.new('Config file version incorrect')
|
26
|
+
end
|
22
27
|
end
|
23
28
|
|
24
29
|
def save
|
25
30
|
File.open( @file_name, 'w' ) do | file |
|
26
|
-
file.write
|
31
|
+
file.write config.to_yaml
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def include_paths=( include_paths )
|
35
|
-
@config[ :include_paths ] = include_paths
|
35
|
+
def config
|
36
|
+
{ :rake_builder => { :config_file => { :version => VERSIONS[-1] } },
|
37
|
+
:include_paths => @include_paths,
|
38
|
+
:compilation_options => @compilation_options }
|
36
39
|
end
|
37
40
|
|
38
41
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rubygems' if RUBY_VERSION < '1.9'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Rake
|
6
|
+
|
7
|
+
module Microsecond
|
8
|
+
# Compensate for file systems with 1s resolution
|
9
|
+
|
10
|
+
class FileTask < Task
|
11
|
+
|
12
|
+
attr_accessor :timestamp
|
13
|
+
|
14
|
+
def self.define_task( *args, &block )
|
15
|
+
task = super( *args, &block )
|
16
|
+
task.timestamp = nil
|
17
|
+
task
|
18
|
+
end
|
19
|
+
|
20
|
+
def needed?
|
21
|
+
return true if ! File.exist?( self.name )
|
22
|
+
@timestamp = File.stat( self.name ).mtime if @timestamp.nil?
|
23
|
+
return self.prerequisites.any? { | n | ! application[n].timestamp.nil? && application[n].timestamp > @timestamp }
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute(*args)
|
27
|
+
@timestamp = Time.now
|
28
|
+
super(*args)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class DirectoryTask < Task
|
34
|
+
|
35
|
+
include FileUtils
|
36
|
+
|
37
|
+
attr_accessor :timestamp
|
38
|
+
|
39
|
+
def self.define_task( *args, &block )
|
40
|
+
task = super( *args, &block )
|
41
|
+
task.timestamp = nil
|
42
|
+
task
|
43
|
+
end
|
44
|
+
|
45
|
+
def needed?
|
46
|
+
exists = File.directory?( self.name )
|
47
|
+
@timestamp = File.stat( self.name ).mtime if exists
|
48
|
+
! exists
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute(*args)
|
52
|
+
mkdir_p self.name, :verbose => false
|
53
|
+
@timestamp = Time.now
|
54
|
+
super(*args)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def microsecond_file(*args, &block)
|
64
|
+
Rake::Microsecond::FileTask.define_task(*args, &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def microsecond_directory(*args, &block)
|
68
|
+
Rake::Microsecond::DirectoryTask.define_task(*args, &block)
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems' if RUBY_VERSION < '1.9'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
module Rake
|
5
|
+
|
6
|
+
# A task whick is no longer needed after its first invocation
|
7
|
+
class OnceTask < Task
|
8
|
+
|
9
|
+
attr_accessor :invoked
|
10
|
+
attr_accessor :timestamp
|
11
|
+
|
12
|
+
def self.define_task( *args, &block )
|
13
|
+
task = super( *args, &block )
|
14
|
+
task.timestamp = nil
|
15
|
+
task.invoked = false
|
16
|
+
task
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute(*args)
|
20
|
+
@timestamp = Time.now
|
21
|
+
@invoked = true
|
22
|
+
super(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def needed?
|
26
|
+
! @invoked
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def once_task(*args, &block)
|
34
|
+
Rake::OnceTask.define_task(*args, &block)
|
35
|
+
end
|
36
|
+
|
data/lib/rake/path.rb
CHANGED
@@ -32,8 +32,18 @@ module Rake
|
|
32
32
|
paths.map{ |path| expand_with_root( path, root ) }
|
33
33
|
end
|
34
34
|
|
35
|
-
def self.
|
36
|
-
path
|
35
|
+
def self.relative_path( path, prefix, options = {} )
|
36
|
+
return path if prefix.nil?
|
37
|
+
m = path.match( /^#{ prefix }\/?/ )
|
38
|
+
if ! m.nil?
|
39
|
+
if options[ :initial_dot_slash ]
|
40
|
+
"./#{ m.post_match }"
|
41
|
+
else
|
42
|
+
m.post_match
|
43
|
+
end
|
44
|
+
else
|
45
|
+
path
|
46
|
+
end
|
37
47
|
end
|
38
48
|
|
39
49
|
end
|
data/spec/c_project_spec.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
-
|
1
|
+
load File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
3
|
describe 'when building a C project' do
|
4
4
|
|
5
5
|
include RakeBuilderHelper
|
6
6
|
|
7
7
|
before( :all ) do
|
8
|
-
@test_output_file = Rake::Path.expand_with_root( 'rake-c-testfile.txt', SPEC_PATH )
|
8
|
+
@test_output_file = Rake::Path.expand_with_root( 'rake-c-testfile.txt', RakeBuilderHelper::SPEC_PATH )
|
9
9
|
end
|
10
10
|
|
11
11
|
before( :each ) do
|
12
12
|
Rake::Task.clear
|
13
13
|
@project = c_task( :executable )
|
14
|
-
@expected_generated = Rake::Path.expand_all_with_root(
|
14
|
+
@expected_generated = Rake::Path.expand_all_with_root(
|
15
|
+
[
|
16
|
+
'./main.o',
|
17
|
+
@project.makedepend_file, @project.target
|
18
|
+
],
|
19
|
+
RakeBuilderHelper::SPEC_PATH
|
20
|
+
)
|
15
21
|
`rm -f #{ @test_output_file }`
|
16
22
|
`rm -f #{ @project.target }`
|
17
23
|
end
|
@@ -19,14 +25,15 @@ describe 'when building a C project' do
|
|
19
25
|
after( :each ) do
|
20
26
|
Rake::Task[ 'clean' ].invoke
|
21
27
|
`rm -f #{ @test_output_file }`
|
28
|
+
`rm -f '#{ @project.local_config }'`
|
22
29
|
end
|
23
30
|
|
24
|
-
it
|
31
|
+
it "builds the program with 'build'" do
|
25
32
|
Rake::Task[ 'build' ].invoke
|
26
33
|
exist?( @project.target ).should be_true
|
27
34
|
end
|
28
35
|
|
29
|
-
it
|
36
|
+
it "runs the program with 'run'" do
|
30
37
|
Rake::Task[ 'run' ].invoke
|
31
38
|
exist?( @test_output_file ).should be_true
|
32
39
|
end
|
data/spec/cpp_project_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
load File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
3
|
describe 'when building an executable' do
|
4
4
|
|
@@ -6,10 +6,10 @@ describe 'when building an executable' do
|
|
6
6
|
|
7
7
|
before( :all ) do
|
8
8
|
@test_output_file = Rake::Path.expand_with_root(
|
9
|
-
'rake-builder-testfile.txt', SPEC_PATH )
|
9
|
+
'rake-builder-testfile.txt', RakeBuilderHelper::SPEC_PATH )
|
10
10
|
@expected_target = Rake::Path.expand_with_root(
|
11
11
|
RakeBuilderHelper::TARGET[ :executable ],
|
12
|
-
SPEC_PATH )
|
12
|
+
RakeBuilderHelper::SPEC_PATH )
|
13
13
|
end
|
14
14
|
|
15
15
|
before( :each ) do
|
@@ -77,8 +77,8 @@ describe 'when using namespaces' do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'creates the correct tasks' do
|
80
|
-
|
81
|
-
missing_tasks =
|
80
|
+
expected = expected_tasks( scoped_tasks( [ @project.target ], 'my_namespace' ), 'my_namespace' )
|
81
|
+
missing_tasks = expected - task_names
|
82
82
|
missing_tasks.should == []
|
83
83
|
end
|
84
84
|
|
@@ -119,7 +119,9 @@ describe 'when building a shared library' do
|
|
119
119
|
|
120
120
|
before( :each ) do
|
121
121
|
Rake::Task.clear
|
122
|
-
@project = cpp_task( :shared_library )
|
122
|
+
@project = cpp_task( :shared_library ) do |builder|
|
123
|
+
builder.compilation_options += ['-fPIC']
|
124
|
+
end
|
123
125
|
`rm -f #{ @project.target }`
|
124
126
|
end
|
125
127
|
|
data/spec/dependencies_spec.rb
CHANGED
@@ -1,27 +1,141 @@
|
|
1
|
-
|
1
|
+
load File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
describe 'the dependencies system' do
|
4
5
|
|
5
6
|
include RakeBuilderHelper
|
7
|
+
include FileUtils
|
6
8
|
|
7
9
|
before( :each ) do
|
8
10
|
Rake::Task.clear
|
9
11
|
@project = cpp_task( :executable )
|
10
12
|
Rake::Task[ 'clean' ].execute
|
13
|
+
rm_f @project.local_config, :verbose => false
|
11
14
|
end
|
12
15
|
|
13
16
|
after( :each ) do
|
14
17
|
Rake::Task[ 'clean' ].execute
|
15
18
|
end
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
context 'objects_path' do
|
21
|
+
|
22
|
+
it 'should not be needed after being called' do
|
23
|
+
Rake::Task[ @project.objects_path ].invoke
|
24
|
+
|
25
|
+
Rake::Task[ @project.objects_path ].needed?.should be_false
|
26
|
+
end
|
27
|
+
|
20
28
|
end
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
|
30
|
+
context 'missing_headers' do
|
31
|
+
|
32
|
+
it 'should not be needed after being invoked' do
|
33
|
+
Rake::Task[ 'missing_headers' ].needed?.should be_true
|
34
|
+
|
35
|
+
Rake::Task[ 'missing_headers' ].invoke
|
36
|
+
|
37
|
+
Rake::Task[ 'missing_headers' ].needed?.should be_false
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'makedepend_file' do
|
43
|
+
|
44
|
+
it 'should create the makedepend_file' do
|
45
|
+
exist?( @project.makedepend_file ).should be_false
|
46
|
+
|
47
|
+
Rake::Task[ @project.makedepend_file ].invoke
|
48
|
+
|
49
|
+
exist?( @project.makedepend_file ).should be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should not be older than its prerequisites' do
|
53
|
+
t = Rake::Task[ @project.makedepend_file ]
|
54
|
+
|
55
|
+
t.invoke
|
56
|
+
|
57
|
+
stamp = t.timestamp
|
58
|
+
t.prerequisites.any? { |n| t.application[n].timestamp > stamp }.should be_false
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should have all prerequisites satisfied' do
|
62
|
+
t = Rake::Task[ @project.makedepend_file ]
|
63
|
+
|
64
|
+
t.invoke
|
65
|
+
|
66
|
+
t.prerequisites.any? { |n| t.application[n].needed? }.should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should not say the makedepend_file is needed' do
|
70
|
+
t = Rake::Task[ @project.makedepend_file ]
|
71
|
+
|
72
|
+
t.needed?.should be_true
|
73
|
+
|
74
|
+
t.invoke
|
75
|
+
|
76
|
+
t.needed?.should be_false
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'build' do
|
82
|
+
|
83
|
+
before :each do
|
84
|
+
@task = Rake::Task[ 'build' ]
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should have all prerequisites satisfied' do
|
88
|
+
@task.invoke
|
89
|
+
|
90
|
+
@task.prerequisites.any? { |n| @task.application[n].needed? }.should be_false
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should create the makedepend_file' do
|
94
|
+
exist?( @project.makedepend_file ).should be_false
|
95
|
+
|
96
|
+
Rake::Task[ 'build' ].invoke
|
97
|
+
|
98
|
+
exist?( @project.makedepend_file ).should be_true
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should create the target' do
|
102
|
+
Rake::Task[ 'build' ].invoke
|
103
|
+
|
104
|
+
exist?( @project.target ).should be_true
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should say the compile task is up to date' do
|
108
|
+
Rake::Task[ 'build' ].invoke
|
109
|
+
|
110
|
+
Rake::Task[ 'compile' ].needed?.should be_false
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should say the build is up to date' do
|
114
|
+
Rake::Task[ 'build' ].invoke
|
115
|
+
|
116
|
+
Rake::Task[ 'build' ].needed?.should be_false
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should say the makedepend_file is up to date' do
|
120
|
+
exist?( @project.makedepend_file ).should be_false
|
121
|
+
|
122
|
+
isolating_seconds do
|
123
|
+
Rake::Task[ 'build' ].invoke
|
124
|
+
end
|
125
|
+
|
126
|
+
Rake::Task[ @project.makedepend_file ].needed?.should be_false
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should say the target is up to date' do
|
130
|
+
Rake::Task[ 'build' ].invoke
|
131
|
+
|
132
|
+
target_mtime = File.stat( @project.target ).mtime
|
133
|
+
@project.target_prerequisites.each do | prerequisite |
|
134
|
+
File.stat( prerequisite ).mtime.should be < target_mtime
|
135
|
+
end
|
136
|
+
Rake::Task[ @project.target ].needed?.should be_false
|
137
|
+
end
|
138
|
+
|
25
139
|
end
|
26
140
|
|
27
141
|
it 'doesn\'t recompile objects, if nothing changes' do
|
@@ -30,7 +144,7 @@ describe 'the dependencies system' do
|
|
30
144
|
end
|
31
145
|
Rake::Task.clear
|
32
146
|
@project = cpp_task( :executable )
|
33
|
-
object_file_path = Rake::Path.expand_with_root( 'main.o', SPEC_PATH )
|
147
|
+
object_file_path = Rake::Path.expand_with_root( 'main.o', RakeBuilderHelper::SPEC_PATH )
|
34
148
|
Rake::Task[ object_file_path ].needed?.should be_false
|
35
149
|
end
|
36
150
|
|
@@ -40,16 +154,16 @@ describe 'the dependencies system' do
|
|
40
154
|
end
|
41
155
|
Rake::Task.clear
|
42
156
|
@project = cpp_task( :executable )
|
43
|
-
source_file_path = Rake::Path.expand_with_root( 'cpp_project/main.cpp', SPEC_PATH )
|
44
|
-
object_file_path = Rake::Path.expand_with_root( 'main.o', SPEC_PATH )
|
157
|
+
source_file_path = Rake::Path.expand_with_root( 'cpp_project/main.cpp', RakeBuilderHelper::SPEC_PATH )
|
158
|
+
object_file_path = Rake::Path.expand_with_root( 'main.o', RakeBuilderHelper::SPEC_PATH )
|
45
159
|
touching_temporarily( source_file_path, File.mtime( object_file_path ) + 1 ) do
|
46
160
|
Rake::Task[ object_file_path ].needed?.should be_true
|
47
161
|
end
|
48
162
|
end
|
49
163
|
|
50
|
-
it 'recompiles source files, if header dependencies' do
|
51
|
-
header_file_path = Rake::Path.expand_with_root( 'cpp_project/main.h', SPEC_PATH )
|
52
|
-
object_file_path = Rake::Path.expand_with_root( 'main.o', SPEC_PATH )
|
164
|
+
it 'recompiles source files, if header dependencies are more recent' do
|
165
|
+
header_file_path = Rake::Path.expand_with_root( 'cpp_project/main.h', RakeBuilderHelper::SPEC_PATH )
|
166
|
+
object_file_path = Rake::Path.expand_with_root( 'main.o', RakeBuilderHelper::SPEC_PATH )
|
53
167
|
isolating_seconds do
|
54
168
|
Rake::Task[ 'compile' ].invoke
|
55
169
|
end
|
@@ -57,8 +171,10 @@ describe 'the dependencies system' do
|
|
57
171
|
@project = cpp_task( :executable )
|
58
172
|
# Header dependencies aren't loaded until we call :compile
|
59
173
|
Rake::Task[ :load_makedepend ].invoke
|
174
|
+
|
60
175
|
touching_temporarily( header_file_path, File.mtime( object_file_path ) + 1 ) do
|
61
|
-
Rake::Task[ object_file_path ].needed?.
|
176
|
+
Rake::Task[ object_file_path ].needed?.
|
177
|
+
should be_true
|
62
178
|
end
|
63
179
|
end
|
64
180
|
|
@@ -82,11 +198,13 @@ describe 'Rakefile dependencies' do
|
|
82
198
|
Rake::Task[ @project.target ].prerequisites.include?( @project.rakefile ).should be_true
|
83
199
|
end
|
84
200
|
|
85
|
-
# In our case this spec file is the spec_helper
|
86
|
-
# i.e., the file that calls Rake::Builder.new
|
87
201
|
it 'should indicate the target is out of date, if the Rakefile is newer' do
|
88
202
|
Rake::Task[ 'build' ].invoke
|
203
|
+
|
89
204
|
Rake::Task[ @project.target ].needed?.should be_false
|
205
|
+
|
206
|
+
Rake::Task.clear
|
207
|
+
@project = cpp_task( :executable )
|
90
208
|
touching_temporarily( @project.target, File.mtime( @project.rakefile ) - 1 ) do
|
91
209
|
Rake::Task[ @project.target ].needed?.should be_true
|
92
210
|
end
|
@@ -94,7 +212,11 @@ describe 'Rakefile dependencies' do
|
|
94
212
|
|
95
213
|
it 'should indicate that a build is needed if the Rakefile changes' do
|
96
214
|
Rake::Task[ 'build' ].invoke
|
215
|
+
|
97
216
|
Rake::Task[ 'build' ].needed?.should be_false
|
217
|
+
|
218
|
+
Rake::Task.clear
|
219
|
+
@project = cpp_task( :executable )
|
98
220
|
touching_temporarily( @project.target, File.mtime( @project.rakefile ) - 1 ) do
|
99
221
|
Rake::Task[ 'build' ].needed?.should be_true
|
100
222
|
end
|