teapot 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NjhkODU0M2VmNzc4OWQwMGQzNGYyZTU4MzM0NTBjMWU1MTMxYmRjNg==
4
+ ZTQyYjk5NWYwZDFhYTJiMmZjOWEzYmE3MGY2ODM2YTBhM2I5NTU2Ng==
5
5
  data.tar.gz: !binary |-
6
- MmFiZDE4M2VlNGJkNzgyYWY4MDk4ZDI1YjMzNmJlNjZhZDJjY2Q5Mg==
6
+ N2NhM2YzMWViNGNjMGVkNWZlMjZmNDMxNzM2NDNhMWU0N2Y5ZmQ4ZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- Y2ExNjk4YzUwM2UyM2QxYTYyOWIzZWQ2OTVlOGQyYWU0NTk4MTU3MWNlMDQ4
10
- NTczNDgyZTA5YjdmNTljYTQ0MTM4ZTRmMzA1NjAyMzVjY2IzZWRmNGEyODVj
11
- MmE3ZjU5ZjAyZDVmNWQwMjc0MmNkNWQzMjE4NzAwODg1NGZlZWY=
9
+ OTRmYmYzN2M4YzRhYmJmMGE5MTY0ZDdlYmI1MGQyMjRhZWYxMzQ2OTg3ODQx
10
+ ODg3ZTFhYWE2NDBkNzcwYTYzNzlmODRlNGQ2ZTZkYWJiZGE5OTc0ZWQ4N2Yz
11
+ Njk0YjYzNzliMjkyZDdmNDE1NGZjZmM1MThmNWZjZmQ3OWRlMjk=
12
12
  data.tar.gz: !binary |-
13
- ZjRlOTE3MmIxOGYxY2ZiZmI0MTg1N2RjZWRjODM5MzRmMGM2MzMyN2YwZDk5
14
- MzYwM2E1YWQ2NjY0ZDg3YjY2MmYxYjEyMDNlNTFiNDkwNjVjMTY0OTQxOTcx
15
- ZTRlYmE1ZmVjYzFjNmMxZWRkMjFlMzhjNjg1ZDAyZDE3MGYwN2I=
13
+ NmNjMGYyNjlkNTY4YmI5YmI5YmI3YmIzYWJiNTRiODFlMzc2M2U0MmYwOWQ2
14
+ MmI0ZTM2N2M3NTE2ZjFiYWE1NWJmYTlkMzdlZTIyNDUxYTM2MzIwYmFlMThk
15
+ MzUwYjU0ZDBjMTdkZjMwNDhiMzdmM2E1NzAyNzA1YmJiODAxNmE=
@@ -59,7 +59,7 @@ module Teapot
59
59
  @parts.each do |path|
60
60
  full_path = @root + path
61
61
 
62
- FileUtils.cp_r(full_path.children, source_path.to_s)
62
+ FileUtils.cp_r(full_path.children, source_path.to_s, :preserve => true)
63
63
  end
64
64
 
65
65
  return source_path
@@ -58,7 +58,7 @@ module Teapot
58
58
  destination_path.dirname.mkpath
59
59
 
60
60
  # Copy the file to the destination:
61
- FileUtils.cp path, destination_path
61
+ FileUtils.cp(path, destination_path, :preserve => true)
62
62
  end
63
63
  end
64
64
  end
@@ -0,0 +1,50 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'pathname'
22
+
23
+ require 'teapot/graph'
24
+ require 'teapot/extractors/preprocessor_extractor'
25
+
26
+ module Teapot
27
+ module Build
28
+ @@graphs = {}
29
+
30
+ def self.dependency_graph(environment)
31
+ @@graphs.fetch(environment) do
32
+ graph = Graph.new
33
+
34
+ buildflags = environment[:buildflags]
35
+ roots = Extractors::PreprocessorExtractor.include_directories(buildflags)
36
+
37
+ # At some point, it would be nice if this process could be driven by environment configuration:
38
+ patterns = [
39
+ /\.c(c|pp)?$/,
40
+ /\.h(pp)?$/,
41
+ /\.mm?/
42
+ ]
43
+
44
+ graph.extractors << Extractors::PreprocessorExtractor.new(patterns, roots)
45
+
46
+ @@graphs[environment] = graph
47
+ end
48
+ end
49
+ end
50
+ end
@@ -56,21 +56,21 @@ module Teapot
56
56
 
57
57
  return instance
58
58
  end
59
-
59
+
60
60
  def execute(command, environment, *arguments)
61
61
  if @configure
62
62
  environment = environment.merge &@configure
63
63
  end
64
-
64
+
65
65
  # Flatten the environment to a hash:
66
- values = environment.flatten
67
-
66
+ flat_environment = environment.flatten
67
+
68
68
  puts "Performing #{self.class}/#{command} for #{root}...".color(:cyan)
69
-
69
+
70
70
  # Show the environment to the user:
