rant 0.3.6 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/NEWS +13 -0
  2. data/README +7 -1
  3. data/Rantfile +10 -14
  4. data/TODO +3 -0
  5. data/devel-notes +5 -0
  6. data/doc/advanced.rdoc +46 -0
  7. data/doc/c.rdoc +64 -0
  8. data/doc/examples/c_dependencies/Rantfile +27 -0
  9. data/doc/examples/c_dependencies/include/hello.h +7 -0
  10. data/doc/examples/c_dependencies/include/util.h +7 -0
  11. data/doc/examples/c_dependencies/src/main.c +9 -0
  12. data/doc/examples/c_dependencies/src/util.c +9 -0
  13. data/doc/examples/directedrule/Rantfile +0 -1
  14. data/doc/rantfile.rdoc +12 -9
  15. data/doc/rubyproject.rdoc +26 -0
  16. data/lib/rant/c/include.rb +51 -0
  17. data/lib/rant/import/autoclean.rb +16 -9
  18. data/lib/rant/import/c/dependencies.rb +127 -0
  19. data/lib/rant/import/directedrule.rb +8 -4
  20. data/lib/rant/import/rubypackage.rb +2 -1
  21. data/lib/rant/import/subfile.rb +41 -0
  22. data/lib/rant/import/truth.rb +6 -1
  23. data/lib/rant/import/win32/rubycmdwrapper.rb +37 -0
  24. data/lib/rant/import.rb +26 -3
  25. data/lib/rant/rantenv.rb +0 -32
  26. data/lib/rant/rantfile.rb +207 -194
  27. data/lib/rant/rantlib.rb +83 -150
  28. data/lib/rant/rantsys.rb +7 -10
  29. data/lib/rant/rantvar.rb +4 -6
  30. data/lib/rant.rb +57 -0
  31. data/rantmethods.rb +1 -47
  32. data/setup.rb +2 -2
  33. data/test/Rantfile +6 -1
  34. data/test/c/source.c +23 -0
  35. data/test/c/test_parse_includes.rb +41 -0
  36. data/test/import/c/dependencies/Rantfile +34 -0
  37. data/test/import/c/dependencies/bar.h +2 -0
  38. data/test/import/c/dependencies/foo.h +5 -0
  39. data/test/import/c/dependencies/hello.c +7 -0
  40. data/test/import/c/dependencies/include/foo.h +0 -0
  41. data/test/import/c/dependencies/include/sub/sub.h +8 -0
  42. data/test/import/c/dependencies/include/with space.h +7 -0
  43. data/test/import/c/dependencies/src/abc +5 -0
  44. data/test/import/c/dependencies/src/abc.c +5 -0
  45. data/test/import/c/dependencies/src/bar.c +11 -0
  46. data/test/import/c/dependencies/test_c_dependencies.rb +92 -0
  47. data/test/import/c/dependencies/test_on_the_fly.rb +44 -0
  48. data/test/import/directedrule/Rantfile +7 -2
  49. data/test/import/directedrule/test_directedrule.rb +6 -0
  50. data/test/import/subfile/Rantfile +28 -0
  51. data/test/import/subfile/autoclean.rf +16 -0
  52. data/test/import/subfile/test_subfile.rb +91 -0
  53. data/test/import/truth/Rantfile +7 -0
  54. data/test/import/truth/test_truth.rb +3 -0
  55. data/test/project2/buildfile +2 -0
  56. data/test/project2/test_project.rb +5 -3
  57. data/test/rant-import/Rantfile +4 -0
  58. data/test/rant-import/test_rant-import.rb +104 -1
  59. data/test/rule.rf +6 -0
  60. data/test/test_autosubfiletask.rb +59 -0
  61. data/test/test_clean.rb +48 -5
  62. data/test/test_dirtask.rb +45 -1
  63. data/test/test_examples.rb +25 -3
  64. data/test/test_filelist.rb +14 -2
  65. data/test/test_lighttask.rb +4 -6
  66. data/test/test_rant_interface.rb +8 -8
  67. data/test/test_rantfile_api.rb +37 -1
  68. data/test/test_rule.rb +6 -3
  69. data/test/test_source.rb +28 -1
  70. data/test/test_sourcenode.rb +163 -0
  71. data/test/test_task.rb +2 -2
  72. data/test/test_var.rb +3 -3
  73. data/test/tutil.rb +23 -2
  74. metadata +45 -3
  75. data/test/test_metatask.rb +0 -29
