--!The Automatic Cross-platform Build Tool -- -- XMake is free software; you can redistribute it and/or modify -- it under the terms of the GNU Lesser General Public License as published by -- the Free Software Foundation; either version 2.1 of the License, or -- (at your option) any later version. -- -- XMake is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public License -- along with XMake; -- If not, see http://www.gnu.org/licenses/ -- -- Copyright (C) 2009 - 2015, ruki All rights reserved. -- -- @author ruki -- @file package.lua -- -- define module: package local package = package or {} -- load modules local os = require("base/os") local rule = require("base/rule") local path = require("base/path") local utils = require("base/utils") local config = require("base/config") local platform = require("platform/platform") -- package target for the library file function package._done_library(target) -- check assert(target and target.name and target.archs) -- the output directory local outputdir = target.outputdir assert(outputdir) -- the plat and mode local plat = config.get("plat") local mode = config.get("mode") assert(plat and mode) -- package it for arch, info in pairs(target.archs) do -- check assert(info.targetdir and info.targetfile) -- copy the library file to the output directory local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s.pkg/lib/%s/%s/%s/%s", outputdir, target.name, mode, plat, arch, path.filename(info.targetfile))) if not ok then utils.error(errors) return -1 end -- copy the config.h to the output directory if info.config_h then local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s.pkg/inc/%s/%s", outputdir, target.name, plat, path.filename(info.config_h))) if not ok then utils.error(errors) return -1 end end end -- copy headers if target.headers then local srcheaders, dstheaders = rule.headerfiles(target, string.format("%s/%s.pkg/inc", outputdir, target.name)) if srcheaders and dstheaders then local i = 1 for _, srcheader in ipairs(srcheaders) do local dstheader = dstheaders[i] if dstheader then local ok, errors = os.cp(srcheader, dstheader) if not ok then utils.error(errors) return -1 end end i = i + 1 end end end -- make xmake.lua local file = io.open(string.format("%s/%s.pkg/xmake.lua", outputdir, target.name), "w") if file then -- the xmake.lua template content local template = [[ -- add [targetname] package add_option("[targetname]") -- show menu set_option_showmenu(true) -- set category set_option_category("package") -- set description set_option_description("The [targetname] package") -- add defines to config.h if checking ok add_option_defines_h_if_ok("$(prefix)_PACKAGE_HAVE_[TARGETNAME]") -- add links for checking add_option_links("[targetname]") -- add link directories add_option_linkdirs("lib/$(mode)/$(plat)/$(arch)") -- add c includes for checking add_option_cincludes("[targetname]/[targetname].h") -- add include directories add_option_includedirs("inc", "inc/$(plat)/$(arch)") ]] -- save file file:write(template:gsub("%[targetname%]", target.name):gsub("%[TARGETNAME%]", target.name:upper())) -- exit file file:close() end -- ok return 1 end -- package target for the binary file function package._done_binary(target) -- check assert(target and target.archs) -- the output directory local outputdir = target.outputdir assert(outputdir) -- the count of architectures local count = 0 for _, _ in pairs(target.archs) do count = count + 1 end -- package it local ok = nil local errors = nil for arch, info in pairs(target.archs) do -- check assert(info.targetdir and info.targetfile) -- copy the binary file to the output directory if count == 1 then ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), outputdir) else ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", outputdir, rule.filename(path.basename(info.targetfile) .. "_" .. arch, "binary"))) end -- ok? if not ok then utils.error(errors) return -1 end end -- ok return 1 end -- package target from the default script function package._done_from_default(target) -- check assert(target.kind) -- the package scripts local pkgscripts = { static = package._done_library , shared = package._done_library , binary = package._done_binary } -- package it local pkgscript = pkgscripts[target.kind] if pkgscript then return pkgscript(target) end -- continue return 0 end -- package target from the project script function package._done_from_project(target) -- check assert(target) -- package it using the project script first local pkgscript = target.pkgscript if type(pkgscript) == "function" then -- remove it target.pkgscript = nil -- package it return pkgscript(target) end -- continue return 0 end -- package target from the platform script function package._done_from_platform(target) -- check assert(target) -- the platform package script file local pkgscript = nil local scriptfile = platform.directory() .. "/package.lua" if os.isfile(scriptfile) then -- load the package script local script, errors = loadfile(scriptfile) if script then pkgscript = script() if type(pkgscript) == "table" and pkgscript.main then pkgscript = pkgscript.main end else utils.error(errors) end end -- package it if type(pkgscript) == "function" then return pkgscript(target) end -- continue return 0 end -- package target from the given target configure function package._done(target) -- check assert(target) -- package it from the project script local ok = package._done_from_project(target) if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end -- package it from the platform script local ok = package._done_from_platform(target) if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end -- package it from the default script local ok = package._done_from_default(target) if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end -- ok return true end -- done package from the configure function package.done(configs) -- check assert(configs) -- package targets for _, target in pairs(configs) do -- package it if not package._done(target) then -- errors utils.error("package %s failed!", target.name) return false end end -- ok return true end -- return module: package return package