summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-12-21 11:28:30 +0800
committerGitHub <[email protected]>2021-12-21 11:28:30 +0800
commitd20addbf37d7ddf32e5b1943a641d7e4072d32fb (patch)
treebd5b5b024372040b144ebbef24ad424e24f4187b
parentfde9f472906c2b7061afa5afed4128817ffd15c1 (diff)
parentce000fa3f72ea6c4ca684a3d08b1e6cf09f5fb68 (diff)
Merge pull request #1931 from xmake-io/vcpkg
Support vcpkg manifest mode
-rw-r--r--tests/projects/package/vcpkg_manifest/.gitignore8
-rw-r--r--tests/projects/package/vcpkg_manifest/src/main.cpp9
-rw-r--r--tests/projects/package/vcpkg_manifest/xmake.lua9
-rw-r--r--xmake/core/package/package.lua23
-rw-r--r--xmake/modules/package/manager/vcpkg/configurations.lua48
-rw-r--r--xmake/modules/package/manager/vcpkg/find_package.lua75
-rw-r--r--xmake/modules/package/manager/vcpkg/install_package.lua147
7 files changed, 240 insertions, 79 deletions
diff --git a/tests/projects/package/vcpkg_manifest/.gitignore b/tests/projects/package/vcpkg_manifest/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/package/vcpkg_manifest/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/package/vcpkg_manifest/src/main.cpp b/tests/projects/package/vcpkg_manifest/src/main.cpp
new file mode 100644
index 000000000..7c435d251
--- /dev/null
+++ b/tests/projects/package/vcpkg_manifest/src/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "hello world!" << endl;
+ return 0;
+}
diff --git a/tests/projects/package/vcpkg_manifest/xmake.lua b/tests/projects/package/vcpkg_manifest/xmake.lua
new file mode 100644
index 000000000..5c08f2869
--- /dev/null
+++ b/tests/projects/package/vcpkg_manifest/xmake.lua
@@ -0,0 +1,9 @@
+add_requires("vcpkg::zlib 1.2.11")
+add_requires("vcpkg::fmt >=8.0.1", {configs = {baseline = "50fd3d9957195575849a49fa591e645f1d8e7156"}})
+add_requires("vcpkg::libpng", {configs = {features = {"apng"}}})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.cpp")
+ add_packages("vcpkg::zlib", "vcpkg::fmt", "vcpkg::libpng")
+
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 88a5d07fb..379d1ddea 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -486,7 +486,7 @@ end
-- is local package?
-- we will use local installdir and cachedir in current project
function _instance:is_local()
- return self:is_embed()
+ return self:is_embed() or self:is_thirdparty()
end
-- is debug package? (deprecated)
@@ -570,10 +570,15 @@ function _instance:cachedir()
cachedir = self:get("cachedir")
if not cachedir then
local name = self:name():lower():gsub("::", "_")
+ local version_str = self:version_str()
+ if self:is_thirdparty() then
+ -- strip `>= <=`
+ version_str = version_str:gsub("[>=<]", "")
+ end
if self:is_local() then
- cachedir = path.join(config.buildir({absolute = true}), ".packages", name:sub(1, 1):lower(), name, self:version_str(), "cache")
+ cachedir = path.join(config.buildir({absolute = true}), ".packages", name:sub(1, 1):lower(), name, version_str, "cache")
else
- cachedir = path.join(package.cachedir(), name:sub(1, 1):lower(), name, self:version_str())
+ cachedir = path.join(package.cachedir(), name:sub(1, 1):lower(), name, version_str)
end
end
self._CACHEDIR = cachedir
@@ -593,8 +598,13 @@ function _instance:installdir(...)
else
installdir = path.join(package.installdir(), name:sub(1, 1):lower(), name)
end
- if self:version_str() then
- installdir = path.join(installdir, self:version_str())
+ local version_str = self:version_str()
+ if version_str then
+ if self:is_thirdparty() then
+ -- strip `>= <=`
+ version_str = version_str:gsub("[>=<]", "")
+ end
+ installdir = path.join(installdir, version_str)
end
installdir = path.join(installdir, self:buildhash())
end
@@ -1054,6 +1064,9 @@ function _instance:buildhash()
-- We cannot directly deserialize the table, so the result may be different each time
local configs_order = {}
for k, v in pairs(table.wrap(configs)) do
+ if type(v) == "table" then
+ v = string.serialize(v, {strip = true, indent = false, orderkeys = true})
+ end
table.insert(configs_order, k .. "=" .. tostring(v))
end
table.sort(configs_order)
diff --git a/xmake/modules/package/manager/vcpkg/configurations.lua b/xmake/modules/package/manager/vcpkg/configurations.lua
new file mode 100644
index 000000000..9021edff0
--- /dev/null
+++ b/xmake/modules/package/manager/vcpkg/configurations.lua
@@ -0,0 +1,48 @@
+--!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 configurations.lua
+--
+
+-- get architecture for vcpkg
+function arch(arch)
+ local archs = {
+ x86_64 = "x64",
+ i386 = "x86",
+
+ -- android: armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mip64
+ -- Offers a doc: https://github.com/microsoft/vcpkg/blob/master/docs/users/android.md
+ ["armeabi-v7a"] = "arm",
+ ["arm64-v8a"] = "arm64",
+
+ -- ios: arm64 armv7 armv7s i386
+ armv7 = "arm",
+ armv7s = "arm",
+ arm64 = "arm64",
+ }
+ return archs[arch] or arch
+end
+
+-- get configurations
+function main()
+ return {
+ baseline = {description = "set the builtin baseline."},
+ features = {description = "set the features of dependency."},
+ default_features = {description = "enables or disables any defaults provided by the dependency.", default = true}
+ }
+end
+
diff --git a/xmake/modules/package/manager/vcpkg/find_package.lua b/xmake/modules/package/manager/vcpkg/find_package.lua
index 24500cc2a..c28f62b07 100644
--- a/xmake/modules/package/manager/vcpkg/find_package.lua
+++ b/xmake/modules/package/manager/vcpkg/find_package.lua
@@ -25,22 +25,9 @@ import("core.base.option")
import("core.project.config")
import("core.project.target")
import("detect.sdks.find_vcpkgdir")
+import("package.manager.vcpkg.configurations")
--- find package from the vcpkg package manager
---
--- @param name the package name, e.g. zlib, pcre
--- @param opt the options, e.g. {verbose = true)
---
-function main(name, opt)
-
- -- attempt to find vcpkg directory
- local vcpkgdir = find_vcpkgdir()
- if not vcpkgdir then
- if option.get("diagnosis") then
- cprint("${color.warning}checkinfo: ${clear dim}vcpkg root directory not found, maybe you need set $VCPKG_ROOT!")
- end
- return
- end
+function _find_package(vcpkgdir, name, opt)
-- fix name, e.g. ffmpeg[x264] as ffmpeg
-- @see https://github.com/xmake-io/xmake/issues/925
@@ -50,35 +37,16 @@ function main(name, opt)
local arch = opt.arch
local plat = opt.plat
local mode = opt.mode
-
- -- mapping plat
if plat == "macosx" then
plat = "osx"
end
+ arch = configurations.arch(arch)
- -- archs mapping for vcpkg
- local archs = {
- x86_64 = "x64",
- i386 = "x86",
-
- -- android: armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mip64
- -- Offers a doc: https://github.com/microsoft/vcpkg/blob/master/docs/users/android.md
- ["armeabi-v7a"] = "arm",
- ["arm64-v8a"] = "arm64",
-
- -- ios: arm64 armv7 armv7s i386
- armv7 = "arm",
- armv7s = "arm",
- arm64 = "arm64",
+ -- get the vcpkg info directories
+ local infodirs = {
+ path.join(opt.installdir, "vcpkg_installed", "vcpkg", "info"),
+ path.join(vcpkgdir, "installed", "vcpkg", "info")
}
- -- mapping arch
- arch = archs[arch] or arch
-
- -- get the vcpkg installed directory
- local installdir = path.join(vcpkgdir, "installed")
-
- -- get the vcpkg info directory
- local infodir = path.join(installdir, "vcpkg", "info")
-- find the package info file, e.g. zlib_1.2.11-3_x86-windows[-static].list
local triplet = arch .. "-" .. plat
@@ -89,11 +57,15 @@ function main(name, opt)
triplet = triplet .. "-md"
end
end
- local infofile = find_file(format("%s_*_%s.list", name, triplet), infodir)
+ local infofile = find_file(format("%s_*_%s.list", name, triplet), infodirs)
+ if not infofile then
+ return
+ end
+ local installdir = path.directory(path.directory(path.directory(infofile)))
-- save includedirs, linkdirs and links
local result = nil
- local info = infofile and io.readfile(infofile) or nil
+ local info = io.readfile(infofile)
if info then
for _, line in ipairs(info:split('\n')) do
line = line:trim()
@@ -135,7 +107,7 @@ function main(name, opt)
end
-- save version
- if result and infofile then
+ if result then
local infoname = path.basename(infofile)
result.version = infoname:match(name .. "_(%d+%.?%d*%.?%d*.-)_" .. arch)
if not result.version then
@@ -155,3 +127,22 @@ function main(name, opt)
return result
end
+-- find package from the vcpkg package manager
+--
+-- @param name the package name, e.g. zlib, pcre
+-- @param opt the options, e.g. {verbose = true)
+--
+function main(name, opt)
+
+ -- attempt to find vcpkg directory
+ local vcpkgdir = find_vcpkgdir()
+ if not vcpkgdir then
+ if option.get("diagnosis") then
+ cprint("${color.warning}checkinfo: ${clear dim}vcpkg root directory not found, maybe you need set $VCPKG_ROOT!")
+ end
+ return
+ end
+
+ -- do find package
+ return _find_package(vcpkgdir, name, opt)
+end
diff --git a/xmake/modules/package/manager/vcpkg/install_package.lua b/xmake/modules/package/manager/vcpkg/install_package.lua
index eaf28710e..9b7ded261 100644
--- a/xmake/modules/package/manager/vcpkg/install_package.lua
+++ b/xmake/modules/package/manager/vcpkg/install_package.lua
@@ -20,52 +20,67 @@
-- imports
import("core.base.option")
+import("core.base.json")
+import("core.base.semver")
import("lib.detect.find_tool")
+import("package.manager.vcpkg.configurations")
--- install package
---
--- @param name the package name, e.g. pcre2, pcre2/libpcre2-8
--- @param opt the options, e.g. {verbose = true}
---
--- @return true or false
---
-function main(name, opt)
-
- -- attempt to find vcpkg
- local vcpkg = find_tool("vcpkg")
- if not vcpkg then
- raise("vcpkg not found!")
+-- need manifest mode?
+function _need_manifest(opt)
+ local require_version = opt.require_version
+ if require_version ~= nil and require_version ~= "latest" then
+ return true
end
+ local configs = opt.configs
+ if configs and (configs.features or configs.default_features == false or configs.baseline) then
+ return true
+ end
+end
+
+-- install for classic mode
+function _install_for_classic(vcpkg, name, opt)
-- get arch, plat and mode
local arch = opt.arch
local plat = opt.plat
local mode = opt.mode
-
- -- mapping plat
if plat == "macosx" then
plat = "osx"
end
+ arch = configurations.arch(arch)
- -- archs mapping for vcpkg
- local archs = {
- x86_64 = "x64",
- i386 = "x86",
+ -- init triplet
+ local triplet = arch .. "-" .. plat
+ if opt.plat == "windows" and opt.shared ~= true then
+ triplet = triplet .. "-static"
+ if opt.vs_runtime and opt.vs_runtime:startswith("MD") then
+ triplet = triplet .. "-md"
+ end
+ end
+
+ -- init argv
+ local argv = {"install", name .. ":" .. triplet}
+ if option.get("diagnosis") then
+ table.insert(argv, "--debug")
+ end
+
+ -- install package
+ os.vrunv(vcpkg, argv)
+end
- -- android: armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mip64
- -- Offers a doc: https://github.com/microsoft/vcpkg/blob/master/docs/users/android.md
- ["armeabi-v7a"] = "arm",
- ["arm64-v8a"] = "arm64",
+-- install for manifest mode
+function _install_for_manifest(vcpkg, name, opt)
- -- ios: arm64 armv7 armv7s i386
- armv7 = "arm",
- armv7s = "arm",
- arm64 = "arm64",
- }
- -- mapping arch
- arch = archs[arch] or arch
+ -- get configs
+ local configs = opt.configs or {}
-- init triplet
+ local arch = opt.arch
+ local plat = opt.plat
+ if plat == "macosx" then
+ plat = "osx"
+ end
+ arch = configurations.arch(arch)
local triplet = arch .. "-" .. plat
if opt.plat == "windows" and opt.shared ~= true then
triplet = triplet .. "-static"
@@ -75,11 +90,79 @@ function main(name, opt)
end
-- init argv
- local argv = {"install", name .. ":" .. triplet}
+ local argv = {"--feature-flags=\"versions\"", "install", "--triplet", triplet}
if option.get("diagnosis") then
table.insert(argv, "--debug")
end
+ -- generate platform
+ local platform = plat .. " & " .. arch
+
+ -- generate dependencies
+ local require_version = opt.require_version
+ if require_version == "latest" then
+ require_version = nil
+ end
+ local minversion = require_version
+ if minversion and minversion:startswith(">=") then
+ minversion = minversion:sub(3)
+ end
+ local dependencies = {}
+ table.insert(dependencies, {
+ name = name,
+ ["version>="] = minversion,
+ platform = platform,
+ features = configs.features,
+ ["default-features"] = configs.default_features})
+
+ -- generate overrides to use fixed version
+ local overrides
+ if require_version and semver.is_valid(require_version) then
+ overrides = {{name = name, version = require_version}}
+ end
+
+ -- generate manifest
+ local baseline = configs.baseline or "44d94c2edbd44f0c01d66c2ad95eb6982a9a61bc" -- 2021.04.30
+ local manifest = {
+ name = "stub",
+ version = "1.0",
+ dependencies = dependencies,
+ ["builtin-baseline"] = baseline,
+ overrides = overrides}
+ local installdir = assert(opt.installdir, "installdir not found!")
+ json.savefile(path.join(installdir, "vcpkg.json"), manifest)
+ if not os.isdir(installdir) then
+ os.mkdir(installdir)
+ end
+ if option.get("diagnosis") then
+ vprint(path.join(installdir, "vcpkg.json"))
+ vprint(manifest)
+ end
+
-- install package
- os.vrunv(vcpkg.program, argv)
+ os.vrunv(vcpkg, argv, {curdir = installdir})
+end
+
+-- install package
+--
+-- @param name the package name, e.g. pcre2, pcre2/libpcre2-8
+-- @param opt the options, e.g. {verbose = true}
+--
+-- @return true or false
+--
+function main(name, opt)
+
+ -- attempt to find vcpkg
+ local vcpkg = find_tool("vcpkg")
+ if not vcpkg then
+ raise("vcpkg not found!")
+ end
+
+ -- do install
+ opt = opt or {}
+ if _need_manifest(opt) then
+ _install_for_manifest(vcpkg.program, name, opt)
+ else
+ _install_for_classic(vcpkg.program, name, opt)
+ end
end