data/NEWS CHANGED
@@ -1,6 +1,19 @@
1
1
 
2
2
  = Rant NEWS
3
3
 
4
+ == Rant 0.3.8
5
+
6
+ This version should be fully backwards compatible to 0.3.6.
7
+
8
+ New features:
9
+ * Dependency checking for C/C++ sources.
10
+ Read doc/c.rdoc[link:files/doc/c_rdoc.html] documentation.
11
+ * Installing ".cmd" files on Windows with the Win32::RubyCmdWrapper.
12
+ Read doc/rubyproject.rdoc[link:files/doc/rubyproject_rdoc.html].
13
+ * Convenient directory/file creation with SubFile.
14
+ Read doc/advanced.rdoc[link:files/doc/advanced_rdoc.html].
15
+ * rant-import inlines specially marked, +require+ files.
16
+
4
17
  == Rant 0.3.6
5
18
 
6
19
  This version should be fully backwards compatible to 0.3.4.
data/README CHANGED
@@ -14,6 +14,7 @@ Rant currently features:
14
14
  applications and libraries.
15
15
  * Primitive support for compiling C# sources portably with csc, cscc
16
16
  and mcs.
17
+ * Dependency checking for C/C++ source files.
17
18
  * A _configure_ plugin for easy environment and build-parameter
18
19
  checking (but not like autoconf!) which saves data in a yaml file.
19
20
  * The <em>rant-import</em> command creates a monolithic rant script,
@@ -36,7 +37,7 @@ Running rant in the directory of this file:
36
37
  will ensure that the "data" file in the "backup" directory is up to
37
38
  date.
38
39
 
39
- This document was written for version 0.3.6 of Rant. Most things
40
+ This document was written for version 0.3.8 of Rant. Most things
40
41
  described here will work for older/newer versions of Rant, but look at
41
42
  the README file in the Rant distribution you've installed for exact
42
43
  documentation of your Rant version.
@@ -67,6 +68,10 @@ Automation for your Ruby library/application::
67
68
  read doc/rubyproject.rdoc[link:files/doc/rubyproject_rdoc.html]
68
69
  Independent from Rant? The <tt>rant-import</tt> command::
69
70
  read doc/rant-import.rdoc[link:files/doc/rant-import_rdoc.html]
71
+ Advanced Rantfiles::
72
+ read doc/advanced.rdoc[link:files/doc/advanced_rdoc.html]
73
+ Compiling C/C++::
74
+ read doc/c.rdoc[link:files/doc/c_rdoc.html]
70
75
  Using the Configure plugin::
71
76
  read doc/configure.rdoc[link:files/doc/configure_rdoc.html]
72
77
  Compiling C#::
@@ -196,6 +201,7 @@ Rant was tested on:
196
201
  System Ruby version
197
202
  =======================================================
198
203
  Linux 1.8.2
204
+ 1.8.3 preview 1
199
205
  1.9
200
206
  MacOS X 1.8.2
201
207
  Windows XP 1.8.2 (OneClick Installer)
data/Rantfile CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  # Rantfile for Rant :)
3
3
 
4
- import %w(rubytest rubydoc rubypackage autoclean)
4
+ import %w(rubytest rubydoc rubypackage autoclean win32/rubycmdwrapper)
5
5
 
6
6
  task :default => :test
7
7
 
@@ -70,7 +70,7 @@ desc "Run all tests and generate coverage with rcov."
70
70
  task :cov do
71
71
  lp = File.expand_path "lib"
72
72
  sys.cd "test" do
