Last active
February 2, 2025 06:12
-
-
Save davidm/5125764 to your computer and use it in GitHub Desktop.
Lua makefile generator in < 100 lines of code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Simple Makefile generator in Lua 5.1. | |
With gcc include dependency support. | |
WARNING: proof of concept; not well tested. GNU style Makefile. | |
See premake for a more complete implementation. | |
(c) David Manura, 2013-03. MIT license (same as Lua). | |
--]] | |
local M = {} | |
-- Replaces file name extension on path s with e. Example: ext('foo.c','.o') | |
function M.ext(s, e) return (s:gsub('%.[^%.]+', e)) end | |
-- Convenience list class. | |
local array_mt = {} | |
array_mt.__index = array_mt | |
function array_mt.__add(a, b) | |
local t = {} | |
for _,x in ipairs(a) do t[#t+1] = x end | |
for _,x in ipairs(b) do t[#t+1] = x end | |
return setmetatable(t, array_mt) | |
end | |
function array_mt.ext(self, e) | |
local t = {} | |
for _,x in ipairs(self) do t[#t+1] = M.ext(x, e) end | |
return setmetatable(t, array_mt) | |
end | |
function array_mt:string() return table.concat(self, ' ') end | |
function array_mt.iter(self) | |
local i=0 | |
return function() i = i + 1; return self[i] end | |
end | |
function M.qw(s) -- Perl-like quote operator | |
s = s or '' | |
local t = {} | |
for x in s:gmatch'%S+' do t[#t+1] = x end | |
return setmetatable(t, array_mt) | |
end | |
function M.builder() | |
local preambles = {'# warning: this file is autogenerated'} | |
local postambles = {} | |
local rules = {} | |
local default_rule | |
local all_outputs = M.qw() | |
local phonies = {} | |
local b = {} | |
local function rule_helper(cmd, output, input, default) | |
table.insert(rules, default and 1 or #rules+1, | |
array_mt.string(output)..' : '..array_mt.string(input).. | |
(cmd and '\n\t'..cmd or '')) | |
end | |
function b:rule(cmd, output, input, opt) | |
opt = opt or '' | |
local phony = opt:match'p'; local default = opt:match'd' | |
rule_helper(cmd, output, input, default) | |
if phony then table.insert(phonies, output[1]) | |
else all_outputs = all_outputs + output end | |
end | |
local function helper(t, k, v) if not t[k] then table.insert(t, v); t[k] = #t end end | |
function b:preamble(text, name) helper(preambles, name, text) end | |
function b:postamble(text, name) helper(postambles, name, text) end | |
function b:gcc(gcc, cmd, output, input) | |
b:preamble([[ | |
__MAKEDEPEND=\ | |
@cp $*.d $*.P; \ | |
sed -e 's/\#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ | |
-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \ | |
rm -f $*.d # http://mad-scientist.net/make/autodep.html]], 'gcc') | |
b:rule(gcc .. ' -MD -MF ' .. output[1]:gsub('%.[^%.]+', '.d') | |
.. ' -c -o ' .. output[1] .. ' ' .. input[1] .. ' ' .. cmd .. '\n\t$(__MAKEDEPEND)', | |
output, input) | |
postambles[#postambles+1] = '-include ' .. M.ext(output[1], '.P') | |
all_outputs = all_outputs + {M.ext(output[1], '.P')} | |
end | |
function b:gen_preamble() for _, text in ipairs(preambles) do b:writeln(text) end end | |
function b:gen_postamble() for _, text in ipairs(postambles) do b:writeln(text) end end | |
function b:write(s) io.stdout:write(s) end | |
function b:writeln(s) io.stdout:write(s, '\n') end | |
function b:generate() | |
if #all_outputs > 0 then | |
b:rule('rm -f ' .. array_mt.string(all_outputs), {'clean'}, {}, 'p') end | |
if #phonies > 0 then rule_helper(nil, {'.PHONY'} , phonies) end | |
b:gen_preamble() | |
if default_rule then b:writeln(default_rule) end | |
for _, rule in ipairs(rules) do b:writeln(rule) end | |
b:gen_postamble() | |
end | |
return b | |
end | |
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- test_lua52.lua - Example of building Lua 5.2 using makebuild.lua. | |
local B = dofile 'lmake.lua' | |
local qw = B.qw; local ext = B.ext | |
local CORE_SRC = qw[[ | |
lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c | |
lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c | |
ltm.c lundump.c lvm.c lzio.c | |
]] | |
local LIB_SRC = qw[[ | |
lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c | |
lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c | |
]] | |
local BASE_SRC = CORE_SRC + LIB_SRC | |
local ALL_SRC = BASE_SRC + qw'lua.c luac.c' | |
local b = B.builder() | |
for src in ALL_SRC:iter() do | |
b:gcc('gcc', '', {ext(src, '.o')}, {src}) | |
end | |
b:rule('ar rcu liblua.a '..BASE_SRC:ext('.o'):string(), {'liblua.a'}, BASE_SRC:ext('.o')) | |
b:rule('gcc -o lua lua.c liblua.a -lm', {'lua'}, {'lua.c', 'liblua.a'}) | |
b:rule('gcc -o luac luac.c liblua.a -lm', {'luac'}, {'luac.c', 'liblua.a'}) | |
b:rule(nil, {'all'}, {'lua'}, 'dp') | |
b:generate() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# example output of running test_lua52.lua | |
# warning: this file is autogenerated | |
__MAKEDEPEND=\ | |
@cp $*.d $*.P; \ | |
sed -e 's/\#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ | |
-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \ | |
rm -f $*.d # http://mad-scientist.net/make/autodep.html | |
all : lua | |
lapi.o : lapi.c | |
gcc -MD -MF lapi.d -c -o lapi.o lapi.c | |
$(__MAKEDEPEND) | |
lcode.o : lcode.c | |
gcc -MD -MF lcode.d -c -o lcode.o lcode.c | |
$(__MAKEDEPEND) | |
lctype.o : lctype.c | |
gcc -MD -MF lctype.d -c -o lctype.o lctype.c | |
$(__MAKEDEPEND) | |
ldebug.o : ldebug.c | |
gcc -MD -MF ldebug.d -c -o ldebug.o ldebug.c | |
$(__MAKEDEPEND) | |
ldo.o : ldo.c | |
gcc -MD -MF ldo.d -c -o ldo.o ldo.c | |
$(__MAKEDEPEND) | |
ldump.o : ldump.c | |
gcc -MD -MF ldump.d -c -o ldump.o ldump.c | |
$(__MAKEDEPEND) | |
lfunc.o : lfunc.c | |
gcc -MD -MF lfunc.d -c -o lfunc.o lfunc.c | |
$(__MAKEDEPEND) | |
lgc.o : lgc.c | |
gcc -MD -MF lgc.d -c -o lgc.o lgc.c | |
$(__MAKEDEPEND) | |
llex.o : llex.c | |
gcc -MD -MF llex.d -c -o llex.o llex.c | |
$(__MAKEDEPEND) | |
lmem.o : lmem.c | |
gcc -MD -MF lmem.d -c -o lmem.o lmem.c | |
$(__MAKEDEPEND) | |
lobject.o : lobject.c | |
gcc -MD -MF lobject.d -c -o lobject.o lobject.c | |
$(__MAKEDEPEND) | |
lopcodes.o : lopcodes.c | |
gcc -MD -MF lopcodes.d -c -o lopcodes.o lopcodes.c | |
$(__MAKEDEPEND) | |
lparser.o : lparser.c | |
gcc -MD -MF lparser.d -c -o lparser.o lparser.c | |
$(__MAKEDEPEND) | |
lstate.o : lstate.c | |
gcc -MD -MF lstate.d -c -o lstate.o lstate.c | |
$(__MAKEDEPEND) | |
lstring.o : lstring.c | |
gcc -MD -MF lstring.d -c -o lstring.o lstring.c | |
$(__MAKEDEPEND) | |
ltable.o : ltable.c | |
gcc -MD -MF ltable.d -c -o ltable.o ltable.c | |
$(__MAKEDEPEND) | |
ltm.o : ltm.c | |
gcc -MD -MF ltm.d -c -o ltm.o ltm.c | |
$(__MAKEDEPEND) | |
lundump.o : lundump.c | |
gcc -MD -MF lundump.d -c -o lundump.o lundump.c | |
$(__MAKEDEPEND) | |
lvm.o : lvm.c | |
gcc -MD -MF lvm.d -c -o lvm.o lvm.c | |
$(__MAKEDEPEND) | |
lzio.o : lzio.c | |
gcc -MD -MF lzio.d -c -o lzio.o lzio.c | |
$(__MAKEDEPEND) | |
lauxlib.o : lauxlib.c | |
gcc -MD -MF lauxlib.d -c -o lauxlib.o lauxlib.c | |
$(__MAKEDEPEND) | |
lbaselib.o : lbaselib.c | |
gcc -MD -MF lbaselib.d -c -o lbaselib.o lbaselib.c | |
$(__MAKEDEPEND) | |
lbitlib.o : lbitlib.c | |
gcc -MD -MF lbitlib.d -c -o lbitlib.o lbitlib.c | |
$(__MAKEDEPEND) | |
lcorolib.o : lcorolib.c | |
gcc -MD -MF lcorolib.d -c -o lcorolib.o lcorolib.c | |
$(__MAKEDEPEND) | |
ldblib.o : ldblib.c | |
gcc -MD -MF ldblib.d -c -o ldblib.o ldblib.c | |
$(__MAKEDEPEND) | |
liolib.o : liolib.c | |
gcc -MD -MF liolib.d -c -o liolib.o liolib.c | |
$(__MAKEDEPEND) | |
lmathlib.o : lmathlib.c | |
gcc -MD -MF lmathlib.d -c -o lmathlib.o lmathlib.c | |
$(__MAKEDEPEND) | |
loslib.o : loslib.c | |
gcc -MD -MF loslib.d -c -o loslib.o loslib.c | |
$(__MAKEDEPEND) | |
lstrlib.o : lstrlib.c | |
gcc -MD -MF lstrlib.d -c -o lstrlib.o lstrlib.c | |
$(__MAKEDEPEND) | |
ltablib.o : ltablib.c | |
gcc -MD -MF ltablib.d -c -o ltablib.o ltablib.c | |
$(__MAKEDEPEND) | |
loadlib.o : loadlib.c | |
gcc -MD -MF loadlib.d -c -o loadlib.o loadlib.c | |
$(__MAKEDEPEND) | |
linit.o : linit.c | |
gcc -MD -MF linit.d -c -o linit.o linit.c | |
$(__MAKEDEPEND) | |
lua.o : lua.c | |
gcc -MD -MF lua.d -c -o lua.o lua.c | |
$(__MAKEDEPEND) | |
luac.o : luac.c | |
gcc -MD -MF luac.d -c -o luac.o luac.c | |
$(__MAKEDEPEND) | |
liblua.a : lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o | |
ar rcu liblua.a lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o | |
lua : lua.c liblua.a | |
gcc -o lua lua.c liblua.a -lm | |
luac : luac.c liblua.a | |
gcc -o luac luac.c liblua.a -lm | |
clean : | |
rm -f lapi.o lapi.P lcode.o lcode.P lctype.o lctype.P ldebug.o ldebug.P ldo.o ldo.P ldump.o ldump.P lfunc.o lfunc.P lgc.o lgc.P llex.o llex.P lmem.o lmem.P lobject.o lobject.P lopcodes.o lopcodes.P lparser.o lparser.P lstate.o lstate.P lstring.o lstring.P ltable.o ltable.P ltm.o ltm.P lundump.o lundump.P lvm.o lvm.P lzio.o lzio.P lauxlib.o lauxlib.P lbaselib.o lbaselib.P lbitlib.o lbitlib.P lcorolib.o lcorolib.P ldblib.o ldblib.P liolib.o liolib.P lmathlib.o lmathlib.P loslib.o loslib.P lstrlib.o lstrlib.P ltablib.o ltablib.P loadlib.o loadlib.P linit.o linit.P lua.o lua.P luac.o luac.P liblua.a lua luac | |
.PHONY : all clean | |
-include lapi.P | |
-include lcode.P | |
-include lctype.P | |
-include ldebug.P | |
-include ldo.P | |
-include ldump.P | |
-include lfunc.P | |
-include lgc.P | |
-include llex.P | |
-include lmem.P | |
-include lobject.P | |
-include lopcodes.P | |
-include lparser.P | |
-include lstate.P | |
-include lstring.P | |
-include ltable.P | |
-include ltm.P | |
-include lundump.P | |
-include lvm.P | |
-include lzio.P | |
-include lauxlib.P | |
-include lbaselib.P | |
-include lbitlib.P | |
-include lcorolib.P | |
-include ldblib.P | |
-include liolib.P | |
-include lmathlib.P | |
-include loslib.P | |
-include lstrlib.P | |
-include ltablib.P | |
-include loadlib.P | |
-include linit.P | |
-include lua.P | |
-include luac.P |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment