1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, Xmake Open Source Community.
--
-- @author ruki
-- @file find_package.lua
--
-- imports
import("core.base.option")
import("core.project.config")
import("core.cache.detectcache")
import("package.manager.find_package")
import("private.utils.package", {alias = "package_utils"})
-- 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", require_version = "1.0.x", version = true,
-- external = true, -- we use sysincludedirs instead of includedirs as results
-- linkdirs = {"/usr/lib"}, includedirs = "/usr/include", links = {"ssl"}, includes = {"ssl.h"}
-- packagedirs = {"/tmp/packages"}, system = true, cachekey = "xxxx"
-- pkgconfigs = {..}}
--
-- @return {links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}}
--
-- @code
--
-- local package = find_package("openssl")
-- local package = find_package("openssl", {require_version = "1.0.*", version = true})
-- 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
--
-- find package from system or package managers
--
-- @param name the package name
-- @param opt the options, e.g. {require_version = ">=1.0", system = true, packagedirs = {}}
-- @return the package info table {links, linkdirs, includedirs, ...}, or nil
--
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()
opt.mode = opt.mode or config.mode() or "release"
-- init cache key
local cachekey = "find_package_" .. opt.plat .. "_" .. opt.arch
if opt.cachekey then
cachekey = cachekey .. "_" .. opt.cachekey
end
-- init package key
local packagekey = name
if opt.buildhash then
packagekey = packagekey .. "_" .. opt.buildhash
end
if opt.mode then
packagekey = packagekey .. "_" .. opt.mode
end
if opt.require_version then
packagekey = packagekey .. "_" .. opt.require_version
end
if opt.external then
packagekey = packagekey .. "_external"
end
-- attempt to get result from cache first
local result = detectcache:get2(cachekey, packagekey)
if result == nil or opt.force then
-- find package
local found_manager_name, package_name
result, found_manager_name, package_name = find_package(name, opt)
-- use isystem?
if result and result.includedirs and opt.external then
result.sysincludedirs = result.includedirs
result.includedirs = nil
local components_base = result.components and result.components.__base
if components_base then
components_base.sysincludedirs = components_base.includedirs
components_base.includedirs = nil
end
end
-- cache result
detectcache:set2(cachekey, packagekey, result and result or false)
-- trace
if opt.verbose or option.get("verbose") then
if result then
-- only display manager of found package if the package we searched for
-- did not specify a package manager
local display_manager = name:find("::", 1, true) and "" or (found_manager_name or "") .. "::"
local display_name = display_manager .. package_name
cprint("checking for %s ... ${color.success}%s %s", name, display_name, result.version and result.version or "")
else
cprint("checking for %s ... ${color.nothing}${text.nothing}", name)
end
end
end
-- does not show version (default)? strip it
if not opt.version and result then
result.version = nil
end
-- register concat
if result then
package_utils.fetchinfo_set_concat(result)
end
return result and result or nil
end
|