71
- Environment::System::dump(values)
72
-
73
- self.send(command, values, *arguments)
71
+ Environment::System::dump(flat_environment)
72
+
73
+ self.send(command, flat_environment, *arguments)
74
74
  end
75
75
  end
76
76
  end
@@ -20,6 +20,8 @@
20
20
 
21
21
  require 'pathname'
22
22
 
23
+ require 'teapot/build/graph'
24
+
23
25
  module Teapot
24
26
  module Build
25
27
  module Targets
@@ -40,12 +42,13 @@ module Teapot
40
42
  return prefix
41
43
  end
42
44
 
43
- def compile(environment, root, source_file, commands)
44
- object_file = (build_prefix!(environment) + source_file).sub_ext('.o')
45
-
45
+ def compile!(environment, root, source_file, object_file, commands)
46
46
  # Ensure there is a directory for the output file:
47
47
  object_file.dirname.mkpath
48
-
48
+
49
+ # Make sure there is no pre-existing object file
50
+ object_file.rmtree if object_file.exist?
51
+
49
52
  case source_file.extname
50
53
  when ".cpp", ".mm"
51
54
  commands.run(
@@ -60,8 +63,19 @@ module Teapot
60
63
  "-c", root + source_file, "-o", object_file
61
64
  )
62
65
  end
63
-
64
- return Array object_file
66
+ end
67
+
68
+ def compile(environment, root, source_file, commands)
69
+ object_file = (build_prefix!(environment) + source_file).sub_ext('.o')
70
+
71
+ # The graph is recreated once per file. This could be improved.
72
+ graph = Build::dependency_graph(environment)
73
+
74
+ if graph.regenerate?(object_file, root + source_file)
75
+ compile!(environment, root, source_file, object_file, commands)
76
+ end
77
+
78
+ return object_file
65
79
  end
66
80
  end
67
81
  end
@@ -31,13 +31,17 @@ module Teapot
31
31
  def link(environment, objects)
32
32
  executable_file = link_prefix!(environment) + @name
33
33
 
34
- Commands.run(
35
- environment[:cxx],
36
- environment[:cxxflags],
37
- "-o", executable_file, objects,
38
- environment[:ldflags]
39
- )
40
-
34
+ graph = Build::dependency_graph(environment)
35
+
36
+ if graph.regenerate?(executable_file, objects)
37
+ Commands.run(
38
+ environment[:cxx],
39
+ environment[:cxxflags],
40
+ "-o", executable_file, objects,
41
+ environment[:ldflags]
42
+ )
43
+ end
44
+
41
45
  return executable_file
42
46
  end
43
47
  end
@@ -58,7 +58,7 @@ module Teapot
58
58
  if !build_source_path.exist?
59
59
  build_source_path.mkpath
60
60
 
61
- FileUtils.cp_r(source_path.children, build_source_path.to_s)
61
+ FileUtils.cp_r(source_path.children, build_source_path.to_s, :preserve => true)
62
62
 
63
63
  # Write the environment checksum out to a file:
64
64
  File.write(build_source_checksum_path, checksum(values))
@@ -23,6 +23,8 @@ require 'teapot/build/targets/directory'
23
23
  require 'teapot/build/targets/files'
24
24
  require 'teapot/build/targets/compiler'
25
25
 
26
+ require 'teapot/build/graph'
27
+
26
28
  require 'fileutils'
27
29
 
28
30
  module Teapot
@@ -48,8 +50,12 @@ module Teapot
48
50
  def link(environment, objects)
49
51
  library_file = link_prefix!(environment) + "lib#{@name}.a"
50
52
 
51
- Linker.link_static(environment, library_file, objects)
52
-
53
+ graph = Build::dependency_graph(environment)
54
+
55
+ if graph.regenerate?(library_file, objects)
56
+ Linker.link_static(environment, library_file, objects)
57
+ end
58
+
53
59
  return library_file
54
60
  end
55
61
 
@@ -75,7 +81,7 @@ module Teapot
75
81
  destination_path = prefix + file_list.prefix + relative_path
76
82
 
77
83
  destination_path.dirname.mkpath
78
- FileUtils.cp path, destination_path
84
+ FileUtils.cp(path, destination_path, :preserve => true)
79
85
  end
80
86
  end
81
87
 
@@ -87,7 +93,7 @@ module Teapot
87
93
 
88
94
  destination_path.dirname.mkpath
89
95
 
90
- FileUtils.cp path, destination_path
96
+ FileUtils.cp(path, destination_path, :preserve => true)
91
97
  end
92
98
 
93
99
  if self.respond_to? :headers
@@ -39,7 +39,7 @@ module Teapot
39
39
  if @parent
40
40
  @parent.flatten_to_hash(hash)
41
41
  end
42
-
42
+
43
43
  @values.each do |key, value|
44
44
  previous = hash[key]
45
45
 
@@ -57,6 +57,5 @@ module Teapot
57
57
  end
58
58
  end
59
59
  end
60
-
61
60
  end
62
61
  end
