diff options
| author | ruki <[email protected]> | 2019-01-12 22:44:41 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-01-12 22:44:41 +0800 |
| commit | 80629131183b4fe1c3587f11fa80707979b18538 (patch) | |
| tree | 2eac5e5626ad05e384070610171e6ee744b30460 | |
| parent | a1afc21b797df768331f7aff6f4b82f0f896700b (diff) | |
support conan for lib.detect.find_package
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/lib/detect/find_package.lua | 8 | ||||
| -rw-r--r-- | xmake/modules/detect/sdks/find_conandir.lua | 99 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/conan.lua | 151 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/vcpkg.lua | 5 |
5 files changed, 263 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a88db2640..61696726f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * [#301](https://github.com/tboox/xmake/issues/301): Improve precompiled header file * [#322](https://github.com/tboox/xmake/issues/322): Add `option.add_features`, `option.add_cxxsnippets` and `option.add_csnippets` * Remove some deprecated interfaces of xmake 1.x, e.g. `add_option_xxx` +* [#327](https://github.com/tboox/xmake/issues/327): Support conan package manager for `lib.detect.find_package` ### Bugs fixed @@ -558,6 +559,7 @@ * [#301](https://github.com/tboox/xmake/issues/301): 改进编译预处理头文件以及依赖头文件生成,编译速度提升30% * [#322](https://github.com/tboox/xmake/issues/322): 添加`option.add_features`, `option.add_cxxsnippets` 和 `option.add_csnippets` * 移除xmake 1.x的一些废弃接口, 例如:`add_option_xxx` +* [#327](https://github.com/tboox/xmake/issues/327): 改进`lib.detect.find_package`增加对conan包管理器的支持 ### Bugs修复 diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_package.lua b/xmake/core/sandbox/modules/import/lib/detect/find_package.lua index b6f1fa838..07660efea 100644 --- a/xmake/core/sandbox/modules/import/lib/detect/find_package.lua +++ b/xmake/core/sandbox/modules/import/lib/detect/find_package.lua @@ -277,6 +277,11 @@ function sandbox_lib_detect_find_package._find_from_vcpkg(name, opt) return import("lib.detect.vcpkg").find(name, opt) end +-- find package from conan +function sandbox_lib_detect_find_package._find_from_conan(name, opt) + return import("lib.detect.conan").find(name, opt) +end + -- find package from the system directories function sandbox_lib_detect_find_package._find_from_systemdirs(name, opt) @@ -399,6 +404,9 @@ function sandbox_lib_detect_find_package._find(name, opt) -- find package from vcpkg (support multi-platforms/architectures) table.insert(findscripts, sandbox_lib_detect_find_package._find_from_vcpkg) + -- find package from conan + table.insert(findscripts, sandbox_lib_detect_find_package._find_from_conan) + -- find package from the current host platform if opt.plat == os.host() and opt.arch == os.arch() then table.insert(findscripts, sandbox_lib_detect_find_package._find_from_pkg_config) diff --git a/xmake/modules/detect/sdks/find_conandir.lua b/xmake/modules/detect/sdks/find_conandir.lua new file mode 100644 index 000000000..7b2ec65ea --- /dev/null +++ b/xmake/modules/detect/sdks/find_conandir.lua @@ -0,0 +1,99 @@ +--!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_conandir.lua +-- + +-- imports +import("lib.detect.cache") +import("lib.detect.find_file") +import("core.base.option") +import("core.base.global") +import("core.project.config") + +-- find conan directory +function _find_conandir(sdkdir) + + -- init the search directories + local pathes = {} + if sdkdir then + table.insert(pathes, sdkdir) + end + table.insert(pathes, path.translate("~/.conan")) + + -- attempt to find conan.conf + local conan = find_file("conan.conf", pathes) + if conan then + return path.directory(conan) + end +end + +-- find conan directory +-- +-- @param sdkdir the conan directory +-- @param opt the argument options, .e.g {verbose = true, force = false} +-- +-- @return the conan directory +-- +-- @code +-- +-- local conandir = find_conandir() +-- +-- @endcode +-- +function main(sdkdir, opt) + + -- init arguments + opt = opt or {} + + -- attempt to load cache first + local key = "detect.sdks.find_conandir" .. (sdkdir or "") + local cacheinfo = cache.load(key) + if not opt.force and cacheinfo.conan ~= nil then + return cacheinfo.conan + end + + -- find conan + local conan = _find_conandir(sdkdir or config.get("conan") or global.get("conan")) + if conan then + + -- save to config + config.set("conan", conan, {force = true, readonly = true}) + + -- trace + if opt.verbose or option.get("verbose") then + cprint("checking for the conan directory ... ${color.success}%s", conan) + end + else + + -- trace + if opt.verbose or option.get("verbose") then + cprint("checking for the conan directory ... ${color.nothing}${text.nothing}") + end + end + + -- save to cache + cacheinfo.conan = conan or false + cache.save(key, cacheinfo) + + -- ok? + return conan +end diff --git a/xmake/modules/lib/detect/conan.lua b/xmake/modules/lib/detect/conan.lua new file mode 100644 index 000000000..4660e0670 --- /dev/null +++ b/xmake/modules/lib/detect/conan.lua @@ -0,0 +1,151 @@ +--!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/vcpkg.lua b/xmake/modules/lib/detect/vcpkg.lua index 56763d9c0..573830fef 100644 --- a/xmake/modules/lib/detect/vcpkg.lua +++ b/xmake/modules/lib/detect/vcpkg.lua @@ -27,6 +27,7 @@ import("lib.detect.find_file") import("lib.detect.find_library") import("detect.sdks.find_vcpkgdir") import("core.project.config") +import("core.project.target") -- get package info -- @@ -96,14 +97,14 @@ function info(name, opt) result.links = result.links or {} result.linkdirs = result.linkdirs or {} table.insert(result.linkdirs, path.join(installdir, path.directory(line))) - table.insert(result.links, path.basename(line)) + table.insert(result.links, target.linkname(path.filename(line))) end end end end -- save version - if opt.version then + if result then local infoname = path.basename(infofile) result.version = infoname:match(name .. "_(%d+%.?%d*%.?%d*.-)_" .. arch) if not result.version then |
