我有一个帮助程序类,它扫描整个项目目录并收集源文件列表和相应的(目标)目标文件。扫描源目录后定义编译任务的依赖关系,如下所示。
CLEAN.include(FileList[obj_dir + '**/*.o'])
CLOBBER.include(FileList[exe_dir + '**/*.exe'])
$proj = DirectoryParser.new(src_dir)
$proj.source_files.each do |source_file|
file source_file.obj_file do
sh "gcc -c ..."
end
end
$proj.obj_files.each do |obj_file|
task :compile => obj_file
end
task :compile do
end
由于$proj
是全局的,因此在调用包括clean
和clobber
的任何任务时会调用DirectoryParser.new()。这使得clean
和clobber
任务变慢,这是不可取的。
为了解决这个问题,我将所有生成的File依赖项都移到了默认任务中。这使我的clean
和clobber
任务变得很快,但是,我现在无法单独调用我的编译或链接任务。
CLEAN.include(FileList[obj_dir + '**/*.o'])
CLOBBER.include(FileList[exe_dir + '**/*.exe'])
task :compile => $proj.source_files do # Throws error!
end
task :default => do
$proj = DirectoryParser.new(src_dir)
$proj.source_files.each do |source_file|
file source_file.obj_file do
sh "gcc -c ..."
end
end
$proj.obj_files.each do |obj_file|
task :compile => obj_file
end
... compile
... link
... execute
end
如何解决这个问题?我相信有人之前遇到过类似的问题。我很感激任何帮助。
答案 0 :(得分:3)
您可以尝试两步法。
创建新任务generate_dependencies
。
此任务使用您的依赖项和操作构建(静态)rake文件。
这个生成的rakefile可以加载到你的rake文件中。
一些示例代码(未经测试):
GENERATED = 'generated_dependencies.rb'
task :generate_dependencies do
$proj = DirectoryParser.new(src_dir)
File.open(GENERATED, 'w') do |f|
$proj.source_files.each do |source_file|
f << <<-code
file #{source_file.obj_file} do
sh "gcc -c " #etc.
end
code
end
$proj.obj_files.each do |obj_file|
f << "task :compile => #{obj_file}"
end
#~ ... compile
#~ ... link
#~ ... execute
end
end
require GENERATED
现在您有两个步骤:
rake generate_dependencies
调用rake compile
或rake link
(或rake
如果您要使用默认任务)... - 依赖项在生成的文件中定义。
答案 1 :(得分:0)
我设法通过使用Singleton设计模式并完全不使用Rake文件/任务依赖关系来优雅地解决这个问题。 DirectoryParser现在是一个单例类(通过混合Ruby的内置'singleton'库)
CLEAN.include(FileList[obj_dir + '**/*.o'])
CLOBBER.include(FileList[exe_dir + '**/*.exe'])
task :compile do
$proj = DirectoryParser.instance
$proj.source_files.each do |source_file|
sh "gcc -c ..." unless uptodate?(obj_file, source_file)
end
end
task :link do
$proj = DirectoryParser.instance
...
end
现在我的clean / clobber任务很快,我仍然可以独立调用编译/链接任务。