xref: /OK3568_Linux_fs/buildroot/package/luarocks/buildroot.lua (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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