Eu sugeriria não criar tarefas gerais de depuração e lançamento, se o projeto for realmente algo compilado e resultar em arquivos. Você deve executar tarefas de arquivo, o que é bastante factível no seu exemplo, como você afirma, que sua saída entra em diretórios diferentes. Digamos que seu projeto compila apenas um arquivo test.c para out / debug / test.out e out / release / test.out com o gcc, você pode configurar seu projeto assim:
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]
Essa configuração pode ser usada como:
rake all # (builds debug and release)
rake debug # (builds only debug)
rake release # (builds only release)
Isso faz um pouco mais, conforme solicitado, mas mostra meus pontos:
- os diretórios de saída são criados, conforme necessário.
- os arquivos são recompilados apenas se necessário (este exemplo está correto apenas para os arquivos test.c mais simples).
- você terá todas as tarefas prontamente em mãos se desejar acionar a versão ou depuração.
- este exemplo inclui uma maneira de definir também pequenas diferenças entre depuração e compilações de versão.
- não é necessário reativar uma tarefa de construção parametrizada com uma variável global, porque agora as diferentes construções têm tarefas diferentes. o uso de código da tarefa de construção é feito reutilizando o código para definir as tarefas de construção. veja como o loop não executa a mesma tarefa duas vezes, mas, em vez disso, cria tarefas que podem ser acionadas posteriormente (pela tarefa completa ou pela escolha de uma delas na linha de comando rake).