1*4882a593Smuzhiyun 2*4882a593Smuzhiyun--- Module implementing the LuaRocks "buildroot" command. 3*4882a593Smuzhiyunlocal buildroot = {} 4*4882a593Smuzhiyun 5*4882a593Smuzhiyunlocal dir = require("luarocks.dir") 6*4882a593Smuzhiyunlocal fs = require("luarocks.fs") 7*4882a593Smuzhiyunlocal util = require("luarocks.util") 8*4882a593Smuzhiyunlocal queries = require("luarocks.queries") 9*4882a593Smuzhiyunlocal search = require("luarocks.search") 10*4882a593Smuzhiyunlocal download = require("luarocks.download") 11*4882a593Smuzhiyunlocal fetch = require("luarocks.fetch") 12*4882a593Smuzhiyun 13*4882a593Smuzhiyunfunction buildroot.add_to_parser(parser) 14*4882a593Smuzhiyun local cmd = parser:command("buildroot", [[ 15*4882a593SmuzhiyunThis addon generates Buildroot package files of a rock. 16*4882a593SmuzhiyunFirst argument is the name of a rock, the second argument is optional 17*4882a593Smuzhiyunand needed when Buildroot uses another name (usually prefixed by lua-). 18*4882a593SmuzhiyunFiles are generated with the source content of the rock and more 19*4882a593Smuzhiyunespecially the rockspec. So, the rock is downloaded and unpacked. 20*4882a593Smuzhiyun]], util.see_also()) 21*4882a593Smuzhiyun :summary("generate buildroot package files of a rock.") 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun cmd:argument("rockname", "the name of a rock to be fetched and unpacked.") 24*4882a593Smuzhiyun cmd:argument("brname", "the name used by Buildroot.") 25*4882a593Smuzhiyun :args("?") 26*4882a593Smuzhiyunend 27*4882a593Smuzhiyun 28*4882a593Smuzhiyunlocal function brname (name) 29*4882a593Smuzhiyun return name:upper():gsub('-', '_') 30*4882a593Smuzhiyunend 31*4882a593Smuzhiyun 32*4882a593Smuzhiyunlocal function brlicense (license) 33*4882a593Smuzhiyun if license:match('MIT/X') then 34*4882a593Smuzhiyun return 'MIT' 35*4882a593Smuzhiyun end 36*4882a593Smuzhiyun return license 37*4882a593Smuzhiyunend 38*4882a593Smuzhiyun 39*4882a593Smuzhiyunlocal function wrap (txt, max) 40*4882a593Smuzhiyun local lines = {} 41*4882a593Smuzhiyun local line = '' 42*4882a593Smuzhiyun for word in txt:gmatch('(%S+)') do 43*4882a593Smuzhiyun if line:len() + word:len() > max - 1 then 44*4882a593Smuzhiyun lines[#lines+1] = line 45*4882a593Smuzhiyun line = '' 46*4882a593Smuzhiyun end 47*4882a593Smuzhiyun if line == '' then 48*4882a593Smuzhiyun line = word 49*4882a593Smuzhiyun else 50*4882a593Smuzhiyun line = line .. ' ' .. word 51*4882a593Smuzhiyun end 52*4882a593Smuzhiyun end 53*4882a593Smuzhiyun lines[#lines+1] = line 54*4882a593Smuzhiyun return lines 55*4882a593Smuzhiyunend 56*4882a593Smuzhiyun 57*4882a593Smuzhiyunlocal function has_c_files (rockspec) 58*4882a593Smuzhiyun for _, mod in pairs(rockspec.build.modules or {}) do 59*4882a593Smuzhiyun if type(mod) == 'string' then 60*4882a593Smuzhiyun if mod:match'%.c$' then 61*4882a593Smuzhiyun return true 62*4882a593Smuzhiyun end 63*4882a593Smuzhiyun elseif type(mod) == 'table' then 64*4882a593Smuzhiyun local sources = mod.sources 65*4882a593Smuzhiyun if type(sources) == 'string' and sources:match'%.c$' then 66*4882a593Smuzhiyun return true 67*4882a593Smuzhiyun end 68*4882a593Smuzhiyun for _, src in ipairs(sources or mod) do 69*4882a593Smuzhiyun if src:match'%.c$' then 70*4882a593Smuzhiyun return true 71*4882a593Smuzhiyun end 72*4882a593Smuzhiyun end 73*4882a593Smuzhiyun end 74*4882a593Smuzhiyun end 75*4882a593Smuzhiyun return false 76*4882a593Smuzhiyunend 77*4882a593Smuzhiyun 78*4882a593Smuzhiyunlocal function get_main_modules (rockspec) 79*4882a593Smuzhiyun local t = {} 80*4882a593Smuzhiyun for name in pairs(rockspec.build.modules or {}) do 81*4882a593Smuzhiyun if not name:match('%.') then 82*4882a593Smuzhiyun t[#t+1] = name 83*4882a593Smuzhiyun end 84*4882a593Smuzhiyun end 85*4882a593Smuzhiyun if #t == 0 then 86*4882a593Smuzhiyun for name in pairs(rockspec.build.modules or {}) do 87*4882a593Smuzhiyun t[#t+1] = name 88*4882a593Smuzhiyun end 89*4882a593Smuzhiyun end 90*4882a593Smuzhiyun if #t == 0 then 91*4882a593Smuzhiyun t[#t+1] = rockspec.package:gsub('%-', '') 92*4882a593Smuzhiyun end 93*4882a593Smuzhiyun table.sort(t) 94*4882a593Smuzhiyun return t 95*4882a593Smuzhiyunend 96*4882a593Smuzhiyun 97*4882a593Smuzhiyunlocal function get_external_dependencies (rockspec) 98*4882a593Smuzhiyun local t = {} 99*4882a593Smuzhiyun for k in pairs(rockspec.external_dependencies or {}) do 100*4882a593Smuzhiyun k = k:lower() 101*4882a593Smuzhiyun if fs.is_dir('package/' .. k) then 102*4882a593Smuzhiyun t[#t+1] = k 103*4882a593Smuzhiyun else 104*4882a593Smuzhiyun t[#t+1] = 'lib' .. k 105*4882a593Smuzhiyun if not fs.is_dir('package/lib' .. k) then 106*4882a593Smuzhiyun util.printout('unkwown external dependency: ' .. k) 107*4882a593Smuzhiyun end 108*4882a593Smuzhiyun end 109*4882a593Smuzhiyun end 110*4882a593Smuzhiyun table.sort(t) 111*4882a593Smuzhiyun return t 112*4882a593Smuzhiyunend 113*4882a593Smuzhiyun 114*4882a593Smuzhiyunlocal function get_dependencies (rockspec) 115*4882a593Smuzhiyun local t = {} 116*4882a593Smuzhiyun for i = 1, #rockspec.dependencies do 117*4882a593Smuzhiyun local dep = tostring(rockspec.dependencies[i]):match('^(%S+)') 118*4882a593Smuzhiyun if dep ~= 'lua' then 119*4882a593Smuzhiyun dep = dep:gsub('_', '-') 120*4882a593Smuzhiyun if fs.is_dir('package/lua-' .. dep) then 121*4882a593Smuzhiyun t[#t+1] = 'lua-' .. dep 122*4882a593Smuzhiyun else 123*4882a593Smuzhiyun t[#t+1] = dep 124*4882a593Smuzhiyun if not fs.is_dir('package/' .. dep) then 125*4882a593Smuzhiyun util.printout('unkwown dependency: ' .. dep) 126*4882a593Smuzhiyun end 127*4882a593Smuzhiyun end 128*4882a593Smuzhiyun end 129*4882a593Smuzhiyun end 130*4882a593Smuzhiyun table.sort(t) 131*4882a593Smuzhiyun return t 132*4882a593Smuzhiyunend 133*4882a593Smuzhiyun 134*4882a593Smuzhiyunfunction get_digest (file) 135*4882a593Smuzhiyun local absname = fs.absolute_name(file) 136*4882a593Smuzhiyun local pipe = io.popen('sha256sum ' .. fs.Q(absname)) 137*4882a593Smuzhiyun local line = pipe:read('*l') 138*4882a593Smuzhiyun pipe:close() 139*4882a593Smuzhiyun local computed = line and line:match('(' .. ('%x'):rep(64) .. ')') 140*4882a593Smuzhiyun if computed then 141*4882a593Smuzhiyun return computed 142*4882a593Smuzhiyun else 143*4882a593Smuzhiyun return nil, "Failed to compute SHA256 hash for file " .. absname 144*4882a593Smuzhiyun end 145*4882a593Smuzhiyunend 146*4882a593Smuzhiyun 147*4882a593Smuzhiyunlocal function generate_config (rockspec, lcname) 148*4882a593Smuzhiyun local ucname = brname(lcname) 149*4882a593Smuzhiyun local only_luajit = rockspec.package:match('^lj') 150*4882a593Smuzhiyun local summary = rockspec.description.summary 151*4882a593Smuzhiyun if not summary then 152*4882a593Smuzhiyun summary = '???' 153*4882a593Smuzhiyun elseif not summary:match('%.%s*$') then 154*4882a593Smuzhiyun summary = summary:gsub('%s*$', '.') 155*4882a593Smuzhiyun end 156*4882a593Smuzhiyun local homepage = rockspec.description.homepage or '???' 157*4882a593Smuzhiyun local external_dependencies = get_external_dependencies(rockspec) 158*4882a593Smuzhiyun local dependencies = get_dependencies(rockspec) 159*4882a593Smuzhiyun local fname = 'package/' .. lcname .. '/Config.in' 160*4882a593Smuzhiyun local f = assert(io.open(fname, 'w')) 161*4882a593Smuzhiyun util.printout('write ' .. fname) 162*4882a593Smuzhiyun f:write('config BR2_PACKAGE_' .. ucname .. '\n') 163*4882a593Smuzhiyun f:write('\tbool "' .. lcname .. '"\n') 164*4882a593Smuzhiyun if only_luajit then 165*4882a593Smuzhiyun f:write('\tdepends on BR2_PACKAGE_LUAJIT\n') 166*4882a593Smuzhiyun end 167*4882a593Smuzhiyun for i = 1, #external_dependencies do 168*4882a593Smuzhiyun f:write('\tselect BR2_PACKAGE_' .. brname(external_dependencies[i]) .. '\n') 169*4882a593Smuzhiyun end 170*4882a593Smuzhiyun for i = 1, #dependencies do 171*4882a593Smuzhiyun f:write('\tselect BR2_PACKAGE_' .. brname(dependencies[i]) .. ' # runtime\n') 172*4882a593Smuzhiyun end 173*4882a593Smuzhiyun f:write('\thelp\n') 174*4882a593Smuzhiyun f:write('\t ' .. table.concat(wrap(summary, 62), '\n\t ') .. '\n') 175*4882a593Smuzhiyun f:write('\n\t ' .. homepage .. '\n') 176*4882a593Smuzhiyun if only_luajit then 177*4882a593Smuzhiyun f:write('\ncomment "' .. lcname .. ' needs LuaJIT"\n') 178*4882a593Smuzhiyun f:write('\tdepends on !BR2_PACKAGE_LUAJIT\n') 179*4882a593Smuzhiyun end 180*4882a593Smuzhiyun f:close() 181*4882a593Smuzhiyunend 182*4882a593Smuzhiyun 183*4882a593Smuzhiyunlocal function generate_mk (rockspec, lcname, licenses) 184*4882a593Smuzhiyun local function escape (s) 185*4882a593Smuzhiyun return s:gsub('-', '%%-'):gsub('%.', '%%.') 186*4882a593Smuzhiyun end 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun local ucname = brname(lcname) 189*4882a593Smuzhiyun local need_name_upstream = false 190*4882a593Smuzhiyun local need_version_upstream = false 191*4882a593Smuzhiyun local name_upstream = rockspec.package 192*4882a593Smuzhiyun local version = rockspec.version 193*4882a593Smuzhiyun local version_upstream = version:match('^([^-]+)-') 194*4882a593Smuzhiyun local revision = version:match('-(%d+)$') 195*4882a593Smuzhiyun local license = rockspec.description.license 196*4882a593Smuzhiyun local subdir = rockspec.source.dir 197*4882a593Smuzhiyun if subdir then 198*4882a593Smuzhiyun local root = subdir:match('^(.-)-' .. escape(version) .. '$') 199*4882a593Smuzhiyun if root then 200*4882a593Smuzhiyun subdir = root .. '-$(' .. ucname .. '_VERSION)' 201*4882a593Smuzhiyun end 202*4882a593Smuzhiyun root = subdir:match('^(.--[Vv])' .. escape(version_upstream) .. '$') 203*4882a593Smuzhiyun if root then 204*4882a593Smuzhiyun need_version_upstream = true 205*4882a593Smuzhiyun subdir = root .. '$(' .. ucname .. '_VERSION_UPSTREAM)' 206*4882a593Smuzhiyun end 207*4882a593Smuzhiyun root = subdir:match('^(.-)-' .. escape(version_upstream) .. '$') 208*4882a593Smuzhiyun if root then 209*4882a593Smuzhiyun if root == lcname then 210*4882a593Smuzhiyun subdir = nil 211*4882a593Smuzhiyun elseif root == name_upstream then 212*4882a593Smuzhiyun subdir = nil 213*4882a593Smuzhiyun need_name_upstream = true 214*4882a593Smuzhiyun else 215*4882a593Smuzhiyun need_version_upstream = true 216*4882a593Smuzhiyun subdir = root .. '-$(' .. ucname .. '_VERSION_UPSTREAM)' 217*4882a593Smuzhiyun end 218*4882a593Smuzhiyun end 219*4882a593Smuzhiyun end 220*4882a593Smuzhiyun local external_dependencies = get_external_dependencies(rockspec) 221*4882a593Smuzhiyun local fname = 'package/' .. lcname .. '/' .. lcname .. '.mk' 222*4882a593Smuzhiyun local f = assert(io.open(fname, 'w')) 223*4882a593Smuzhiyun util.printout('write ' .. fname) 224*4882a593Smuzhiyun f:write('################################################################################\n') 225*4882a593Smuzhiyun f:write('#\n') 226*4882a593Smuzhiyun f:write('# ' .. lcname .. '\n') 227*4882a593Smuzhiyun f:write('#\n') 228*4882a593Smuzhiyun f:write('################################################################################\n') 229*4882a593Smuzhiyun f:write('\n') 230*4882a593Smuzhiyun if need_version_upstream then 231*4882a593Smuzhiyun f:write(ucname .. '_VERSION_UPSTREAM = ' .. version_upstream .. '\n') 232*4882a593Smuzhiyun f:write(ucname .. '_VERSION = $(' .. ucname .. '_VERSION_UPSTREAM)-' .. revision .. '\n') 233*4882a593Smuzhiyun else 234*4882a593Smuzhiyun f:write(ucname .. '_VERSION = ' .. version .. '\n') 235*4882a593Smuzhiyun end 236*4882a593Smuzhiyun if lcname ~= name_upstream:lower() or need_name_upstream then 237*4882a593Smuzhiyun f:write(ucname .. '_NAME_UPSTREAM = ' .. name_upstream .. '\n') 238*4882a593Smuzhiyun end 239*4882a593Smuzhiyun if subdir then 240*4882a593Smuzhiyun f:write(ucname .. '_SUBDIR = ' .. subdir .. '\n') 241*4882a593Smuzhiyun end 242*4882a593Smuzhiyun if license then 243*4882a593Smuzhiyun f:write(ucname .. '_LICENSE = ' .. brlicense(license) .. '\n') 244*4882a593Smuzhiyun end 245*4882a593Smuzhiyun if #licenses == 1 then 246*4882a593Smuzhiyun f:write(ucname .. '_LICENSE_FILES = $(' .. ucname .. '_SUBDIR)/' .. licenses[1] .. '\n') 247*4882a593Smuzhiyun elseif #licenses > 1 then 248*4882a593Smuzhiyun f:write(ucname .. '_LICENSE_FILES =') 249*4882a593Smuzhiyun for i = 1, #licenses do 250*4882a593Smuzhiyun local file = licenses[i] 251*4882a593Smuzhiyun f:write(' \\\n\t$(' .. ucname .. '_SUBDIR)/' .. file) 252*4882a593Smuzhiyun end 253*4882a593Smuzhiyun f:write('\n') 254*4882a593Smuzhiyun end 255*4882a593Smuzhiyun if #external_dependencies > 0 then 256*4882a593Smuzhiyun f:write(ucname .. '_DEPENDENCIES = ' .. table.concat(external_dependencies, ' ') .. '\n') 257*4882a593Smuzhiyun end 258*4882a593Smuzhiyun f:write('\n$(eval $(luarocks-package))\n') 259*4882a593Smuzhiyun f:close() 260*4882a593Smuzhiyunend 261*4882a593Smuzhiyun 262*4882a593Smuzhiyunlocal function generate_hash (rockspec, lcname, rock_file, licenses, digest) 263*4882a593Smuzhiyun local subdir = rockspec.source.dir 264*4882a593Smuzhiyun local fname = 'package/' .. lcname .. '/' .. lcname .. '.hash' 265*4882a593Smuzhiyun local f = assert(io.open(fname, 'w')) 266*4882a593Smuzhiyun util.printout('write ' .. fname) 267*4882a593Smuzhiyun f:write('# computed by luarocks/buildroot\n') 268*4882a593Smuzhiyun f:write('sha256 ' .. digest[rock_file] .. ' ' .. rock_file .. '\n') 269*4882a593Smuzhiyun for i = 1, #licenses do 270*4882a593Smuzhiyun local file = licenses[i] 271*4882a593Smuzhiyun f:write('sha256 ' .. digest[file] .. ' ' .. subdir .. '/' .. file .. '\n') 272*4882a593Smuzhiyun end 273*4882a593Smuzhiyun f:close() 274*4882a593Smuzhiyunend 275*4882a593Smuzhiyun 276*4882a593Smuzhiyunlocal function generate_test (rockspec, lcname) 277*4882a593Smuzhiyun local ucname = brname(lcname) 278*4882a593Smuzhiyun local classname = rockspec.package:gsub('%-', ''):gsub('%.', '') 279*4882a593Smuzhiyun classname = classname:sub(1, 1):upper() .. classname:sub(2) 280*4882a593Smuzhiyun local modnames = get_main_modules(rockspec) 281*4882a593Smuzhiyun local fname = 'support/testing/tests/package/test_' .. ucname:lower() .. '.py' 282*4882a593Smuzhiyun local f = assert(io.open(fname, 'w')) 283*4882a593Smuzhiyun util.printout('write ' .. fname) 284*4882a593Smuzhiyun f:write('from tests.package.test_lua import TestLuaBase\n') 285*4882a593Smuzhiyun f:write('\n') 286*4882a593Smuzhiyun f:write('\n') 287*4882a593Smuzhiyun f:write('class TestLua' .. classname .. '(TestLuaBase):\n') 288*4882a593Smuzhiyun f:write(' config = TestLuaBase.config + \\\n') 289*4882a593Smuzhiyun f:write(' """\n') 290*4882a593Smuzhiyun f:write(' BR2_PACKAGE_LUA=y\n') 291*4882a593Smuzhiyun f:write(' BR2_PACKAGE_' .. ucname .. '=y\n') 292*4882a593Smuzhiyun f:write(' """\n') 293*4882a593Smuzhiyun f:write('\n') 294*4882a593Smuzhiyun f:write(' def test_run(self):\n') 295*4882a593Smuzhiyun f:write(' self.login()\n') 296*4882a593Smuzhiyun for i = 1, #modnames do 297*4882a593Smuzhiyun f:write(' self.module_test("' .. modnames[i] .. '")\n') 298*4882a593Smuzhiyun end 299*4882a593Smuzhiyun f:write('\n') 300*4882a593Smuzhiyun f:write('\n') 301*4882a593Smuzhiyun f:write('class TestLuajit' .. classname .. '(TestLuaBase):\n') 302*4882a593Smuzhiyun f:write(' config = TestLuaBase.config + \\\n') 303*4882a593Smuzhiyun f:write(' """\n') 304*4882a593Smuzhiyun f:write(' BR2_PACKAGE_LUAJIT=y\n') 305*4882a593Smuzhiyun f:write(' BR2_PACKAGE_' .. ucname .. '=y\n') 306*4882a593Smuzhiyun f:write(' """\n') 307*4882a593Smuzhiyun f:write('\n') 308*4882a593Smuzhiyun f:write(' def test_run(self):\n') 309*4882a593Smuzhiyun f:write(' self.login()\n') 310*4882a593Smuzhiyun for i = 1, #modnames do 311*4882a593Smuzhiyun f:write(' self.module_test("' .. modnames[i] .. '")\n') 312*4882a593Smuzhiyun end 313*4882a593Smuzhiyun f:close() 314*4882a593Smuzhiyunend 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun--- Driver function for the "buildroot" command. 317*4882a593Smuzhiyun-- @return boolean: true if successful 318*4882a593Smuzhiyunfunction buildroot.command(args) 319*4882a593Smuzhiyun local rockname = assert(args.rockname) 320*4882a593Smuzhiyun local fsname = args.brname or rockname 321*4882a593Smuzhiyun 322*4882a593Smuzhiyun local query = queries.new(rockname:lower(), nil, nil, false, 'src') 323*4882a593Smuzhiyun local url, err = search.find_suitable_rock(query) 324*4882a593Smuzhiyun if not url then 325*4882a593Smuzhiyun return nil, "Could not find a result named " .. tostring(query) .. ": " .. err 326*4882a593Smuzhiyun end 327*4882a593Smuzhiyun local rock_file = dir.base_name(url) 328*4882a593Smuzhiyun 329*4882a593Smuzhiyun local temp_dir, err = fs.make_temp_dir(rockname) 330*4882a593Smuzhiyun if not temp_dir then 331*4882a593Smuzhiyun return nil, "Failed creating temporary dir: " .. err 332*4882a593Smuzhiyun end 333*4882a593Smuzhiyun local ok, err = fs.change_dir(temp_dir) 334*4882a593Smuzhiyun if not ok then return nil, err end 335*4882a593Smuzhiyun 336*4882a593Smuzhiyun ok = fs.download(url, rock_file, true) 337*4882a593Smuzhiyun if not ok then 338*4882a593Smuzhiyun return nil, "Failed downloading " .. url 339*4882a593Smuzhiyun end 340*4882a593Smuzhiyun 341*4882a593Smuzhiyun local digest = {} 342*4882a593Smuzhiyun digest[rock_file], err = get_digest(rock_file) 343*4882a593Smuzhiyun if not digest[rock_file] then return nil, err end 344*4882a593Smuzhiyun ok, err = fs.unzip(rock_file) 345*4882a593Smuzhiyun if not ok then return nil, err end 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun local rockspec_file = rock_file:gsub('%.src%.rock$', '.rockspec') 348*4882a593Smuzhiyun local rockspec, err = fetch.load_rockspec(rockspec_file) 349*4882a593Smuzhiyun if not rockspec then 350*4882a593Smuzhiyun return nil, "Error loading rockspec: " .. err 351*4882a593Smuzhiyun end 352*4882a593Smuzhiyun if rockspec.source.file then 353*4882a593Smuzhiyun ok, err = fs.unpack_archive(rockspec.source.file) 354*4882a593Smuzhiyun if not ok then return nil, err end 355*4882a593Smuzhiyun end 356*4882a593Smuzhiyun 357*4882a593Smuzhiyun if rockspec.source.dir ~= '.' then 358*4882a593Smuzhiyun fs.copy(rockspec.local_abs_filename, rockspec.source.dir, 'read') 359*4882a593Smuzhiyun end 360*4882a593Smuzhiyun 361*4882a593Smuzhiyun local build_type = rockspec.build.type 362*4882a593Smuzhiyun if build_type ~= 'none' and build_type ~= 'builtin' and build_type ~= 'module' then 363*4882a593Smuzhiyun util.printout('[' .. rockspec.package .. "] build_type '" .. build_type .. "' not supported") 364*4882a593Smuzhiyun end 365*4882a593Smuzhiyun 366*4882a593Smuzhiyun local licenses = {} 367*4882a593Smuzhiyun ok, err = fs.change_dir(rockspec.source.dir) 368*4882a593Smuzhiyun if not ok then return nil, err end 369*4882a593Smuzhiyun local files = fs.find() 370*4882a593Smuzhiyun for i = 1, #files do 371*4882a593Smuzhiyun local v = files[i] 372*4882a593Smuzhiyun if v == 'COPYING' 373*4882a593Smuzhiyun or v == 'COPYRIGHT' 374*4882a593Smuzhiyun or v:match('^LICENSE') then 375*4882a593Smuzhiyun licenses[#licenses+1] = v 376*4882a593Smuzhiyun digest[v], err = get_digest(v) 377*4882a593Smuzhiyun if not digest[v] then return nil, err end 378*4882a593Smuzhiyun end 379*4882a593Smuzhiyun end 380*4882a593Smuzhiyun if #licenses == 0 then 381*4882a593Smuzhiyun for i = 1, #files do 382*4882a593Smuzhiyun local v = files[i] 383*4882a593Smuzhiyun if v:match('^docs?/LICENSE') 384*4882a593Smuzhiyun or v:match('^docs?/license') 385*4882a593Smuzhiyun or v:match('^doc/us/license') then 386*4882a593Smuzhiyun licenses[#licenses+1] = v 387*4882a593Smuzhiyun digest[v], err = get_digest(v) 388*4882a593Smuzhiyun if not digest[v] then return nil, err end 389*4882a593Smuzhiyun end 390*4882a593Smuzhiyun end 391*4882a593Smuzhiyun end 392*4882a593Smuzhiyun fs.pop_dir() 393*4882a593Smuzhiyun table.sort(licenses) 394*4882a593Smuzhiyun 395*4882a593Smuzhiyun fs.pop_dir() 396*4882a593Smuzhiyun ok, err = fs.make_dir('package/' .. fsname:lower()) 397*4882a593Smuzhiyun if not ok then return nil, err end 398*4882a593Smuzhiyun 399*4882a593Smuzhiyun generate_config(rockspec, fsname:lower()) 400*4882a593Smuzhiyun generate_mk(rockspec, fsname:lower(), licenses) 401*4882a593Smuzhiyun generate_hash(rockspec, fsname:lower(), rock_file, licenses, digest) 402*4882a593Smuzhiyun if has_c_files(rockspec) then 403*4882a593Smuzhiyun ok, err = fs.make_dir('support/testing/tests/package') 404*4882a593Smuzhiyun if not ok then return nil, err end 405*4882a593Smuzhiyun generate_test(rockspec, fsname:lower()) 406*4882a593Smuzhiyun end 407*4882a593Smuzhiyun 408*4882a593Smuzhiyun return true 409*4882a593Smuzhiyunend 410*4882a593Smuzhiyun 411*4882a593Smuzhiyunreturn buildroot 412