rakefile.rdoc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. = Rakefile Format (as of version 0.8.7)
  2. First of all, there is no special format for a Rakefile. A Rakefile
  3. contains executable Ruby code. Anything legal in a ruby script is
  4. allowed in a Rakefile.
  5. Now that we understand there is no special syntax in a Rakefile, there
  6. are some conventions that are used in a Rakefile that are a little
  7. unusual in a typical Ruby program. Since a Rakefile is tailored to
  8. specifying tasks and actions, the idioms used in a Rakefile are
  9. designed to support that.
  10. So, what goes into a Rakefile?
  11. == Tasks
  12. Tasks are the main unit of work in a Rakefile. Tasks have a name
  13. (usually given as a symbol or a string), a list of prerequisites (more
  14. symbols or strings) and a list of actions (given as a block).
  15. === Simple Tasks
  16. A task is declared by using the +task+ method. +task+ takes a single
  17. parameter that is the name of the task.
  18. task :name
  19. === Tasks with Prerequisites
  20. Any prerequisites are given as a list (enclosed in square brackets)
  21. following the name and an arrow (=>).
  22. task :name => [:prereq1, :prereq2]
  23. <b>NOTE:</b> Although this syntax looks a little funky, it is legal
  24. Ruby. We are constructing a hash where the key is :name and the value
  25. for that key is the list of prerequisites. It is equivalent to the
  26. following ...
  27. hash = Hash.new
  28. hash[:name] = [:prereq1, :prereq2]
  29. task(hash)
  30. === Tasks with Actions
  31. Actions are defined by passing a block to the +task+ method. Any Ruby
  32. code can be placed in the block. The block may reference the task
  33. object via the block parameter.
  34. task :name => [:prereq1, :prereq2] do |t|
  35. # actions (may reference t)
  36. end
  37. === Multiple Definitions
  38. A task may be specified more than once. Each specification adds its
  39. prerequisites and actions to the existing definition. This allows one
  40. part of a rakefile to specify the actions and a different rakefile
  41. (perhaps separately generated) to specify the dependencies.
  42. For example, the following is equivalent to the single task
  43. specification given above.
  44. task :name
  45. task :name => [:prereq1]
  46. task :name => [:prereq2]
  47. task :name do |t|
  48. # actions
  49. end
  50. == File Tasks
  51. Some tasks are designed to create a file from one or more other files.
  52. Tasks that generate these files may be skipped if the file already
  53. exists. File tasks are used to specify file creation tasks.
  54. File tasks are declared using the +file+ method (instead of the +task+
  55. method). In addition, file tasks are usually named with a string
  56. rather than a symbol.
  57. The following file task creates a executable program (named +prog+)
  58. given two object files name <tt>a.o</tt> and <tt>b.o</tt>. The tasks
  59. for creating <tt>a.o</tt> and <tt>b.o</tt> are not shown.
  60. file "prog" => ["a.o", "b.o"] do |t|
  61. sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
  62. end
  63. == Directory Tasks
  64. It is common to need to create directories upon demand. The
  65. +directory+ convenience method is a short-hand for creating a FileTask
  66. that creates the directory. For example, the following declaration
  67. ...
  68. directory "testdata/examples/doc"
  69. is equivalent to ...
  70. file "testdata" do |t| mkdir t.name end
  71. file "testdata/examples" do |t| mkdir t.name end
  72. file "testdata/examples/doc" do |t| mkdir t.name end
  73. The +directory+ method does not accept prerequisites or actions, but
  74. both prerequisites and actions can be added later. For example ...
  75. directory "testdata"
  76. file "testdata" => ["otherdata"]
  77. file "testdata" do
  78. cp Dir["standard_data/*.data"], "testdata"
  79. end
  80. == Tasks with Parallel Prerequisites
  81. Rake allows parallel execution of prerequisites using the following syntax:
  82. multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do
  83. puts "All Copies Complete"
  84. end
  85. In this example, +copy_files+ is a normal rake task. Its actions are
  86. executed whenever all of its prerequisites are done. The big
  87. difference is that the prerequisites (+copy_src+, +copy_bin+ and
  88. +copy_doc+) are executed in parallel. Each of the prerequisites are
  89. run in their own Ruby thread, possibly allowing faster overall runtime.
  90. === Secondary Prerequisites
  91. If any of the primary prerequisites of a multitask have common secondary
  92. prerequisites, all of the primary/parallel prerequisites will wait
  93. until the common prerequisites have been run.
  94. For example, if the <tt>copy_<em>xxx</em></tt> tasks have the
  95. following prerequisites:
  96. task :copy_src => [:prep_for_copy]
  97. task :copy_bin => [:prep_for_copy]
  98. task :copy_doc => [:prep_for_copy]
  99. Then the +prep_for_copy+ task is run before starting all the copies in
  100. parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+,
  101. and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is
  102. run only once, even though it is referenced in multiple threads.
  103. === Thread Safety
  104. The Rake internal data structures are thread-safe with respect
  105. to the multitask parallel execution, so there is no need for the user
  106. to do extra synchronization for Rake's benefit. However, if there are
  107. user data structures shared between the parallel prerequisites, the
  108. user must do whatever is necessary to prevent race conditions.
  109. == Tasks with Arguments
  110. Prior to version 0.8.0, rake was only able to handle command line
  111. arguments of the form NAME=VALUE that were passed into Rake via the
  112. ENV hash. Many folks had asked for some kind of simple command line
  113. arguments, perhaps using "--" to separate regular task names from
  114. argument values on the command line. The problem is that there was no
  115. easy way to associate positional arguments on the command line with
  116. different tasks. Suppose both tasks :a and :b expect a command line
  117. argument: does the first value go with :a? What if :b is run first?
  118. Should it then get the first command line argument.
  119. Rake 0.8.0 solves this problem by explicitly passing values directly
  120. to the tasks that need them. For example, if I had a release task
  121. that required a version number, I could say:
  122. rake release[0.8.2]
  123. And the string "0.8.2" will be passed to the :release task. Multiple
  124. arguments can be passed by separating them with a comma, for example:
  125. rake name[john,doe]
  126. Just a few words of caution. The rake task name and its arguments
  127. need to be a single command line argument to rake. This generally
  128. means no spaces. If spaces are needed, then the entire rake +
  129. argument string should be quoted. Something like this:
  130. rake "name[billy bob, smith]"
  131. (Quoting rules vary between operating systems and shells, so make sure
  132. you consult the proper docs for your OS/shell).
  133. === Tasks Arguments and the Environment
  134. Task argument values can also be picked up from the environment. For
  135. example, if the "release" task expected a parameter named
  136. "release_version", then either
  137. rake release[0.8.2]
  138. or
  139. RELEASE_VERSION rake release
  140. will work. Environment variable names must either match the task
  141. parameter exactly, or match an all-uppercase version of the task
  142. parameter.
  143. === Tasks that Expect Parameters
  144. Parameters are only given to tasks that are setup to expect them. In
  145. order to handle named parameters, the task declaration syntax for
  146. tasks has been extended slightly.
  147. For example, a task that needs a first name and last name might be
  148. declared as:
  149. task :name, [:first_name, :last_name]
  150. The first argument is still the name of the task (:name in this case).
  151. The next two arguments are the names of the parameters expected by
  152. :name in an array (:first_name and :last_name in the example).
  153. To access the values of the parameters, the block defining the task
  154. behaviour can now accept a second parameter:
  155. task :name, [:first_name, :last_name] do |t, args|
  156. puts "First name is #{args.first_name}"
  157. puts "Last name is #{args.last_name}"
  158. end
  159. The first argument of the block "t" is always bound to the current
  160. task object. The second argument "args" is an open-struct like object
  161. that allows access to the task arguments. Extra command line
  162. arguments to a task are ignored. Missing command line arguments are
  163. picked up from matching environment variables. If there are no
  164. matching environment variables, they are given the nil value.
  165. If you wish to specify default values for the arguments, you can use
  166. the with_defaults method in the task body. Here is the above example
  167. where we specify default values for the first and last names:
  168. task :name, [:first_name, :last_name] do |t, args|
  169. args.with_defaults(:first_name => "John", :last_name => "Dough")
  170. puts "First name is #{args.first_name}"
  171. puts "Last name is #{args.last_name}"
  172. end
  173. === Tasks that Expect Parameters and Have Prerequisites
  174. Tasks that use parameters have a slightly different format for
  175. prerequisites. Use the arrow notation to indicate the prerequisites
  176. for tasks with arguments. For example:
  177. task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
  178. args.with_defaults(:first_name => "John", :last_name => "Dough")
  179. puts "First name is #{args.first_name}"
  180. puts "Last name is #{args.last_name}"
  181. end
  182. === Deprecated Task Parameters Format
  183. There is an older format for declaring task parameters that omitted
  184. the task argument array and used the :needs keyword to introduce the
  185. dependencies. That format is still supported for compatibility, but
  186. is not recommended for use. The older format may be dropped in future
  187. versions of rake.
  188. == Accessing Task Programmatically
  189. Sometimes it is useful to manipulate tasks programmatically in a
  190. Rakefile. To find a task object, use the <tt>:[]</tt> operator on the
  191. <tt>Rake::Task</tt>.
  192. === Programmatic Task Example
  193. For example, the following Rakefile defines two tasks. The :doit task
  194. simply prints a simple "DONE" message. The :dont class will lookup
  195. the doit class and remove (clear) all of its prerequisites and
  196. actions.
  197. task :doit do
  198. puts "DONE"
  199. end
  200. task :dont do
  201. Rake::Task[:doit].clear
  202. end
  203. Running this example:
  204. $ rake doit
  205. (in /Users/jim/working/git/rake/x)
  206. DONE
  207. $ rake dont doit
  208. (in /Users/jim/working/git/rake/x)
  209. $
  210. The ability to programmatically manipulate tasks gives rake very
  211. powerful meta-programming capabilities w.r.t. task execution, but
  212. should be used with cation.
  213. == Rules
  214. When a file is named as a prerequisite, but does not have a file task
  215. defined for it, Rake will attempt to synthesize a task by looking at a
  216. list of rules supplied in the Rakefile.
  217. Suppose we were trying to invoke task "mycode.o", but no task is
  218. defined for it. But the rakefile has a rule that look like this ...
  219. rule '.o' => ['.c'] do |t|
  220. sh "cc #{t.source} -c -o #{t.name}"
  221. end
  222. This rule will synthesize any task that ends in ".o". It has a
  223. prerequisite a source file with an extension of ".c" must exist. If
  224. Rake is able to find a file named "mycode.c", it will automatically
  225. create a task that builds "mycode.o" from "mycode.c".
  226. If the file "mycode.c" does not exist, rake will attempt
  227. to recursively synthesize a rule for it.
  228. When a task is synthesized from a rule, the +source+ attribute of the
  229. task is set to the matching source file. This allows us to write
  230. rules with actions that reference the source file.
  231. === Advanced Rules
  232. Any regular expression may be used as the rule pattern. Additionally,
  233. a proc may be used to calculate the name of the source file. This
  234. allows for complex patterns and sources.
  235. The following rule is equivalent to the example above.
  236. rule( /\.o$/ => [
  237. proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') }
  238. ]) do |t|
  239. sh "cc #{t.source} -c -o #{t.name}"
  240. end
  241. <b>NOTE:</b> Because of a _quirk_ in Ruby syntax, parenthesis are
  242. required on *rule* when the first argument is a regular expression.
  243. The following rule might be used for Java files ...
  244. rule '.java' => [
  245. proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') }
  246. ] do |t|
  247. java_compile(t.source, t.name)
  248. end
  249. <b>NOTE:</b> +java_compile+ is a hypothetical method that invokes the
  250. java compiler.
  251. == Importing Dependencies
  252. Any ruby file (including other rakefiles) can be included with a
  253. standard Ruby +require+ command. The rules and declarations in the
  254. required file are just added to the definitions already accumulated.
  255. Because the files are loaded _before_ the rake targets are evaluated,
  256. the loaded files must be "ready to go" when the rake command is
  257. invoked. This make generated dependency files difficult to use. By
  258. the time rake gets around to updating the dependencies file, it is too
  259. late to load it.
  260. The +Rake.import+ command addresses this by specifying a file to be
  261. loaded _after_ the main rakefile is loaded, but _before_ any targets
  262. on the command line are invoked. In addition, if the file name
  263. matches an explicit task, that task is invoked before loading the
  264. file. This allows dependency files to be generated and used in a
  265. single rake command invocation.
  266. <b>NOTE:</b> Starting in Rake version 0.9.0, the top level +import+
  267. command is deprecated and we recommend using the scoped
  268. "+Rake.import+" command mentioned above. Future versions of Rake will
  269. drop support for the top level +import+ command.
  270. === Example:
  271. require 'rake/loaders/makefile'
  272. file ".depends.mf" => [SRC_LIST] do |t|
  273. sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}"
  274. end
  275. Rake.import ".depends.mf"
  276. If ".depends" does not exist, or is out of date w.r.t. the source
  277. files, a new ".depends" file is generated using +makedepend+ before
  278. loading.
  279. == Comments
  280. Standard Ruby comments (beginning with "#") can be used anywhere it is
  281. legal in Ruby source code, including comments for tasks and rules.
  282. However, if you wish a task to be described using the "-T" switch,
  283. then you need to use the +desc+ command to describe the task.
  284. === Example:
  285. desc "Create a distribution package"
  286. task :package => [ ... ] do ... end
  287. The "-T" switch (or "--tasks" if you like to spell things out) will
  288. display a list of tasks that have a description. If you use +desc+ to
  289. describe your major tasks, you have a semi-automatic way of generating
  290. a summary of your Rake file.
  291. traken$ rake -T
  292. (in /home/.../rake)
  293. rake clean # Remove any temporary products.
  294. rake clobber # Remove any generated file.
  295. rake clobber_rdoc # Remove rdoc products
  296. rake contrib_test # Run tests for contrib_test
  297. rake default # Default Task
  298. rake install # Install the application
  299. rake lines # Count lines in the main rake file
  300. rake rdoc # Build the rdoc HTML Files
  301. rake rerdoc # Force a rebuild of the RDOC files
  302. rake test # Run tests
  303. rake testall # Run all test targets
  304. Only tasks with descriptions will be displayed with the "-T" switch.
  305. Use "-P" (or "--prereqs") to get a list of all tasks and their
  306. prerequisites.
  307. == Namespaces
  308. As projects grow (and along with it, the number of tasks), it is
  309. common for task names to begin to clash. For example, if you might
  310. have a main program and a set of sample programs built by a single
  311. Rakefile. By placing the tasks related to the main program in one
  312. namespace, and the tasks for building the sample programs in a
  313. different namespace, the task names will not will not interfere with
  314. each other.
  315. For example:
  316. namespace "main" do
  317. task :build do
  318. # Build the main program
  319. end
  320. end
  321. namespace "samples" do
  322. task :build do
  323. # Build the sample programs
  324. end
  325. end
  326. task :build => ["main:build", "samples:build"]
  327. Referencing a task in a separate namespace can be achieved by
  328. prefixing the task name with the namespace and a colon
  329. (e.g. "main:build" refers to the :build task in the +main+ namespace).
  330. Nested namespaces are supported, so
  331. Note that the name given in the +task+ command is always the unadorned
  332. task name without any namespace prefixes. The +task+ command always
  333. defines a task in the current namespace.
  334. === FileTasks
  335. File task names are not scoped by the namespace command. Since the
  336. name of a file task is the name of an actual file in the file system,
  337. it makes little sense to include file task names in name space.
  338. Directory tasks (created by the +directory+ command) are a type of
  339. file task and are also not affected by namespaces.
  340. === Name Resolution
  341. When looking up a task name, rake will start with the current
  342. namespace and attempt to find the name there. If it fails to find a
  343. name in the current namespace, it will search the parent namespaces
  344. until a match is found (or an error occurs if there is no match).
  345. The "rake" namespace is a special implicit namespace that refers to
  346. the toplevel names.
  347. If a task name begins with a "^" character, the name resolution will
  348. start in the parent namespace. Multiple "^" characters are allowed.
  349. Here is an example file with multiple :run tasks and how various names
  350. resolve in different locations.
  351. task :run
  352. namespace "one" do
  353. task :run
  354. namespace "two" do
  355. task :run
  356. # :run => "one:two:run"
  357. # "two:run" => "one:two:run"
  358. # "one:two:run" => "one:two:run"
  359. # "one:run" => "one:run"
  360. # "^run" => "one:run"
  361. # "^^run" => "rake:run" (the top level task)
  362. # "rake:run" => "rake:run" (the top level task)
  363. end
  364. # :run => "one:run"
  365. # "two:run" => "one:two:run"
  366. # "^run" => "rake:run"
  367. end
  368. # :run => "rake:run"
  369. # "one:run" => "one:run"
  370. # "one:two:run" => "one:two:run"
  371. == FileLists
  372. FileLists are the way Rake manages lists of files. You can treat a
  373. FileList as an array of strings for the most part, but FileLists
  374. support some additional operations.
  375. === Creating a FileList
  376. Creating a file list is easy. Just give it the list of file names:
  377. fl = FileList['file1.rb', file2.rb']
  378. Or give it a glob pattern:
  379. fl = FileList['*.rb']
  380. == Odds and Ends
  381. === do/end versus { }
  382. Blocks may be specified with either a +do+/+end+ pair, or with curly
  383. braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the
  384. actions for tasks and rules. Because the rakefile idiom tends to
  385. leave off parentheses on the task/file/rule methods, unusual
  386. ambiguities can arise when using curly braces.
  387. For example, suppose that the method +object_files+ returns a list of
  388. object files in a project. Now we use +object_files+ as the
  389. prerequisites in a rule specified with actions in curly braces.
  390. # DON'T DO THIS!
  391. file "prog" => object_files {
  392. # Actions are expected here (but it doesn't work)!
  393. }
  394. Because curly braces have a higher precedence than +do+/+end+, the
  395. block is associated with the +object_files+ method rather than the
  396. +file+ method.
  397. This is the proper way to specify the task ...
  398. # THIS IS FINE
  399. file "prog" => object_files do
  400. # Actions go here
  401. end
  402. ----
  403. == See
  404. * README.rdoc -- Main documentation for Rake.