diff options
| author | A2va <[email protected]> | 2024-02-25 21:33:53 +0100 |
|---|---|---|
| committer | A2va <[email protected]> | 2024-02-25 21:33:53 +0100 |
| commit | 60b16964ace5bbd1314c490c0b44d20338f7bf1d (patch) | |
| tree | d80f10bbe585912edbc1c877ffcddcf3900f5dc1 | |
| parent | 2b6e7e48ee574e0155b9160cb57c6a734954b854 (diff) | |
Xpack: wix toolset
| -rw-r--r-- | xmake/plugins/pack/wix/main.lua | 192 | ||||
| -rw-r--r-- | xmake/plugins/pack/xpack.lua | 3 | ||||
| -rw-r--r-- | xmake/scripts/xpack/wix/msi.wxs | 36 |
3 files changed, 231 insertions, 0 deletions
diff --git a/xmake/plugins/pack/wix/main.lua b/xmake/plugins/pack/wix/main.lua new file mode 100644 index 000000000..acfd9ce83 --- /dev/null +++ b/xmake/plugins/pack/wix/main.lua @@ -0,0 +1,192 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author A2va +-- @file main.lua +-- + +import("lib.detect.find_tool") +import("private.action.require.impl.packagenv") +import("private.action.require.impl.install_packages") + +import(".batchcmds") + +-- get the wixtoolset +function _get_wix() + + -- enter the environments of wix + local oldenvs = packagenv.enter("wixtoolset") + + -- find makensis + local packages = {} + local wix = find_tool("wix", {require_version = ">=4.0.0"}) + if not wix then + table.join2(packages, install_packages("wixtoolset")) + end + + -- enter the environments of installed packages + for _, instance in ipairs(packages) do + instance:envs_enter() + end + + -- we need to force detect and flush detect cache after loading all environments + if not wix then + wix = find_tool("wix", {force = true}) + end + assert(wix, "wix not found (ensure that wix is up to date)!") + return wix, oldenvs +end + +-- get command string +function _get_command_strings(package, cmd, opt) + opt = table.join(cmd.opt or {}, opt) + local result = {} + local kind = cmd.kind + if kind == "cp" then + -- https://nsis.sourceforge.io/Reference/File + local srcfiles = os.files(cmd.srcpath) + for _, srcfile in ipairs(srcfiles) do + -- the destination is directory? append the filename + local dstfile = cmd.dstpath + if #srcfiles > 1 or path.islastsep(dstfile) then + if opt.rootdir then + dstfile = path.join(dstfile, path.relative(srcfile, opt.rootdir)) + else + dstfile = path.join(dstfile, path.filename(srcfile)) + end + end + srcfile = path.normalize(srcfile) + local dstname = path.filename(dstfile) + local dstdir = path.normalize(path.directory(dstfile)) + local relative_dstdir = path.relative(dstdir, package:install_rootdir()) + + local subdirectory = dstdir ~= package:install_rootdir() and string.format([[Subdirectory="%s"]], relative_dstdir) or "" + local component_string = string.format([[<Component Id="%s" Directory="INSTALLFOLDER" %s>"]], dstname, subdirectory) + local file_string = string.format([[<File Source="%s" Name="%s" KeyPath="yes"/>]], srcfile, dstname) + + table.insert(result, component_string) + table.insert(result, file_string) + table.insert(result, "</Component>") + end + elseif kind == "rm" then + wprint("rm kind is not supported") + elseif kind == "rmdir" then + wprint("rmdir kind is not supported") + elseif kind == "mv" then + wprint("mv kind is not supported") + elseif kind == "cd" then + wprint("cd kind is not supported") + elseif kind == "mkdir" then + wprint("mkdir kind is not supported") + elseif kind == "wix" then + wprint("wix kind is not supported") + end + return result +end + +-- get commands string +function _get_commands_string(package, cmds, opt) + local cmdstrs = {} + for _, cmd in ipairs(cmds) do + table.join2(cmdstrs, _get_command_strings(package, cmd, opt)) + end + return table.concat(cmdstrs, "\n ") +end + +-- get install commands +function _get_installcmds(package) + return _get_commands_string(package, batchcmds.get_installcmds(package):cmds(), {install = true}) +end + +-- get uninstall commands +function _get_uninstallcmds(package) + return _get_commands_string(package, batchcmds.get_uninstallcmds(package):cmds(), {install = false}) +end + +-- get install commands of component +function _get_component_installcmds(component) + return _get_commands_string(component, batchcmds.get_installcmds(component):cmds(), {install = true}) +end + +-- get uninstall commands of component +function _get_component_uninstallcmds(component) + return _get_commands_string(component, batchcmds.get_uninstallcmds(component):cmds(), {install = false}) +end + +-- get specvars +function _get_specvars(package) + local specvars = table.clone(package:specvars()) + specvars.PACKAGE_INSTALLCMDS = function () + return _get_installcmds(package) + end + + specvars.PACKAGE_WIX_UPGRADECODE = hash.uuid(package:name()) + + -- company cannot be empty with wix + if package:get("company") == nil or package:get("company") == "" then + specvars.PACKAGE_COMPANY = package:name() + end + return specvars +end + +function _pack_wix(wix, package) + + -- install the initial specfile + local specfile = package:specfile() + if not os.isfile(specfile) then + local specfile_template = path.join(os.programdir(), "scripts", "xpack", "wix", "msi.wxs") + os.cp(specfile_template, specfile) + end + + -- replace variables in specfile + local specvars = _get_specvars(package) + local pattern = package:extraconf("specfile", "pattern") or "%${([^\n]-)}" + io.gsub(specfile, "(" .. pattern .. ")", function(_, name) + name = name:trim() + local value = specvars[name] + if type(value) == "function" then + value = value() + end + if value ~= nil then + dprint(" > replace %s -> %s", name, value) + end + if type(value) == "table" then + dprint("invalid variable value", value) + end + return value + end) + + -- make package + -- os.vrunv(wix, {specfile}) +end + +function main(package) + -- only for windows + if not is_host("windows") then + return + end + + cprint("packing %s", package:outputfile()) + + -- get wix + local wix, oldenvs = _get_wix() + + -- pack nsis package + _pack_wix(wix.program, package) + + -- done + os.setenvs(oldenvs) +end
\ No newline at end of file diff --git a/xmake/plugins/pack/xpack.lua b/xmake/plugins/pack/xpack.lua index 0eae84a7a..3dced3d1e 100644 --- a/xmake/plugins/pack/xpack.lua +++ b/xmake/plugins/pack/xpack.lua @@ -230,6 +230,7 @@ function xpack:inputkind() local inputkind = self:get("inputkind") if inputkind == nil then local inputkinds = { + wix = "binary", nsis = "binary", zip = "binary", targz = "binary", @@ -361,6 +362,7 @@ end -- get the specfile path function xpack:specfile() local extensions = { + wix = ".wxs", nsis = ".nsi", srpm = ".spec", rpm = ".spec", @@ -375,6 +377,7 @@ function xpack:extension() local extension = self:get("extension") if extension == nil then local extensions = { + wix = ".msi", nsis = ".exe", zip = ".zip", targz = ".tar.gz", diff --git a/xmake/scripts/xpack/wix/msi.wxs b/xmake/scripts/xpack/wix/msi.wxs new file mode 100644 index 000000000..1860df810 --- /dev/null +++ b/xmake/scripts/xpack/wix/msi.wxs @@ -0,0 +1,36 @@ +<!-- this is a WIX spec file --> +<!-- it is autogenerated by the xmake build system. --> +<!-- do not edit by hand. --> +<?define PackageName = "${PACKAGE_NAME}"?> +<?define PackageTitle = "${PACKAGE_TITLE}"?> +<?define PackageDescription = "${PACKAGE_DESCRIPTION}"?> +<?define PackageAuthor = "${PACKAGE_AUTHOR}"?> +<?define PackageMaintainer = "${PACKAGE_MAINTAINER}"?> +<?define PackageHomepage = "${PACKAGE_HOMEPAGE}"?> +<?define PackageCoypright = "${PACKAGE_COPYRIGHT}"?> +<?define PackageCompany = "${PACKAGE_COMPANY}"?> +<?define PackageIconFile = "${PACKAGE_ICONFILE}"?> +<?define PackageLicense = "${PACKAGE_LICENSE}"?> +<?define PackageLicenseFile = "${PACKAGE_LICENSEFILE}"?> +<?define PackageVersion = "${PACKAGE_VERSION}"?> + +<?define UpgradeCode = "${PACKAGE_WIX_UPGRADECODE}"?> + +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui"> + <Package Language="1033" Manufacturer="$(PackageCompany)" Name="$(PackageName)" UpgradeCode="$(UpgradeCode)" Version="$(PackageVersion)"> + <MajorUpgrade DowngradeErrorMessage="A later version of $(PackageName) is already installed. Setup will now exit." /> + <?if $(PackageIconFile) != "" ?> + <Icon Id="Icon.ico" SourceFile="$(PackageIconFile)"/> + <?endif ?> + <MediaTemplate EmbedCab="yes" /> + <ui:WixUI Id="WixUI_FeatureTree" InstallDirectory="INSTALLFOLDER" /> + <StandardDirectory Id="ProgramFiles6432Folder"> + <Directory Id="CompanyFolder" Name="$(PackageCompany)"> + <Directory Id="INSTALLFOLDER" Name="$(PackageName)"/> + </Directory> + </StandardDirectory> + <Feature Id="MainFeature" Title="$(PackageName)" Description="Installs all the files needed for $(PackageName)" Level="1" AllowAbsent="no" AllowAdvertise="no" ConfigurableDirectory="INSTALLFOLDER"> + ${PACKAGE_INSTALLCMDS} + </Feature> + </Package> +</Wix>
\ No newline at end of file |
