diff options
| author | ruki <[email protected]> | 2021-06-02 17:07:31 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-06-02 17:07:31 +0800 |
| commit | 6002be8be0d3b4813f9b4ee98bae56955295f2e1 (patch) | |
| tree | d8983a239903cbc00dca0bcd4dbf56c612cabf98 | |
| parent | 171780c824fdacef1173f6363c8c173b9906ab9d (diff) | |
| parent | 2394ef36175e66ac6aa5e958f6e487263e0bd6c0 (diff) | |
Merge pull request #1435 from xmake-io/package
Add new local package format
20 files changed, 812 insertions, 255 deletions
diff --git a/tests/actions/package/localpkg/bar/.gitignore b/tests/actions/package/localpkg/bar/.gitignore new file mode 100644 index 000000000..152105761 --- /dev/null +++ b/tests/actions/package/localpkg/bar/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + + diff --git a/tests/actions/package/localpkg/bar/src/main.cpp b/tests/actions/package/localpkg/bar/src/main.cpp new file mode 100644 index 000000000..0102fba75 --- /dev/null +++ b/tests/actions/package/localpkg/bar/src/main.cpp @@ -0,0 +1,10 @@ +#include "foo.h" +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + cout << "foo(1, 2) = " << foo(1, 2) << endl; + return 0; +} diff --git a/tests/actions/package/localpkg/bar/xmake.lua b/tests/actions/package/localpkg/bar/xmake.lua new file mode 100644 index 000000000..9024b2065 --- /dev/null +++ b/tests/actions/package/localpkg/bar/xmake.lua @@ -0,0 +1,11 @@ +add_rules("mode.debug", "mode.release") + +add_repositories("local-repo build") +add_requires("foo") + +target("bar") + set_kind("binary") + add_files("src/*.cpp") + add_packages("foo") + + diff --git a/tests/actions/package/localpkg/libfoo/.gitignore b/tests/actions/package/localpkg/libfoo/.gitignore new file mode 100644 index 000000000..152105761 --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + + diff --git a/tests/actions/package/localpkg/libfoo/src/add.cpp b/tests/actions/package/localpkg/libfoo/src/add.cpp new file mode 100644 index 000000000..e73473e0f --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/src/add.cpp @@ -0,0 +1,6 @@ +#include "add.h" + +int add(int a, int b) +{ + return a + b; +} diff --git a/tests/actions/package/localpkg/libfoo/src/add.h b/tests/actions/package/localpkg/libfoo/src/add.h new file mode 100644 index 000000000..62a39427c --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/src/add.h @@ -0,0 +1,16 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/*! calculate add(a, b) + * + * @param a the first argument + * @param b the second argument + * + * @return the result + */ +int add(int a, int b); + +#ifdef __cplusplus +} +#endif diff --git a/tests/actions/package/localpkg/libfoo/src/foo.cpp b/tests/actions/package/localpkg/libfoo/src/foo.cpp new file mode 100644 index 000000000..b13e8e761 --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/src/foo.cpp @@ -0,0 +1,8 @@ +#include "add.h" +#include "sub.h" +#include "foo.h" + +int foo(int a, int b) +{ + return add(sub(a, b), sub(b, a)); +} diff --git a/tests/actions/package/localpkg/libfoo/src/foo.h b/tests/actions/package/localpkg/libfoo/src/foo.h new file mode 100644 index 000000000..d53be3150 --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/src/foo.h @@ -0,0 +1,16 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/*! calculate foo(a, b) + * + * @param a the first argument + * @param b the second argument + * + * @return the result + */ +int foo(int a, int b); + +#ifdef __cplusplus +} +#endif diff --git a/tests/actions/package/localpkg/libfoo/src/sub.cpp b/tests/actions/package/localpkg/libfoo/src/sub.cpp new file mode 100644 index 000000000..a65acd40f --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/src/sub.cpp @@ -0,0 +1,6 @@ +#include "sub.h" + +int sub(int a, int b) +{ + return a - b; +} diff --git a/tests/actions/package/localpkg/libfoo/src/sub.h b/tests/actions/package/localpkg/libfoo/src/sub.h new file mode 100644 index 000000000..1bda92bc5 --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/src/sub.h @@ -0,0 +1,16 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/*! calculate sub(a, b) + * + * @param a the first argument + * @param b the second argument + * + * @return the result + */ +int sub(int a, int b); + +#ifdef __cplusplus +} +#endif diff --git a/tests/actions/package/localpkg/libfoo/xmake.lua b/tests/actions/package/localpkg/libfoo/xmake.lua new file mode 100644 index 000000000..a6e5c7cb0 --- /dev/null +++ b/tests/actions/package/localpkg/libfoo/xmake.lua @@ -0,0 +1,19 @@ +add_rules("mode.debug", "mode.release") +set_license("Apache-2.0") + +target("sub") + set_kind("static") + add_files("src/sub.cpp") + add_headerfiles("src/sub.h") + +target("add") + set_kind("static") + add_files("src/add.cpp") + add_headerfiles("src/add.h") + +target("foo") + add_deps("add", "sub") + set_kind("static") + add_files("src/foo.cpp") + add_headerfiles("src/foo.h") + diff --git a/tests/actions/package/localpkg/test.lua b/tests/actions/package/localpkg/test.lua new file mode 100644 index 000000000..a1f03b215 --- /dev/null +++ b/tests/actions/package/localpkg/test.lua @@ -0,0 +1,10 @@ +function main(t) + if (os.subarch():startswith("x") or os.subarch() == "i386") and not is_host("bsd") then + os.cd("libfoo") + os.exec("xmake package -D -o ../bar/build") + os.cd("../bar") + os.exec("xmake f -c -D") + os.exec("xmake -D") + os.exec("xmake run") + end +end diff --git a/xmake/actions/package/local/main.lua b/xmake/actions/package/local/main.lua new file mode 100644 index 000000000..75c6b4d72 --- /dev/null +++ b/xmake/actions/package/local/main.lua @@ -0,0 +1,288 @@ +--!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 ruki +-- @file main.lua +-- + +-- imports +import("core.base.option") +import("core.base.task") +import("core.project.rule") +import("core.project.config") +import("core.project.project") +import("lib.luajit.bit") + +-- package binary +function _package_binary(target) + + -- get the output directory + local outputdir = option.get("outputdir") or config.buildir() + local packagename = target:name():lower() + if bit.band(packagename:byte(2), 0xc0) == 0x80 then + wprint("package(%s): cannot generate package, becauese it contains unicode characters!", packagename) + return + end + local packagedir = path.join(outputdir, "packages", packagename:sub(1, 1), packagename) + local binarydir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "bin") + + -- copy the binary file to the output directory + local targetfile = target:targetfile() + os.mkdir(binarydir) + os.vcp(targetfile, binarydir) + os.trycp(target:symbolfile(), binarydir) + + -- generate xmake.lua + local file = io.open(path.join(packagedir, "xmake.lua"), "w") + if file then + local deps = {} + for _, dep in ipairs(target:orderdeps()) do + table.insert(deps, dep:name()) + end + file:print("package(\"%s\")", packagename) + local homepage = option.get("homepage") + if homepage then + file:print(" set_homepage(\"%s\")", homepage) + end + local description = option.get("description") or ("The " .. packagename .. " package") + file:print(" set_description(\"%s\")", description) + if target:license() then + file:print(" set_license(\"%s\")", target:license()) + end + if #deps > 0 then + file:print(" add_deps(\"%s\")", table.concat(deps, "\", \"")) + end + file:print("") + file:print([[ + on_load(function (package) + package:set("installdir", path.join(os.scriptdir(), package:plat(), package:arch(), package:mode())) + end) + + on_fetch(function (package) + return {program = path.join(package:installdir("bin"), "%s")} + end)]], #deps > 0 and ("add_deps(\"" .. table.concat(deps, "\", \"") .. "\")") or "", + path.filename(targetfile)) + file:close() + end + + -- show tips + print("package(%s): %s generated", packagename, packagedir) +end + +-- package library +function _package_library(target) + + -- get the output directory + local outputdir = option.get("outputdir") or config.buildir() + local packagename = target:name():lower() + if bit.band(packagename:byte(2), 0xc0) == 0x80 then + wprint("package(%s): cannot generate package, becauese it contains unicode characters!", packagename) + return + end + local packagedir = path.join(outputdir, "packages", packagename:sub(1, 1), packagename) + local binarydir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "bin") + local librarydir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "lib") + local headerdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "include") + + -- copy the library file to the output directory + local targetfile = target:targetfile() + if target:is_shared() and target:is_plat("windows", "mingw") then + os.mkdir(binarydir) + os.vcp(targetfile, binarydir) + os.trycp(target:symbolfile(), binarydir) + local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib") + if os.isfile(targetfile_lib) then + os.mkdir(librarydir) + os.vcp(targetfile_lib, librarydir) + end + else + os.mkdir(librarydir) + os.vcp(targetfile, librarydir) + os.trycp(target:symbolfile(), librarydir) + end + + -- copy headers + local srcheaders, dstheaders = target:headerfiles(headerdir) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + os.vcp(srcheader, dstheader) + end + i = i + 1 + end + end + + -- generate xmake.lua + local file = io.open(path.join(packagedir, "xmake.lua"), "w") + if file then + local deps = {} + for _, dep in ipairs(target:orderdeps()) do + table.insert(deps, dep:name()) + end + file:print("package(\"%s\")", packagename) + local homepage = option.get("homepage") + if homepage then + file:print(" set_homepage(\"%s\")", homepage) + end + local description = option.get("description") or ("The " .. packagename .. " package") + file:print(" set_description(\"%s\")", description) + if target:license() then + file:print(" set_license(\"%s\")", target:license()) + end + if #deps > 0 then + file:print(" add_deps(\"%s\")", table.concat(deps, "\", \"")) + end + file:print("") + file:print([[ + on_load(function (package) + package:set("installdir", path.join(os.scriptdir(), package:plat(), package:arch(), package:mode())) + end) + + on_fetch(function (package) + local result = {} + result.links = "%s" + result.linkdirs = package:installdir("lib") + result.includedirs = package:installdir("include") + return result + end)]], target:linkname(), + path.filename(targetfile)) + file:close() + end + + -- show tips + print("package(%s): %s generated", packagename, packagedir) +end + +-- do package target +function _do_package_target(target) + if not target:is_phony() then + local scripts = + { + binary = _package_binary + , static = _package_library + , shared = _package_library + } + local kind = target:kind() + assert(scripts[kind], "this target(%s) with kind(%s) can not be packaged!", target:name(), kind) + scripts[kind](target) + end +end + +-- package target +function _on_package_target(target) + local done = false + for _, r in ipairs(target:orderules()) do + local on_package = r:script("package") + if on_package then + on_package(target) + done = true + end + end + if done then return end + _do_package_target(target) +end + +-- package the given target +function _package_target(target) + + -- has been disabled? + if not target:is_enabled() then + return + end + + -- enter project directory + local oldir = os.cd(project.directory()) + + -- enter the environments of the target packages + local oldenvs = os.addenvs(target:pkgenvs()) + + -- the target scripts + local scripts = + { + target:script("package_before") + , function (target) + for _, r in ipairs(target:orderules()) do + local before_package = r:script("package_before") + if before_package then + before_package(target) + end + end + end + , target:script("package", _on_package_target) + , function (target) + for _, r in ipairs(target:orderules()) do + local after_package = r:script("package_after") + if after_package then + after_package(target) + end + end + end + , target:script("package_after") + } + + -- package the target scripts + for i = 1, 5 do + local script = scripts[i] + if script ~= nil then + script(target) + end + end + + -- leave the environments of the target packages + os.setenvs(oldenvs) + + -- leave project directory + os.cd(oldir) +end + +-- package the given targets +function _package_targets(targets) + for _, target in ipairs(targets) do + _package_target(target) + end +end + +-- main +function main() + + -- lock the whole project + project.lock() + + -- get the target name + local targetname = option.get("target") + + -- build it first + task.run("build", {target = targetname, all = option.get("all")}) + + -- package the given target? + if targetname then + local target = project.target(targetname) + _package_targets(target:orderdeps()) + _package_target(target) + else + -- package default or all targets + for _, target in ipairs(project.ordertargets()) do + if target:is_default() or option.get("all") then + _package_target(target) + end + end + end + + -- unlock the whole project + project.unlock() +end diff --git a/xmake/actions/package/main.lua b/xmake/actions/package/main.lua index a1fcab5ed..78835bb61 100644 --- a/xmake/actions/package/main.lua +++ b/xmake/actions/package/main.lua @@ -20,217 +20,8 @@ -- imports import("core.base.option") -import("core.base.task") -import("core.base.global") -import("core.project.rule") -import("core.project.config") -import("core.project.project") -import("core.platform.platform") --- package library -function _package_library(target) - - -- the output directory - local outputdir = option.get("outputdir") or config.buildir() - - -- the target name - local targetname = target:name() - - -- copy the library file to the output directory - os.vcp(target:targetfile(), format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(target:targetfile()))) - - -- copy the symbol file to the output directory - local symbolfile = target:symbolfile() - if os.isfile(symbolfile) then - os.vcp(symbolfile, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(symbolfile))) - end - - -- copy *.lib for shared/windows (*.dll) target - -- @see https://github.com/xmake-io/xmake/issues/787 - if target:kind() == "shared" and is_plat("windows", "mingw") then - local targetfile = target:targetfile() - local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib") - if os.isfile(targetfile_lib) then - os.vcp(targetfile_lib, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/", outputdir, targetname)) - end - end - - -- copy the config.h to the output directory (deprecated) - local configheader = target:configheader() - if configheader then - os.vcp(configheader, format("%s/%s.pkg/$(plat)/$(arch)/include/%s", outputdir, targetname, path.filename(configheader))) - end - - -- copy headers - local srcheaders, dstheaders = target:headerfiles(format("%s/%s.pkg/$(plat)/$(arch)/include", outputdir, targetname)) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - os.vcp(srcheader, dstheader) - end - i = i + 1 - end - end - - -- make xmake.lua - local file = io.open(format("%s/%s.pkg/xmake.lua", outputdir, targetname), "w") - if file then - file:print("option(\"%s\")", targetname) - file:print(" set_showmenu(true)") - file:print(" set_category(\"package\")") - file:print(" add_links(\"%s\")", target:basename()) - file:write(" add_linkdirs(\"$(plat)/$(arch)/lib/$(mode)\")\n") - file:write(" add_includedirs(\"$(plat)/$(arch)/include\")\n") - local languages = target:get("languages") - if languages then - file:print(" set_languages(\"%s\")", table.concat(table.wrap(languages), "\", \"")) - end - file:close() - end -end - --- do package target -function _do_package_target(target) - - -- is phony target? - if target:is_phony() then - return - end - - -- get kind - local kind = target:kind() - - -- get script - local scripts = - { - binary = function (target) end - , static = _package_library - , shared = _package_library - } - - -- check - assert(scripts[kind], "this target(%s) with kind(%s) can not be packaged!", target:name(), kind) - - -- package it - scripts[kind](target) -end - --- package target -function _on_package_target(target) - - -- build target with rules - local done = false - for _, r in ipairs(target:orderules()) do - local on_package = r:script("package") - if on_package then - on_package(target) - done = true - end - end - if done then return end - - -- do package - _do_package_target(target) -end - --- package the given target -function _package_target(target) - - -- has been disabled? - if not target:is_enabled() then - return - end - - -- enter project directory - local oldir = os.cd(project.directory()) - - -- enter the environments of the target packages - local oldenvs = os.addenvs(target:pkgenvs()) - - -- the target scripts - local scripts = - { - target:script("package_before") - , function (target) - for _, r in ipairs(target:orderules()) do - local before_package = r:script("package_before") - if before_package then - before_package(target) - end - end - end - , target:script("package", _on_package_target) - , function (target) - for _, r in ipairs(target:orderules()) do - local after_package = r:script("package_after") - if after_package then - after_package(target) - end - end - end - , target:script("package_after") - } - - -- package the target scripts - for i = 1, 5 do - local script = scripts[i] - if script ~= nil then - script(target) - end - end - - -- leave the environments of the target packages - os.setenvs(oldenvs) - - -- leave project directory - os.cd(oldir) -end - --- package the given targets -function _package_targets(targets) - for _, target in ipairs(targets) do - _package_target(target) - end -end - --- main +-- main entry function main() - - -- --archs? deprecated - if option.get("archs") then - - -- load config - config.load() - - -- deprecated - raise("please run \"xmake m package %s\" instead of \"xmake p --archs=%s\"", config.get("plat"), option.get("archs")) - end - - -- lock the whole project - project.lock() - - -- get the target name - local targetname = option.get("target") - - -- build it first - task.run("build", {target = targetname, all = option.get("all")}) - - -- package the given target? - if targetname then - local target = project.target(targetname) - _package_targets(target:orderdeps()) - _package_target(target) - else - -- package default or all targets - for _, target in ipairs(project.ordertargets()) do - if target:is_default() or option.get("all") then - _package_target(target) - end - end - end - - -- unlock the whole project - project.lock() + import(option.get("format") or "local")() end diff --git a/xmake/actions/package/oldpkg/main.lua b/xmake/actions/package/oldpkg/main.lua new file mode 100644 index 000000000..d47d8d474 --- /dev/null +++ b/xmake/actions/package/oldpkg/main.lua @@ -0,0 +1,209 @@ +--!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 ruki +-- @file main.lua +-- + +-- imports +import("core.base.option") +import("core.base.task") +import("core.project.rule") +import("core.project.config") +import("core.project.project") + +-- package library +function _package_library(target) + + -- the output directory + local outputdir = option.get("outputdir") or config.buildir() + + -- the target name + local targetname = target:name() + + -- copy the library file to the output directory + os.vcp(target:targetfile(), format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(target:targetfile()))) + + -- copy the symbol file to the output directory + local symbolfile = target:symbolfile() + if os.isfile(symbolfile) then + os.vcp(symbolfile, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(symbolfile))) + end + + -- copy *.lib for shared/windows (*.dll) target + -- @see https://github.com/xmake-io/xmake/issues/787 + if target:is_shared() and target:is_plat("windows", "mingw") then + local targetfile = target:targetfile() + local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib") + if os.isfile(targetfile_lib) then + os.vcp(targetfile_lib, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/", outputdir, targetname)) + end + end + + -- copy the config.h to the output directory (deprecated) + local configheader = target:configheader() + if configheader then + os.vcp(configheader, format("%s/%s.pkg/$(plat)/$(arch)/include/%s", outputdir, targetname, path.filename(configheader))) + end + + -- copy headers + local srcheaders, dstheaders = target:headerfiles(format("%s/%s.pkg/$(plat)/$(arch)/include", outputdir, targetname)) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + os.vcp(srcheader, dstheader) + end + i = i + 1 + end + end + + -- make xmake.lua + local file = io.open(format("%s/%s.pkg/xmake.lua", outputdir, targetname), "w") + if file then + file:print("option(\"%s\")", targetname) + file:print(" set_showmenu(true)") + file:print(" set_category(\"package\")") + file:print(" add_links(\"%s\")", target:basename()) + file:write(" add_linkdirs(\"$(plat)/$(arch)/lib/$(mode)\")\n") + file:write(" add_includedirs(\"$(plat)/$(arch)/include\")\n") + local languages = target:get("languages") + if languages then + file:print(" set_languages(\"%s\")", table.concat(table.wrap(languages), "\", \"")) + end + file:close() + end +end + +-- do package target +function _do_package_target(target) + if not target:is_phony() then + local scripts = + { + binary = function (target) end + , static = _package_library + , shared = _package_library + } + local kind = target:kind() + assert(scripts[kind], "this target(%s) with kind(%s) can not be packaged!", target:name(), kind) + scripts[kind](target) + end +end + +-- package target +function _on_package_target(target) + local done = false + for _, r in ipairs(target:orderules()) do + local on_package = r:script("package") + if on_package then + on_package(target) + done = true + end + end + if done then return end + _do_package_target(target) +end + +-- package the given target +function _package_target(target) + + -- has been disabled? + if not target:is_enabled() then + return + end + + -- enter project directory + local oldir = os.cd(project.directory()) + + -- enter the environments of the target packages + local oldenvs = os.addenvs(target:pkgenvs()) + + -- the target scripts + local scripts = + { + target:script("package_before") + , function (target) + for _, r in ipairs(target:orderules()) do + local before_package = r:script("package_before") + if before_package then + before_package(target) + end + end + end + , target:script("package", _on_package_target) + , function (target) + for _, r in ipairs(target:orderules()) do + local after_package = r:script("package_after") + if after_package then + after_package(target) + end + end + end + , target:script("package_after") + } + + -- package the target scripts + for i = 1, 5 do + local script = scripts[i] + if script ~= nil then + script(target) + end + end + + -- leave the environments of the target packages + os.setenvs(oldenvs) + + -- leave project directory + os.cd(oldir) +end + +-- package the given targets +function _package_targets(targets) + for _, target in ipairs(targets) do + _package_target(target) + end +end + +-- main +function main() + + -- lock the whole project + project.lock() + + -- get the target name + local targetname = option.get("target") + + -- build it first + task.run("build", {target = targetname, all = option.get("all")}) + + -- package the given target? + if targetname then + local target = project.target(targetname) + _package_targets(target:orderdeps()) + _package_target(target) + else + -- package default or all targets + for _, target in ipairs(project.ordertargets()) do + if target:is_default() or option.get("all") then + _package_target(target) + end + end + end + + -- unlock the whole project + project.unlock() +end diff --git a/xmake/actions/package/remote/main.lua b/xmake/actions/package/remote/main.lua new file mode 100644 index 000000000..0e8383890 --- /dev/null +++ b/xmake/actions/package/remote/main.lua @@ -0,0 +1,137 @@ +--!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 ruki +-- @file main.lua +-- + +-- imports +import("core.base.option") +import("core.base.task") +import("core.project.rule") +import("core.project.config") +import("core.project.project") +import("lib.luajit.bit") + +-- package remote +function _package_remote(target) + + -- get the output directory + local outputdir = option.get("outputdir") or config.buildir() + local packagename = target:name():lower() + if bit.band(packagename:byte(2), 0xc0) == 0x80 then + wprint("package(%s): cannot generate package, becauese it contains unicode characters!", packagename) + return + end + local packagedir = path.join(outputdir, "packages", packagename:sub(1, 1), packagename) + + -- generate xmake.lua + local file = io.open(path.join(packagedir, "xmake.lua"), "w") + if file then + local deps = {} + for _, dep in ipairs(target:orderdeps()) do + table.insert(deps, dep:name()) + end + file:print("package(\"%s\")", packagename) + if target:is_binary() then + file:print(" set_kind(\"binary\")") + end + local homepage = option.get("homepage") + if homepage then + file:print(" set_homepage(\"%s\")", homepage) + end + local description = option.get("description") or ("The " .. packagename .. " package") + file:print(" set_description(\"%s\")", description) + if target:license() then + file:print(" set_license(\"%s\")", target:license()) + end + if #deps > 0 then + file:print(" add_deps(\"%s\")", table.concat(deps, "\", \"")) + end + file:print("") + local url = option.get("url") or "https://github.com/myrepo/foo.git" + local version = option.get("version") or target:version() and (target:version()) or "1.0" + local shasum = option.get("shasum") or "<shasum256 or gitcommit>" + file:print(" add_urls(\"%s\")", url) + file:print(" add_versions(\"%s\", \"%s\")", version, shasum) + file:print("") + file:print([[ + on_install(function (package) + local configs = {} + if package:config("shared") then + configs.kind = "shared" + end + import("package.tools.xmake").install(package, configs) + end) + + on_test(function (package) + -- TODO check includes and interfaces + -- assert(package:has_cfuncs("foo", {includes = "foo.h"}) + end)]]) + file:close() + end + + -- show tips + print("package(%s): %s generated", packagename, packagedir) +end + +-- package target +function _package_target(target) + if not target:is_phony() then + local scripts = + { + binary = _package_remote + , static = _package_remote + , shared = _package_remote + } + local kind = target:kind() + assert(scripts[kind], "this target(%s) with kind(%s) can not be packaged!", target:name(), kind) + scripts[kind](target) + end +end + +-- package the given targets +function _package_targets(targets) + for _, target in ipairs(targets) do + _package_target(target) + end +end + +-- main +function main() + + -- lock the whole project + project.lock() + + -- package the given target? + local targetname = option.get("target") + if targetname then + local target = project.target(targetname) + _package_targets(target:orderdeps()) + _package_target(target) + else + -- package default or all targets + for _, target in ipairs(project.ordertargets()) do + if target:is_default() or option.get("all") then + _package_target(target) + end + end + end + + -- unlock the whole project + project.unlock() +end + diff --git a/xmake/actions/package/xmake.lua b/xmake/actions/package/xmake.lua index d30815a98..dd7b1846f 100644 --- a/xmake/actions/package/xmake.lua +++ b/xmake/actions/package/xmake.lua @@ -18,36 +18,31 @@ -- @file xmake.lua -- --- define task task("package") - - -- set category set_category("action") - - -- on run on_run("main") - - -- set menu set_menu { - -- usage - usage = "xmake package|p [options] [target]" - - -- description - , description = "Package target." - - -- xmake p - , shortname = 'p' - - -- options - , options = - { - {'o', "outputdir", "kv", nil , "Set the output directory." } - , {'a', "all", "k", nil , "Package all targets." } - , {} - , {nil, "target", "v", nil , "The target name. It will package all default targets if this parameter is not specified." - , values = function (complete, opt) return import("private.utils.complete_helper.targets")(complete, opt) end } - } - } + usage = "xmake package|p [options] [target]", + description = "Package target.", + shortname = 'p', + options = { + {'o', "outputdir", "kv", nil, "Set the output directory."}, + {'a', "all", "k", nil, "Package all targets."}, + {}, + {'f', "format", "kv", "local", "Set the package format.", + values = {"oldpkg", "local", "remote"}}, + {nil, "homepage", "kv", nil, "Set the homepage of package."}, + {nil, "description","kv", nil, "Set the description of package."}, + {nil, "url", "kv", nil, "Set the url of remote package."}, + {nil, "version", "kv", nil, "Set the version of remove package."}, + {nil, "shasum", "kv", nil, "Set the sha256 or commit of remote package."}, + {}, + {nil, "target", "v", nil, "The target name. It will package all default targets if this parameter is not specified.", + values = function (complete, opt) + return import("private.utils.complete_helper.targets")(complete, opt) + end } + } + } diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua index c53a43d38..d68bcff57 100644 --- a/xmake/core/package/package.lua +++ b/xmake/core/package/package.lua @@ -475,12 +475,20 @@ end -- get the installed directory of this package function _instance:installdir(...) - local name = self:name():lower():gsub("::", "_") - local dir = path.join(package.installdir(), name:sub(1, 1):lower(), name) - if self:version_str() then - dir = path.join(dir, self:version_str()) + local installdir = self._INSTALLDIR + if not installdir then + installdir = self:get("installdir") + if not installdir then + local name = self:name():lower():gsub("::", "_") + installdir = path.join(package.installdir(), name:sub(1, 1):lower(), name) + if self:version_str() then + installdir = path.join(installdir, self:version_str()) + end + installdir = path.join(installdir, self:buildhash()) + end + self._INSTALLDIR = installdir end - dir = path.join(dir, self:buildhash(), ...) + local dir = path.join(installdir, ...) if not os.isdir(dir) then os.mkdir(dir) end @@ -1226,7 +1234,7 @@ function _instance:fetch(opt) if self:is_binary() then -- only fetch it from the xmake repository first - if not fetchinfo and system ~= true and not self:is_thirdparty() and not self:is_fetchonly() then + if not fetchinfo and system ~= true and not self:is_thirdparty() then fetchinfo = self:_fetch_tool({require_version = self:version_str(), force = opt.force}) if fetchinfo then is_system = self._is_system @@ -1243,7 +1251,7 @@ function _instance:fetch(opt) else -- only fetch it from the xmake repository first - if not fetchinfo and system ~= true and not self:is_thirdparty() and not self:is_fetchonly() then + if not fetchinfo and system ~= true and not self:is_thirdparty() then fetchinfo = self:_fetch_library({require_version = self:version_str(), external = external, force = opt.force}) if fetchinfo then is_system = self._is_system @@ -1646,6 +1654,7 @@ function package.apis() , "package.set_homepage" , "package.set_description" , "package.set_parallelize" + , "package.set_installdir" -- package.add_xxx , "package.add_deps" , "package.add_urls" diff --git a/xmake/modules/net/proxy.lua b/xmake/modules/net/proxy.lua index 8259a07c9..6aac4af4c 100644 --- a/xmake/modules/net/proxy.lua +++ b/xmake/modules/net/proxy.lua @@ -108,7 +108,7 @@ function config(url) -- enable proxy for the given url and configuration pattern if url then - -- get proxy from the given hosts pattern + -- filter proxy host from the given hosts pattern local host = url:match("://(.-)/") or url:match("@(.-):") local proxy_hosts = _proxy_hosts() if host and proxy_hosts then @@ -121,11 +121,13 @@ function config(url) end end - -- get proxy from the pac file + -- filter proxy host from the pac file local proxy_pac = _proxy_pac() - if proxy_pac and _is_callable(proxy_pac) and proxy_pac(url, host) then + if proxy_pac and host and _is_callable(proxy_pac) and proxy_pac(url, host) then return global.get("proxy") end + + -- use global proxy if not proxy_pac and not proxy_hosts then return global.get("proxy") end diff --git a/xmake/modules/private/action/require/impl/repository.lua b/xmake/modules/private/action/require/impl/repository.lua index 6a0471f8b..f997ee703 100644 --- a/xmake/modules/private/action/require/impl/repository.lua +++ b/xmake/modules/private/action/require/impl/repository.lua @@ -70,17 +70,9 @@ function packagedir(packagename, reponame) break end end - - -- found? if foundir then - - -- save package directory packagedirs[packagename] = foundir - - -- update cache _g._PACKAGEDIRS = packagedirs - - -- ok return foundir[1], foundir[2] end end |
