2009-02-27

Rakefile multiplataforma para erlang

Los últimos días estuve programando un toque en Erlang. Como estoy tratando de armar un proyectito algo más en serio, necesito algo como un makefile. Y como los makefiles son un dolor de huevos, decidí que es mejor hacer un rakefile.
Para eso estuve googleando un poco y encontré este post. Que casi resolvía los quilombos, pero le falta poder andar en Windows. Así que lo toquetié un poco para hacerlo multiplataforma.
Las cosas que tuve que hacer son:

  • Usar ruby en vez de llamar a pwd para obtener el path actual.
  • Generar nombres de archivos con back-slashes.
  • Hacer que maneje bien cosas con espacios.
Para obtener el PATH actual hice esto:
PWD = Pathname(".").realpath

Para que el Pathname fuera con backslashes, después de consultarlo con Luis Lavena, monkey-patchié Pathname para que el to_s mande "back-slashes":
#Hack to generate paths with back-slashes
class Pathname
alias_method :old_to_s, :to_s
def to_s
File::ALT_SEPARATOR ? old_to_s.gsub(File::SEPARATOR,File::ALT_SEPARATOR) : old_to_s
end
end

Por último, cambié un toque las llamadas a "sh" para que maneje paths con espacios. Para eso, en vez de pasarle un String le paso un Array por parámetro. Las llamadas quedaron algo así:
sh *%W{erl -switch param1 #{param_calculado}}

Al final, el Rakefile quedó así:

#Based on the Rakefile shown in http://medevyoujane.com/blog/2008/8/21/erlang-make-rake-and-emake.html

require 'rake'
require 'rake/clean'
require 'pathname'

#Hack to generate paths with back-slashes
class Pathname

alias_method :old_to_s, :to_s

def to_s
File::ALT_SEPARATOR ? old_to_s.gsub(File::SEPARATOR,File::ALT_SEPARATOR) : old_to_s
end
end


# Configuration
START_MODULE = "hellman"
TEST_MODULE = "TEST MODULE NOT DEFINED"

# No Need to change
PWD = Pathname(".").realpath
INCLUDE = "include"
ERLC_FLAGS = "-I#{INCLUDE} +warn_unused_vars +warn_unused_import"

SRC = FileList['src/**/*.erl']
OBJ = SRC.pathmap("%{src,ebin}X.beam")
CLEAN.include(['**/*.dump'])
CLOBBER.include(['**/*.beam'])

directory 'ebin'

rule ".beam" => ["%{ebin,src}X.erl"] do |t|
sh *%W{erlc -pa ebin -W #{ERLC_FLAGS} -o ebin #{t.source}}
end

desc "Compile all"
task :compile => ['ebin'] + OBJ

desc "Open up a shell"
task :shell => [:compile] do
sh *%W{erl -sname #{START_MODULE} -pa #{PWD + 'ebin'}}
end


desc "Open up a shell and run #{START_MODULE}:start()"
task :run => [:compile] do
sh *%W{erl -sname #{START_MODULE} -pa #{PWD + 'ebin'} -run #{START_MODULE} start}
end

desc "Run Unit Tests"
task :test do
sh *%W{erl -noshell -s #{TEST_MODULE} test -s init stop}
end

task :default => :compile


Happy jakin,
Aureliano.

3 comentarios:

Francisco dijo...

Qué onda los Bakefiles?

"Bakefile is cross-platform, cross-compiler native makefiles generator. It takes compiler-independent description of build tasks as input and generates native makefile (autoconf's Makefile.in, Visual C++ project, bcc makefile etc.)"

http://www.bakefile.org/

aurelianito dijo...

Los fui a ver por tu comentario.

La verdad es que no me gustaron. Parece un remake del autoconf mezclado con ant. Prefiero el enfoque de hacer un DSL en un lenguaje de scripting antes de escribir scripts en XML.

aurelianito dijo...

Ah! Y generar un generador (autoconf) de un archivo que sirve para generar (makefile) un ejecutable me hace saltar el detector de abstracciones inútiles. Evidentemente hay algún problema ahí.