diff options
| author | ruki <[email protected]> | 2019-01-24 00:48:14 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-01-23 22:49:27 +0800 |
| commit | dae284b933cea7f3717a5a0dee3f18304b3fb1e0 (patch) | |
| tree | 4c8e23bb698b570ff5d150f9004106384ff1c359 /xmake/modules | |
| parent | 7d9fe778c235da802039bf46c62cd4142f4719e4 (diff) | |
improve lib.detect.find_package
Diffstat (limited to 'xmake/modules')
| -rw-r--r-- | xmake/modules/detect/packages/find_libxml2.lua | 27 | ||||
| -rw-r--r-- | xmake/modules/detect/packages/find_mysql.lua | 13 | ||||
| -rw-r--r-- | xmake/modules/detect/packages/find_pcre.lua | 28 | ||||
| -rw-r--r-- | xmake/modules/detect/packages/find_pcre2.lua | 36 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/conan.lua | 151 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/find_package.lua | 96 | ||||
| -rw-r--r-- | xmake/modules/package/manager/find_package.lua | 129 | ||||
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/find_package.lua (renamed from xmake/modules/lib/detect/vcpkg.lua) | 31 |
8 files changed, 246 insertions, 265 deletions
diff --git a/xmake/modules/detect/packages/find_libxml2.lua b/xmake/modules/detect/packages/find_libxml2.lua index 307ac0899..2a71e3b99 100644 --- a/xmake/modules/detect/packages/find_libxml2.lua +++ b/xmake/modules/detect/packages/find_libxml2.lua @@ -23,7 +23,7 @@ -- -- imports -import("lib.detect.pkg_config") +import("package.manager.find_package") -- find libxml2 -- @@ -33,16 +33,25 @@ import("lib.detect.pkg_config") -- function main(opt) - -- find package from the current host platform - if opt.plat == os.host() and opt.arch == os.arch() then - local result = pkg_config.find("libxml2") - if result then - local includedirs = {} - for _, includedir in ipairs(result.includedirs) do + -- find package by the builtin script + local result = opt.find_package("libxml2", opt) + + -- find package from the homebrew package manager + if not result and opt.plat == os.host() and opt.arch == os.arch() then + result = find_package("brew::libxml2/libxml-2.0", opt) + end + + -- patch "include/libxml2" + if result then + local includedirs = {} + for _, includedir in ipairs(result.includedirs) do + if includedir:endswith("include") then table.insert(includedirs, path.join(includedir, "libxml2")) + else + table.insert(includedirs, includedir) end - result.includedirs = includedirs - return result end + result.includedirs = includedirs end + return result end diff --git a/xmake/modules/detect/packages/find_mysql.lua b/xmake/modules/detect/packages/find_mysql.lua index 430bf5149..eedd2fad4 100644 --- a/xmake/modules/detect/packages/find_mysql.lua +++ b/xmake/modules/detect/packages/find_mysql.lua @@ -23,7 +23,7 @@ -- -- imports -import("lib.detect.pkg_config") +import("package.manager.find_package") -- find mysql -- @@ -33,8 +33,13 @@ import("lib.detect.pkg_config") -- function main(opt) - -- find package from the current host platform - if opt.plat == os.host() and opt.arch == os.arch() then - return pkg_config.find("mysqlclient") + -- find package by the builtin script + local result = opt.find_package("mysql", opt) + + -- find package from the homebrew package manager + if not result and opt.plat == os.host() and opt.arch == os.arch() then + result = find_package("brew::mysqlclient", opt) end + return result end + diff --git a/xmake/modules/detect/packages/find_pcre.lua b/xmake/modules/detect/packages/find_pcre.lua index 149f29c90..f109673f4 100644 --- a/xmake/modules/detect/packages/find_pcre.lua +++ b/xmake/modules/detect/packages/find_pcre.lua @@ -23,8 +23,7 @@ -- -- imports -import("lib.detect.vcpkg") -import("lib.detect.pkg_config") +import("package.manager.find_package") -- find pcre -- @@ -34,28 +33,17 @@ import("lib.detect.pkg_config") -- function main(opt) - -- find package from vcpkg first - local result = vcpkg.find("pcre", opt) - if result then - local links = {} - for _, link in ipairs(result.links) do - links[link] = true - end - for _, width in ipairs({"", "16", "32"}) do - if links["pcre" .. width] then - result.links = {"pcre" .. width} - return result - end - end - end + -- find package by the builtin script + local result = opt.find_package("pcre", opt) - -- find package from the current host platform - if opt.plat == os.host() and opt.arch == os.arch() then + -- find package from the homebrew package manager + if not result and opt.plat == os.host() and opt.arch == os.arch() then for _, width in ipairs({"", "16", "32"}) do - local result = pkg_config.find("libpcre" .. width, {brewhint = "pcre"}) + result = find_package("brew::pcre/libpcre" .. width, opt) if result then - return result + break end end end + return result end diff --git a/xmake/modules/detect/packages/find_pcre2.lua b/xmake/modules/detect/packages/find_pcre2.lua index 8754382f3..c65022c9c 100644 --- a/xmake/modules/detect/packages/find_pcre2.lua +++ b/xmake/modules/detect/packages/find_pcre2.lua @@ -23,8 +23,7 @@ -- -- imports -import("lib.detect.vcpkg") -import("lib.detect.pkg_config") +import("package.manager.find_package") -- find pcre2 -- @@ -34,30 +33,31 @@ import("lib.detect.pkg_config") -- function main(opt) - -- find package from vcpkg first - local result = vcpkg.find("pcre2", opt) - if result then - local links = {} - for _, link in ipairs(result.links) do - links[link] = true - end + -- find package by the builtin script + local result = opt.find_package("pcre2", opt) + + -- find package from the homebrew package manager + if not result and opt.plat == os.host() and opt.arch == os.arch() then for _, width in ipairs({"8", "16", "32"}) do - if links["pcre2-" .. width] then - result.links = {"pcre2-" .. width} - result.defines = {"PCRE2_CODE_UNIT_WIDTH=" .. width} - return result + result = find_package("brew::pcre2/libpcre2-" .. width, opt) + if result then + break end end end - -- find package from the current host platform - if opt.plat == os.host() and opt.arch == os.arch() then + -- patch PCRE2_CODE_UNIT_WIDTH + if result and not result.defines then + local links = {} + for _, link in ipairs(result.links) do + links[link] = true + end for _, width in ipairs({"8", "16", "32"}) do - local result = pkg_config.find("libpcre2-" .. width, {brewhint = "pcre2"}) - if result then + if links["pcre2-" .. width] then result.defines = {"PCRE2_CODE_UNIT_WIDTH=" .. width} - return result + break end end end + return result end diff --git a/xmake/modules/lib/detect/conan.lua b/xmake/modules/lib/detect/conan.lua deleted file mode 100644 index 4660e0670..000000000 --- a/xmake/modules/lib/detect/conan.lua +++ /dev/null @@ -1,151 +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 conan.lua --- - --- imports -import("lib.detect.find_file") -import("lib.detect.find_library") -import("detect.sdks.find_conandir") -import("core.project.config") -import("core.project.target") - --- get package info --- --- @param name the package name --- @param opt the argument options, {version = true, arch = "", plat = "", mode = "", conandir = ""} --- --- @return {links = {"ssl", "crypto", "z"}, linkdirs = {""}, includedirs = {""}, version = ""} --- --- @code --- --- local pkginfo = conan.info("openssl") --- --- @endcode --- -function info(name, opt) - - -- init options - opt = opt or {} - - -- attempt to find the conan root directory - local conandir = find_conandir(opt.conandir) - if not conandir then - return - end - - -- init cache - _g._INFO = _g._INFO or {} - - -- get it from cache first - local key = name - local result = _g._INFO[key] - if result ~= nil then - return result and result or nil - end - - -- find the package conanmanifest file, .e.g ~/.conan/data/pcre2/10.31/bincrafters/stable/package/519f362e9832d00859a5da6d5f76da34ecf8e237/conanmanifest.txt - local manifestfile = find_file("conanmanifest.txt", path.join(conandir, "data", name, "*", "*", "*", "package", "*")) - - -- save includedirs, linkdirs and links - local info = manifestfile and io.readfile(manifestfile) or nil - if info then - local installdir = path.directory(manifestfile) - result = {includedirs = path.join(installdir, "include"), linkdirs = path.join(installdir, "lib")} - for _, line in ipairs(info:split('\n')) do - line = line:split(':')[1]:trim() - if line:startswith("lib") and (line:endswith(".lib") or line:endswith(".a")) then - result.links = result.links or {} - table.insert(result.links, target.linkname(path.filename(line))) - end - end - end - - -- save version - if result and manifestfile then - result.version = manifestfile:match(path.join(name, "(%d+%.?%d*%.?%d*.-)")) - if not result.version then - result.version = manifestfile:match(path.join(name, "(%d+%.?%d*%.-)")) - end - end - - -- save result to cache - _g._INFO[key] = result and result or false - - -- ok? - return result -end - --- find package --- --- @param name the package name --- @param opt the argument options, {version = "1.0.1", links = {...}, conandir = ""} --- --- @return {links = {"ssl", "crypto", "z"}, linkdirs = {""}, includedirs = {""}} --- --- @code --- --- local pkginfo = conan.find("openssl") --- --- @endcode --- -function find(name, opt) - - -- get package info - local pkginfo = info(name, opt) - if not pkginfo then - return - end - - -- match version? - opt = opt or {} - if opt.version and pkginfo.version ~= opt.version then - return - end - - -- get links - local links = pkginfo.links - if not links or #links == 0 then - links = opt.links - end - - -- find library - local result = nil - for _, link in ipairs(table.wrap(links)) do - local libinfo = find_library(link, pkginfo.linkdirs) - if libinfo then - result = result or {} - result.links = table.join(result.links or {}, libinfo.link) - result.linkdirs = table.join(result.linkdirs or {}, libinfo.linkdir) - end - end - - -- found? - if result and result.links then - result.linkdirs = table.unique(result.linkdirs) - result.includedirs = table.join(result.includedirs or {}, pkginfo.includedirs) - end - - -- ok? - return result -end - diff --git a/xmake/modules/lib/detect/find_package.lua b/xmake/modules/lib/detect/find_package.lua new file mode 100644 index 000000000..6c069dd67 --- /dev/null +++ b/xmake/modules/lib/detect/find_package.lua @@ -0,0 +1,96 @@ +--!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 find_package.lua +-- + +-- imports +import("core.base.option") +import("core.project.config") +import("lib.detect.cache") +import("package.manager.find_package") + +-- find package using the package manager +-- +-- @param name the package name +-- e.g. zlib 1.12.x (try all), xmake::zlib 1.12.x, brew::zlib, brew::pcre/libpcre16, vcpkg::zlib, conan::OpenSSL/1.0.2n@conan/stable +-- @param opt the options +-- e.g. { verbose = false, force = false, plat = "iphoneos", arch = "arm64", mode = "debug", version = "1.0.x", +-- linkdirs = {"/usr/lib"}, includedirs = "/usr/include", links = {"ssl"}, includes = {"ssl.h"} +-- packagedirs = {"/tmp/packages"}, system = true, cachekey = "xxxx"} +-- +-- @return {links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}} +-- +-- @code +-- +-- local package = find_package("openssl") +-- local package = find_package("openssl", {version = "1.0.*"}) +-- local package = find_package("openssl", {plat = "iphoneos"}) +-- local package = find_package("openssl", {linkdirs = {"/usr/lib", "/usr/local/lib"}, includedirs = "/usr/local/include", version = "1.0.1"}) +-- local package = find_package("openssl", {linkdirs = {"/usr/lib", "/usr/local/lib", links = {"ssl", "crypto"}, includes = {"ssl.h"}}) +-- +-- @endcode +-- +function main(name, opt) + + -- get the copied options + opt = table.copy(opt) + opt.plat = opt.plat or config.get("plat") or os.host() + opt.arch = opt.arch or config.get("arch") or os.arch() + + -- init cache key + local key = "find_package_" .. opt.plat .. "_" .. opt.arch + if opt.version then + key = key .. "_" .. opt.version + end + if opt.cachekey then + key = key .. "_" .. opt.cachekey + end + if opt.mode then + key = key .. "_" .. opt.mode + end + + -- attempt to get result from cache first + local cacheinfo = cache.load(key) + local result = cacheinfo[name] + if result ~= nil and not opt.force then + return result and result or nil + end + + -- find package + result = find_package(name, opt) + + -- cache result + cacheinfo[name] = result and result or false + cache.save(key, cacheinfo) + + -- trace + 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}") + else + cprint("checking for the %s ... ${color.nothing}${text.nothing}", name) + end + end + + -- ok? + return result +end diff --git a/xmake/modules/package/manager/find_package.lua b/xmake/modules/package/manager/find_package.lua index 41c342095..0cd2463b8 100644 --- a/xmake/modules/package/manager/find_package.lua +++ b/xmake/modules/package/manager/find_package.lua @@ -26,51 +26,44 @@ import("core.base.semver") import("core.base.option") import("core.project.config") -import("lib.detect.cache") --- find package +-- find package with the builtin rule -- -- opt.system: -- nil: find local or system packages -- true: only find system package -- false: only find local packages -- -function _find_package(manager_name, package_name, opt) +function _find_package_with_builtin_rule(package_name, opt) - -- get managers + -- we cannot find it from xmake repo and package directories if only find system packages local managers = {} - if manager_name then - table.insert(managers, manager_name) - else + if opt.system ~= true then + table.insert(managers, "xmake") + end - -- we cannot find it from xmake repo and package directories if only find system packages - if opt.system ~= true then - table.insert(managers, "xmake") - end + -- find system package if be not disabled + if opt.system ~= false then - -- find system package if be not disabled - if opt.system ~= false then + -- find it from homebrew + if not is_host("windows") and (opt.mode == nil or opt.mode == "release") then + table.insert(managers, "brew") + end - -- find it from homebrew - if not is_host("windows") and (opt.mode == nil or opt.mode == "release") then - table.insert(managers, "brew") - end + -- find it from vcpkg (support multi-platforms/architectures) +-- table.insert(managers, "vcpkg") - -- find it from vcpkg - table.insert(managers, "vcpkg") + -- find it from conan (support multi-platforms/architectures) +-- table.insert(managers, "conan") - -- find it from conan - table.insert(managers, "conan") - - -- only support the current host platform and architecture - if opt.plat == os.host() and opt.arch == os.arch() and (opt.mode == nil or opt.mode == "release") then + -- only support the current host platform and architecture + if opt.plat == os.host() and opt.arch == os.arch() and (opt.mode == nil or opt.mode == "release") then - -- find it from pkg-config - table.insert(managers, "pkg_config") + -- find it from pkg-config + table.insert(managers, "pkg_config") - -- find it from system - table.insert(managers, "system") - end + -- find it from system + table.insert(managers, "system") end end @@ -84,6 +77,50 @@ function _find_package(manager_name, package_name, opt) end end + -- check result? + if result and not result.includedirs then + result = nil + end + + -- ok? + return result +end + +-- find package +function _find_package(manager_name, package_name, opt) + + -- find package from the given package manager + local result = nil + if manager_name then + + -- trace + dprint("finding %s from %s ..", package_name, manager_name) + + -- find it + result = import("package.manager." .. manager_name .. ".find_package", {anonymous = true})(package_name, opt) + else + + -- find package from the given custom "detect.packages.find_xxx" script + local builtin = false + local find_package = import("detect.packages.find_" .. package_name, {anonymous = true, try = true}) + if find_package then + + -- trace + dprint("finding %s from find_%s ..", package_name, package_name) + + -- find it + result = find_package(table.join(opt, { find_package = function (...) + builtin = true + return _find_package_with_builtin_rule(...) + end})) + end + + -- find package with the builtin rule + if not result and not builtin then + result = _find_package_with_builtin_rule(package_name, opt) + end + end + -- found? if result then @@ -113,7 +150,7 @@ end -- @param opt the options -- e.g. { verbose = false, force = false, plat = "iphoneos", arch = "arm64", mode = "debug", version = "1.0.x", -- linkdirs = {"/usr/lib"}, includedirs = "/usr/include", links = {"ssl"}, includes = {"ssl.h"} --- packagedirs = {"/tmp/packages"}, system = true, cachekey = "xxxx"} +-- packagedirs = {"/tmp/packages"}, system = true} -- -- @return {links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}} -- @@ -148,25 +185,6 @@ function main(name, opt) package_name, require_version = unpack(package_name:trim():split("%s+")) opt.version = require_version or opt.version - -- init cache key - local key = "find_package_" .. opt.plat .. "_" .. opt.arch - if opt.version then - key = key .. "_" .. opt.version - end - if opt.cachekey then - key = key .. "_" .. opt.cachekey - end - if opt.mode then - key = key .. "_" .. opt.mode - end - - -- attempt to get result from cache first - local cacheinfo = cache.load(key) - local result = cacheinfo[package_name] - if result ~= nil and not opt.force then - return result and result or nil - end - -- find package result = _find_package(manager_name, package_name, opt) @@ -177,19 +195,6 @@ function main(name, opt) end end - -- cache result - cacheinfo[package_name] = result and result or false - cache.save(key, cacheinfo) - - -- trace - if opt.verbose or option.get("verbose") then - if result then - cprint("checking for the %s ... ${color.success}%s", package_name, result.version and result.version or "${text.success}") - else - cprint("checking for the %s ... ${color.nothing}${text.nothing}", package_name) - end - end - -- ok? return result end diff --git a/xmake/modules/lib/detect/vcpkg.lua b/xmake/modules/package/manager/vcpkg/find_package.lua index 573830fef..9bb06d767 100644 --- a/xmake/modules/lib/detect/vcpkg.lua +++ b/xmake/modules/package/manager/vcpkg/find_package.lua @@ -19,7 +19,7 @@ -- Copyright (C) 2015 - 2019, TBOOX Open Source Group. -- -- @author ruki --- @file vcpkg.lua +-- @file find_package.lua -- -- imports @@ -173,3 +173,32 @@ function find(name, opt) return result end +-- find package from the brew package manager +-- +-- @param name the package name, e.g. zlib, pcre/libpcre16 +-- @param opt the options, .e.g {verbose = true, version = "1.12.x") +-- +function main(name, opt) + + -- find brew + local brew = find_tool("brew") + if not brew then + return + end + + -- parse name, .e.g pcre/libpcre16 + local nameinfo = name:split('/') + local pcname = nameinfo[2] or nameinfo[1] + + -- find the prefix directory of brew + local brew_pkg_root = try { function () return os.iorunv(brew.program, {"--prefix"}) end } or "/usr/local" + brew_pkg_root = path.join(brew_pkg_root:trim(), opt.plat == "macosx" and "Cellar" or "opt") + local pcfile = find_file(pcname .. ".pc", path.join(brew_pkg_root, nameinfo[1], "*/lib/pkgconfig")) + if not pcfile then + return + end + + -- do find + opt.configdirs = path.directory(pcfile) + return pkg_config.find(pcname, opt) +end |
