[Luarocks-developers] rockspec-to-Makefile converter

David Manura dm.lua at math2.org
Fri Sep 4 22:43:21 GMT+3 2009


At bottom is an initial implementation of a rockspec-to-Makefile
converter.  This is a "build script generator" in the pattern of
cmake.

As an example, http://luarocks.luaforge.net/rocks/lpeg-0.9-1.rockspec
is translated to

  all : lpeg.so
  lpeg.o : lpeg.c
  lpeg.so : lpeg.o
          $(CC) -shared $< -o $@ $(LDFLAGS) -llua
  $(LIBDIR)/lpeg.so : lpeg.so
          install -D $< $@
  $(LUADIR)/re.lua : re.lua
          install -D $< $@
  install : $(LIBDIR)/lpeg.so $(LUADIR)/re.lua

This may allay some criticism from those who may prefer familiar
Makefiles to .rockspec files or don't want to add LuaRocks to their
build toolchain (see recent lua-l discussion on luamc).  It may also
be used as a pattern for generating alternative methods of
compilation.  For example, one may adapt this to statically link
modules to lua.c.

I don't have particular need for this myself, so feel free to extend
it as you see fit.

<snip>

-- rockspec2make.lua
-- Initial implementation of rockspec-to-Makefile converter.
-- Warning: This is only an initial proof-of-concept. Use at own risk.
-- David Manura. May be incorporated into LuaRocks.
-- Licensed under the same terms as LuaRocks, www.luarocks.org

local fname = ...
if not fname then
  print "usage: rockspec2make <rockspec>"
  os.exit(1)
end

-- Load rockspec into table.
local function loadrockspec(fname)
  local _G = _G
  local f = assert(_G.loadfile(fname))
  local t = {}
  setfenv(f, t)
  f()
  return t
end

-- Convert module name into module relative path
local function modname_to_path(name, ext)
  ext = ext or '.lua'
  local path = name:gsub("%.", "/") .. ext
  return path
end

-- Translate.
local makefile = ''
local targets = {}
local installtargets = {}
local rspec = loadrockspec(fname)
if rspec.build and rspec.build.type == "module" then
  local modules = rspec.build.modules
  if modules then
    for modname, deps in pairs(modules) do
      local function build_c(deps)
        local target = modname:gsub("%.", "_") -- TODO:IMPROVE
        makefile = makefile .. target .. ".o : " .. table.concat(deps,
" ") .. "\n"
        makefile = makefile .. target .. ".so : " .. target .. ".o\n"
        makefile = makefile .. "\t" .. "$(CC) -shared $< -o $@
$(LDFLAGS) -llua\n"
        table.insert(targets, target .. ".so")
        local installtarget = "$(LIBDIR)/" .. modname_to_path(modname, '.so')
        makefile = makefile .. installtarget .. " : " .. target .. ".so\n" ..
                   "\tinstall -D $< $@\n"
        table.insert(installtargets, installtarget)
      end

      if type(deps) == "string" then
        if deps:match("%.lua$") then
          local installtarget = "$(LUADIR)/" .. modname_to_path(modname)
          makefile = makefile .. installtarget .. " : " .. deps .. "\n" ..
                     "\tinstall -D $< $@\n"
          table.insert(installtargets, installtarget)
        elseif deps:match("%.c$") then
          build_c({deps})
        else
          error("unrecognized format")
        end
      elseif type(deps) == "table" and type(deps[1]) == "string" then
        build_c(deps)
      elseif type(deps) == "table" then
        error("TODO:NO IMPL")
      else
        error("unrecognized format")
      end
    end
  end
else
  print "can't translate"
  os.exit(1)
end
makefile = "all : " .. table.concat(targets, " ") .. "\n"
           .. makefile
makefile = makefile .. "install : " .. table.concat(installtargets, " ") .. "\n"

io.stdout:write(makefile)

</snip>



More information about the Luarocks-developers mailing list