summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-03-20 14:54:49 +0800
committerruki <[email protected]>2019-03-20 14:54:49 +0800
commit85deccc73a0278e01fa8580b68b38f16e0598bf7 (patch)
treea9a446a5be5ca662525df921e50ce66029bc3359
parent57506c7b8ba8941ebac3676a241f8444e0079a56 (diff)
parent8bb6ddf5c40f15fe6570f73dc5c4e5295ce95180 (diff)
Merge branch 'repo' into dev
-rw-r--r--.appveyor.yml4
-rw-r--r--CHANGELOG.md2
-rw-r--r--xmake/actions/build/build.lua12
-rw-r--r--xmake/actions/clean/main.lua12
-rw-r--r--xmake/actions/install/install.lua12
-rw-r--r--xmake/actions/package/main.lua12
-rw-r--r--xmake/actions/require/clean.lua87
-rw-r--r--xmake/actions/require/impl/action/download.lua12
-rw-r--r--xmake/actions/require/impl/action/install.lua121
-rw-r--r--xmake/actions/require/impl/action/prefix/install.lua352
-rw-r--r--xmake/actions/require/impl/action/prefix/uninstall.lua53
-rw-r--r--xmake/actions/require/impl/environment.lua105
-rw-r--r--xmake/actions/require/impl/package.lua112
-rw-r--r--xmake/actions/require/info.lua113
-rw-r--r--xmake/actions/require/install.lua39
-rw-r--r--xmake/actions/require/list.lua14
-rw-r--r--xmake/actions/require/main.lua14
-rw-r--r--xmake/actions/require/unlink.lua77
-rw-r--r--xmake/actions/require/xmake.lua3
-rw-r--r--xmake/actions/run/main.lua12
-rw-r--r--xmake/actions/uninstall/uninstall.lua12
-rw-r--r--xmake/core/base/scopeinfo.lua6
-rw-r--r--xmake/core/base/string.lua6
-rw-r--r--xmake/core/package/package.lua534
-rw-r--r--xmake/core/package/repository.lua9
-rw-r--r--xmake/core/platform/environment.lua30
-rw-r--r--xmake/core/project/project.lua17
-rw-r--r--xmake/core/project/target.lua22
-rw-r--r--xmake/core/sandbox/modules/has_package.lua (renamed from xmake/actions/require/clear.lua)29
-rw-r--r--xmake/core/sandbox/modules/import/core/package/package.lua14
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_program.lua43
-rw-r--r--xmake/core/sandbox/modules/irpairs.lua72
-rw-r--r--xmake/core/tool/builder.lua2
-rw-r--r--xmake/core/tool/compiler.lua21
-rw-r--r--xmake/core/tool/linker.lua23
-rw-r--r--xmake/languages/asm/api.lua13
-rw-r--r--xmake/languages/c++/api.lua29
-rw-r--r--xmake/languages/dlang/api.lua11
-rw-r--r--xmake/modules/detect/tools/find_cmake.lua2
-rw-r--r--xmake/modules/lib/detect/check_cxsnippets.lua18
-rw-r--r--xmake/modules/lib/detect/find_package.lua1
-rw-r--r--xmake/modules/lib/detect/has_cfuncs.lua5
-rw-r--r--xmake/modules/lib/detect/has_cincludes.lua5
-rw-r--r--xmake/modules/lib/detect/has_ctypes.lua5
-rw-r--r--xmake/modules/lib/detect/has_cxxfuncs.lua5
-rw-r--r--xmake/modules/lib/detect/has_cxxincludes.lua5
-rw-r--r--xmake/modules/lib/detect/has_cxxtypes.lua5
-rw-r--r--xmake/modules/package/manager/find_package.lua12
-rw-r--r--xmake/modules/package/manager/xmake/find_package.lua100
-rw-r--r--xmake/modules/package/tools/autoconf.lua86
-rw-r--r--xmake/modules/package/tools/cmake.lua63
-rw-r--r--xmake/modules/package/tools/xmake.lua45
-rw-r--r--xmake/repository/packages/c/cmake/xmake.lua12
-rw-r--r--xmake/repository/packages/g/git/xmake.lua1
54 files changed, 1377 insertions, 1054 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 54ebe5014..4b1715292 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -13,10 +13,10 @@ install:
build_script:
- ps: Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-Webrequest "https://raw.githubusercontent.com/xmake-io/xmake/dev/scripts/get.ps1" -UseBasicParsing).Content)) -ArgumentList "dev"
- - cmd: xmake lua versioninfo
+ - cmd: xmake --version
- cmd: xmake -P core
- cmd: set XMAKE_PROGRAM_DIR=%cd%\xmake
- - cmd: core\build\xmake lua versioninfo
+ - cmd: core\build\xmake --version
- ps: Copy-Item -Force core\build\xmake.exe $HOME\xmake
- cmd: xmake lua -D tests\test.lua
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d587c7526..7b2f4bf81 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@
* [#179](https://github.com/xmake-io/xmake/issues/179): Generate CMakelist.txt file for `xmake project` plugin
* [#361](https://github.com/xmake-io/xmake/issues/361): Support vs2019 preview
* [#368](https://github.com/xmake-io/xmake/issues/368): Support `private, public, interface` to improve dependency inheritance like cmake
+* [#284](https://github.com/xmake-io/xmake/issues/284): Add passing user configs description for `package()`
### Changes
@@ -572,6 +573,7 @@
* [#179](https://github.com/xmake-io/xmake/issues/179): 扩展`xmake project`插件,新增CMakelist.txt生成支持
* [#361](https://github.com/xmake-io/xmake/issues/361): 增加对vs2019 preview的支持
* [#368](https://github.com/xmake-io/xmake/issues/368): 支持`private, public, interface`属性设置去继承target配置
+* [#284](https://github.com/xmake-io/xmake/issues/284): 通过`add_configs()`添加和传递用户自定义配置到`package()`
### 改进
diff --git a/xmake/actions/build/build.lua b/xmake/actions/build/build.lua
index 33bb920dc..03045ec8c 100644
--- a/xmake/actions/build/build.lua
+++ b/xmake/actions/build/build.lua
@@ -71,6 +71,13 @@ end
-- build the given target
function _build_target(target)
+ -- enter the environments of the target packages
+ local oldenvs = {}
+ for name, values in pairs(target:pkgenvs()) do
+ oldenvs[name] = os.getenv(name)
+ os.addenv(name, unpack(values))
+ end
+
-- the target scripts
local scripts =
{
@@ -138,6 +145,11 @@ function _build_target(target)
end
end
+ -- leave the environments of the target packages
+ for name, values in pairs(oldenvs) do
+ os.setenv(name, values)
+ end
+
-- update target index
_g.targetindex = _g.targetindex + 1
end
diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua
index b5c90cd75..7717baf1d 100644
--- a/xmake/actions/clean/main.lua
+++ b/xmake/actions/clean/main.lua
@@ -114,6 +114,13 @@ end
-- clean the given target files
function _clean_target(target)
+ -- enter the environments of the target packages
+ local oldenvs = {}
+ for name, values in pairs(target:pkgenvs()) do
+ oldenvs[name] = os.getenv(name)
+ os.addenv(name, unpack(values))
+ end
+
-- the target scripts
local scripts =
{
@@ -159,6 +166,11 @@ function _clean_target(target)
script(target, {origin = (i == 3 and _do_clean_target or nil)})
end
end
+
+ -- leave the environments of the target packages
+ for name, values in pairs(oldenvs) do
+ os.setenv(name, values)
+ end
end
-- clean the given target and all dependent targets
diff --git a/xmake/actions/install/install.lua b/xmake/actions/install/install.lua
index fc8db342c..db035b3fb 100644
--- a/xmake/actions/install/install.lua
+++ b/xmake/actions/install/install.lua
@@ -157,6 +157,13 @@ function _install_target(target)
-- enter project directory
local oldir = os.cd(project.directory())
+ -- enter the environments of the target packages
+ local oldenvs = {}
+ for name, values in pairs(target:pkgenvs()) do
+ oldenvs[name] = os.getenv(name)
+ os.addenv(name, unpack(values))
+ end
+
-- the target scripts
local scripts =
{
@@ -203,6 +210,11 @@ function _install_target(target)
end
end
+ -- leave the environments of the target packages
+ for name, values in pairs(oldenvs) do
+ os.setenv(name, values)
+ end
+
-- leave project directory
os.cd(oldir)
end
diff --git a/xmake/actions/package/main.lua b/xmake/actions/package/main.lua
index f4cd40405..38a7df462 100644
--- a/xmake/actions/package/main.lua
+++ b/xmake/actions/package/main.lua
@@ -168,6 +168,13 @@ function _package(target)
-- enter project directory
local oldir = os.cd(project.directory())
+ -- enter the environments of the target packages
+ local oldenvs = {}
+ for name, values in pairs(target:pkgenvs()) do
+ oldenvs[name] = os.getenv(name)
+ os.addenv(name, unpack(values))
+ end
+
-- the target scripts
local scripts =
{
@@ -200,6 +207,11 @@ function _package(target)
end
end
+ -- leave the environments of the target packages
+ for name, values in pairs(oldenvs) do
+ os.setenv(name, values)
+ end
+
-- leave project directory
os.cd(oldir)
end
diff --git a/xmake/actions/require/clean.lua b/xmake/actions/require/clean.lua
new file mode 100644
index 000000000..cb69d85a4
--- /dev/null
+++ b/xmake/actions/require/clean.lua
@@ -0,0 +1,87 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you 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 - 2019, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file clean.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.cache")
+import("core.package.package")
+
+-- clean all installed package caches
+function main()
+
+ -- trace
+ print("clear all package caches ..")
+
+ -- clear cache directory
+ os.rm(package.cachedir())
+
+ -- clear require cache
+ local require_cache = cache("local.require")
+ require_cache:clear()
+ require_cache:flush()
+
+ -- trace
+ print("clear all unused packages ..")
+
+ -- clear all unused packages
+ local installdir = package.installdir()
+ for _, references_file in ipairs(os.files(path.join(installdir, "*", "*", "*", "*", "references.txt"))) do
+ local references = io.load(references_file)
+ if references then
+ local found = false
+ for projectdir, refdate in pairs(references) do
+ if os.isdir(projectdir) then
+ found = true
+ break
+ end
+ end
+ if not found then
+
+ -- get package directory
+ local packagedir = path.directory(references_file)
+ print("remove %s ..", packagedir)
+
+ -- get confirm
+ local confirm = option.get("yes")
+ if confirm == nil then
+
+ -- show tips
+ cprint("${bright color.warning}note: ${clear}no projects are using this package, remove it (pass -y to skip confirm)?")
+ cprint("please input: y (y/n)")
+
+ -- get answer
+ io.flush()
+ local answer = io.read()
+ if answer == 'y' or answer == '' then
+ confirm = true
+ end
+ end
+ if confirm then
+ os.rm(packagedir)
+ end
+ end
+ end
+ end
+end
+
diff --git a/xmake/actions/require/impl/action/download.lua b/xmake/actions/require/impl/action/download.lua
index a01d9aef2..9eba21afd 100644
--- a/xmake/actions/require/impl/action/download.lua
+++ b/xmake/actions/require/impl/action/download.lua
@@ -91,13 +91,13 @@ function _download(package, url, sourcedir, url_alias, url_excludes)
-- get package file
local packagefile = path.filename(url)
- -- get sha256
- local sha256 = package:sha256(url_alias)
- assert(sha256, "cannot get sha256 of %s in package(%s)", url, package:name())
+ -- get sourcehash
+ local sourcehash = package:sourcehash(url_alias)
+ assert(sourcehash, "cannot get source hash of %s in package(%s)", url, package:name())
-- the package file have been downloaded?
local cached = true
- if option.get("force") or not os.isfile(packagefile) or sha256 ~= hash.sha256(packagefile) then
+ if option.get("force") or not os.isfile(packagefile) or sourcehash ~= hash.sha256(packagefile) then
-- no cached
cached = false
@@ -109,7 +109,7 @@ function _download(package, url, sourcedir, url_alias, url_excludes)
http.download(url, packagefile)
-- check hash
- if sha256 and sha256 ~= hash.sha256(packagefile) then
+ if sourcehash and sourcehash ~= hash.sha256(packagefile) then
raise("unmatched checksum!")
end
end
@@ -146,7 +146,7 @@ function _urls(package)
for _, url in ipairs(package:urls()) do
if git.checkurl(url) then
table.insert(urls[1], url)
- elseif package:sha256(package:url_alias(url)) then
+ elseif package:sourcehash(package:url_alias(url)) then
table.insert(urls[2], url)
end
end
diff --git a/xmake/actions/require/impl/action/install.lua b/xmake/actions/require/impl/action/install.lua
index 181bded44..6bb9d85ca 100644
--- a/xmake/actions/require/impl/action/install.lua
+++ b/xmake/actions/require/impl/action/install.lua
@@ -27,7 +27,62 @@ import("core.base.option")
import("core.project.target")
import("test")
import(".utils.filter")
-import("prefix")
+
+-- patch pkgconfig if not exists
+function _patch_pkgconfig(package)
+
+ -- get lib/pkgconfig/*.pc file
+ local pcfile = path.join(package:installdir(), "lib", "pkgconfig", package:name() .. ".pc")
+ if os.isfile(pcfile) then
+ return
+ end
+
+ -- trace
+ vprint("patching %s ..", pcfile)
+
+ -- fetch package
+ local fetchinfo = package:fetchdeps()
+ if not fetchinfo then
+ return
+ end
+
+ -- get libs
+ local libs = ""
+ for _, linkdir in ipairs(fetchinfo.linkdirs) do
+ libs = libs .. "-L" .. linkdir
+ end
+ libs = libs .. " -L${libdir}"
+ for _, link in ipairs(fetchinfo.links) do
+ libs = libs .. " -l" .. link
+ end
+ for _, link in ipairs(fetchinfo.syslinks) do
+ libs = libs .. " -l" .. link
+ end
+
+ -- cflags
+ local cflags = ""
+ for _, includedir in ipairs(fetchinfo.includedirs) do
+ cflags = cflags .. "-I" .. includedir
+ end
+ cflags = cflags .. " -I${includedir}"
+
+ -- patch a *.pc file
+ local file = io.open(pcfile, 'w')
+ if file then
+ file:print("prefix=%s", package:installdir())
+ file:print("exec_prefix=${prefix}")
+ file:print("libdir=${exec_prefix}/lib")
+ file:print("includedir=${prefix}/include")
+ file:print("")
+ file:print("Name: %s", package:name())
+ file:print("Description: %s", package:description())
+ file:print("Version: %s", package:version_str())
+ file:print("Libs: %s", libs)
+ file:print("Libs.private: ")
+ file:print("Cflags: %s", cflags)
+ file:close()
+ end
+end
-- install the given package
function main(package)
@@ -80,6 +135,7 @@ function main(package)
local installtask = function ()
-- install the third-party package directly, e.g. brew::pcre2/libpcre2-8, conan::OpenSSL/1.0.2n@conan/stable
+ local installed_now = false
if package:is3rd() then
local script = package:script("install")
if script ~= nil then
@@ -87,16 +143,17 @@ function main(package)
end
else
- -- uninstall it from the prefix directory first
- prefix.uninstall(package)
-
-- build and install package to the install directory
- local installedfile = path.join(package:installdir(), "installed.txt")
- if not os.isfile(installedfile) then
+ if option.get("force") or not package:manifest_load() then
-- clean install directory first
os.tryrm(package:installdir())
+ -- enter the environments of all package dependencies
+ for _, dep in ipairs(package:orderdeps()) do
+ dep:envs_enter()
+ end
+
-- do install
for i = 1, 3 do
local script = scripts[i]
@@ -105,16 +162,39 @@ function main(package)
end
end
- -- mark as installed
- io.writefile(installedfile, "")
+ -- leave the environments of all package dependencies
+ for _, dep in irpairs(package:orderdeps()) do
+ dep:envs_leave()
+ end
+
+ -- save the package info to the manifest file
+ package:manifest_save()
+ installed_now = true
end
+ end
+
+ -- enter the package environments
+ package:envs_enter()
+
+ -- fetch package and force to flush the cache
+ local fetchinfo = package:fetch({force = true})
+ if option.get("verbose") or option.get("diagnosis") then
+ print(fetchinfo)
+ end
+ assert(fetchinfo, "fetch %s failed!", tipname)
+
+ -- this package is installed now
+ if installed_now then
- -- install to the prefix directory
- prefix.install(package)
+ -- patch pkg-config files for package
+ _patch_pkgconfig(package)
-- test it
test(package)
end
+
+ -- leave the package environments
+ package:envs_leave()
end
-- install package
@@ -124,13 +204,6 @@ function main(package)
process.asyncrun(installtask)
end
- -- fetch package and force to flush the cache
- local fetchinfo = package:fetch({force = true})
- if option.get("verbose") or option.get("diagnosis") then
- print(fetchinfo)
- end
- assert(fetchinfo, "fetch %s failed!", tipname)
-
-- trace
cprint("${color.success}${text.success}")
end,
@@ -147,6 +220,20 @@ function main(package)
-- trace
cprint("${color.failure}${text.failure}")
+ -- leave the package environments
+ package:envs_leave()
+
+ -- copy the invalid package directory to cache
+ local installdir = package:installdir()
+ if os.isdir(installdir) then
+ local installdir_failed = path.join(package:cachedir(), "installdir.failed")
+ os.tryrm(installdir_failed)
+ if not os.isdir(installdir_failed) then
+ os.cp(installdir, installdir_failed)
+ end
+ end
+ os.tryrm(installdir)
+
-- failed
if not package:requireinfo().optional then
raise("install failed!")
diff --git a/xmake/actions/require/impl/action/prefix/install.lua b/xmake/actions/require/impl/action/prefix/install.lua
deleted file mode 100644
index 041c3c983..000000000
--- a/xmake/actions/require/impl/action/prefix/install.lua
+++ /dev/null
@@ -1,352 +0,0 @@
---!The Make-like install Utility based on Lua
---
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements. See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership. The ASF licenses this file
--- to you 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 - 2019, TBOOX Open Source Group.
---
--- @author ruki
--- @file install.lua
---
-
--- imports
-import("core.base.global")
-import("core.project.config")
-import("core.project.target")
-import("uninstall")
-
--- copy files to the prefix directory
-function _copy(mode, pattern)
-
- -- do install
- local prefixdir = _g.prefixdir
- local installdir = _g.installdir
- local relative_pathes = _g.relative_pathes
- for _, sourcepath in ipairs(os.match(path.join(installdir, pattern), mode)) do
-
- -- get relative path
- local relative_path = path.relative(sourcepath, installdir)
-
- -- trace
- vprint("copying %s ..", relative_path)
-
- -- copy file to the prefix directory
- os.vcp(sourcepath, path.absolute(relative_path, prefixdir))
-
- -- save this relative path
- table.insert(relative_pathes, relative_path)
- end
-end
-
--- copy directories to the prefix directory
-function _copy_dirs(pattern)
- _copy('d', pattern)
-end
-
--- copy files to the prefix directory
-function _copy_files(pattern)
- _copy('f', pattern)
-end
-
--- copy files and directories to the prefix directory
-function _copy_filedirs(pattern)
- _copy('a', pattern)
-end
-
--- find the prefix info file of the previous package
-function _find_prefixfile(originpath)
- local parentdir = path.directory(originpath)
- while parentdir and os.isdir(parentdir) and parentdir ~= "/" do
- local relative_path = path.relative(parentdir, path.join(global.directory(), "installed"))
- local prefixfile_local = path.join(config.directory(), "prefix", "info", relative_path, "info.txt")
- if os.isfile(prefixfile_local) then
- return prefixfile_local
- end
- local prefixfile_global = path.join(global.directory(), "prefix", "info", relative_path, "info.txt")
- if os.isfile(prefixfile_global) then
- return prefixfile_global
- end
- parentdir = path.directory(parentdir)
- end
-end
-
--- do link
-function _do_link(sourcepath, relativepath)
-
- -- link conflicts?
- local destpath = path.absolute(relativepath, _g.prefixdir)
- if os.islink(destpath) then
-
- -- get the original path of destpath
- local originpath = os.readlink(destpath)
-
- -- fix conflicts
- if os.isdir(sourcepath) and os.isdir(originpath) then
-
- -- trace
- vprint("unlinking %s ..", relativepath)
-
-
- -- find the prefix info file of the previous package
- local prefixfile = _find_prefixfile(originpath)
-
- -- get the prefix info
- local prefixinfo = nil
- if prefixfile and os.isfile(prefixfile) then
- prefixinfo = io.load(prefixfile)
- end
-
- -- remove the previous link
- os.rm(destpath)
- if prefixinfo then
- for idx, installfile in ipairs(prefixinfo.installed) do
- if installfile == relativepath then
- table.remove(prefixinfo.installed, idx)
- break
- end
- end
- end
-
- -- expand and relink the previous directories
- for _, filedir in ipairs(os.filedirs(path.join(originpath, "*"))) do
-
- -- get file or directory name
- local filename = path.filename(filedir)
-
- -- trace
- vprint("relinking %s ..", path.join(relativepath, filename))
-
- -- do link
- os.vln(filedir, path.join(destpath, filename))
-
- -- save this relative path
- table.insert(prefixinfo.installed, path.join(relativepath, filename))
- end
-
- -- update the previous prefix info file
- if prefixinfo then
- io.save(prefixfile, prefixinfo)
- end
-
- -- link the child pathes
- for _, filedir in ipairs(os.filedirs(path.join(sourcepath, "*"))) do
- _do_link(filedir, path.join(relativepath, path.filename(filedir)))
- end
-
- -- fix broken link path
- elseif os.isdir(sourcepath) and not os.exists(originpath) then
-
- -- remove the broken link path
- os.rm(destpath)
-
- -- trace
- vprint("linking %s ..", relativepath)
-
- -- do link
- os.vln(sourcepath, destpath)
-
- -- save this relative path
- table.insert(_g.relative_pathes, relativepath)
- else
- -- link conflicts
- os.raise("cannot link %s => %s", sourcepath, destpath)
- end
- elseif os.isdir(destpath) then
-
- -- link the child pathes
- for _, filedir in ipairs(os.filedirs(path.join(sourcepath, "*"))) do
- _do_link(filedir, path.join(relativepath, path.filename(filedir)))
- end
- else
-
- -- trace
- vprint("linking %s ..", relativepath)
-
- -- do link
- os.vln(sourcepath, destpath)
-
- -- save this relative path
- table.insert(_g.relative_pathes, relativepath)
- end
-end
-
--- link files to the prefix directory
-function _link(mode, pattern)
- local installdir = _g.installdir
- for _, sourcepath in ipairs(os.match(path.join(installdir, pattern), mode)) do
- _do_link(sourcepath, path.relative(sourcepath, installdir))
- end
-end
-
--- link directories to the prefix directory
-function _link_dirs(pattern)
- _link('d', pattern)
-end
-
--- link files to the prefix directory
-function _link_files(pattern)
- _link('f', pattern)
-end
-
--- link files and directories to the prefix directory
-function _link_filedirs(pattern)
- _link('a', pattern)
-end
-
--- patch pkgconfig if not exists
-function _patch_pkgconfig(package)
-
- -- get lib/pkgconfig/*.pc file
- local pcfile = path.join(package:installdir("lib", "pkgconfig"), package:name() .. ".pc")
- if os.isfile(pcfile) then
- return
- end
-
- -- trace
- vprint("patching %s ..", pcfile)
-
- -- get libs
- local libs = ""
- for _, linkdir in ipairs(package:getvar("linkdirs")) do
- libs = libs .. "-L" .. linkdir
- end
- libs = libs .. " -L${libdir}"
- local links = package:getvar("links")
- if links then
- for _, link in ipairs(links) do
- libs = libs .. " -l" .. link
- end
- else
- local found = false
- for _, libfile in ipairs(os.files(path.join(package:installdir("lib"), "*.a"))) do
- local link = target.linkname(path.filename(libfile))
- if link then
- libs = libs .. " -l" .. link
- found = true
- end
- end
- if not found then
- for _, libfile in ipairs(os.files(path.join(package:installdir("lib"), "*.so"))) do
- local link = target.linkname(path.filename(libfile))
- if link then
- libs = libs .. " -l" .. link
- end
- end
- end
- end
- for _, link in ipairs(package:getvar("syslinks")) do
- libs = libs .. " -l" .. link
- end
-
- -- cflags
- local cflags = ""
- for _, includedir in ipairs(package:getvar("includedirs")) do
- cflags = cflags .. "-I" .. includedir
- end
- cflags = cflags .. " -I${includedir}"
-
- -- patch a *.pc file
- local file = io.open(pcfile, 'w')
- if file then
- file:print("prefix=%s", package:prefixdir())
- file:print("exec_prefix=${prefix}")
- file:print("libdir=${exec_prefix}/lib")
- file:print("includedir=${prefix}/include")
- file:print("")
- file:print("Name: %s", package:name())
- file:print("Description: %s", package:description())
- file:print("Version: %s", package:version_str())
- file:print("Libs: %s", libs)
- file:print("Libs.private: ")
- file:print("Cflags: %s", cflags)
- file:close()
- end
-end
-
--- install package with link
-function _install_with_link(package)
- _link_files("bin/*")
- _link_files("sbin/*")
- _link_filedirs("include/*")
- _link_filedirs("lib/*")
- _link_filedirs("share/*|info")
- _link_filedirs("share/info/*|dir")
-end
-
--- install package without link (windows)
-function _install_without_link(package)
- if package:kind() == "binary" then
- _copy_filedirs("**")
- else
- _copy_filedirs("lib/**")
- _copy_filedirs("include/**")
- end
-end
-
--- install package
-function _install(package)
-
- -- patch pkgconfig if not exists
- if not is_plat("windows") then
- _patch_pkgconfig(package)
- end
-
- -- install package to the prefix directory
- if is_host("windows") then
- _install_without_link(package)
- else
- _install_with_link(package)
- end
-end
-
--- install package to the prefix directory
-function main(package)
-
- -- init some pathes
- _g.prefixdir = package:prefixdir()
- _g.installdir = package:installdir()
- _g.relative_pathes = {}
-
- -- trace
- vprint("installing %s to %s ..", _g.installdir, _g.prefixdir)
-
- -- install to the prefix directory
- local relative_pathes = {}
- try
- {
- function ()
- _install(package)
- end,
- finally
- {
- function (ok, errors)
- -- save the prefix info to file
- local prefixinfo = package:prefixinfo()
- prefixinfo.installed = _g.relative_pathes
- io.save(package:prefixfile(), prefixinfo)
-
- -- register this package
- package:register()
-
- -- continue to raise errors
- if not ok then
- raise(errors)
- end
- end
- }
- }
-end
-
diff --git a/xmake/actions/require/impl/action/prefix/uninstall.lua b/xmake/actions/require/impl/action/prefix/uninstall.lua
deleted file mode 100644
index 3e48695ed..000000000
--- a/xmake/actions/require/impl/action/prefix/uninstall.lua
+++ /dev/null
@@ -1,53 +0,0 @@
---!The Make-like install Utility based on Lua
---
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements. See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership. The ASF licenses this file
--- to you 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 - 2019, TBOOX Open Source Group.
---
--- @author ruki
--- @file uninstall.lua
---
-
--- uninstall package from the prefix directory
-function main(package)
-
- -- remove the previous installed files
- local prefixdir = package:prefixdir()
- for _, relativefile in ipairs(package:prefixinfo().installed) do
-
- -- trace
- vprint("removing %s ..", relativefile)
-
- -- remove file
- local prefixfile = path.absolute(relativefile, prefixdir)
- os.tryrm(prefixfile)
-
- -- remove it if the parent directory is empty
- local parentdir = path.directory(prefixfile)
- while parentdir and os.isdir(parentdir) and os.emptydir(parentdir) do
- os.tryrm(parentdir)
- parentdir = path.directory(parentdir)
- end
- end
-
- -- unregister this package
- package:unregister()
-
- -- remove the prefix file
- os.tryrm(package:prefixfile())
-end
-
diff --git a/xmake/actions/require/impl/environment.lua b/xmake/actions/require/impl/environment.lua
index e4cf1ff10..8fffddd7f 100644
--- a/xmake/actions/require/impl/environment.lua
+++ b/xmake/actions/require/impl/environment.lua
@@ -29,9 +29,69 @@ import("core.package.package", {alias = "core_package"})
import("lib.detect.find_tool")
import("package")
+-- enter the package environments
+function _enter_package(package_name, envs, installdir)
+
+ -- save the old environments
+ _g._OLDENVS = _g._OLDENVS or {}
+ local oldenvs = _g._OLDENVS[package_name]
+ if not oldenvs then
+ oldenvs = {}
+ _g._OLDENVS[package_name] = oldenvs
+ end
+
+ -- add the new environments
+ oldenvs.PATH = os.getenv("PATH")
+ for name, values in pairs(envs) do
+ oldenvs[name] = oldenvs[name] or os.getenv(name)
+ if name == "PATH" then
+ for _, value in ipairs(values) do
+ if path.is_absolute(value) then
+ os.addenv(name, value)
+ else
+ os.addenv(name, path.join(installdir, value))
+ end
+ end
+ else
+ os.addenv(name, unpack(table.wrap(values)))
+ end
+ end
+end
+
+-- leave the package environments
+function _leave_package(package_name)
+ _g._OLDENVS = _g._OLDENVS or {}
+ local oldenvs = _g._OLDENVS[package_name]
+ if oldenvs then
+ for name, values in pairs(oldenvs) do
+ os.setenv(name, values)
+ end
+ _g._OLDENVS[package_name] = nil
+ end
+end
+
+-- enter environment of the given binary packages, git, 7z, ..
+function _enter_packages(...)
+ for _, name in ipairs({...}) do
+ for _, manifest_file in ipairs(os.files(path.join(core_package.installdir(), name:sub(1, 1), name, "*", "*", "manifest.txt"))) do
+ local manifest = io.load(manifest_file)
+ if manifest and manifest.plat == os.host() and manifest.arch == os.arch() then
+ _enter_package(name, manifest.envs, path.directory(manifest_file))
+ end
+ end
+ end
+end
+
+-- leave environment of the given binary packages, git, 7z, ..
+function _leave_packages(...)
+ for _, name in ipairs({...}) do
+ _leave_package(name)
+ end
+end
+
-- enter environment
--
--- ensure that we can find some basic tools: git, make/nmake/cmake, msbuild ...
+-- ensure that we can find some basic tools: git, unzip, ...
--
-- If these tools not exist, we will install it first.
--
@@ -45,45 +105,38 @@ function enter()
raise("unzip not found! we need install it first")
end
+ -- enter the environments of git and 7z
+ _enter_packages("git", "7z")
+
-- git not found? install it first
+ local packages = {}
if not find_tool("git") then
- package.install_packages("git")
+ table.join2(packages, package.install_packages("git"))
end
-- missing the necessary unarchivers for *.gz, *.7z? install them first, e.g. gzip, 7z, tar ..
if not ((find_tool("gzip") and find_tool("tar")) or find_tool("7z")) then
- package.install_packages("7z")
+ table.join2(packages, package.install_packages("7z"))
end
- -- get prefix directories
- local plat = get_config("plat")
- local arch = get_config("arch")
- _g.prefixdirs = _g.prefixdirs or
- {
- core_package.prefixdir(false, "release", plat, arch),
- core_package.prefixdir(true, "release", plat, arch),
- }
-
- -- add search directories of pkgconfig, aclocal, cmake
- _g._ACLOCAL_PATH = os.getenv("ACLOCAL_PATH")
- _g._PKG_CONFIG_PATH = os.getenv("PKG_CONFIG_PATH")
- _g._CMAKE_PREFIX_PATH = os.getenv("CMAKE_PREFIX_PATH")
- for _, prefixdir in ipairs(_g.prefixdirs) do
- if not is_plat("windows") then
- os.addenv("ACLOCAL_PATH", path.join(prefixdir, "share", "aclocal"))
- os.addenv("PKG_CONFIG_PATH", path.join(prefixdir, "lib", "pkgconfig"))
- end
- os.addenv("CMAKE_PREFIX_PATH", prefixdir)
+ -- enter the environments of installed packages
+ for _, instance in ipairs(packages) do
+ instance:envs_enter()
end
+ _g._PACKAGES = packages
end
-- leave environment
function leave()
- -- restore search directories of pkgconfig, aclocal, cmake
- os.setenv("ACLOCAL_PATH", _g._ACLOCAL_PATH)
- os.setenv("PKG_CONFIG_PATH", _g._PKG_CONFIG_PATH)
- os.setenv("CMAKE_PREFIX_PATH", _g._CMAKE_PREFIX_PATH)
+ -- leave the environments of installed packages
+ for _, instance in irpairs(_g._PACKAGES) do
+ instance:envs_leave()
+ end
+ _g._PACKAGES = nil
+
+ -- leave the environments of git and 7z
+ _leave_packages("7z", "git")
-- restore search pathes of toolchains
environment.leave("toolchains")
diff --git a/xmake/actions/require/impl/package.lua b/xmake/actions/require/impl/package.lua
index 159497b60..f55b6a98a 100644
--- a/xmake/actions/require/impl/package.lua
+++ b/xmake/actions/require/impl/package.lua
@@ -114,6 +114,13 @@ function _parse_require(require_str, requires_extra, parentinfo)
require_extra = requires_extra[require_str] or {}
end
+ -- get required building configurations
+ local require_build_configs = require_extra.configs or require_extra.config
+ if require_extra.debug then
+ require_build_configs = require_build_configs or {}
+ require_build_configs.debug = true
+ end
+
-- init required item
local required = {}
parentinfo = parentinfo or {}
@@ -124,11 +131,10 @@ function _parse_require(require_str, requires_extra, parentinfo)
reponame = reponame,
version = version,
alias = require_extra.alias, -- set package alias name
- debug = require_extra.debug, -- uses the debug package, default: false
group = require_extra.group, -- only uses the first package in same group
system = require_extra.system, -- default: true, we can set it to disable system package manually
option = require_extra.option, -- set and attach option
- config = require_extra.config, -- the build configuration of package
+ configs = require_build_configs, -- the required building configurations
default = require_extra.default, -- default: true, we can set it to disable package manually
optional = parentinfo.optional or require_extra.optional -- default: false, inherit parentinfo.optional
}
@@ -240,6 +246,16 @@ function _sort_packagedeps(package)
return orderdeps
end
+-- add some builtin configs to package
+function _add_package_configs(package)
+ package:add("configs", "debug", {builtin = true, description = "Enable debug symbols.", default = false, type = "boolean"})
+ package:add("configs", "cflags", {builtin = true, description = "Set the C compiler flags."})
+ package:add("configs", "cxflags", {builtin = true, description = "Set the C/C++ compiler flags."})
+ package:add("configs", "cxxflags", {builtin = true, description = "Set the C++ compiler flags."})
+ package:add("configs", "asflags", {builtin = true, description = "Set the assembler flags."})
+ package:add("configs", "vs_runtime", {builtin = true, description = "Set vs compiler runtime.", default = "MT", values = {"MT", "MD"}})
+end
+
-- load all required packages
function _load_packages(requires, opt)
@@ -270,6 +286,9 @@ function _load_packages(requires, opt)
package._ORDERDEPS = table.unique(_sort_packagedeps(package))
end
+ -- add some builtin configs to package
+ _add_package_configs(package)
+
-- save this package package
table.insert(packages, package)
end
@@ -292,6 +311,50 @@ function _sort_packages_urls(packages)
package:urls_set(fasturl.sort(package:urls()))
end
end
+
+-- check the configurations of packages
+--
+-- package("pcre2")
+-- add_configs("bitwidth", {description = "Set the code unit width.", default = "8", values = {"8", "16", "32"}})
+-- add_configs("bitwidth", {type = "number", values = {8, 16, 32}})
+-- add_configs("bitwidth", {restrict = function(value) if tonumber(value) < 100 then return true end})
+--
+function _check_packages_configs(packages)
+ for _, package in ipairs(packages) do
+ local configs_defined = {}
+ for _, name in ipairs(package:get("configs")) do
+ configs_defined[name] = package:extraconf("configs", name) or {}
+ end
+ for name, value in pairs(package:configs()) do
+ local conf = configs_defined[name]
+ if conf then
+ local config_type = conf.type or "string"
+ if type(value) ~= config_type then
+ raise("package(%s %s): invalid type(%s) for config(%s), need type(%s)!", package:name(), package:version_str(), type(value), name, config_type)
+ end
+ if conf.values then
+ local found = false
+ for _, config_value in ipairs(conf.values) do
+ if tostring(value) == tostring(config_value) then
+ found = true
+ break
+ end
+ end
+ if not found then
+ raise("package(%s %s): invalid value(%s) for config(%s), please run `xmake require --info %s` to get all valid values!", package:name(), package:version_str(), value, name, package:name())
+ end
+ end
+ if conf.restrict then
+ if not conf.restrict(value) then
+ raise("package(%s %s): invalid value(%s) for config(%s)!", package:name(), package:version_str(), value, name)
+ end
+ end
+ else
+ raise("package(%s %s): invalid config(%s), please run `xmake require --info %s` to get all configurations!", package:name(), package:version_str(), name, package:name())
+ end
+ end
+ end
+end
-- select packages version
function _select_packages_version(packages)
@@ -344,7 +407,7 @@ function _get_confirm(packages)
-- get packages for each repositories
local packages_repo = {}
for _, package in ipairs(packages) do
- local reponame = package:repo() and package:repo():name() or package:fromkind()
+ local reponame = package:repo() and package:repo():name() or (package:isSys() and "system" or "")
if package:is3rd() then
reponame = package:name():lower():split("::")[1]
end
@@ -355,7 +418,9 @@ function _get_confirm(packages)
-- show tips
cprint("${bright color.warning}note: ${clear}try installing these packages (pass -y to skip confirm)?")
for reponame, packages in pairs(packages_repo) do
- print("in %s:", reponame)
+ if reponame ~= "" then
+ print("in %s:", reponame)
+ end
for _, package in ipairs(packages) do
print(" -> %s %s %s", package:name(), package:version_str() or "", package:debug() and "(debug)" or "")
end
@@ -409,6 +474,9 @@ function load_packages(requires, opt)
-- select packages version
_select_packages_version(packages)
+ -- check the configurations of packages
+ _check_packages_configs(packages)
+
-- remove repeat packages with same the package name and version
local unique = {}
local results = {}
@@ -551,48 +619,14 @@ function uninstall_packages(requires, opt)
-- remove all packages
local packages = {}
for _, instance in ipairs(load_packages(requires, opt)) do
- if os.isfile(instance:prefixfile()) then
-
- -- uninstall package from the prefix directory
- action.prefix.uninstall(instance)
-
- -- remove ok
+ if os.isfile(instance:manifest_file()) then
table.insert(packages, instance)
end
-
- -- remove the installed files
os.tryrm(instance:installdir())
end
return packages
end
--- only unlink packages from the prefix directory
-function unlink_packages(requires, opt)
-
- -- init options
- opt = opt or {}
-
- -- do not remove dependent packages
- opt.nodeps = true
-
- -- clear the detect cache
- detectcache.clear()
-
- -- unlink all packages
- local packages = {}
- for _, instance in ipairs(load_packages(requires, opt)) do
- if os.isfile(instance:prefixfile()) then
-
- -- uninstall package from the prefix directory
- action.prefix.uninstall(instance)
-
- -- remove ok
- table.insert(packages, instance)
- end
- end
- return packages
-end
-
-- search packages
function search_packages(names)
diff --git a/xmake/actions/require/info.lua b/xmake/actions/require/info.lua
index d0060e0f7..d35f503cf 100644
--- a/xmake/actions/require/info.lua
+++ b/xmake/actions/require/info.lua
@@ -31,14 +31,20 @@ import("impl.package")
import("impl.repository")
import("impl.environment")
--- from local/global/system/remote?
+-- from xmake/system/remote?
function _from(instance)
- local fetchinfo, fetchfrom = instance:fetch()
+ local fetchinfo = instance:fetch()
if fetchinfo then
- return ", ${green}" .. fetchfrom .. "${clear}"
+ if instance:is3rd() then
+ return ", ${green}3rd${clear}"
+ elseif instance:isSys() then
+ return ", ${green}system${clear}"
+ else
+ return ""
+ end
elseif #instance:urls() > 0 then
return instance:supported() and format(", ${yellow}remote${clear}(in %s)", instance:repo():name()) or format(", ${yellow}remote${clear}(${red}unsupported${clear} in %s)", instance:repo():name())
- elseif instance:from("system") then
+ elseif instance:isSys() then
return ", ${red}missing${clear}"
else
return ""
@@ -116,13 +122,19 @@ function main(package_names)
cprint(" -> ${magenta}urls${clear}:")
for _, url in ipairs(urls) do
print(" -> %s", filter.handle(url, instance))
- local sha256 = instance:sha256(instance:url_alias(url))
- if sha256 then
- cprint(" -> ${yellow}%s${clear}", sha256)
+ local sourcehash = instance:sourcehash(instance:url_alias(url))
+ if sourcehash then
+ cprint(" -> ${yellow}%s${clear}", sourcehash)
end
end
end
+ -- show repository
+ local repo = instance:repo()
+ if repo then
+ cprint(" -> ${magenta}repo${clear}: %s %s %s", repo:name(), repo:url(), repo:branch() or "")
+ end
+
-- show deps
local deps = instance:orderdeps()
if deps and #deps > 0 then
@@ -136,12 +148,6 @@ function main(package_names)
-- show cache directory
cprint(" -> ${magenta}cachedir${clear}: %s", instance:cachedir())
- -- show prefix directory
- cprint(" -> ${magenta}prefixdir${clear}: %s", instance:prefixdir())
-
- -- show prefix file
- cprint(" -> ${magenta}prefixfile${clear}: %s", instance:prefixfile())
-
-- show install directory
cprint(" -> ${magenta}installdir${clear}: %s", instance:installdir())
@@ -154,6 +160,87 @@ function main(package_names)
end
end
+ -- show supported platforms
+ local platforms = {}
+ local on_install = instance:get("install")
+ if type(on_install) == "table" then
+ for plat, _ in pairs(on_install) do
+ table.insert(platforms, plat)
+ end
+ else
+ table.insert(platforms, "all")
+ end
+ cprint(" -> ${magenta}platforms${clear}: %s", table.concat(platforms, ", "))
+
+ -- show requires
+ cprint(" -> ${magenta}requires${clear}:")
+ cprint(" -> ${cyan}plat${clear}: %s", instance:plat())
+ cprint(" -> ${cyan}arch${clear}: %s", instance:arch())
+ local configs_required = instance:configs()
+ if configs_required then
+ cprint(" -> ${cyan}configs${clear}:")
+ for name, value in pairs(configs_required) do
+ cprint(" -> %s: %s", name, value)
+ end
+ end
+
+ -- show user configs
+ local configs_defined = instance:get("configs")
+ if configs_defined then
+ cprint(" -> ${magenta}configs${clear}:")
+ for _, conf in ipairs(configs_defined) do
+ local configs_extra = instance:extraconf("configs", conf)
+ if configs_extra and not configs_extra.builtin then
+ cprintf(" -> ${cyan}%s${clear}: ", conf)
+ if configs_extra.description then
+ printf(configs_extra.description)
+ end
+ if configs_extra.default ~= nil then
+ printf(" (default: %s)", configs_extra.default)
+ elseif configs_extra.type ~= nil and configs_extra.type ~= "string" then
+ printf(" (type: %s)", configs_extra.type)
+ end
+ print("")
+ if configs_extra.values then
+ cprint(" -> values: %s", string.serialize(configs_extra.values, true))
+ end
+ end
+ end
+ end
+
+ -- show builtin configs
+ local configs_defined = instance:get("configs")
+ if configs_defined then
+ cprint(" -> ${magenta}configs (builtin)${clear}:")
+ for _, conf in ipairs(configs_defined) do
+ local configs_extra = instance:extraconf("configs", conf)
+ if configs_extra and configs_extra.builtin then
+ cprintf(" -> ${cyan}%s${clear}: ", conf)
+ if configs_extra.description then
+ printf(configs_extra.description)
+ end
+ if configs_extra.default ~= nil then
+ printf(" (default: %s)", configs_extra.default)
+ elseif configs_extra.type ~= nil and configs_extra.type ~= "string" then
+ printf(" (type: %s)", configs_extra.type)
+ end
+ print("")
+ if configs_extra.values then
+ cprint(" -> values: %s", string.serialize(configs_extra.values, true))
+ end
+ end
+ end
+ end
+
+ -- show references
+ local references = instance:references()
+ if references then
+ cprint(" -> ${magenta}references${clear}:")
+ for projectdir, refdate in pairs(references) do
+ cprint(" -> %s: %s%s", refdate, projectdir, os.isdir(projectdir) and "" or " ${red}(not found)${clear}")
+ end
+ end
+
-- end
print("")
end
diff --git a/xmake/actions/require/install.lua b/xmake/actions/require/install.lua
index 80df043ba..65c624d99 100644
--- a/xmake/actions/require/install.lua
+++ b/xmake/actions/require/install.lua
@@ -38,11 +38,11 @@ function _register_required_package(instance, requireinfo)
if _g.optional_missing[instance:name()] then
requireinfo:enable(false)
else
- -- add this package info
+ -- clear require info first
requireinfo:clear()
- requireinfo:add(instance:fetch())
- -- add all dependent packages info
+ -- add include and links info
+ requireinfo:add(instance:fetch())
local orderdeps = instance:orderdeps()
if orderdeps then
local total = #orderdeps
@@ -54,6 +54,29 @@ function _register_required_package(instance, requireinfo)
end
end
+ -- add environments
+ local envs = {}
+ local hasenvs = false
+ local installdir = instance:installdir()
+ for name, values in pairs(instance:envs()) do
+ if name == "PATH" then
+ for _, value in ipairs(values) do
+ envs[name] = envs[name] or {}
+ if path.is_absolute(value) then
+ table.insert(envs[name], value)
+ else
+ table.insert(envs[name], path.join(installdir, value))
+ end
+ end
+ else
+ envs[name] = values
+ end
+ hasenvs = true
+ end
+ if hasenvs then
+ requireinfo:add({envs = envs})
+ end
+
-- save this package version
requireinfo:version_set(instance:version_str())
@@ -75,11 +98,9 @@ function _register_required_packages(packages)
if not group or not registered_in_group[group] then
-- do not register binary package
- if instance:kind() ~= "binary" then
- local requireinfo = project.require(instance:alias() or instance:name())
- if requireinfo then
- _register_required_package(instance, requireinfo)
- end
+ local requireinfo = project.require(instance:alias() or instance:name())
+ if requireinfo then
+ _register_required_package(instance, requireinfo)
end
-- mark as registered in group
@@ -97,7 +118,7 @@ function _check_missing_packages(packages)
local packages_missing = {}
local optional_missing = {}
for _, instance in ipairs(packages) do
- if not instance:exists() and (#instance:urls() > 0 or instance:from("system")) then
+ if not instance:exists() and (#instance:urls() > 0 or instance:isSys()) then
if instance:optional() then
optional_missing[instance:name()] = instance
else
diff --git a/xmake/actions/require/list.lua b/xmake/actions/require/list.lua
index 71d50c18f..5fd282b26 100644
--- a/xmake/actions/require/list.lua
+++ b/xmake/actions/require/list.lua
@@ -29,14 +29,20 @@ import("impl.package")
import("impl.repository")
import("impl.environment")
--- from local/global/system/remote?
+-- from xmake/system/remote?
function _from(instance)
- local fetchinfo, fetchfrom = instance:fetch()
+ local fetchinfo = instance:fetch()
if fetchinfo then
- return ", ${green}" .. fetchfrom .. "${clear}"
+ if instance:is3rd() then
+ return ", ${green}3rd${clear}"
+ elseif instance:isSys() then
+ return ", ${green}system${clear}"
+ else
+ return ""
+ end
elseif #instance:urls() > 0 then
return instance:supported() and format(", ${yellow}remote${clear}(in %s)", instance:repo():name()) or format(", ${yellow}remote${clear}(${red}unsupported${clear} in %s)", instance:repo():name())
- elseif instance:from("system") then
+ elseif instance:isSys() then
return ", ${red}missing${clear}"
else
return ""
diff --git a/xmake/actions/require/main.lua b/xmake/actions/require/main.lua
index 5e5ccd830..6311434cc 100644
--- a/xmake/actions/require/main.lua
+++ b/xmake/actions/require/main.lua
@@ -30,11 +30,10 @@ import("core.project.project")
import("core.platform.platform")
import("list")
import("info")
-import("clear")
+import("clean")
import("search")
import("install")
import("uninstall")
-import("unlink")
--
-- the default repositories:
@@ -74,10 +73,10 @@ function main()
-- load project first
_load_project()
- -- clear all installed packages cache
- if option.get("clear") then
+ -- clean all installed packages cache
+ if option.get("clean") then
- clear(option.get("global"))
+ clean(option.get("global"))
-- search for the given packages from repositories
elseif option.get("search") then
@@ -89,11 +88,6 @@ function main()
uninstall(option.get("requires"))
- -- unlink the installed packages
- elseif option.get("unlink") then
-
- unlink(option.get("requires"))
-
-- show the given package info
elseif option.get("info") then
diff --git a/xmake/actions/require/unlink.lua b/xmake/actions/require/unlink.lua
deleted file mode 100644
index de1cd5f99..000000000
--- a/xmake/actions/require/unlink.lua
+++ /dev/null
@@ -1,77 +0,0 @@
---!A cross-platform build utility based on Lua
---
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements. See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership. The ASF licenses this file
--- to you 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 - 2019, TBOOX Open Source Group.
---
--- @author ruki
--- @file unlink.lua
---
-
--- imports
-import("core.base.task")
-import("core.base.option")
-import("core.project.project")
-import("impl.package")
-import("impl.repository")
-import("impl.environment")
-
--- unlink the given packages
-function main(package_names)
-
- -- no package names?
- if not package_names then
- return
- end
-
- -- enter environment
- environment.enter()
-
- -- pull all repositories first if not exists
- if not repository.pulled() then
- task.run("repo", {update = true})
- end
-
- -- get project requires
- local project_requires, requires_extra = project.requires_str()
- if not project_requires then
- raise("requires(%s) not found in project!", table.concat(requires, " "))
- end
-
- -- find required package in project
- local requires = {}
- for _, name in ipairs(package_names) do
- for _, require_str in ipairs(project_requires) do
- if require_str:split(' ')[1]:lower():find(name:lower()) then
- table.insert(requires, require_str)
- end
- end
- end
- if #requires == 0 then
- raise("%s not found in project!", table.concat(package_names, " "))
- end
-
- -- unlink packages
- local packages = package.unlink_packages(requires, {requires_extra = requires_extra})
- for _, instance in ipairs(packages) do
- print("unlink: %s%s ok!", instance:name(), instance:version_str() and ("-" .. instance:version_str()) or "")
- end
-
- -- leave environment
- environment.leave()
-end
-
diff --git a/xmake/actions/require/xmake.lua b/xmake/actions/require/xmake.lua
index 35d6e0853..06147576a 100644
--- a/xmake/actions/require/xmake.lua
+++ b/xmake/actions/require/xmake.lua
@@ -45,13 +45,12 @@ task("require")
-- options
, options =
{
- {'c', "clear", "k", nil, "Clear all installed package caches." }
+ {'c', "clean", "k", nil, "Clear all package caches and uninstall all not-referenced packages." }
, {'f', "force", "k", nil, "Force to reinstall all package dependencies." }
, {'l', "list", "k", nil, "List all package dependencies." }
, { }
, {nil, "info", "k", nil, "Show the given package info." }
, {'s', "search", "k", nil, "Search for the given packages from repositories." }
- , {nil, "unlink", "k", nil, "Only unlink the installed packages." }
, {nil, "uninstall", "k", nil, "Uninstall the installed packages." }
, {nil, "extra", "kv", nil, "Set the extra info of packages." }
, { }
diff --git a/xmake/actions/run/main.lua b/xmake/actions/run/main.lua
index 21783a125..156170871 100644
--- a/xmake/actions/run/main.lua
+++ b/xmake/actions/run/main.lua
@@ -103,6 +103,13 @@ end
-- run the given target
function _run(target)
+ -- enter the environments of the target packages
+ local oldenvs = {}
+ for name, values in pairs(target:pkgenvs()) do
+ oldenvs[name] = os.getenv(name)
+ os.addenv(name, unpack(values))
+ end
+
-- the target scripts
local scripts =
{
@@ -148,6 +155,11 @@ function _run(target)
script(target, {origin = (i == 3 and _do_run_target or nil)})
end
end
+
+ -- leave the environments of the target packages
+ for name, values in pairs(oldenvs) do
+ os.setenv(name, values)
+ end
end
-- run the all dependent targets
diff --git a/xmake/actions/uninstall/uninstall.lua b/xmake/actions/uninstall/uninstall.lua
index f79727947..0d1c07d51 100644
--- a/xmake/actions/uninstall/uninstall.lua
+++ b/xmake/actions/uninstall/uninstall.lua
@@ -134,6 +134,13 @@ function _uninstall_target(target)
-- enter project directory
local oldir = os.cd(project.directory())
+ -- enter the environments of the target packages
+ local oldenvs = {}
+ for name, values in pairs(target:pkgenvs()) do
+ oldenvs[name] = os.getenv(name)
+ os.addenv(name, unpack(values))
+ end
+
-- the target scripts
local scripts =
{
@@ -180,6 +187,11 @@ function _uninstall_target(target)
end
end
+ -- leave the environments of the target packages
+ for name, values in pairs(oldenvs) do
+ os.setenv(name, values)
+ end
+
-- leave project directory
os.cd(oldir)
end
diff --git a/xmake/core/base/scopeinfo.lua b/xmake/core/base/scopeinfo.lua
index 351572dfa..1fe04a6eb 100644
--- a/xmake/core/base/scopeinfo.lua
+++ b/xmake/core/base/scopeinfo.lua
@@ -451,7 +451,7 @@ function _instance:apival_set(name, ...)
for k, v in pairs(dict) do
self:apival_set(k, unpack(table.wrap(v)))
end
- else
+ elseif name ~= nil then
os.raise("unknown type(%s) for %s:set(%s, ...)", type(name), self:kind(), name)
end
end
@@ -487,7 +487,7 @@ function _instance:apival_add(name, ...)
for k, v in pairs(dict) do
self:apival_add(k, unpack(table.wrap(v)))
end
- else
+ elseif name ~= nil then
os.raise("unknown type(%s) for %s:add(%s, ...)", type(name), self:kind(), name)
end
end
@@ -506,7 +506,7 @@ function _instance:apival_del(name, ...)
else
os.raise("unknown api(%s) for %s:del(%s, ...)", name, self:kind(), name)
end
- else
+ elseif name ~= nil then
-- TODO
os.raise("cannot support to remove a dictionary!")
end
diff --git a/xmake/core/base/string.lua b/xmake/core/base/string.lua
index c3f3958d5..cf6f7b124 100644
--- a/xmake/core/base/string.lua
+++ b/xmake/core/base/string.lua
@@ -43,7 +43,9 @@ function string._makestr(object, deflate, serialize, level)
if deflate then
s = s .. "{"
else
- s = s .. "\n"
+ if level > 0 then
+ s = s .. "\n"
+ end
for l = 1, level do
s = s .. " "
end
@@ -69,7 +71,7 @@ function string._makestr(object, deflate, serialize, level)
-- make key = value
if type(k) == "string" then
- if serialize then
+ if serialize and not k:match("^%a[%w_]+$") then
k = string.format("[%q]", k)
end
if deflate then
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 87c075439..eeae38819 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -38,6 +38,7 @@ local interpreter = require("base/interpreter")
local sandbox = require("sandbox/sandbox")
local config = require("project/config")
local platform = require("platform/platform")
+local language = require("language/language")
local sandbox = require("sandbox/sandbox")
local sandbox_os = require("sandbox/modules/os")
local sandbox_module = require("sandbox/modules/import/core/sandbox/module")
@@ -50,6 +51,11 @@ function _instance.new(name, info)
return instance
end
+-- get the package name
+function _instance:name()
+ return self._NAME
+end
+
-- get the package configure
function _instance:get(name)
@@ -60,9 +66,19 @@ function _instance:get(name)
end
end
--- get the package name
-function _instance:name()
- return self._NAME
+-- set the value to the package info
+function _instance:set(name, ...)
+ self._INFO:apival_set(name, ...)
+end
+
+-- add the value to the package info
+function _instance:add(name, ...)
+ self._INFO:apival_add(name, ...)
+end
+
+-- get the extra configuration
+function _instance:extraconf(name, item, key)
+ return self._INFO:extraconf(name, item, key)
end
-- get the package description
@@ -167,47 +183,30 @@ function _instance:orderdeps()
return self._ORDERDEPS
end
--- get sha256 of the url_alias@version_str
-function _instance:sha256(url_alias)
+-- get hash of the source package for the url_alias@version_str
+function _instance:sourcehash(url_alias)
- -- get sha256
+ -- get sourcehash
local versions = self:get("versions")
local version_str = self:version_str()
if versions and version_str then
- local sha256 = nil
+ local sourcehash = nil
if url_alias then
- sha256 = versions[url_alias .. ":" ..version_str]
+ sourcehash = versions[url_alias .. ":" ..version_str]
end
- if not sha256 then
- sha256 = versions[version_str]
+ if not sourcehash then
+ sourcehash = versions[version_str]
end
-- ok?
- return sha256
+ return sourcehash
end
end
-- get revision(commit, tag, branch) of the url_alias@version_str, only for git url
function _instance:revision(url_alias)
- return self:sha256(url_alias)
-end
-
--- this package is from system/local/global?
---
--- @param kind the from kind
---
--- system: from the system directories (.e.g /usr/local)
--- local: from the local project package directories (.e.g projectdir/.xmake/packages)
--- global: from the global package directories (.e.g ~/.xmake/packages)
---
-function _instance:from(kind)
- return self._FROMKIND == kind
-end
-
--- get from kind
-function _instance:fromkind()
- return self._FROMKIND
+ return self:sourcehash(url_alias)
end
-- get the package kind, binary or nil(static, shared)
@@ -223,94 +222,164 @@ end
-- get the installed directory of this package
function _instance:installdir(...)
-
- -- make the given install directory
local name = self:name():lower():gsub("::", "_")
- local dir = path.join(package.installdir(table.concat({self:mode(), self:configs_hash()}, '_'), self:plat(), self:arch()), name:sub(1, 1):lower(), name, self:version_str(), ...)
-
- -- ensure the install directory
+ local dir = path.join(package.installdir(), name:sub(1, 1):lower(), name, self:version_str(), self:buildhash(), ...)
if not os.isdir(dir) then
os.mkdir(dir)
end
return dir
end
--- get the prefix directory
-function _instance:prefixdir(...)
-
- -- make the given prefix directory
- local dir = path.join(package.prefixdir(self:from("global"), table.concat({self:mode(), self:configs_hash()}, '_'), self:plat(), self:arch()), ...)
-
- -- ensure the prefix directory
- if not os.isdir(dir) then
- os.mkdir(dir)
+-- get the references info of this package
+function _instance:references()
+ local references_file = path.join(self:installdir(), "references.txt")
+ if os.isfile(references_file) then
+ local references, errors = io.load(references_file)
+ if not references then
+ os.raise(errors)
+ end
+ return references
end
- return dir
end
--- get the prefix info
-function _instance:prefixinfo()
- if self._PREFIXINFO == nil then
- local prefixfile = self:prefixfile()
- self._PREFIXINFO = os.isfile(prefixfile) and io.load(prefixfile) or {}
- end
- return self._PREFIXINFO
+-- get the manifest file of this package
+function _instance:manifest_file()
+ return path.join(self:installdir(), "manifest.txt")
end
--- get the prefix info file
-function _instance:prefixfile()
- local name = self:name():lower():gsub("::", "_")
- return path.join(package.prefixinfodir(self:from("global"), table.concat({self:mode(), self:configs_hash()}, '_'), self:plat(), self:arch()), name:sub(1, 1):lower(), name, self:version_str(), "info.txt")
+-- load the manifest file of this package
+function _instance:manifest_load()
+ local manifest_file = self:manifest_file()
+ if os.isfile(manifest_file) then
+
+ -- load manifest
+ local manifest, errors = io.load(manifest_file)
+ if not manifest then
+ os.raise(errors)
+ end
+ return manifest
+ end
end
--- get prefix variables
-function _instance:getvar(name)
- return self:prefixinfo()[name]
+-- save the manifest file of this package
+function _instance:manifest_save()
+
+ -- make manifest
+ local manifest = {}
+ manifest.name = self:name()
+ manifest.description = self:description()
+ manifest.version = self:version_str()
+ manifest.kind = self:kind()
+ manifest.plat = self:plat()
+ manifest.arch = self:arch()
+ manifest.mode = self:mode()
+ manifest.configs = self:configs()
+ manifest.envs = self:envs()
+
+ -- save variables
+ local vars = {}
+ local apis = language.apis()
+ for _, apiname in ipairs(table.join(apis.values, apis.pathes)) do
+ if apiname:startswith("package.add_") or apiname:startswith("package.set_") then
+ local name = apiname:sub(13)
+ local value = self:get(name)
+ if value ~= nil then
+ vars[name] = value
+ end
+ end
+ end
+ manifest.vars = vars
+
+ -- save repository
+ local repo = self:repo()
+ if repo then
+ manifest.repo = {}
+ manifest.repo.name = repo:name()
+ manifest.repo.url = repo:url()
+ manifest.repo.branch = repo:branch()
+ end
+
+ -- save manifest
+ local ok, errors = io.save(self:manifest_file(), manifest)
+ if not ok then
+ os.raise(errors)
+ end
end
--- set prefix variables
+-- TODO: set the given variable, deprecated
function _instance:setvar(name, ...)
- self:prefixinfo()[name] = {...}
+ self:set(name, ...)
end
--- add prefix variables
+-- TODO add the given variable, deprecated
function _instance:addvar(name, ...)
- self:prefixinfo()[name] = table.join(self:prefixinfo()[name] or {}, ...)
+ self:add(name, ...)
end
--- get environment variables
-function _instance:getenv(name)
- return self:prefixinfo().envars and self:prefixinfo().envars[name] or nil
+-- get the exported environments
+function _instance:envs()
+ local envs = self._ENVS
+ if not envs then
+ envs = {}
+ if self:kind() == "binary" then
+ envs.PATH = {"bin"}
+ end
+ self._ENVS = envs
+ end
+ return envs
end
--- set environment variables
-function _instance:setenv(name, ...)
- self:prefixinfo().envars = self:prefixinfo().envars or {}
- self:prefixinfo().envars[name] = {...}
-end
+-- enter the package environments
+function _instance:envs_enter()
--- add values to environment variable
-function _instance:addenv(name, ...)
- self:prefixinfo().envars = self:prefixinfo().envars or {}
- self:prefixinfo().envars[name] = table.join(self:prefixinfo().envars[name] or {}, ...)
-end
+ -- save the old environments
+ local oldenvs = self._OLDENVS
+ if not oldenvs then
+ oldenvs = {}
+ self._OLDENVS = oldenvs
+ end
--- register package info in the root prefix info
-function _instance:register()
+ -- add the new environments
+ local installdir = self:installdir()
+ for name, values in pairs(self:envs()) do
+ oldenvs[name] = oldenvs[name] or os.getenv(name)
+ if name == "PATH" then
+ for _, value in ipairs(values) do
+ if path.is_absolute(value) then
+ os.addenv(name, value)
+ else
+ os.addenv(name, path.join(installdir, value))
+ end
+ end
+ else
+ os.addenv(name, unpack(table.wrap(values)))
+ end
+ end
+end
- -- register the environment variables
- for name, values in pairs(table.wrap(self:prefixinfo().envars)) do
- package.addenv(self:from("global"), table.concat({self:mode(), self:configs_hash()}, '_'), self:plat(), self:arch(), name, values)
+-- leave the package environments
+function _instance:envs_leave()
+ if self._OLDENVS then
+ for name, values in pairs(self._OLDENVS) do
+ os.setenv(name, values)
+ end
+ self._OLDENVS = nil
end
end
--- unregister package info from the root prefix info
-function _instance:unregister()
+-- get the given environment variable
+function _instance:getenv(name)
+ return self:envs()[name]
+end
+
+-- set the given environment variable
+function _instance:setenv(name, ...)
+ self:envs()[name] = {...}
+end
- -- unregister the environment variables
- for name, values in pairs(table.wrap(self:prefixinfo().envars)) do
- package.delenv(self:from("global"), table.concat({self:mode(), self:configs_hash()}, '_'), self:plat(), self:arch(), name, values)
- end
+-- add the given environment variable
+function _instance:addenv(name, ...)
+ self:envs()[name] = table.join(self:envs()[name] or {}, ...)
end
-- get user private data
@@ -406,44 +475,52 @@ end
-- set the require info
function _instance:requireinfo_set(requireinfo)
-
- -- save require info
self._REQUIREINFO = requireinfo
+end
- -- get version
- local version = requireinfo and requireinfo.version or nil
- local limitversion = version and version ~= "master" and version ~= "lastest"
- if requireinfo and not self:is3rd() then
-
- -- switch to local package if exists package configuration or debug package or limit version
- if requireinfo.config or requireinfo.debug or limitversion then
- self._FROMKIND = "local"
- end
-
- -- disable the system package if limit version
- if limitversion then
- requireinfo.system = false
- end
+-- get the given configuration value of package
+function _instance:config(name)
+ local configs = self:configs()
+ if configs then
+ return configs[name]
end
end
--- get the all configuration values of package
+-- get the configurations of package
function _instance:configs()
- local requireinfo = self:requireinfo()
- if requireinfo then
- return requireinfo.config
+ local configs = self._CONFIGS
+ if configs == nil then
+ local configs_defined = self:get("configs")
+ if configs_defined then
+ configs = {}
+ local requireinfo = self:requireinfo()
+ local configs_required = requireinfo and requireinfo.configs or {}
+ for _, name in ipairs(table.wrap(configs_defined)) do
+ local value = configs_required[name]
+ if value == nil then
+ value = self:extraconf("configs", name, "default")
+ end
+ configs[name] = value
+ end
+ else
+ configs = false
+ end
+ self._CONFIGS = configs
end
+ return configs and configs or nil
end
--- get the hash of configs
-function _instance:configs_hash()
- if self._CONFIGS_HASH == nil then
+-- get the build hash
+function _instance:buildhash()
+ if self._BUILDHASH == nil then
+ local str = self:plat() .. self:arch()
local configs = self:configs()
if configs then
- self._CONFIGS_HASH = hash.uuid(string.serialize(configs, true)):split('-')[1]:lower()
+ str = str .. string.serialize(configs, true)
end
+ self._BUILDHASH = hash.uuid(str):gsub('-', ''):lower()
end
- return self._CONFIGS_HASH
+ return self._BUILDHASH
end
-- get the group name
@@ -454,14 +531,6 @@ function _instance:group()
end
end
--- get the given configuration value of package
-function _instance:config(name)
- local configs = self:configs()
- if configs then
- return configs[name]
- end
-end
-
-- is optional package?
function _instance:optional()
local requireinfo = self:requireinfo()
@@ -470,12 +539,7 @@ end
-- is debug package?
function _instance:debug()
- -- @note always release for the binary package
- if self:kind() == "binary" then
- return false
- end
- local requireinfo = self:requireinfo()
- return requireinfo and requireinfo.debug or false
+ return self:config("debug")
end
-- is the supported package?
@@ -488,7 +552,12 @@ end
-- we need install and find package by third-party package manager directly
--
function _instance:is3rd()
- return self:name():find("::", 1, true)
+ return self._is3rd
+end
+
+-- is the system package?
+function _instance:isSys()
+ return self._isSys
end
-- get xxx_script
@@ -545,11 +614,11 @@ function _instance:script(name, generic)
return result
end
--- fetch package info from the local packages
+-- fetch the local package info
--
-- @param opt the fetch option, .e.g {force = true, system = false}
--
--- @return {packageinfo}, fetchfrom (.e.g local/global/system)
+-- @return {packageinfo}, fetchfrom (.e.g xmake/system)
--
function _instance:fetch(opt)
@@ -557,10 +626,9 @@ function _instance:fetch(opt)
opt = opt or {}
-- attempt to get it from cache
- local fetchfrom = self._FETCHFROM
local fetchinfo = self._FETCHINFO
if not opt.force and fetchinfo then
- return fetchinfo, fetchfrom
+ return fetchinfo
end
-- fetch the require version
@@ -569,39 +637,52 @@ function _instance:fetch(opt)
require_ver = nil
end
+ -- nil: find xmake or system packages
+ -- true: only find system package
+ -- false: only find xmake packages
+ local system = opt.system or self:requireinfo().system
+
-- fetch binary tool?
fetchinfo = nil
- fetchfrom = nil
+ local isSys = nil
if self:kind() == "binary" then
-- import find_tool
self._find_tool = self._find_tool or sandbox_module.import("lib.detect.find_tool", {anonymous = true})
- -- fetch it from the system directories, TODO find the given version
- fetchinfo = self._find_tool(self:name(), {force = opt.force})
- if fetchinfo then
- fetchfrom = "system" -- ignore self:requireinfo().system
+ -- only fetch it from the xmake repository first
+ if not fetchinfo and system ~= true and not self:is3rd() then
+ fetchinfo = self._find_tool(self:name(), {version = self:version_str(),
+ cachekey = "fetch_package_xmake",
+ buildhash = self:buildhash(),
+ force = opt.force})
+ if fetchinfo then
+ isSys = self._isSys
+ end
+ end
+
+ -- fetch it from the system directories
+ if not fetchinfo and system ~= false then
+ fetchinfo = self._find_tool(self:name(), {cachekey = "fetch_package_system",
+ force = opt.force})
+ if fetchinfo then
+ isSys = true
+ end
end
else
-- import find_package
self._find_package = self._find_package or sandbox_module.import("lib.detect.find_package", {anonymous = true})
- -- nil: find local or system packages
- -- true: only find system package
- -- false: only find local packages
- local system = opt.system or self:requireinfo().system
-
-- only fetch it from the xmake repository first
if not fetchinfo and system ~= true and not self:is3rd() then
- fetchinfo = self._find_package("xmake::" .. self:name(), {prefixdirs = self:prefixdir(),
- mode = self:mode(),
- islocal = self:from("local"),
- version = require_ver,
+ fetchinfo = self._find_package("xmake::" .. self:name(), {version = self:version_str(),
cachekey = "fetch_package_xmake",
- configs_hash = self:configs_hash(),
- force = opt.force or self:from("local")})
- if fetchinfo then fetchfrom = self._FROMKIND end
+ buildhash = self:buildhash(),
+ force = opt.force})
+ if fetchinfo then
+ isSys = self._isSys
+ end
end
-- fetch it from the system directories
@@ -611,21 +692,76 @@ function _instance:fetch(opt)
mode = self:mode(),
cachekey = "fetch_package_system",
system = true})
- if fetchinfo then fetchfrom = "system" end
+ if fetchinfo then
+ isSys = true
+ end
end
end
-- save to cache
self._FETCHINFO = fetchinfo
- self._FETCHFROM = fetchfrom
+
+ -- mark as system package?
+ if isSys ~= nil then
+ self._isSys = isSys
+ end
-- ok
- return fetchinfo, fetchfrom
+ return fetchinfo
end
--- exists this package in local
+-- exists this package?
function _instance:exists()
- return self._FETCHINFO
+ return self._FETCHINFO ~= nil
+end
+
+-- fetch all local info with dependencies
+function _instance:fetchdeps()
+ local fetchinfo = self:fetch()
+ if not fetchinfo then
+ return
+ end
+ local orderdeps = self:orderdeps()
+ if orderdeps then
+ local total = #orderdeps
+ for idx, _ in ipairs(orderdeps) do
+ local dep = orderdeps[total + 1 - idx]
+ local depinfo = dep:fetch()
+ if depinfo then
+ for name, values in pairs(depinfo) do
+ fetchinfo[name] = table.wrap(fetchinfo[name])
+ table.join2(fetchinfo[name], values)
+ end
+ end
+ end
+ end
+ return fetchinfo
+end
+
+-- has the given c funcs?
+--
+-- @param funcs the funcs
+-- @param opt the argument options, .e.g { includes = ""}
+--
+-- @return true or false
+--
+function _instance:has_cfuncs(funcs, opt)
+ opt = opt or {}
+ opt.configs = self:fetchdeps()
+ return sandbox_module.import("lib.detect.has_cfuncs", {anonymous = true})(funcs, opt)
+end
+
+-- has the given c++ funcs?
+--
+-- @param funcs the funcs
+-- @param opt the argument options, .e.g { includes = ""}
+--
+-- @return true or false
+--
+function _instance:has_cxxfuncs(funcs, opt)
+ opt = opt or {}
+ opt.configs = self:fetchdeps()
+ return sandbox_module.import("lib.detect.has_cxxfuncs", {anonymous = true})(funcs, opt)
end
-- the current mode is belong to the given modes?
@@ -662,6 +798,9 @@ function package._interpreter()
-- define apis
interp:api_define(package.apis())
+
+ -- define apis for language
+ interp:api_define(language.apis())
-- save interpreter
package._INTERPRETER = interp
@@ -686,6 +825,7 @@ function package.apis()
, "package.add_deps"
, "package.add_urls"
, "package.add_imports"
+ , "package.add_configs"
}
, script =
{
@@ -724,77 +864,8 @@ function package.cachedir()
end
-- the install directory
-function package.installdir(mode, plat, arch)
- return path.join(global.directory(), "installed", plat or os.host(), arch or os.arch(), mode or "release")
-end
-
--- get the prefix directory
-function package.prefixdir(is_global, mode, plat, arch)
- return path.join(is_global and global.directory() or config.directory(), "prefix", plat or os.host(), arch or os.arch(), mode or "release")
-end
-
--- get the prefix info directory
-function package.prefixinfodir(is_global, mode, plat, arch)
- return path.join(is_global and global.directory() or config.directory(), "prefix", "info", plat or os.host(), arch or os.arch(), mode or "release")
-end
-
--- get the prefix info
-function package.prefixinfo(is_global, mode, plat, arch)
- local prefixfile = package.prefixfile(is_global, mode, plat, arch)
- return os.isfile(prefixfile) and io.load(prefixfile) or {}
-end
-
--- get the prefix info file
-function package.prefixfile(is_global, mode, plat, arch)
- return path.join(package.prefixinfodir(is_global, mode, plat, arch), "info.txt")
-end
-
--- get environment variables
-function package.getenv(is_global, mode, plat, arch, name)
- local prefixinfo = package.prefixinfo(is_global, mode, plat, arch)
- return prefixinfo.envars and prefixinfo.envars[name] or nil
-end
-
--- add values to environment variable
-function package.addenv(is_global, mode, plat, arch, name, values)
-
- -- add to the root prefix info
- local prefixinfo = package.prefixinfo(is_global, mode, plat, arch)
- prefixinfo.envars = prefixinfo.envars or {}
- prefixinfo.envars[name] = table.join(prefixinfo.envars[name] or {}, values)
- io.save(package.prefixfile(is_global, mode, plat, arch), prefixinfo)
-
- -- add to the current environment
- if values then
- -- PATH? add the prefix root directory
- if name:lower() == "path" then
- local prefixdir = package.prefixdir(is_global, mode, plat, arch)
- for _, value in ipairs(values) do
- os.addenv(name, path.join(prefixdir, value))
- end
- else
- os.addenv(name, unpack(values))
- end
- end
-end
-
--- remove values to environment variable
-function package.delenv(is_global, mode, plat, arch, name, values)
- local prefixinfo = package.prefixinfo(is_global, mode, plat, arch)
- local prefixvalues = prefixinfo.envars and prefixinfo.envars[name] or nil
- if prefixvalues then
- local exists = {}
- for _, value in ipairs(values) do
- exists[value:trim()] = true
- end
- for i = #prefixvalues, 1, -1 do
- value = prefixvalues[i]:trim()
- if exists[value] then
- table.remove(prefixvalues, i)
- end
- end
- io.save(package.prefixfile(is_global, mode, plat, arch), prefixinfo)
- end
+function package.installdir()
+ return path.join(global.directory(), "packages")
end
-- load the package from the system directories
@@ -808,6 +879,7 @@ function package.load_from_system(packagename)
-- get package info
local packageinfo = {}
+ local is3rd = false
if packagename:find("::", 1, true) then
-- get interpreter
@@ -830,6 +902,11 @@ function package.load_from_system(packagename)
-- save the install script
packageinfo.install = instance:script()
+
+ -- is third-party package?
+ if not packagename:startswith("xmake::") then
+ is3rd = true
+ end
end
-- new an instance
@@ -838,8 +915,9 @@ function package.load_from_system(packagename)
return nil, errors
end
- -- mark as system package
- instance._FROMKIND = "system"
+ -- mark as system or 3rd package
+ instance._isSys = true
+ instance._is3rd = is3rd
-- save instance to the cache
package._PACKAGES[packagename] = instance
@@ -874,9 +952,6 @@ function package.load_from_project(packagename, project)
return nil, errors
end
- -- mark as local package
- instance._FROMKIND = "local"
-
-- save instance to the cache
package._PACKAGES[packagename] = instance
@@ -942,9 +1017,6 @@ function package.load_from_repository(packagename, repo, packagedir, packagefile
-- save repository
instance._REPO = repo
- -- mark as global/project package?
- instance._FROMKIND = repo:is_global() and "global" or "local"
-
-- save instance to the cache
package._PACKAGES[packagename] = instance
diff --git a/xmake/core/package/repository.lua b/xmake/core/package/repository.lua
index 7c28b1b9a..9f10153a0 100644
--- a/xmake/core/package/repository.lua
+++ b/xmake/core/package/repository.lua
@@ -244,7 +244,8 @@ function repository.add(name, url, branch, is_global)
repository._cache(is_global):set("repositories", repositories)
-- flush it
- return repository._cache(is_global):flush()
+ repository._cache(is_global):flush()
+ return true
end
-- remove repository from gobal or local directory
@@ -263,7 +264,8 @@ function repository.remove(name, is_global)
repository._cache(is_global):set("repositories", repositories)
-- flush it
- return repository._cache(is_global):flush()
+ repository._cache(is_global):flush()
+ return true
end
-- clear all repositories
@@ -273,7 +275,8 @@ function repository.clear(is_global)
repository._cache(is_global):set("repositories", {})
-- flush it
- return repository._cache(is_global):flush()
+ repository._cache(is_global):flush()
+ return true
end
diff --git a/xmake/core/platform/environment.lua b/xmake/core/platform/environment.lua
index b20d55fd7..5da87d2d1 100644
--- a/xmake/core/platform/environment.lua
+++ b/xmake/core/platform/environment.lua
@@ -39,20 +39,6 @@ function environment._enter_toolchains()
-- save the toolchains environment
environment._PATH = os.getenv("PATH")
- -- add global search binary pathes
- local globaldir = package.prefixdir(true, "release", os.host(), os.arch())
- for _, dir in ipairs(table.wrap(package.getenv(true, "release", os.host(), os.arch(), "PATH"))) do
- os.addenv("PATH", path.join(globaldir, dir))
- end
- os.addenv("PATH", path.join(globaldir, "bin"))
-
- -- add local search binary pathes
- local localdir = package.prefixdir(false, "release", os.host(), os.arch())
- for _, dir in ipairs(table.wrap(package.getenv(false, "release", os.host(), os.arch(), "PATH"))) do
- os.addenv("PATH", path.join(localdir, dir))
- end
- os.addenv("PATH", path.join(localdir, "bin"))
-
-- add $programdir/winenv/bin to $path
if os.host() == "windows" then
os.addenv("PATH", path.join(os.programdir(), "winenv", "bin"))
@@ -72,22 +58,6 @@ function environment._enter_run()
-- save the running environment
environment._PATH = os.getenv("PATH")
environment._LD_LIBRARY_PATH = os.getenv("LD_LIBRARY_PATH")
-
- -- add global search library pathes of pathes
- local globaldir = package.prefixdir(true, "release", os.host(), os.arch())
- if os.host() == "windows" then
- os.addenv("PATH", path.join(globaldir, "lib"))
- else
- os.addenv("LD_LIBRARY_PATH", path.join(globaldir, "lib"))
- end
-
- -- add local search library pathes of pathes
- local localdir = package.prefixdir(false, "release", os.host(), os.arch())
- if os.host() == "windows" then
- os.addenv("PATH", path.join(localdir, "lib"))
- else
- os.addenv("LD_LIBRARY_PATH", path.join(localdir, "lib"))
- end
end
-- leave the running environment
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 1e0403fc3..e20884f54 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -195,7 +195,8 @@ function project.interpreter()
{
-- set_xxx
"set_project"
- , "set_modes"
+ , "set_modes" -- TODO deprecated
+ , "set_description"
-- add_xxx
, "add_requires"
, "add_repositories"
@@ -305,7 +306,7 @@ function project.get(name)
end
-- load the project file
-function project._load(force)
+function project._load(force, disable_filter)
-- has already been loaded?
if project._INFO and not force then
@@ -328,13 +329,13 @@ function project._load(force)
end
-- load the root info of the project
- local rootinfo, errors = project._load_scope("root", true, true)
+ local rootinfo, errors = project._load_scope("root", true, not disable_filter)
if not rootinfo then
return false, errors
end
-- load the root info of the target
- local rootinfo_target, errors = project._load_scope("root.target", true, true)
+ local rootinfo_target, errors = project._load_scope("root.target", true, not disable_filter)
if not rootinfo_target then
return false, errors
end
@@ -411,8 +412,8 @@ function project._load_tasks()
return {}, nil
end
- -- load the project file first
- local ok, errors = project._load(true)
+ -- load the project file first and disable filter
+ local ok, errors = project._load(true, true)
if not ok then
return nil, errors
end
@@ -570,7 +571,7 @@ function project._load_options(disable_filter)
end
-- reload the project file to ensure `if is_plat() then add_packagedirs() end` works
- local ok, errors = project._load(true)
+ local ok, errors = project._load(true, disable_filter)
if not ok then
return nil, errors
end
@@ -783,7 +784,6 @@ end
-- get requires info
function project.requires()
-
if not project._REQUIRES then
local requires, errors = project._load_requires()
if not requires then
@@ -796,7 +796,6 @@ end
-- get string requires
function project.requires_str()
-
if not project._REQUIRES_STR then
-- reload the project file to handle `has_config()`
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 1bf85014d..a47291b5c 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -572,6 +572,28 @@ function _instance:orderpkgs()
return self._ORDERPKGS_ENABLED
end
+-- get the environments of packages
+function _instance:pkgenvs()
+ local pkgenvs = self._PKGENVS
+ if not pkgenvs then
+ pkgenvs = {}
+ self._PKGENVS = pkgenvs
+ for _, pkgname in ipairs(table.wrap(self:get("packages"))) do
+ local pkg = self:pkg(pkgname)
+ if pkg then
+ local envs = pkg:get("envs")
+ if envs then
+ for name, values in pairs(envs) do
+ pkgenvs[name] = pkgenvs[name] or {}
+ table.join2(pkgenvs[name], values)
+ end
+ end
+ end
+ end
+ end
+ return pkgenvs
+end
+
-- get the config info of the given package
function _instance:pkgconfig(pkgname)
local extra_packages = self:get("__extra_packages")
diff --git a/xmake/actions/require/clear.lua b/xmake/core/sandbox/modules/has_package.lua
index ffe73ed26..7873a5d26 100644
--- a/xmake/actions/require/clear.lua
+++ b/xmake/core/sandbox/modules/has_package.lua
@@ -19,22 +19,19 @@
-- Copyright (C) 2015 - 2019, TBOOX Open Source Group.
--
-- @author ruki
--- @file clear.lua
+-- @file has_package.lua
--
--- imports
-import("core.project.cache")
-import("core.package.package")
-
--- clear all installed package caches
-function main()
-
- -- clear cache directory
- os.rm(package.cachedir())
-
- -- clear require cache
- local require_cache = cache("local.require")
- require_cache:clear()
- require_cache:flush()
+-- return module
+return function (...)
+ require("sandbox/modules/import/core/sandbox/module").import("core.project.project")
+ local requires = project.requires()
+ if requires then
+ for _, name in ipairs(table.join(...)) do
+ local pkg = requires[name]
+ if pkg and pkg:enabled() then
+ return true
+ end
+ end
+ end
end
-
diff --git a/xmake/core/sandbox/modules/import/core/package/package.lua b/xmake/core/sandbox/modules/import/core/package/package.lua
index 54a1ce1de..563032482 100644
--- a/xmake/core/sandbox/modules/import/core/package/package.lua
+++ b/xmake/core/sandbox/modules/import/core/package/package.lua
@@ -36,18 +36,8 @@ function sandbox_core_package_package.cachedir()
end
-- the install directory
-function sandbox_core_package_package.installdir(mode, plat, arch)
- return package.installdir(mode, plat, arch)
-end
-
--- get the prefix directory
-function sandbox_core_package_package.prefixdir(is_global, mode, plat, arch)
- return package.prefixdir(is_global, mode, plat, arch)
-end
-
--- get the prefix info directory
-function sandbox_core_package_package.prefixinfodir(is_global, mode, plat, arch)
- return package.prefixinfodir(is_global, mode, plat, arch)
+function sandbox_core_package_package.installdir()
+ return package.installdir()
end
-- load the package from the project file
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
index 18c9be5e3..1cb1c1a81 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
@@ -117,16 +117,49 @@ function sandbox_lib_detect_find_program._find_from_pathes(name, pathes, opt)
end
end
+-- find program from the xmake packages
+function sandbox_lib_detect_find_program._find_from_packages(name, opt)
+
+ -- get the manifest file of package, .e.g ~/.xmake/packages/g/git/1.1.12/ed41d5327fad3fc06fe376b4a94f62ef/manifest.txt
+ local manifest_file = path.join(package.installdir(), name:sub(1, 1), name, opt.version, opt.buildhash, "manifest.txt")
+ if not os.isfile(manifest_file) then
+ return
+ end
+
+ -- get install directory of this package
+ local installdir = path.directory(manifest_file)
+
+ -- init pathes
+ local pathes = {}
+ local manifest = io.load(manifest_file)
+ if manifest and manifest.envs then
+ local pathenvs = manifest.envs.PATH
+ if pathenvs then
+ for _, pathenv in ipairs(pathenvs) do
+ table.insert(pathes, path.join(installdir, pathenv))
+ end
+ end
+ end
+
+ -- find it
+ return sandbox_lib_detect_find_program._find_from_pathes(name, pathes, opt)
+end
+
-- find program
function sandbox_lib_detect_find_program._find(name, pathes, opt)
- -- attempt to check it from the given directories
+ -- attempt to find it from the given directories
local program_path = sandbox_lib_detect_find_program._find_from_pathes(name, pathes, opt)
if program_path then
return program_path
end
- -- attempt to check it from regists
+ -- attempt to find it from the xmake packages
+ if opt.version and opt.buildhash then
+ return sandbox_lib_detect_find_program._find_from_packages(name, opt)
+ end
+
+ -- attempt to find it from regists
if os.host() == "windows" then
local program_name = name:lower()
if not program_name:endswith(".exe") then
@@ -143,7 +176,7 @@ function sandbox_lib_detect_find_program._find(name, pathes, opt)
end
end
else
- -- attempt to check it use `which program` command
+ -- attempt to find it use `which program` command
local ok, program_path = os.iorunv("which", {name})
if ok and program_path then
-- check it
@@ -156,7 +189,7 @@ function sandbox_lib_detect_find_program._find(name, pathes, opt)
end
end
- -- attempt to check it from the some default system directories
+ -- attempt to find it from the some default system directories
local syspathes = {}
if os.host() ~= "windows" then
table.insert(syspathes, "/usr/local/bin")
@@ -169,7 +202,7 @@ function sandbox_lib_detect_find_program._find(name, pathes, opt)
end
end
- -- attempt to check it directly in current environment
+ -- attempt to find it directly in current environment
--
-- @note must be detected at the end, because full path is more accurate
--
diff --git a/xmake/core/sandbox/modules/irpairs.lua b/xmake/core/sandbox/modules/irpairs.lua
new file mode 100644
index 000000000..e498ae363
--- /dev/null
+++ b/xmake/core/sandbox/modules/irpairs.lua
@@ -0,0 +1,72 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you 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 - 2019, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file irpairs.lua
+--
+
+-- load modules
+local table = require("base/table")
+
+-- irpairs
+--
+-- .e.g
+--
+-- @code
+--
+-- for idx, val in irpairs({"a", "b", "c", "d", "e", "f"}) do
+-- print("%d %s", idx, val)
+-- end
+--
+-- for idx, val in irpairs({"a", "b", "c", "d", "e", "f"}, function (v) return v:upper() end) do
+-- print("%d %s", idx, val)
+-- end
+--
+-- for idx, val in irpairs({"a", "b", "c", "d", "e", "f"}, function (v, a, b) return v:upper() .. a .. b end, "a", "b") do
+-- print("%d %s", idx, val)
+-- end
+--
+-- @endcode
+function sandbox_irpairs(t, filter, ...)
+
+ -- has filter?
+ local has_filter = type(filter) == "function"
+
+ -- init iterator
+ local args = {...}
+ local iter = function (t, i)
+ if i > 1 then
+ i = i - 1
+ local v = t[i]
+ if has_filter then
+ v = filter(v, unpack(args))
+ end
+ return i, v
+ end
+ end
+
+ -- return iterator and initialized state
+ t = table.wrap(t)
+ return iter, t, #t + 1
+end
+
+-- load module
+return sandbox_irpairs
+
diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua
index a08f7226f..0eee93313 100644
--- a/xmake/core/tool/builder.lua
+++ b/xmake/core/tool/builder.lua
@@ -366,6 +366,8 @@ function builder:_add_flags_from_argument(flags, target, args)
if target then
local key = target:type()
self:_add_flags_from_language(flags, target, {[key] = function (name) return args[name] end})
+ else
+ self:_add_flags_from_language(flags, nil, {target = function (name) return args[name] end})
end
end
diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua
index 781e95e7d..01b9bf659 100644
--- a/xmake/core/tool/compiler.lua
+++ b/xmake/core/tool/compiler.lua
@@ -47,12 +47,10 @@ end
-- add flags from the platform
function compiler:_add_flags_from_platform(flags, targetkind)
- -- add flags
- local toolname = self:name()
- for _, flagkind in ipairs(self:_flagkinds()) do
-
- -- add flags for platform with the given target kind, e.g. binary.gcc.cxflags or binary.cxflags
- if targetkind then
+ -- add flags for platform with the given target kind, e.g. binary.gcc.cxflags or binary.cxflags
+ if targetkind then
+ local toolname = self:name()
+ for _, flagkind in ipairs(self:_flagkinds()) do
local toolflags = platform.get(targetkind .. '.' .. toolname .. '.' .. flagkind)
table.join2(flags, toolflags or platform.get(targetkind .. '.' .. flagkind))
end
@@ -266,7 +264,7 @@ end
--
-- @param opt the argument options (contain all the compiler attributes of target),
-- .e.g
--- {target = ..., targetkind = "static", config = {defines = "", cxflags = "", includedirs = ""}}
+-- {target = ..., targetkind = "static", configs = {defines = "", cxflags = "", includedirs = ""}}
--
-- @return flags string, flags list
--
@@ -300,14 +298,13 @@ function compiler:compflags(opt)
end
-- add flags for the argument
- if opt.config then
- self:_add_flags_from_argument(flags, target, opt.config)
+ local configs = opt.configs or opt.config
+ if configs then
+ self:_add_flags_from_argument(flags, target, configs)
end
-- add flags from the platform
- if target then
- self:_add_flags_from_platform(flags, targetkind)
- end
+ self:_add_flags_from_platform(flags, targetkind)
-- add flags from the compiler
self:_add_flags_from_compiler(flags, targetkind)
diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua
index f7482888c..d582d62bb 100644
--- a/xmake/core/tool/linker.lua
+++ b/xmake/core/tool/linker.lua
@@ -43,13 +43,11 @@ local compiler = require("tool/compiler")
-- add flags from the platform
function linker:_add_flags_from_platform(flags, targetkind)
- -- add flags
- local toolkind = self:kind()
- local toolname = self:name()
- for _, flagkind in ipairs(self:_flagkinds()) do
-
- -- attempt to add special lanugage flags first for target kind, .e.g gc-ldflags, dc-arflags
- if targetkind then
+ -- attempt to add special lanugage flags first for target kind, .e.g binary.gc-ldflags, static.dc-arflags
+ if targetkind then
+ local toolkind = self:kind()
+ local toolname = self:name()
+ for _, flagkind in ipairs(self:_flagkinds()) do
local toolflags = platform.get(targetkind .. '.' .. toolname .. '.' .. toolkind .. 'flags') or platform.get(targetkind .. '.' .. toolname .. '.' .. flagkind)
table.join2(flags, toolflags or platform.get(targetkind .. '.' .. toolkind .. 'flags') or platform.get(targetkind .. '.' .. flagkind))
end
@@ -247,7 +245,7 @@ end
-- get the link flags
--
-- @param opt the argument options (contain all the linker attributes of target),
--- .e.g {target = ..., targetkind = "static", config = {ldflags = "", links = "", linkdirs = "", ...}}
+-- .e.g {target = ..., targetkind = "static", configs = {ldflags = "", links = "", linkdirs = "", ...}}
--
function linker:linkflags(opt)
@@ -271,14 +269,13 @@ function linker:linkflags(opt)
self:_add_flags_from_target(flags, target)
-- add flags for the argument
- if opt.config then
- self:_add_flags_from_argument(flags, target, opt.config)
+ local configs = opt.configs or opt.config
+ if configs then
+ self:_add_flags_from_argument(flags, target, configs)
end
-- add flags from the platform
- if target then
- self:_add_flags_from_platform(flags, targetkind)
- end
+ self:_add_flags_from_platform(flags, targetkind)
-- add flags from the compiler
if target then
diff --git a/xmake/languages/asm/api.lua b/xmake/languages/asm/api.lua
index ddc850383..ac3378fa5 100644
--- a/xmake/languages/asm/api.lua
+++ b/xmake/languages/asm/api.lua
@@ -48,6 +48,16 @@ function apis()
, "option.add_defines"
, "option.add_undefines"
, "option.add_rpathdirs"
+ -- package.add_xxx
+ , "package.add_links"
+ , "package.add_syslinks"
+ , "package.add_asflags"
+ , "package.add_ldflags"
+ , "package.add_arflags"
+ , "package.add_shflags"
+ , "package.add_defines"
+ , "package.add_undefines"
+ , "package.add_rpathdirs"
}
_g.pathes =
{
@@ -60,6 +70,9 @@ function apis()
-- option.add_xxx
, "option.add_linkdirs"
, "option.add_includedirs"
+ -- package.add_xxx
+ , "package.add_linkdirs"
+ , "package.add_includedirs"
}
-- ok
diff --git a/xmake/languages/c++/api.lua b/xmake/languages/c++/api.lua
index 3b4506abd..9cba73bf1 100644
--- a/xmake/languages/c++/api.lua
+++ b/xmake/languages/c++/api.lua
@@ -48,7 +48,7 @@ function _funcinfo(func)
return name:trim(), code
end
--- add c function
+-- TODO add c function, deprecated
function _api_add_cfunc(interp, module, alias, links, includes, func)
-- parse the function info
@@ -93,7 +93,7 @@ function _api_add_cfunc(interp, module, alias, links, includes, func)
interp:api_call("add_options", name)
end
--- add c functions
+-- TODO add c functions, deprecated
function _api_add_cfuncs(interp, module, links, includes, ...)
-- done
@@ -102,7 +102,7 @@ function _api_add_cfuncs(interp, module, links, includes, ...)
end
end
--- add c++ function
+-- TODO add c++ function, deprecated
function _api_add_cxxfunc(interp, module, alias, links, includes, func)
-- parse the function info
@@ -147,7 +147,7 @@ function _api_add_cxxfunc(interp, module, alias, links, includes, func)
interp:api_call("add_options", name)
end
--- add c++ functions
+-- TODO add c++ functions, deprecated
function _api_add_cxxfuncs(interp, module, links, includes, ...)
-- done
@@ -205,6 +205,19 @@ function apis()
, "option.add_undefines_h_if_ok"-- TODO deprecated
, "option.add_frameworks"
, "option.add_rpathdirs"
+ -- package.add_xxx
+ , "package.add_links"
+ , "package.add_syslinks"
+ , "package.add_cflags"
+ , "package.add_cxflags"
+ , "package.add_cxxflags"
+ , "package.add_ldflags"
+ , "package.add_arflags"
+ , "package.add_shflags"
+ , "package.add_defines"
+ , "package.add_undefines"
+ , "package.add_frameworks"
+ , "package.add_rpathdirs"
}
_g.pathes =
{
@@ -215,8 +228,8 @@ function apis()
, "target.set_pcheader"
, "target.set_pcxxheader"
-- target.add_xxx
- , "target.add_headers" -- TODO deprecated
- , "target.add_headerdirs"
+ , "target.add_headers" -- TODO deprecated
+ , "target.add_headerdirs" -- TODO deprecated
, "target.add_headerfiles"
, "target.add_linkdirs"
, "target.add_includedirs"
@@ -225,6 +238,10 @@ function apis()
, "option.add_linkdirs"
, "option.add_includedirs"
, "option.add_frameworkdirs"
+ -- package.add_xxx
+ , "package.add_linkdirs"
+ , "package.add_includedirs"
+ , "package.add_frameworkdirs"
}
_g.dictionary =
{
diff --git a/xmake/languages/dlang/api.lua b/xmake/languages/dlang/api.lua
index 09d55c654..63ba3ec2d 100644
--- a/xmake/languages/dlang/api.lua
+++ b/xmake/languages/dlang/api.lua
@@ -44,6 +44,14 @@ function apis()
, "option.add_arflags"
, "option.add_shflags"
, "option.add_rpathdirs"
+ -- package.add_xxx
+ , "package.add_links"
+ , "package.add_syslinks"
+ , "package.add_dcflags"
+ , "package.add_ldflags"
+ , "package.add_arflags"
+ , "package.add_shflags"
+ , "package.add_rpathdirs"
}
_g.pathes =
{
@@ -53,6 +61,9 @@ function apis()
-- option.add_xxx
, "option.add_linkdirs"
, "option.add_includedirs"
+ -- package.add_xxx
+ , "package.add_linkdirs"
+ , "package.add_includedirs"
}
-- ok
diff --git a/xmake/modules/detect/tools/find_cmake.lua b/xmake/modules/detect/tools/find_cmake.lua
index e9a20232d..021133052 100644
--- a/xmake/modules/detect/tools/find_cmake.lua
+++ b/xmake/modules/detect/tools/find_cmake.lua
@@ -52,7 +52,7 @@ function main(opt)
-- find program version
local version = nil
- if opt and opt.version then
+ if program and opt and opt.version then
version = find_programver(program, opt)
end
diff --git a/xmake/modules/lib/detect/check_cxsnippets.lua b/xmake/modules/lib/detect/check_cxsnippets.lua
index e44043b99..48a56fe1b 100644
--- a/xmake/modules/lib/detect/check_cxsnippets.lua
+++ b/xmake/modules/lib/detect/check_cxsnippets.lua
@@ -120,7 +120,7 @@ end
-- .e.g
-- { verbose = false, target = [target|option], sourcekind = "[cc|cxx]"
-- , types = {"wchar_t", "char*"}, includes = "stdio.h", funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"}
--- , config = {defines = "xx", cxflags = ""}}
+-- , configs = {defines = "xx", cxflags = ""}}
--
-- funcs:
-- sigsetjmp
@@ -144,11 +144,23 @@ function main(snippets, opt)
-- init snippets
snippets = snippets or {}
+ -- get configs
+ local configs = opt.configs or opt.config
+
-- get links
- local links = table.wrap(opt.links)
+ local links = {}
+ if configs and configs.links then
+ table.join2(links, configs.links)
+ end
if opt.target then
table.join2(links, opt.target:get("links"))
end
+ if configs and configs.syslinks then
+ table.join2(links, configs.syslinks)
+ end
+ if opt.target then
+ table.join2(links, opt.target:get("syslinks"))
+ end
-- get types
local types = table.wrap(opt.types)
@@ -199,7 +211,7 @@ function main(snippets, opt)
-- trace
if opt.verbose or option.get("verbose") or option.get("diagnosis") then
- local kind = ifelse(sourcekind == "cc", "c", "c++")
+ local kind = opt.sourcekind == "cc" and "c" or "c++"
if #includes > 0 then
cprint("${dim}> checking for the %s includes(%s)", kind, table.concat(includes, ", "))
end
diff --git a/xmake/modules/lib/detect/find_package.lua b/xmake/modules/lib/detect/find_package.lua
index dc9286c54..63745c48d 100644
--- a/xmake/modules/lib/detect/find_package.lua
+++ b/xmake/modules/lib/detect/find_package.lua
@@ -87,7 +87,6 @@ function main(name, opt)
if opt.verbose or option.get("verbose") then
if result then
cprint("checking for the %s ... ${color.success}%s", name, result.version and result.version or "${text.success}")
- dprint(result)
else
cprint("checking for the %s ... ${color.nothing}${text.nothing}", name)
end
diff --git a/xmake/modules/lib/detect/has_cfuncs.lua b/xmake/modules/lib/detect/has_cfuncs.lua
index 6cf8f4cd3..73ab54eca 100644
--- a/xmake/modules/lib/detect/has_cfuncs.lua
+++ b/xmake/modules/lib/detect/has_cfuncs.lua
@@ -30,7 +30,7 @@ import("lib.detect.check_cxsnippets")
-- @param funcs the funcs
-- @param opt the argument options
-- .e.g
--- { verbose = false, target = [target|option], includes = "", config = {linkdirs = .., links = .., defines = .., ..}}
+-- { verbose = false, target = [target|option], includes = "", configs = {linkdirs = .., links = .., defines = .., ..}}
--
-- funcs:
-- sigsetjmp
@@ -55,5 +55,6 @@ function main(funcs, opt)
opt.funcs = funcs
-- has funcs?
- return check_cxsnippets("", opt)
+ local name = opt.name or "has_cfuncs"
+ return check_cxsnippets({[name] = ""}, opt)
end
diff --git a/xmake/modules/lib/detect/has_cincludes.lua b/xmake/modules/lib/detect/has_cincludes.lua
index a70c17f56..195a482e1 100644
--- a/xmake/modules/lib/detect/has_cincludes.lua
+++ b/xmake/modules/lib/detect/has_cincludes.lua
@@ -30,7 +30,7 @@ import("lib.detect.check_cxsnippets")
-- @param includes the includes
-- @param opt the argument options
-- .e.g
--- { verbose = false, target = [target|option], config = {defines = "..", .. }}
+-- { verbose = false, target = [target|option], configs = {defines = "..", .. }}
--
-- @return true or false
--
@@ -49,5 +49,6 @@ function main(includes, opt)
opt.includes = includes
-- has includes?
- return check_cxsnippets("", opt)
+ local name = opt.name or "has_cincludes"
+ return check_cxsnippets({[name] = ""}, opt)
end
diff --git a/xmake/modules/lib/detect/has_ctypes.lua b/xmake/modules/lib/detect/has_ctypes.lua
index 2341b983d..2ac05a30e 100644
--- a/xmake/modules/lib/detect/has_ctypes.lua
+++ b/xmake/modules/lib/detect/has_ctypes.lua
@@ -30,7 +30,7 @@ import("lib.detect.check_cxsnippets")
-- @param types the types
-- @param opt the argument options
-- .e.g
--- { verbose = false, target = [target|option], includes = .., config = {defines = .., ..}}
+-- { verbose = false, target = [target|option], includes = .., configs = {defines = .., ..}}
--
-- @return true or false
--
@@ -49,5 +49,6 @@ function main(types, opt)
opt.types = types
-- has types?
- return check_cxsnippets("", opt)
+ local name = opt.name or "has_ctypes"
+ return check_cxsnippets({[name] = ""}, opt)
end
diff --git a/xmake/modules/lib/detect/has_cxxfuncs.lua b/xmake/modules/lib/detect/has_cxxfuncs.lua
index 0ee26c897..e30a21416 100644
--- a/xmake/modules/lib/detect/has_cxxfuncs.lua
+++ b/xmake/modules/lib/detect/has_cxxfuncs.lua
@@ -30,7 +30,7 @@ import("lib.detect.check_cxsnippets")
-- @param funcs the funcs
-- @param opt the argument options
-- .e.g
--- { verbose = false, target = [target|option], includes = "", config = {linkdirs = .., links = .., defines = .., ..}}
+-- { verbose = false, target = [target|option], includes = "", configs = {linkdirs = .., links = .., defines = .., ..}}
--
-- funcs:
-- sigsetjmp
@@ -55,5 +55,6 @@ function main(funcs, opt)
opt.funcs = funcs
-- has funcs?
- return check_cxsnippets("", opt)
+ local name = opt.name or "has_cxxfuncs"
+ return check_cxsnippets({[name] = ""}, opt)
end
diff --git a/xmake/modules/lib/detect/has_cxxincludes.lua b/xmake/modules/lib/detect/has_cxxincludes.lua
index 57c08ddb6..6c4846134 100644
--- a/xmake/modules/lib/detect/has_cxxincludes.lua
+++ b/xmake/modules/lib/detect/has_cxxincludes.lua
@@ -30,7 +30,7 @@ import("lib.detect.check_cxsnippets")
-- @param includes the includes
-- @param opt the argument options
-- .e.g
--- { verbose = false, target = [target|option], config = {defines = "..", .. }}
+-- { verbose = false, target = [target|option], configs = {defines = "..", .. }}
--
-- @return true or false
--
@@ -49,5 +49,6 @@ function main(includes, opt)
opt.includes = includes
-- has includes?
- return check_cxsnippets("", opt)
+ local name = opt.name or "has_cxxincludes"
+ return check_cxsnippets({[name] = ""}, opt)
end
diff --git a/xmake/modules/lib/detect/has_cxxtypes.lua b/xmake/modules/lib/detect/has_cxxtypes.lua
index 1011a4b5f..f52cee697 100644
--- a/xmake/modules/lib/detect/has_cxxtypes.lua
+++ b/xmake/modules/lib/detect/has_cxxtypes.lua
@@ -30,7 +30,7 @@ import("lib.detect.check_cxsnippets")
-- @param types the types
-- @param opt the argument options
-- .e.g
--- { verbose = false, target = [target|option], includes = .., config = {defines = .., ..}}
+-- { verbose = false, target = [target|option], includes = .., configs = {defines = .., ..}}
--
-- @return true or false
--
@@ -49,5 +49,6 @@ function main(types, opt)
opt.types = types
-- has types?
- return check_cxsnippets("", opt)
+ local name = opt.name or "has_cxxtypes"
+ return check_cxsnippets({[name] = ""}, opt)
end
diff --git a/xmake/modules/package/manager/find_package.lua b/xmake/modules/package/manager/find_package.lua
index 7fec292e5..49ec98208 100644
--- a/xmake/modules/package/manager/find_package.lua
+++ b/xmake/modules/package/manager/find_package.lua
@@ -127,16 +127,6 @@ function _find_package(manager_name, package_name, opt)
-- remove repeat
result.linkdirs = table.unique(result.linkdirs)
result.includedirs = table.unique(result.includedirs)
-
- -- check valid version
- if result.version then
- local version = try { function () return semver.new(result.version) end }
- if version then
- result.version = version:rawstr()
- else
- result.version = nil
- end
- end
end
-- ok?
@@ -191,7 +181,7 @@ function main(name, opt)
-- match version?
if opt.version and result then
- if not result.version or not semver.satisfies(result.version, opt.version) then
+ if not (result.version and (result.version == opt.version or semver.satisfies(result.version, opt.version))) then
result = nil
end
end
diff --git a/xmake/modules/package/manager/xmake/find_package.lua b/xmake/modules/package/manager/xmake/find_package.lua
index cb00d5756..0c6461480 100644
--- a/xmake/modules/package/manager/xmake/find_package.lua
+++ b/xmake/modules/package/manager/xmake/find_package.lua
@@ -27,6 +27,7 @@ import("core.base.global")
import("core.project.config")
import("core.project.option")
import("core.project.target")
+import("core.package.package")
import("core.language.language")
import("lib.detect.find_file")
import("lib.detect.find_library")
@@ -34,86 +35,76 @@ import("lib.detect.find_library")
-- find package from the repository (maybe only include and no links)
function _find_package_from_repo(name, opt)
- -- get build mode, e.g. debug_f7821231
- local mode = table.concat({opt.mode or "release", opt.configs_hash}, '_')
-
- -- get the prefix directories
- local prefixdirs = table.wrap(opt.prefixdirs)
- local platsubdirs = path.join(config.get("plat") or os.host(), config.get("arch") or os.arch())
- if #prefixdirs == 0 then
- table.insert(prefixdirs, path.join(opt.islocal and config.directory() or global.directory(), "prefix", platsubdirs, mode))
- end
-
- -- find the prefix info file of package, .e.g prefix/info/z/zlib/1.2.11/info.txt
+ -- find the manifest file of package, .e.g ~/.xmake/packages/z/zlib/1.1.12/ed41d5327fad3fc06fe376b4a94f62ef/manifest.txt
local packagedirs = {}
- local packagepath = path.join(name:sub(1, 1), name, "*")
- table.insert(packagedirs, path.join(opt.islocal and config.directory() or global.directory(), "prefix", "info", platsubdirs, mode, packagepath))
- local prefixfile = find_file("info.txt", packagedirs)
- if not prefixfile then
+ table.insert(packagedirs, path.join(package.installdir(), name:sub(1, 1), name, opt.version or "*", opt.buildhash))
+ local manifest_file = find_file("manifest.txt", packagedirs)
+ if not manifest_file then
return
end
- -- load prefix info
- local prefixinfo = io.load(prefixfile)
- if not prefixinfo then
+ -- load manifest info
+ local manifest = io.load(manifest_file)
+ if not manifest then
return
end
- -- get prefix directory of this package
- local prefixdir = path.translate(path.directory(path.directory(path.directory(path.directory(prefixfile)))):gsub("[/\\]prefix[/\\]info[/\\]", "/prefix/"))
+ -- get manifest variables
+ local vars = manifest.vars or {}
+
+ -- get install directory of this package
+ local installdir = path.directory(manifest_file)
-- save includedirs to result (maybe only include and no links)
local result = {}
local includedirs = {}
- for _, includedir in ipairs(prefixinfo.includedirs) do
- table.insert(includedirs, path.join(prefixdir, includedir))
+ for _, includedir in ipairs(vars.includedirs) do
+ table.insert(includedirs, path.join(installdir, includedir))
end
if #includedirs == 0 then
- table.insert(includedirs, path.join(prefixdir, "include"))
+ table.insert(includedirs, path.join(installdir, "include"))
end
result.includedirs = table.unique(includedirs)
-- get links and link directories
local links = {}
local linkdirs = {}
- for _, linkdir in ipairs(prefixinfo.linkdirs) do
- table.insert(linkdirs, path.join(prefixdir, linkdir))
+ for _, linkdir in ipairs(vars.linkdirs) do
+ table.insert(linkdirs, path.join(installdir, linkdir))
end
- if prefixinfo.links then
- table.join2(links, prefixinfo.links)
+ if vars.links then
+ table.join2(links, vars.links)
end
- if prefixinfo.installed and (not prefixinfo.linkdirs or not prefixinfo.links) then
+ if not vars.linkdirs or not vars.links then
local found = false
- for _, line in ipairs(prefixinfo.installed) do
- line = line:trim()
- if line:endswith(".lib") or line:endswith(".a") then
+ for _, file in ipairs(os.files(path.join(installdir, "lib", "*"))) do
+ if file:endswith(".lib") or file:endswith(".a") then
found = true
- if not prefixinfo.linkdirs then
- table.insert(linkdirs, path.join(prefixdir, path.directory(line)))
+ if not vars.linkdirs then
+ table.insert(linkdirs, path.directory(file))
end
- if not prefixinfo.links then
- table.insert(links, target.linkname(path.filename(line)))
+ if not vars.links then
+ table.insert(links, target.linkname(path.filename(file)))
end
end
end
if not found then
- for _, line in ipairs(prefixinfo.installed) do
- line = line:trim()
- if line:endswith(".so") or line:endswith(".dylib") then
- if not prefixinfo.linkdirs then
- table.insert(linkdirs, path.join(prefixdir, path.directory(line)))
+ for _, file in ipairs(os.files(path.join(installdir, "lib", "*"))) do
+ if file:endswith(".so") or file:endswith(".dylib") then
+ if not vars.linkdirs then
+ table.insert(linkdirs, path.directory(file))
end
- if not prefixinfo.links then
- table.insert(links, target.linkname(path.filename(line)))
+ if not vars.links then
+ table.insert(links, target.linkname(path.filename(file)))
end
end
end
end
end
- -- add root include and link directories
+ -- add root link directories
if #linkdirs == 0 then
- table.insert(linkdirs, path.join(prefixdir, "lib"))
+ table.insert(linkdirs, path.join(installdir, "lib"))
end
-- uses name as links directly .e.g libname.a
@@ -135,16 +126,25 @@ function _find_package_from_repo(name, opt)
end
-- inherit the other prefix variables
- for name, values in pairs(prefixinfo) do
- if name ~= "links" and name ~= "linkdirs" and name ~= "includedirs" and name ~= "installed" and name ~= "prefixdir" then
+ for name, values in pairs(vars) do
+ if name ~= "links" and name ~= "linkdirs" and name ~= "includedirs" then
result[name] = values
end
end
- -- get version
- result.version = path.filename(path.directory(prefixfile))
+ -- update the project references file
+ if result then
+ local projectdir = os.projectdir()
+ if projectdir and os.isdir(projectdir) then
+ local references_file = path.join(installdir, "references.txt")
+ local references = os.isfile(references_file) and io.load(references_file) or {}
+ references[projectdir] = os.date("%y%m%d")
+ io.save(references_file, references)
+ end
+ end
- -- ok
+ -- get version
+ result.version = manifest.version or path.filename(path.directory(path.directory(manifest_file)))
return result
end
@@ -247,7 +247,7 @@ end
-- find package using the xmake package manager
--
-- @param name the package name
--- @param opt the options, .e.g {verbose = true, version = "1.12.x", configs_hash = "xxxxxx")
+-- @param opt the options, .e.g {verbose = true, version = "1.12.x", buildhash = "xxxxxx")
--
function main(name, opt)
diff --git a/xmake/modules/package/tools/autoconf.lua b/xmake/modules/package/tools/autoconf.lua
index 29e147636..32186a080 100644
--- a/xmake/modules/package/tools/autoconf.lua
+++ b/xmake/modules/package/tools/autoconf.lua
@@ -22,6 +22,68 @@
-- @file autoconf.lua
--
+-- get configs
+function _get_configs(package, configs)
+ local configs = configs or {}
+ table.insert(configs, "--prefix=" .. package:installdir())
+ return configs
+end
+
+-- enter environments
+function _enter_envs(package)
+
+ -- get old environments
+ local envs = {}
+ envs.CFLAGS = os.getenv("CFLAGS")
+ envs.CXXFLAGS = os.getenv("CXXFLAGS")
+ envs.ASFLAGS = os.getenv("ASFLAGS")
+ envs.ACLOCAL_PATH = os.getenv("ACLOCAL_PATH")
+ envs.PKG_CONFIG_PATH = os.getenv("PKG_CONFIG_PATH")
+
+ -- set new environments
+ local cflags = package:config("cflags")
+ local cxflags = package:config("cxflags")
+ local cxxflags = package:config("cxxflags")
+ local asflags = package:config("asflags")
+ if package:plat() == "windows" then
+ local vs_runtime = package:config("vs_runtime")
+ if vs_runtime then
+ cxflags = (cxflags or "") .. " /" .. vs_runtime .. (package:debug() and "d" or "")
+ end
+ end
+ if cflags then
+ os.addenv("CFLAGS", cflags)
+ end
+ if cxflags then
+ os.addenv("CFLAGS", cxflags)
+ os.addenv("CXXFLAGS", cxflags)
+ end
+ if cxxflags then
+ os.addenv("CXXFLAGS", cxxflags)
+ end
+ if asflags then
+ os.addenv("ASFLAGS", asflags)
+ end
+ for _, dep in ipairs(package:orderdeps()) do
+ local pkgconfig = path.join(dep:installdir(), "lib", "pkgconfig")
+ if os.isdir(pkgconfig) then
+ os.addenv("PKG_CONFIG_PATH", pkgconfig)
+ end
+ local aclocal = path.join(dep:installdir(), "share", "aclocal")
+ if os.isdir(aclocal) then
+ os.addenv("ACLOCAL_PATH", aclocal)
+ end
+ end
+ return envs
+end
+
+-- leave environments
+function _leave_envs(package, envs)
+ for k, v in pairs(envs) do
+ os.setenv(k, v)
+ end
+end
+
-- install package
function install(package, configs)
@@ -34,12 +96,9 @@ function install(package, configs)
end
end
- -- inherit require and option configs
+ -- pass configurations
local argv = {}
- if not configs or not configs.prefix then
- table.insert(argv, "--prefix=" .. package:installdir())
- end
- for name, value in pairs(configs) do
+ for name, value in pairs(_get_configs(package, configs)) do
value = tostring(value):trim()
if type(name) == "number" then
if value ~= "" then
@@ -50,15 +109,8 @@ function install(package, configs)
end
end
- -- inherit flags from configs
- local flags_prev = {}
- for _, name in ipairs({"cflags", "cxxflags", "ldflags"}) do
- local flags = package:config(name) or (configs and configs[name] or nil)
- if flags then
- flags_prev[name] = os.getenv(name:upper())
- os.addenv(name:upper(), flags)
- end
- end
+ -- enter environments
+ local envs = _enter_envs(package)
-- do configure
os.vrunv("./configure", argv)
@@ -67,9 +119,7 @@ function install(package, configs)
os.vrun("make -j4")
os.vrun("make install")
- -- restore flags
- for name, flags in pairs(flags_prev) do
- os.setenv(name:upper(), flags)
- end
+ -- leave environments
+ _leave_envs(package, envs)
end
diff --git a/xmake/modules/package/tools/cmake.lua b/xmake/modules/package/tools/cmake.lua
index cbcf99014..f7afc56c5 100644
--- a/xmake/modules/package/tools/cmake.lua
+++ b/xmake/modules/package/tools/cmake.lua
@@ -26,6 +26,59 @@
import("core.base.option")
import("lib.detect.find_file")
+-- get configs
+function _get_configs(package, configs)
+ local configs = configs or {}
+ if package:plat() == "windows" then
+ local vs_runtime = package:config("vs_runtime")
+ if vs_runtime then
+ table.insert(configs, '-DCMAKE_CXX_FLAGS_DEBUG="/' .. vs_runtime .. 'd"')
+ table.insert(configs, '-DCMAKE_CXX_FLAGS_RELEASE="/' .. vs_runtime .. '"')
+ table.insert(configs, '-DCMAKE_C_FLAGS_DEBUG="/' .. vs_runtime .. 'd"')
+ table.insert(configs, '-DCMAKE_C_FLAGS_RELEASE="/' .. vs_runtime .. '"')
+ end
+ end
+ local cflags = package:config("cflags")
+ if cflags then
+ table.insert(configs, '-DCMAKE_C_FLAGS="' .. cflags .. '"')
+ end
+ local cxflags = package:config("cxflags")
+ if cxflags then
+ table.insert(configs, '-DCMAKE_C_FLAGS="' .. cxflags .. '"')
+ table.insert(configs, '-DCMAKE_CXX_FLAGS="' .. cxflags .. '"')
+ end
+ local cxxflags = package:config("cxxflags")
+ if cxxflags then
+ table.insert(configs, '-DCMAKE_CXX_FLAGS="' .. cxxflags .. '"')
+ end
+ local asflags = package:config("asflags")
+ if asflags then
+ table.insert(configs, '-DCMAKE_ASM_FLAGS="' .. asflags .. '"')
+ end
+ return configs
+end
+
+-- enter environments
+function _enter_envs(package)
+
+ -- get old environments
+ local envs = {}
+ envs.CMAKE_PREFIX_PATH = os.getenv("CMAKE_PREFIX_PATH")
+
+ -- set new environments
+ for _, dep in ipairs(package:orderdeps()) do
+ os.addenv("CMAKE_PREFIX_PATH", dep:installdir())
+ end
+ return envs
+end
+
+-- leave environments
+function _leave_envs(package, envs)
+ for k, v in pairs(envs) do
+ os.setenv(k, v)
+ end
+end
+
-- install package
function install(package, configs)
@@ -39,7 +92,9 @@ function install(package, configs)
table.insert(argv, "-A")
table.insert(argv, "x64")
end
- for name, value in pairs(configs) do
+
+ -- pass configurations
+ for name, value in pairs(_get_configs(package, configs)) do
value = tostring(value):trim()
if type(name) == "number" then
if value ~= "" then
@@ -51,6 +106,9 @@ function install(package, configs)
end
table.insert(argv, '..')
+ -- enter environments
+ local envs = _enter_envs(package)
+
-- generate build file
os.vrunv("cmake", argv)
@@ -74,6 +132,9 @@ function install(package, configs)
os.cp("install/lib", package:installdir())
os.cp("install/include", package:installdir())
end
+
+ -- leave environments
+ _leave_envs(package, envs)
os.cd(oldir)
end
diff --git a/xmake/modules/package/tools/xmake.lua b/xmake/modules/package/tools/xmake.lua
index 042b0c468..cc0fe0d45 100644
--- a/xmake/modules/package/tools/xmake.lua
+++ b/xmake/modules/package/tools/xmake.lua
@@ -25,11 +25,40 @@
-- imports
import("core.base.option")
+-- get configs
+function _get_configs(package, configs)
+ local configs = configs or {}
+ local cflags = package:config("cflags")
+ local cxflags = package:config("cxflags")
+ local cxxflags = package:config("cxxflags")
+ local asflags = package:config("asflags")
+ if package:plat() == "windows" then
+ local vs_runtime = package:config("vs_runtime")
+ if vs_runtime then
+ cxflags = (cxflags or "") .. " /" .. vs_runtime .. (package:debug() and "d" or "")
+ end
+ end
+ table.insert(configs, "--mode=" .. (package:debug() and "debug" or "release"))
+ if cflags then
+ table.insert(configs, '--cflags="' .. cflags .. '"')
+ end
+ if cxflags then
+ table.insert(configs, '--cxflags="' .. cxflags .. '"')
+ end
+ if cxxflags then
+ table.insert(configs, '--cxxflags="' .. cxxflags .. '"')
+ end
+ if asflags then
+ table.insert(configs, '--asflags="' .. asflags .. '"')
+ end
+ return configs
+end
+
-- install package
function install(package, configs)
-- inherit builtin configs
- local argv = {"f", "-y"}
+ local argv = {"f", "-y"}
local names = {"plat", "arch", "ndk", "ndk_sdkver", "vs", "sdk", "bin", "cross", "ld", "sh", "ar", "cc", "cxx", "mm", "mxx"}
for _, name in ipairs(names) do
local value = get_config(name)
@@ -37,11 +66,17 @@ function install(package, configs)
table.insert(argv, "--" .. name .. "=" .. tostring(value))
end
end
- table.insert(argv, "--mode=" .. (package:debug() and "debug" or "release"))
- -- inherit require and option configs
- for name, value in pairs(table.join(package:configs() or {}, configs or {})) do
- table.insert(argv, "--" .. name .. "=" .. tostring(value))
+ -- pass configurations
+ for name, value in pairs(_get_configs(package, configs)) do
+ value = tostring(value):trim()
+ if type(name) == "number" then
+ if value ~= "" then
+ table.insert(argv, value)
+ end
+ else
+ table.insert(argv, "--" .. name .. "=" .. value)
+ end
end
if option.get("verbose") then
table.insert(argv, "-v")
diff --git a/xmake/repository/packages/c/cmake/xmake.lua b/xmake/repository/packages/c/cmake/xmake.lua
index e0994cf52..fd1b22be2 100644
--- a/xmake/repository/packages/c/cmake/xmake.lua
+++ b/xmake/repository/packages/c/cmake/xmake.lua
@@ -6,16 +6,28 @@ package("cmake")
if is_host("macosx") then
add_urls("https://cmake.org/files/v3.11/cmake-3.11.4-Darwin-x86_64.tar.gz")
+ add_urls("https://github.com/Kitware/CMake/releases/download/v3.11.4/cmake-3.11.4-Darwin-x86_64.tar.gz")
+ add_urls("https://gitlab.com/xmake-mirror/cmake-releases/raw/master/cmake-3.11.4-Darwin-x86_64.tar.gz")
+ add_urls("https://dev.tencent.com/u/waruqi/p/cmake-releases/git/raw/master/cmake-3.11.4-Darwin-x86_64.tar.gz")
add_versions("3.11.4", "2b5eb705f036b1906a5e0bce996e9cd56d43d73bdee8318ece3e5ce31657b812")
elseif is_host("linux") and is_arch("x86_64") then
add_urls("https://cmake.org/files/v3.11/cmake-3.11.4-Linux-x86_64.tar.gz")
+ add_urls("https://github.com/Kitware/CMake/releases/download/v3.11.4/cmake-3.11.4-Linux-x86_64.tar.gz")
+ add_urls("https://gitlab.com/xmake-mirror/cmake-releases/raw/master/cmake-3.11.4-Linux-x86_64.tar.gz")
+ add_urls("https://dev.tencent.com/u/waruqi/p/cmake-releases/git/raw/master/cmake-3.11.4-Linux-x86_64.tar.gz")
add_versions("3.11.4", "6dab016a6b82082b8bcd0f4d1e53418d6372015dd983d29367b9153f1a376435")
elseif is_host("windows") then
if os.arch() == "x64" then
add_urls("https://cmake.org/files/v3.11/cmake-3.11.4-win64-x64.zip", {excludes = "*/doc/*"})
+ add_urls("https://github.com/Kitware/CMake/releases/download/v3.11.4/cmake-3.11.4-win64-x64.zip", {excludes = "*/doc/*"})
+ add_urls("https://gitlab.com/xmake-mirror/cmake-releases/raw/master/cmake-3.11.4-win64-x64.zip", {excludes = "*/doc/*"})
+ add_urls("https://dev.tencent.com/u/waruqi/p/cmake-releases/git/raw/master/cmake-3.11.4-win64-x64.zip", {excludes = "*/doc/*"})
add_versions("3.11.4", "d3102abd0ded446c898252b58857871ee170312d8e7fd5cbff01fbcb1068a6e5")
else
add_urls("https://cmake.org/files/v3.11/cmake-3.11.4-win32-x86.zip", {excludes = "*/doc/*"})
+ add_urls("https://github.com/Kitware/CMake/releases/download/v3.11.4/cmake-3.11.4-win32-x86.zip", {excludes = "*/doc/*"})
+ add_urls("https://gitlab.com/xmake-mirror/cmake-releases/raw/master/cmake-3.11.4-win32-x86.zip", {excludes = "*/doc/*"})
+ add_urls("https://dev.tencent.com/u/waruqi/p/cmake-releases/git/raw/master/cmake-3.11.4-win32-x86.zip", {excludes = "*/doc/*"})
add_versions("3.11.4", "b068001ff879f86e704977c50a8c5917e4b4406c66242366dba2674abe316579")
end
end
diff --git a/xmake/repository/packages/g/git/xmake.lua b/xmake/repository/packages/g/git/xmake.lua
index 74f000b65..f14d0c71b 100644
--- a/xmake/repository/packages/g/git/xmake.lua
+++ b/xmake/repository/packages/g/git/xmake.lua
@@ -27,6 +27,7 @@ package("git")
end
on_load("windows", function (package)
+ package:addenv("PATH", path.join("share", "MinGit", "mingw32", "bin"))
package:addenv("PATH", path.join("share", "MinGit", "cmd"))
end)