I have a Rakefile that compiles the project in two ways based on the global variable $build_type, which can be debug or: release (the result goes to a different directory):
task :build => [:some_other_tasks] do end
I want to create a task that compiles the two configurations of the project in turn, as follows:
task :build_all do [ :debug, :release ].each do |t| $build_type = t # call task :build with all the tasks it depends on (?) end end
Is there a way to call a task a method?Or how can I achieve similar results?
#1st floor
If you need to use tasks as a method, what about using the actual method?
task :build => [:some_other_tasks] do build end task :build_all do [:debug, :release].each { |t| build t } end def build(type = :debug) # ... end
If you prefer to stick to rake's idioms, write your possibilities based on past answers:
-
This always performs tasks, but it does not perform its dependencies:
Rake::Task["build"].execute
-
This execution dependency, but it only executes tasks without being invoked:
Rake::Task["build"].invoke
-
This first resets the already_invoked state of the task, then executes the task again, dependencies and all:
Rake::Task["build"].reenable Rake::Task["build"].invoke
(Note that dependencies that have been invoked will not be reexecuted)
#2nd floor
If you want each task to run regardless of any failure, you can do the following:
task :build_all do [:debug, :release].each do |t| ts = 0 begin Rake::Task["build"].invoke(t) rescue ts = 1 next ensure Rake::Task["build"].reenable # If you need to reenable end return ts # Return exit code 1 if any failed, 0 if all success end end
#3rd floor
I recommend not creating generic debugging and publishing tasks if the project is really compiled and results in files.You should use a file task that is very workable in your example, and as you mentioned, your output will go to a different directory.Assuming your project only compiles test.c files as out/debug/test.out and out/release/test.out using gcc, you can set up your project like this:
WAYS = ['debug', 'release'] FLAGS = {} FLAGS['debug'] = '-g' FLAGS['release'] = '-O' def out_dir(way) File.join('out', way) end def out_file(way) File.join(out_dir(way), 'test.out') end WAYS.each do |way| desc "create output directory for #{way}" directory out_dir(way) desc "build in the #{way}-way" file out_file(way) => [out_dir(way), 'test.c'] do |t| sh "gcc #{FLAGS[way]} -c test.c -o #{t.name}" end end desc 'build all ways' task :all => WAYS.map{|way|out_file(way)} task :default => [:all]
This setting can be used as follows:
rake all # (builds debug and release) rake debug # (builds only debug) rake release # (builds only release)
This requires more, but it shows my point of view:
- Create output directory if necessary.
- Recompile the file only if necessary (this example only applies to the simplest test.c file).
- If you want to trigger a release or debug version, you can have all the tasks at any time.
- This example contains a way to define small differences between debug and release versions.
- There is no need to re-enable construction tasks that use global variables for parameterization, since different builds now have different tasks.Code reuse for build tasks is accomplished by reusing code to define build tasks.See how the loop does not perform the same task twice, but instead creates a task that can be triggered later (either by all tasks or by selecting one on the rake command line).
#4th floor
task :invoke_another_task do # some code Rake::Task["another:task"].invoke end
#5th floor
task :build_all do [ :debug, :release ].each do |t| $build_type = t Rake::Task["build"].execute end end