local u = dofile('common.lua')
local default = function(var,def)
local v = os.getenv(var)
if v then return v else return def end
end
local function coalesce(x,...)
if x ~= nil then return x else
if select('#',...) == 0 then return nil end
return coalesce(...)
end
end
local posixes = {
linux = true; osx = true;
android = true; haiku = true;
}
local default_os = 'linux'
local defaultlist = function(env, ...)
local e = os.getenv(env)
local lst = {}
if e then
for v in e:gmatch('([^:]*)') do lst[#lst + 1] = v end
return lst
else return {...} end
end
local conf = {
pkg = {};
dist = default('parsav_dist', coalesce(
os.getenv('NIX_PATH') and 'nixos',
os.getenv('NIX_STORE') and 'nixos',
''));
tgttrip = default('parsav_arch_triple'); -- target triple, used in xcomp
tgtcpu = default('parsav_arch_cpu'); -- target cpu, used in xcomp
tgthf = u.tobool(default('parsav_arch_armhf',true));
endian = default('parsav_arch_endian', 'little');
build = {
id = u.rndstr(6);
release = u.ingest('release');
when = os.date();
};
feat = {};
backends = defaultlist('parsav_backends', 'pgsql');
braingeniousmode = false;
}
if u.ping '.fslckout' or u.ping '_FOSSIL_' then
if u.ping '_FOSSIL_' then default_os = 'windows' end
conf.build.branch = u.exec { 'fossil', 'branch', 'current' }
conf.build.checkout = (u.exec { 'fossil', 'sql',
[[select value from localdb.vvar where name = 'checkout-hash']]
}):gsub("^'(.*)'$", '%1')
end
conf.os = default('parsav_host_os', default_os);
conf.tgtos = default('parsav_target_os', default_os);
conf.posix = posixes[conf.os]
conf.exe = u.tobool(default('parsav_link',not conf.tgttrip)); -- turn off for partial builds
conf.build.origin = coalesce(
os.getenv('parsav_builder'),
string.format('%s@%s', coalesce (
os.getenv('USER'),
u.exec{'whoami'}
), u.exec{'hostname'}) -- whoami and hostname are present on both windows & unix
)
if conf.build.release then
local v = conf.build.release
conf.build.str = string.format('release %s', conf.build.release)
else
conf.build.str = string.format('build %s-%s', conf.build.id, conf.build.origin)
if conf.build.branch then
conf.build.str = conf.build.str .. string.format(':%s(%s)',
conf.build.branch, string.sub(conf.build.checkout,1,10))
end
end
if conf.tgtos == 'linux' then
conf.feat.randomizer = default('parsav_feat_randomizer', 'kern')
else
conf.feat.randomizer = default('parsav_feat_randomizer', 'libc')
end
local choplib = function(l)
if string.sub(l,1,3) == 'lib' then return string.sub(l,4) end
return l
end
local fallback = dofile('pkgdata.lua')
local libfind do local mkf = function(p)
return function(l) return string.format(p,l) end
end
local unx = function(p)
return function(l)
if string.sub(l,1,3) == 'lib'
then return string.format('%s.%s',l,p)
else return string.format('lib%s.%s',l,p)
end
end
end
libfind = {
linux = { static = unx 'a', dynamic = unx 'so'; };
osx = { dynamic = mkf '%s.dylib'; };
win = { dynamic = mkf '%s.dll'; };
}
end
local pkg = function(name)
local fbo = fallback[name] and fallback[name].osvars and coalesce(
fallback[name].osvars[conf.os .. '_' .. conf.dist],
fallback[name].osvars[conf.os]
)
local fbv = fallback[name] and fallback[name].vars
local fb = fallback[name]
local pkgenv = function(e)
return os.getenv(string.format('parsav_pkg_%s_%s',name,e))
end
local nul = function() end
local pkc, pkv = nul, nul
local locdep = false
local cnfvar = function(v,e)
local eval = function(e)
if type(e) == 'function'
then return e(conf)
else return e
end
end
return coalesce(
pkgenv(v),
pkv(e or v),
(fbo and eval(fbo[v])),
(fbv and eval(fbv[v])))
end
local name = cnfvar('override') or name
local pcname = coalesce(cnfvar('pcname'), name)
if conf.posix then
pkc = function(...) if locdep then return nil end
return u.exec { 'pkg-config'; pcname; ... } end
local pkcv = function(...) return u.exec({ 'pkg-config'; pcname; ... }, true) end
if pkcv('--exists') == 0 then
pkv = function(v)
if locdep then return nil end
return pkc('--variable', v)
end
else pkc = nul end
else
print '(warn) configuring on non-POSIX OS, all relevant paths must be specified manually in environment variables or build will fail!'
end
locdep = u.ping('./lib/' .. name)
local incdir, libdir, prefix
if locdep then
prefix = './lib/' .. name
libdir = prefix .. coalesce(cnfvar('libbuilddir'),cnfvar('builddir'),'')
incdir = prefix .. coalesce(cnfvar('srcincdir'),cnfvar('builddir'),'/include')
else
prefix = coalesce(cnfvar('prefix'), '/usr')
libdir = cnfvar('libdir')
incdir = cnfvar('incdir','includedir')
end
libdir = libdir or prefix .. '/lib'
incdir = incdir or prefix .. '/include'
local libstr = pkc '--libs-only-l' -- (--static is not reliable)
local libs = fb and fb.libs or {}
local linkstatic = locdep
if (not locdep) and libstr then
libs = {}
for m in string.gmatch(libstr, '-l(%g+)') do
libs[#libs + 1] = m
end
else
if #libs == 0 then libs = { name } end
end
conf.pkg[name] = {
prefix = prefix;
libdir = libdir;
incdir = incdir;
dylibs = {}, statlibs = {};
}
local me = conf.pkg[name]
local lf = libfind[conf.os]
if lf.dynamic then me.dylibs = u.map(libs, lf.dynamic) end
if lf.static then me.statlibs = u.map(libs, lf.static) end
if linkstatic then
local ldf = {}
for _,v in pairs(me.statlibs) do
local fl = libdir .. '/' .. v
if u.ping(fl) then ldf[#ldf+1] = fl end
end
me.linkargs = ldf
else
local arg = choplib(name)
local linkline = libstr
if not linkline and #libs == 0 then
linkline = string.format('-l%s', arg)
elseif not linkline then linkline = '' end
me.linkargs = {
string.format('-L%s', me.libdir);
}
for m in string.gmatch(linkline, '(%g+)') do
me.linkargs[#me.linkargs+1] = m
end
-- siiiiigh
for _,l in pairs(libs) do
local sw = string.format('-l%s', choplib(l))
local found = false
for _,a in pairs(me.linkargs) do
if a == sw then found = true break end
end
if not found then
me.linkargs[#me.linkargs+1] = sw
end
end
end
end
pkg('mbedtls')
pkg('mongoose')
pkg('json-c')
pkg('libc')
pkg('libpq')
return conf