@@ -0,0 +1,62 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'teapot/graph'
22
+
23
+ module Teapot
24
+ module Extractors
25
+ class PreprocessorExtractor < Graph::Extractor
26
+ def self.include_directories(flags)
27
+ roots = []
28
+
29
+ # Extract include directories:
30
+ flags.each do |option|
31
+ if option.to_s =~ /^-I(.+)/
32
+ roots << Pathname($1)
33
+ end
34
+ end
35
+
36
+ return roots
37
+ end
38
+
39
+ def initialize(patterns, roots = [])
40
+ super patterns
41
+
42
+ @roots = roots
43
+ end
44
+
45
+ def extract(path)
46
+ local_root = Pathname(path).dirname
47
+
48
+ File.open(path).each do |line|
49
+ if line =~ /\#(?:include|import) "(.*?)"/
50
+ path = local_root + $1
51
+
52
+ yield path if path.exist?
53
+ elsif line =~ /\#(?:include|import) \<(.*?)\>/
54
+ path = @roots.collect{|root| root+$1}.find{|path| path.exist?}
55
+
56
+ yield path if path
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,134 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'set'
22
+ require 'pathname'
23
+
24
+ module Teapot
25
+ class Graph
26
+ def initialize
27
+ @nodes = {}
28
+
29
+ @extractors = []
30
+ end
31
+
32
+ attr :root
33
+ attr :nodes
34
+ attr :extractors
35
+
36
+ def << node
37
+ @nodes[node.path] = node
38
+ end
39
+
40
+ def regenerate?(output_path, input_paths)
41
+ return true unless output_path.exist?
42
+
43
+ output_modified_time = output_path.mtime
44
+
45
+ Array(input_paths).each do |path|
46
+ node = fetch(path)
47
+
48
+ return true if node.changed_since?(output_modified_time)
49
+ end
50
+
51
+ return false
52
+ end
53
+
54
+ def extract(source_path)
55
+ dependencies = Set.new
56
+
57
+ @extractors.each do |extractor|
58
+ extractor.call(source_path) do |path|
59
+ dependencies << path
60
+ end
61
+ end
62
+
63
+ nodes = dependencies.map{|path| fetch(path)}
64
+ end
65
+
66
+ def fetch(path)
67
+ @nodes.fetch(path) do
68
+ node = @nodes[path] = Node.new(self, path)
69
+ node.extract_dependencies!
70
+
71
+ node
72
+ end
73
+ end
74
+
75
+ class Node
76
+ def initialize(graph, path)
77
+ @graph = graph
78
+
79
+ @path = Pathname(path)
80
+
81
+ @dependencies = []
82
+
83
+ @changed = nil
84
+ end
85
+
86
+ attr :path
87
+ attr :dependencies
88
+
89
+ def changed_since?(modified_time)
90
+ if @changed == nil
91
+ # If the file was modified in the future relative to old modified_time:
92
+ if @path.mtime > modified_time
93
+ puts "Changed: #{path.to_s.inspect}"
94
+ return @changed = true
95
+ else
96
+ @changed = false
97
+ end
98
+
99
+ # If any of the file's dependencies have changed relative to the old modified_time:
100
+ @dependencies.each do |dependency|
101
+ if dependency.changed_since?(modified_time)
102
+ return @changed = true
103
+ end
104
+ end
105
+ end
106
+
107
+ return @changed
108
+ end
109
+
110
+ def extract_dependencies!
111
+ @dependencies = @graph.extract(path)
112
+ end
113
+ end
114
+
115
+ class Extractor
116
+ def initialize(patterns = [])
117
+ @patterns = Array(patterns)
118
+ end
119
+
120
+ def extract(path)
121
+ end
122
+
123
+ def call(path, &block)
124
+ return unless path.exist?
125
+
126
+ basename = path.basename.to_s
127
+
128
+ if @patterns.find{|pattern| pattern.match(basename)}
129
+ extract(path, &block)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Teapot
22
- VERSION = "0.7.1"
22
+ VERSION = "0.7.2"
23
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teapot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-27 00:00:00.000000000 Z
11
+ date: 2013-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -86,6 +86,7 @@ files:
86
86
  - lib/teapot/build.rb
87
87
  - lib/teapot/build/component.rb
88
88
  - lib/teapot/build/file_list.rb
89
+ - lib/teapot/build/graph.rb
89
90
  - lib/teapot/build/linker.rb
90
91
  - lib/teapot/build/target.rb
91
92
  - lib/teapot/build/targets/application.rb
@@ -113,7 +114,9 @@ files:
113
114
  - lib/teapot/environment/evaluator.rb
114
115
  - lib/teapot/environment/flatten.rb
115
116
  - lib/teapot/environment/system.rb
117
+ - lib/teapot/extractors/preprocessor_extractor.rb
116
118
  - lib/teapot/generator.rb
119
+ - lib/teapot/graph.rb
117
120
  - lib/teapot/loader.rb
118
121
  - lib/teapot/name.rb
119
122
  - lib/teapot/package.rb