73
- sys %W(rcov -xts_*,tc_*,test_* -I#{lp} ts_all.rb)
73
+ sys %W(rcov -xtutil.rb,*.t,ts_*,tc_*,test_* -I#{lp} ts_all.rb)
74
74
  end
75
75
  end
76
76
 
@@ -92,6 +92,12 @@ gen RubyTest, :timport do |t|
92
92
  t.test_files = sys["test/import/**/test_*.rb"]
93
93
  end
94
94
 
95
+ desc "Test C support."
96
+ gen RubyTest, :tc do |t|
97
+ t.libs << "test"
98
+ t.test_files = sys["test/c/test_*.rb", "test/import/c/**/test_*.rb"]
99
+ end
100
+
95
101
  desc "Run all tests."
96
102
  gen RubyTest, :tall do |g|
97
103
  g.libs << "test"
@@ -128,22 +134,12 @@ task "to-win" => :package do
128
134
  end
129
135
 
130
136
  desc "Install Rant."
131
- install = task :install do
137
+ task :install do
132
138
  sys.ruby "setup.rb"
133
139
  end
134
140
 
135
141
  if Env.on_windows?
136
- cmd_files = bin_files.find_all { |f| f !~ /\.cmd$/}
137
- cmd_files.map! { |f| "#{f}.cmd" }
138
- cmd_files.zip(bin_files).each { |cmd, bin|
139
- file cmd do |t|
140
- File.open(t.name, "w") { |f|
141
- i_bin = File.join(Env::RUBY_BINDIR, File.basename(bin))
142
- f.puts "@#{sys.sp Env::RUBY} #{sys.sp i_bin} %*"
143
- }
144
- end
145
- install << cmd
146
- }
142
+ enhance :install => (gen Win32::RubyCmdWrapper, sys["bin/*"])
147
143
  end
148
144
 
149
145
  # vim:ft=ruby:
data/TODO CHANGED
@@ -1,6 +1,9 @@
1
1
 
2
2
  = TODO
3
3
 
4
+ == GET RID OF CLASS Rant::Path
5
+ Done.
6
+
4
7
  == Packaging
5
8
  Try minitar if tar is not available.
6
9
 
data/devel-notes CHANGED
@@ -3,6 +3,11 @@
3
3
  Don't use here documents in the Rant sources, imports and plugins.
4
4
  They'll get messed up by the rant-import command.
5
5
 
6
+ == More notes on rant-import
7
+ rant-import removes all lines matching /^\s*#/ per default. Remember
8
+ that, I was already bitten by that one in multiline regex!
9
+ (FileList#mk_all_rx)
10
+
6
11
  == Running RDoc programmatically
7
12
  require 'rdoc/rdoc'
8
13
  rdoc = RDoc::RDoc.new
data/doc/advanced.rdoc CHANGED
@@ -102,6 +102,7 @@ Use the +Clean+ generator in your Rantfiles:
102
102
 
103
103
  Use the +AutoClean+ generator which will remove all files generated by
104
104
  any filetask (include those created by rules):
105
+
105
106
  import "autoclean"
106
107
 
107
108
  file "junk" do
@@ -114,12 +115,39 @@ any filetask (include those created by rules):
114
115
 
115
116
  desc "Cleanup generated files."
116
117
  gen AutoClean, :clean
118
+
117
119
  # The clean task automatically detects which files where created
118
120
  # by our rule and the junk task.
119
121
  # Additionally we can add files to remove to the variable with the
120
122
  # same name as the AutoClean taskname (here: clean):
121
123
  var[:clean].include "**/*.bak"
122
124
 
125
+ TAKE CARE:: AutoClean will recursively remove directories for which
126
+ a task exists. Meaning:
127
+ gen Directory, "doc/html"
128
+ AutoClean will recursively remove the doc directory!
129
+
130
+ The Directory generator takes an optional base directory as first
131
+ argument. Example:
132
+ gen Directory, "doc", "html"
133
+ Now Rant assumes that the "doc" directory already exists and creates
134
+ only a task for the "doc/html" directory. If you run AutoClean now, it
135
+ will only remove the "html" directory.
136
+
137
+ The same goes for the SubFile generator:
138
+
139
+ gen SubFile, "doc/html/index.html" do |t|
140
+ # do something
141
+ end
142
+ This creates (amongst the other two tasks) a task for the "doc"
143
+ directory, thus AutoClean will recursively unlink the "doc" directory.
144
+
145
+ gen SubFile, "doc", "html/index.html" do |t|
146
+ # do something
147
+ end
148
+ This doesn't create a task for the "doc" directory, thus AutoClean
149
+ will only unlink the "doc/html" directory.
150
+
123
151
  === The DirectedRule generator
124
152
 
125
153
  A directed rule is some sort of special rule. It searches for source
@@ -142,6 +170,22 @@ Practically, this means that it compiles the C files in src_x/, src_y,
142
170
  Look in the doc/examples/directedrule directory of the Rant
143
171
  distribution for a small example project.
144
172
 
173
+ === The SubFile generator
174
+
175
+ A _SubFile_ is just a shortcut for the combination of a _Directory_
176
+ and a _file_ task.
177
+ The following example without the SubFile generator:
178
+ gen Directory, "backup"
179
+ file "backup/data" => %w(data backup) do |t|
180
+ sys.cp t.source, t.name
181
+ end
182
+ can be directly translated to:
183
+ gen SubFile, "backup/data" => "data" do |t|
184
+ sys.cp t.source, t.name
185
+ end
186
+ The SubFile generator automatically creates all necessary directory
187
+ tasks and adds them as prerequisites to the final file task.
188
+
145
189
  === Constraining variables
146
190
 
147
191
  Rant allows you to constrain variables which are managed by the +var+
@@ -239,5 +283,7 @@ rant-import.
239
283
 
240
284
  Rantfile basics::
241
285
  doc/rantfile.rdoc[link:files/doc/rantfile_rdoc.html]
286
+ Support for C/C++::
287
+ doc/c.rdoc[link:files/doc/c_rdoc.html]
242
288
  Rant Overview::
243
289
  README[link:files/README.html]
data/doc/c.rdoc ADDED
@@ -0,0 +1,64 @@
1
+
2
+ == Support for C/C++
3
+
4
+ Rant can automatically determine the dependencies between C/C++ source
5
+ files. Use the C::Dependencies generator:
6
+
7
+ import "c/dependencies"
8
+ gen C::Dependencies
9
+
10
+ This generates a task called "c_dependencies" which will scan all
11
+ C/C++ source files in the current directory and all subdirectories for
12
+ #include statements and write the dependencies to the file
13
+ "c_dependencies". It searches for include files in the current
14
+ directory.
15
+
16
+ If you want to specify which directories it should search for include
17
+ files, give the +search+ option:
18
+ gen C::Dependencies, :search => %w(. include)
19
+ Rant will search for include files in the current and in the "include"
20
+ directory now.
21
+
22
+ If you want to create the dependencies only for a specific set of
23
+ source files or for source files with non-standard filename
24
+ extensions, give a list with the +sources+ option:
25
+ gen C::Dependencies, :sources => sys["**/*.cxx"]
26
+ This task will create the dependencies for all files ending in ".cxx".
27
+
28
+ Of course you can combine this options and you can give another
29
+ task/filename as first argument:
30
+ gen C::Dependencies, "depend.rf"
31
+ :search => "include",
32
+ :sources => sys["**/*.cxx"]
33
+ This creates a file task with the name "depend.rf".
34
+
35
+ Note that all our previous examples only created a filetask with the
36
+ dependencies, to use them you have to load them in your Rantfile. So
37
+ you probably want to call the +source+ command:
38
+
39
+ gen C::Dependencies
40
+
41
+ # invoke task "c_dependencies" and load the created file
42
+ source "c_dependencies"
43
+
44
+ And a good habit would be to wrap the +source+ expression in an
45
+ +Action+ block:
46
+
47
+ gen C::Dependencies
48
+
49
+ # Do dependency checking only if at least one task will be
50
+ # invoked.
51
+ gen Action do source "c_dependencies" end
52
+
53
+ For a little example project using the C::Dependency generator look
54
+ into the doc/examples/c_dependencies[link:../examples/c_dependencies]
55
+ directory of the Rant distribution.
56
+
57
+ == See also
58
+
59
+ Rantfile basics::
60
+ doc/rantfile.rdoc[link:files/doc/rantfile_rdoc.html]
61
+ Advanced Rantfiles::
62
+ doc/advanced.rdoc[link:files/doc/advanced_rdoc.html]
63
+ Rant Overview::
64
+ README[link:files/README.html]
@@ -0,0 +1,27 @@
1
+
2
+ import %w(c/dependencies clean autoclean)
3
+
4
+ desc "Compile hello world program."
5
+ file "hello" => %w(src/main.o src/util.o) do |t|
6
+ sys "cc -Wall -o #{t.name} #{t.prerequisites.arglist}"
7
+ end
8
+
9
+ gen Rule, :o => :c do |t|
10
+ sys "cc -Wall -c -Iinclude -o #{t.name} #{t.source}"
11
+ end
12
+
13
+ # Similar to the "makedepend" program:
14
+ # Create dependencies between C/C++ source/header files by parsing them
15
+ # for #include statements. The dependencies will be written to a file
16
+ # called "c_dependencies".
17
+ gen C::Dependencies, :search => "include"
18
+ # Automatically make and load the dependency file before invoking any
19
+ # task.
20
+ gen Action do source "c_dependencies" end
21
+
22
+ desc "Remove C compiler products."
23
+ gen Clean
24
+ var[:clean].include "**/*.o", "hello"
25
+
26
+ desc "Remove all generated files."
27
+ gen AutoClean, :distclean
@@ -0,0 +1,7 @@
1
+
2
+ #ifndef HELLO_H
3
+ #define HELLO_H
4
+
5
+ #define RECEIVER "world"
6
+
7
+ #endif
@@ -0,0 +1,7 @@
1
+
2
+ #ifndef UTIL_H
3
+ #define UTIL_H
4
+
5
+ void println(char* msg);
6
+
7
+ #endif
@@ -0,0 +1,9 @@
1
+
2
+ #include "util.h"
3
+ #include "hello.h"
4
+
5
+ int main(int argc, char** argv)
6
+ {
7
+ println("Hello, " RECEIVER "!");
8
+ return 0;
9
+ }
@@ -0,0 +1,9 @@
1
+
2
+ #include "util.h"
3
+ #include <stdio.h>
4
+
5
+ void println(char* msg)
6
+ {
7
+ printf(msg);
8
+ printf("\n");
9
+ }
@@ -9,7 +9,6 @@ end
9
9
  gen Directory, "obj"
10
10
 
11
11
  ro = gen DirectedRule, "obj" => sys["src_*"], :o => :c do |t|
12
- rac.build "obj"
13
12
  sys "cc -c -o #{t.name} #{t.source}"
14
13
  end
15
14
 
data/doc/rantfile.rdoc CHANGED
@@ -42,7 +42,7 @@ methods with the Rant application:
42
42
  Just call the +task+ function and give it a task name as argument. The
43
43
  task name may be a string or symbol:
44
44
  task :taskname
45
- That's it, your first task. Not very usefull, because it doesn't do
45
+ That's it, your first task. Not very useful, because it doesn't do
46
46
  anything. To associate an action with the task, add a block:
47
47
  task :mytask do
48
48
  puts "Hello, mytask running."
@@ -305,16 +305,19 @@ last dot with the given string.
305
305
 
306
306
  The +import+ function lets you import additional generators.
307
307
  Currently the following are coming with Rant:
308
- +Clean+:: Remove selected files.
309
- +AutoClean+:: Remove all files generated by any file task (including
308
+ Clean:: Remove selected files.
309
+ AutoClean:: Remove all files generated by any file task (including
310
310
  those generated by rules).
311
- +DirectedRule+:: A Rule which takes sources from one or more
312
- directories and puts generated files into a specified
313
- directory.
314
- +RubyTest+:: Run Test::Unit tests for your Ruby code.
315
- +RubyDoc+:: Run RDoc.
316
- +RubyPackage+:: Generate tar, zip and gem packages of your Ruby
311
+ DirectedRule:: A Rule which takes sources from one or more
312
+ directories and puts generated files into a specified
313
+ directory.
314
+ SubFile:: Create file task and necessary directory tasks.
315
+ RubyTest:: Run Test::Unit tests for your Ruby code.
316
+ RubyDoc:: Run RDoc.
317
+ RubyPackage:: Generate tar, zip and gem packages of your Ruby
317
318
  application/library.
319
+ Win32::RubyCmdWrapper:: Create .cmd wrapper scripts for installation
320
+ of Ruby scripts on Windows.
318
321
 
319
322
  Read doc/advanced.rdoc[link:files/doc/advanced_rdoc.html] and
320
323
  doc/rubyproject.rdoc[link:files/doc/rubyproject_rdoc.html] for
data/doc/rubyproject.rdoc CHANGED
@@ -202,6 +202,32 @@ task is run. If you want to see one, set the verbose attribute to
202
202
  +true+:
203
203
  t.verbose = true
204
204
 
205
+ === Installation
206
+
207
+ Since we get a RubyGem from the RubyPackage generator, our package is
208
+ ready for distribution and installation. But probably you also want to
209
+ provide a "normal" zip/tar archive. In this case you can use a
210
+ conventional install.rb or setup.rb script for installation.
211
+
212
+ If we install the "wgrep" script on Windows, it won't run out of the
213
+ box, because Windows doesn't know that it has to run it with the Ruby
214
+ interpreter. This problem can be solved with Rant. Add the following
215
+ lines to your Rantfile:
216
+
217
+ import "win32/rubycmdwrapper"
218
+
219
+ desc "Install wgrep."
220
+ task :install do
221
+ # Run setup.rb with the Ruby interpreter.
222
+ sys.ruby "setup.rb"
223
+ end
224
+
225
+ if Env.on_windows?
226
+ # Create .cmd files for all scripts in the bin/ directory and
227
+ # make the install task dependent on them.
228
+ enhance :install => (gen Win32::RubyCmdWrapper, sys["bin/*"])
229
+ end
230
+
205
231
  == See also
206
232
 
207
233
  Rant Overview::
@@ -0,0 +1,51 @@
1
+
2
+ # include.rb - Support for C - parsing #include statements.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ module Rant end
7
+ module Rant::C
8
+ module Include
9
+ # Searches for all `#include' statements in the C/C++ source
10
+ # from the string +src+.
11
+ #
12
+ # Returns two arguments:
13
+ # 1. A list of all standard library includes (e.g. #include <stdio.h>).
14
+ # 2. A list of all local includes (e.g. #include "stdio.h").
15
+ def parse_includes(src)
16
+ if src.respond_to? :to_str
17
+ src = src.to_str
18
+ else
19
+ raise ArgumentError, "src has to be a string"
20
+ end
21
+ s_includes = []
22
+ l_includes = []
23
+ in_block_comment = false
24
+ prev_line = nil
25
+ src.each { |line|
26
+ line.chomp!
27
+ if prev_line
28
+ line = prev_line << line
29
+ prev_line = nil
30
+ end
31
+ if line =~ /\\$/
32
+ prev_line = line.chomp[0...line.length-1]
33
+ end
34
+ if in_block_comment
35
+ in_block_comment = false if line =~ %r|\*/|
36
+ next
37
+ end
38
+ case line
39
+ when /\s*#\s*include\s+"([^"]+)"/
40
+ l_includes << $1
41
+ when /\s*#\s*include\s+<([^>]+)>/
42
+ s_includes << $1
43
+ when %r|(?!//)[^/]*/\*|
44
+ in_block_comment = true
45
+ end
46
+ }
47
+ [s_includes, l_includes]
48
+ end
49
+ module_function :parse_includes
50
+ end # module Include
51
+ end # module Rant::C
@@ -22,15 +22,13 @@ class Rant::Generators::AutoClean
22
22
  # create task
23
23
  rac.task :__caller__ => ch, tname => [] do |t|
24
24
  rac.tasks.each { |n, worker|
25
- worker.each_target { |entry|
26
- if test ?e, entry
27
- if test ?f, entry
28
- rac.cx.sys.rm_f entry
29
- else
30
- rac.cx.sys.rm_rf entry
31
- end
32
- end
33
- }
25
+ if Array === worker
26
+ worker.each { |subw|
27
+ subw.each_target { |entry| clean rac, entry }
28
+ }
29
+ else
30
+ worker.each_target { |entry| clean rac, entry }
31
+ end
34
32
  }
35
33
  target_rx = nil
36
34
  rac.resolve_hooks.each { |hook|
@@ -62,4 +60,13 @@ class Rant::Generators::AutoClean
62
60
  end
63
61
  end
64
62
  end
63
+ def self.clean(rac, entry)
64
+ if test ?e, entry
65
+ if test ?f, entry
66
+ rac.cx.sys.rm_f entry
67
+ else
68
+ rac.cx.sys.rm_rf entry
69
+ end
70
+ end
71
+ end
65
72
  end
@@ -0,0 +1,127 @@
1
+
2
+ # dependencies.rb - C::Dependencies generator for Rant.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ require 'rant/rantlib'
7
+ require 'rant/c/include'
8
+
9
+ module Rant::Generators::C end
10
+ class Rant::Generators::C::Dependencies
11
+ def self.rant_generate(rac, ch, args, &block)
12
+ c_files, out_fn, include_pathes, opts = nil
13
+ # args validation
14
+ if block
15
+ rac.warn_msg "C::Dependencies: ignoring block"
16
+ end
17
+ case args.size
18
+ when 0 # noop
19
+ when 1
20
+ farg = args.first
21
+ Hash === farg ? (opts = farg) : (out_fn = farg)
22
+ when 2
23
+ out_fn = args.first
24
+ opts = args[1]
25
+ else
26
+ rac.abort_at(ch,
27
+ "C::Dependencies takes one or two arguments.")
28
+ end
29
+ if opts
30
+ if opts.respond_to? :to_hash
31
+ opts = opts.to_hash
32
+ else
33
+ rac.abort_at(ch,
34
+ "C::Dependencies: second argument has to be a hash.")
35
+ end
36
+ opts.each { |k, v|
37
+ case k
38
+ when :sources
39
+ c_files = v
40
+ when :search, :search_pathes, :include_pathes
41
+ include_pathes =
42
+ if v.respond_to? :to_str
43
+ [v.to_str]
44
+ else
45
+ v
46
+ end
47
+ else
48
+ rac.abort_at(ch,
49
+ "C::Dependencies: no such option -- #{k}")
50
+ end
51
+ }
52
+ end
53
+ out_fn ||= "c_dependencies"
54
+ c_files ||= rac.cx.sys["**/*.{c,cpp,cc,h,hpp}"]
55
+ include_pathes ||= ["."]
56
+ if out_fn.respond_to? :to_str
57
+ out_fn = out_fn.to_str
58
+ else
59
+ rac.abort_at(ch, "filename has to be a string")
60
+ end
61
+ unless ::Rant::FileList === c_files
62
+ if c_files.respond_to? :to_ary
63
+ c_files = c_files.to_ary
64
+ else
65
+ rac.abort_at(ch, "sources has to be a list of files")
66
+ end
67
+ end
68
+ unless ::Rant::FileList === include_pathes
69
+ if include_pathes.respond_to? :to_ary
70
+ include_patehs = include_pathes.to_ary
71
+ else
72
+ rac.abort_at(ch,
73
+ "search has to be a list of directories")
74
+ end
75
+ end
76
+ # define file task
77
+ rac.cx.file({:__caller__ => ch, out_fn => c_files}) do |t|
78
+ tmp_rac = ::Rant::RantApp.new
79
+ depfile_ts = Time.at(0)
80
+ if File.exist? t.name
81
+ tmp_rac.source(t.name)
82
+ depfile_ts = File.mtime(t.name)
83
+ end
84
+ rf_str = ""
85
+ c_files.each { |cf|
86
+ f_task = nil
87
+ unless test(?f, cf)
88
+ rac.warn_msg "#{t.name}: no such file -- #{cf}"
89
+ next
90
+ end
91
+ f_task = tmp_rac.tasks[cf.to_str]
92
+ deps = f_task ? f_task.prerequisites : nil
93
+ if !deps or File.mtime(cf) > depfile_ts
94
+ rac.cmd_msg "parsing #{cf}"
95
+ std_includes, local_includes =
96
+ ::Rant::C::Include.parse_includes(File.read(cf))
97
+ deps = []
98
+ (std_includes + local_includes).each { |fn|
99
+ path = existing_file(include_pathes, fn)
100
+ deps << path if path
101
+ }
102
+ end
103
+ rf_str << file_deps(cf, deps) << "\n"
104
+ }
105
+ rac.msg 1, "writing C source dependencies to #{t.name}"
106
+ open(t.name, "w") { |f|
107
+ f.puts
108
+ f.puts "# #{t.name}"
109
+ f.puts "# C source dependencies generated by Rant #{Rant::VERSION}"
110
+ f.puts "# WARNING: Modifications to this file will get lost!"
111
+ f.puts
112
+ f.write rf_str
113
+ }
114
+ end
115
+ end
116
+ def self.existing_file(dirs, fn)
117
+ dirs.each { |dir|
118
+ path = dir == "." ? fn : File.join(dir, fn)
119
+ return path if test ?f, path
120
+ }
121
+ nil
122
+ end
123
+ def self.file_deps(target, deps)
124
+ s = "gen SourceNode, #{target.to_str.inspect} => "
125
+ s << "[#{ deps.map{ |fn| fn.to_str.inspect }.join(', ')}]"
126
+ end
127
+ end # class Rant::Generators::C::Dependencies
@@ -67,7 +67,7 @@ class Rant::Generators::DirectedRule
67
67
  @target_dir = target_dir
68
68
  # target should be a string (file extension)
69
69
  @target = target.sub(/^\./, '')
70
- @target_rx = /#{Regexp.escape(target)}$/o
70
+ @target_rx = /#{Regexp.escape(target)}$/
71
71
  # source should be a string (file extension)
72
72
  @source = source.sub(/^\./, '')
73
73
  @esc_target_dir = Regexp.escape(target_dir)
@@ -77,8 +77,8 @@ class Rant::Generators::DirectedRule
77
77
  self[name]
78
78
  end
79
79
  def [](name)
80
- #puts "rule for #{name} ?"
81
- if name =~ /^#@esc_target_dir\//o && name =~ @target_rx
80
+ #puts "rule (#@target) for #{name} ?"
81
+ if name =~ /^#@esc_target_dir\// && name =~ @target_rx
82
82
  #puts " matches"
83
83
  fn = File.basename(name)
84
84
  src_fn = fn.sub_ext(@source)
@@ -90,7 +90,11 @@ class Rant::Generators::DirectedRule
90
90
  (src = path) && break if test(?e, path)
91
91
  }
92
92
  if src
93
- [@rac.file(:__caller__ => @ch, name => src, &@block)]
93
+ # pre 0.3.7
94
+ #[@rac.file(:__caller__ => @ch, name => src, &@block)]
95
+ [@rac.prepare_task({name => src}, @block, @ch) { |name,pre,blk|
96
+ ::Rant::AutoSubFileTask.new(@rac, name, pre, &blk)
97
+ }]
94
98
  else
95
99
  nil
96
100
  end
@@ -57,7 +57,8 @@ class Rant::Generators::RubyPackage
57
57
  PACKAGE_ATTRS = PACKAGE_SINGLE_ATTRS + PACKAGE_TO_LIST_ATTRS
58
58
 
59
59
  EXPLICIT_GEM_MAPPING = {
60
- "executable" => "executables"
60
+ "executable" => "executables",
61
+ "requires" => "requirements",
61
62
  # add requires => requirements ?
62
63
  }
63
64