指定 Rake 任务的文件先决条件

发布于 12-18 13:56 字数 1243 浏览 3 评论 0原文

我有一个帮助程序类,可以扫描整个项目目录并收集源文件列表和相应的(目标)对象文件。扫描源目录后定义编译任务的依赖关系,如下所示。

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 是全局的,因此当调用任何任务(包括 cleanclobber)时,都会调用 DirectoryParser.new()。这会使 cleanclobber 任务变慢,这是不可取的。

为了解决这个问题,我将所有文件依赖项的生成移至默认任务中。这使得我的 cleanclobber 任务变得更快,但是,我现在无法独立调用我的编译或链接任务。

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

我该如何解决这个问题?我确信以前有人遇到过类似的问题。我将不胜感激任何帮助。

I've got a helper class that scans my entire project directory and collects a list of source files and the corresponding (target) object files. The dependencies on the compile task is defined after scanning the source directory as shown below.

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

Since $proj is global, the DirectoryParser.new() is invoked when any of the tasks are called including clean and clobber. This makes the clean and clobber tasks slow and that is not desirable.

To get around the problem I moved all the generation of File dependencies into the default task. This makes my clean and clobber tasks fast, however, I can't call my compile or link tasks independently now.

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

How do I get around this problem? I am sure someone has previously encountered a similar problem. I'd appreciate any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别忘他2024-12-25 13:56:25

我通过使用 Singleton 设计模式并完全放弃使用 Rake 文件/任务依赖项,成功地解决了这个问题。 DirectoryParser 现在是一个单例类(通过混合在 Ruby 的内置“单例”库中)

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

现在我的清理/破坏任务速度很快,而且我仍然可以独立调用编译/链接任务。

I managed to get around this problem elegantly by using the Singleton design pattern and moving away from using Rake file/task dependencies completely. DirectoryParser is now a singleton class (by mixing in Ruby's built-in 'singleton' library)

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

Now my clean/clobber tasks are fast and I can still call compile/link tasks independently.

末が日狂欢2024-12-25 13:56:24

您可以尝试分两步走的方法。

创建一个新任务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

现在您有两个步骤:

  1. 创建一个空的“ generated_dependency.rb”(这样您第一次调用脚本时不会出现错误)
  2. 调用rakegenerate_dependency
  3. 检查生成的文件- 如果不好,请更改生成器;)
  4. 调用rake编译rake链接(或者rake,如果你想使用默认任务)... - 依赖项在生成的文件中定义。

    • 当出现变化(新文件)时,请从第 2 步继续。
    • 如果结构保持不变(没有新文件,仅更改代码),则只需执行第 4 步。

You could try a two step approach.

Create a new task generate_dependencies.
This task builds a (static) rake file with your dependencies and actions.

This generated rakefile can be loaded in your rake file.

Some sample code (untested):

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

Now you have two steps:

  1. create an empty 'generated_dependencies.rb' (so you get no error when you call the script the first time)
  2. call rake generate_dependencies
  3. Check the generated file - if it's not good, change the generator ;)
  4. call rake compile or rake link (or rake if you want to use the default task) ... - the dependencies are defined in the generated file.

    • When something changes (new files), continue from step 2.
    • If the structure stays the same (no new files, only code changes) you need only step 4.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文