1
function rfind(s, what)
4
n = string.find(s, what, p)
15
for ext in string.gfind(s, "%.%a+$") do
16
return string.sub(ext, 2)
27
return string.sub(s,1,string.len(s)-string.len(file_ext(s))-1)
33
return string.sub(s,1,n)
38
function str_replace(s, pattern, what)
39
return string.gsub(s, pattern, function(v) return what end)
42
function flattern_table(collection, t)
43
for i,v in ipairs(t) do
44
if type(v) == type({}) then
45
flattern_table(collection, v)
46
elseif type(v) == type("") then
47
table.insert(collection, v)
52
function collect_input(a)
54
flattern_table(inputs, a)
59
function tbl_to_str(tbl, prefix, postfix)
61
for index,value in ipairs(tbl) do
62
if type(value) == type("") then
63
s = s .. prefix .. value .. postfix
71
function PathFilename(path)
74
return string.sub(path,n+1)
81
t.add = function(self, ...)
82
for i,what in ipairs(arg) do
83
table.insert(self, what)
89
function NewPathTable()
91
t.add = function(self, value)
92
table.insert(self, Path(value))
97
function NewAntiPathTable()
99
t.add = function(self, value)
101
table.insert(self, PathFilename(value))
107
function default_intermediate_output_func(dir, input, extension)
108
if not (dir == "") then
109
return Path(dir .. "/" .. PathBase(PathFilename(input)) .. extension)
111
return PathBase(input) .. extension
114
function default_link_output_func(dir, input, extension)
115
if not (dir == "") then
116
return Path(dir .. "/" .. PathFilename(input) .. extension)
118
return Path(input) .. extension
121
function table.copy(self, ud_copy_fn)
122
ud_copy_fn = ud_copy_fn or function ( ud ) return ud end
125
for key, value in self do
127
if(type(key) == 'table') then
128
new_key = table.copy(key, ud_copy_fn)
129
elseif (type(key) == 'userdata') then
130
new_key = ud_copy_fn(key)
136
if(type( value ) == 'table' ) then
137
new_value = table.copy(value, ud_copy_fn)
138
elseif(type(value) == 'userdata') then
139
new_value = ud_copy_fn(value)
144
new_table[new_key] = new_value
150
function table.lock(t)
152
if not mt then mt = {} end
153
mt.__newindex = function(t, key, value)
154
error("trying to create key '" .. key .. "' on a locked table")
159
function NewSettings()
172
s.cc.c_compiler = "gcc"
173
s.cc.cxx_compiler = "g++"
175
s.cc.includes = NewPathTable()
176
s.cc.defines = NewTable()
177
s.cc.frameworks = NewTable()
178
s.cc.output = default_intermediate_output_func
180
s.cc._propagate = function(cc, s)
183
s.cc._propagate(s.cc, s)
186
s.linker.linker = "g++"
187
s.linker.inputflags = ""
189
s.linker.libs = NewTable()
190
s.linker.frameworks = NewTable()
191
s.linker.frameworkpath = NewPathTable()
192
s.linker.libpath = NewPathTable()
193
s.linker.extrafiles = NewPathTable()
194
s.linker.output = default_intermediate_output_func
195
s.linker._propagate = function(linker, s)
196
linker.debug = s.debug
198
s.linker._propagate(s.linker, s)
202
s.lib.output = default_intermediate_output_func
203
s.lib._propagate = function(lib, s)
206
s.lib._propagate(s.lib, s)
210
s.dll.inputflags = ""
212
s.dll.libs = NewTable()
213
s.dll.frameworks = NewTable()
214
s.dll.frameworkpath = NewPathTable()
215
s.dll.libpath = NewPathTable()
216
s.dll.extrafiles = NewPathTable()
217
s.dll.output = default_intermediate_output_func
218
s.dll._propagate = function(dll, s)
221
s.dll._propagate(s.dll, s)
223
if family == "windows" then
224
s.cc.extension = ".obj"
225
s.linker.extension = ".exe"
226
s.lib.extension = ".lib"
227
s.dll.extension = ".dll"
229
s.cc.extension = ".o"
230
s.linker.extension = ""
231
s.lib.extension = ".a"
232
if platform == "macosx" then
233
s.dll.extension = ".dylib"
235
s.dll.extension = ".so"
249
function Collect(...)
251
for i,what in ipairs(arg) do
252
directory = file_path(what)
253
pattern = string.sub(what, string.len(directory)+1)
254
pattern = str_replace(pattern, "%.", "%.")
255
pattern = str_replace(pattern, "%*", ".*")
256
pattern = pattern .. "$"
257
k = CollectAdv(bam_path_fix(directory), pattern)
258
for index,value in k do
259
table.insert(f,value)
265
function CollectAdv(directory, pattern)
266
local d = support.listdir(directory)
269
if string.find(v,pattern) then
276
function copy(output, input)
277
print("copy " .. PathFilename(output))
280
if family == "windows" then
281
copy_command = "copy"
282
input = str_replace(input, "/", "\\")
283
output = str_replace(output, "/", "\\")
288
os.execute(copy_command .. " " .. input .. " " .. output)
292
function Copy(outputdir, ...)
293
local inputs = collect_input(arg)
296
-- compile all the files
297
for index, inname in inputs do
298
output = Path(outputdir .. "/" .. PathFilename(inname))
300
bam_add_job("copy", output, input)
301
bam_add_dependency(output, input)
302
table.insert(outputs, output)
308
function Compile(settings, ...)
309
local inputs = collect_input(arg)
312
settings.cc:_propagate(settings);
314
-- compile all the files
315
for index, inname in inputs do
317
-- fetch correct compiler
318
ext = file_ext(inname)
320
if ext == "cpp" then compiler = "cxx" end
321
if ext == "c++" then compiler = "cxx" end
322
if ext == "cxx" then compiler = "cxx" end
323
if ext == "cc" then compiler = "cxx" end
324
if ext == "c" then compiler = "c" end
325
if ext == "S" then compiler = "c" end
326
if ext == "m" then compiler = "c" end
328
if compiler == "" then
329
error("don't know how to compile a file with the ending '"..ext.."'")
332
outname = settings.cc.output(settings.objdir, inname, settings.config_ext ..settings.cc.extension)
334
-- add job and run dependencies
335
bam_add_job("compile_"..compiler, outname, inname, settings.cc)
336
bam_add_dependency(outname, inname)
338
bam_dependency_cpp(inname, settings.cc.includes)
340
table.insert(outputs, outname)
347
function Link(settings, output, ...)
348
local inputs = collect_input(arg)
350
settings.linker:_propagate(settings);
352
output = settings.linker.output(settings.exedir, Path(output), settings.config_ext .. settings.linker.extension)
353
bam_add_job("link", output, inputs, settings.linker)
356
for index, inname in inputs do
357
bam_add_dependency(output, inname)
360
for index, inname in ipairs(settings.linker.extrafiles) do
361
bam_add_dependency(output, inname)
367
function StaticLibrary(settings, output, ...)
368
local inputs = collect_input(arg)
370
settings.lib:_propagate(settings);
372
output = settings.lib.output(settings.libdir, Path(output), settings.config_ext ..settings.lib.extension)
373
bam_add_job("lib", output, inputs, settings.lib)
375
for index, inname in inputs do
376
bam_add_dependency(output, inname)
382
function SharedLibrary(settings, output, ...)
383
local inputs = collect_input(arg)
385
settings.dll:_propagate(settings);
387
output = settings.dll.output(settings.libdir, Path(output), settings.config_ext .. settings.dll.extension)
388
bam_add_job("dll", output, inputs, settings.dll)
390
for index, inname in inputs do
391
bam_add_dependency(output, inname)
397
function Import(filename, options)
398
-- filename = Path(filename)
400
-- clone the bam base stuff
402
for i,v in _bam_clone do
406
local x = loadfile(bam_path_fix(filename))
408
error("Import: Could not open '" .. filename .. "'")
414
local mypath = _bam_path
415
module._bam_path = file_path(bam_path_fix(filename))
416
_bam_path = module._bam_path
419
module.options = options
424
-- restore magic values
429
Target = bam_add_target
430
DefaultTarget = bam_default_target
432
function pseudo(output)
435
function PseudoTarget(name, ...)
436
local inputs = collect_input(arg)
437
local name = bam_path_fix(name)
438
bam_add_job("pseudo", name)
441
for index, inname in inputs do
442
bam_add_dependency(name, inname)
448
function Debug_DumpArguments()
449
print("-- Dumping arguments --")
450
for index, value in _cn_options do
459
----- gcc/g++ compiler ------
460
function compile_c_cxx_gcc(type, output, input, settings)
461
local d = tbl_to_str(settings.defines, '-D', ' ')
462
local i = tbl_to_str(settings.includes, '-I', ' ')
463
local i = i .. tbl_to_str(settings.frameworks, '-framework ', ' ')
464
local f = settings.flags .. ' '
465
if settings.debug > 0 then f = f .. "-g " end
466
if settings.optimize > 0 then f = f .. "-O2 " end
467
local e = type .. ' ' .. f ..'-c ' .. input .. ' -o ' .. output .. ' ' .. d .. i
468
if verbose > 0 then print(e) end
472
function compile_cxx_gcc(output,input,settings)
473
print("c++ " .. PathFilename(input))
474
return compile_c_cxx_gcc(settings.cxx_compiler,output,input,settings)
477
function compile_c_gcc(output,input,settings)
478
print("c " .. PathFilename(input))
479
return compile_c_cxx_gcc(settings.c_compiler,output,input,settings)
483
function lib_ar(output, inputs, settings)
484
print("lib " .. PathFilename(output))
485
local e = "ar qc " .. output
486
local e = e .. " " .. tbl_to_str(inputs, '', ' ') .. settings.flags
487
if verbose > 0 then print(e) end
488
os.execute("rm -f " .. output)
492
function dll_gcc(output, inputs, settings)
493
print("dll " .. PathFilename(output))
494
local shared_flags = ""
496
if platform == "macosx" then
497
shared_flags = " -dynamiclib"
499
shared_flags = " -shared"
502
local e = settings.linker .. shared_flags .. " -o " .. output
503
local e = e .. " " .. settings.inputflags .. " " .. tbl_to_str(inputs, '', ' ')
504
local e = e .. tbl_to_str(settings.extrafiles, '', ' ')
505
local e = e .. tbl_to_str(settings.libpath, '-L', ' ')
506
local e = e .. tbl_to_str(settings.libs, '-l', ' ')
507
local e = e .. tbl_to_str(settings.frameworkpath, '-F', ' ')
508
local e = e .. tbl_to_str(settings.frameworks, '-framework ', ' ')
509
local e = e .. settings.flags
510
if verbose > 0 then print(e) end
514
function link_gcc(output, inputs, settings)
515
print("link " .. PathFilename(output))
516
local e = settings.linker .. " -o " .. output
517
local e = e .. " " .. settings.inputflags .. " " .. tbl_to_str(inputs, '', ' ')
518
local e = e .. tbl_to_str(settings.extrafiles, '', ' ')
519
local e = e .. tbl_to_str(settings.libpath, '-L', ' ')
520
local e = e .. tbl_to_str(settings.libs, '-l', ' ')
521
local e = e .. tbl_to_str(settings.frameworkpath, '-F', ' ')
522
local e = e .. tbl_to_str(settings.frameworks, '-framework ', ' ')
523
local e = e .. settings.flags
524
if verbose > 0 then print(e) end
528
----- cl compiler ------
529
function compile_c_cxx_cl(output, input, settings)
530
local defs = tbl_to_str(settings.defines, "-D", " ") .. " "
531
local incs = tbl_to_str(settings.includes, "-I", " ")
532
local flags = settings.flags
533
if platform =="win32" then
534
flags = flags .. " /D \"WIN32\" "
536
flags = flags .. " /D \"WIN64\" "
538
if settings.debug > 0 then flags = flags .. "/Od /MTd /Zi /D \"_DEBUG\" " end
539
if settings.optimize > 0 then flags = flags .. "/Ox /Ot /MT /D \"NDEBUG\" " end
540
local exec = "cl /nologo /D_CRT_SECURE_NO_DEPRECATE /c " .. flags .. input .. " " .. incs .. defs .. " /Fo" .. output
541
if verbose > 0 then print(exec) end
542
return os.execute(exec)
545
function compile_cxx_cl(output,input,settings)
546
-- support.simpleprint("c++ ")
547
return compile_c_cxx_cl(output,input,settings)
550
function compile_c_cl(output,input,settings)
551
-- support.simpleprint("c ")
552
return compile_c_cxx_cl(output,input,settings)
555
function lib_cl(output, inputs, settings)
556
-- support.simpleprint("lib ")
557
local input = tbl_to_str(inputs, "", " ")
558
local exec = "lib /nologo " .. settings.flags .. " /OUT:" .. output .. " " .. input
559
if verbose > 0 then print(exec) end
560
return os.execute(exec)
563
function dll_cl(output, inputs, settings)
564
-- support.simpleprint("lib ")
565
local input = tbl_to_str(inputs, "", " ")
566
local flags = settings.flags .. " "
567
local libs = tbl_to_str(settings.libs, "", " ")
568
local libpaths = tbl_to_str(settings.libpath, "/libpath:\"", "\" ")
569
local exec = "link /nologo /DLL" .. flags .. libpaths .. libs .. " /OUT:" .. output .. " " .. input
570
if verbose > 0 then print(exec) end
571
return os.execute(exec)
574
function link_cl(output, inputs, settings)
575
support.simpleprint("link ")
576
local input = tbl_to_str(inputs, "", " ")
577
local flags = settings.flags .. " "
578
local libs = tbl_to_str(settings.libs, "", " ")
579
local libpaths = tbl_to_str(settings.libpath, "/libpath:\"", "\" ")
580
if settings.debug > 0 then flags = flags .. "/DEBUG " end
581
local exec = "link /nologo /incremental:no " .. flags .. libpaths .. libs .. " /OUT:" .. output .. " " .. input
582
if verbose > 0 then print(exec) end
583
return os.execute(exec)
586
if platform == "win32" then
587
compile_cxx = compile_cxx_cl
588
compile_c = compile_c_cl
593
compile_cxx = compile_cxx_gcc
594
compile_c = compile_c_gcc