summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-01-11 23:13:39 +0800
committerGitHub <[email protected]>2024-01-11 23:13:39 +0800
commit2d32603c5ed7811599517d10d47a73d192ecc4a2 (patch)
treed7c8f611b77f2940135050d7058944af41d4b311
parentcaa2858df5409ec288006c81bd2fb981b236bbe1 (diff)
parent7cfdda07ab460cac40ef42f74fe4430f34b559be (diff)
Merge pull request #4600 from xmake-io/system
improve system::find_package
-rw-r--r--xmake/core/package/package.lua9
-rw-r--r--xmake/modules/package/manager/system/find_package.lua219
2 files changed, 41 insertions, 187 deletions
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 8704b3df1..4190c43c1 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -1760,8 +1760,13 @@ function _instance:find_package(name, opt)
buildhash = self:buildhash(), -- for xmake package or 3rd package manager, e.g. go:: ..
cachekey = opt.cachekey or "fetch_package_system",
external = opt.external,
- includes = opt.includes, -- system/find_package need it
- system = system})
+ system = system,
+ -- the following options is only for system::find_package
+ sourcekind = opt.sourcekind,
+ package = self,
+ funcs = opt.funcs,
+ snippets = opt.snippets,
+ includes = opt.includes})
end
-- fetch the local package info
diff --git a/xmake/modules/package/manager/system/find_package.lua b/xmake/modules/package/manager/system/find_package.lua
index 55cf839c0..862862d5a 100644
--- a/xmake/modules/package/manager/system/find_package.lua
+++ b/xmake/modules/package/manager/system/find_package.lua
@@ -19,207 +19,56 @@
--
-- imports
-import("lib.detect.find_file")
-import("lib.detect.find_path")
-import("lib.detect.find_library")
-import("lib.detect.pkgconfig")
-import("detect.sdks.find_xcode")
-import("core.project.config")
+import("core.language.language")
+import("lib.detect.check_cxsnippets")
--- find package
-function _find_package(name, links, linkdirs, includedirs, opt)
-
- -- find library
- local result = nil
- for _, link in ipairs(links) do
- local libinfo = find_library(link, linkdirs, {plat = opt.plat})
- 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
-
- -- find includes
- if opt.includes then
- for _, include in ipairs(opt.includes) do
- local includedir = find_path(include, includedirs)
- if includedir then
- result = result or {}
- result.includedirs = table.join(result.includedirs or {}, includedir)
- end
- end
- for _, include in ipairs({name .. "/" .. name .. ".h", name .. ".h"}) do
- local includedir = find_path(include, includedirs)
- if includedir then
- result = result or {}
- result.includedirs = table.join(result.includedirs or {}, includedir)
- break
- end
- end
- elseif result and result.links and opt.includedirs then
- result.includedirs = opt.includedirs
- end
- return result
-end
-
--- find package from the environment variables
--- @see https://github.com/xmake-io/xmake/issues/1776
---
-function _find_package_from_envs(name, links, opt)
-
- -- add default search includedirs on pc host
- local includedirs = table.wrap(opt.includedirs)
- if #includedirs == 0 then
- if opt.plat == "windows" then
- table.insert(includedirs, "$(env INCLUDE)")
- else
- table.insert(includedirs, "$(env CPATH)")
- table.insert(includedirs, "$(env C_INCLUDE_PATH)")
- table.insert(includedirs, "$(env CPLUS_INCLUDE_PATH)")
- end
- end
-
- -- add default search linkdirs on pc host
- local linkdirs = table.wrap(opt.linkdirs)
- if #linkdirs == 0 then
- if opt.plat == "windows" then
- table.insert(linkdirs, "$(env LIB)")
- else
- table.insert(linkdirs, "$(env LIBRARY_PATH)")
- end
- end
- return _find_package(name, links, linkdirs, includedirs, opt)
-end
-
--- find package from the unix-like system directories
-function _find_package_from_unixdirs(name, links, opt)
-
- -- add default search includedirs on pc host
- local includedirs = table.wrap(opt.includedirs)
- if #includedirs == 0 then
- if opt.plat == "linux" or opt.plat == "macosx" then
- table.insert(includedirs, "/usr/local/include")
- table.insert(includedirs, "/usr/include")
- table.insert(includedirs, "/opt/local/include")
- table.insert(includedirs, "/opt/include")
- end
- end
-
- -- add default search linkdirs on pc host
- local linkdirs = table.wrap(opt.linkdirs)
- if #linkdirs == 0 then
- if opt.plat == "linux" or opt.plat == "macosx" then
- table.insert(linkdirs, "/usr/local/lib")
- table.insert(linkdirs, "/usr/lib")
- table.insert(linkdirs, "/opt/local/lib")
- table.insert(linkdirs, "/opt/lib")
- if opt.plat == "linux" and opt.arch == "x86_64" then
- table.insert(linkdirs, "/usr/local/lib/x86_64-linux-gnu")
- table.insert(linkdirs, "/usr/lib/x86_64-linux-gnu")
- table.insert(linkdirs, "/usr/lib64")
- table.insert(linkdirs, "/opt/lib64")
+-- get package items
+function _get_package_items()
+ local items = {}
+ for _, apiname in ipairs(table.join(language.apis().values, language.apis().paths)) do
+ if apiname:startswith("target.") then
+ local valuename = apiname:split('.add_', {plain = true})[2]
+ if valuename then
+ table.insert(items, valuename)
end
end
end
- return _find_package(name, links, linkdirs, includedirs, opt)
+ return items
end
--- find package from the xcode directories
-function _find_package_from_xcodedirs(name, links, opt)
-
- -- find xcode first
- local xcode = find_xcode(config.get("xcode"), {plat = opt.plat, arch = opt.arch})
- if not xcode then
- return
- end
-
- -- get sdk root directory
- local platname = nil
- if opt.plat == "macosx" then
- platname = "MacOSX"
- elseif opt.plat == "iphoneos" then
- platname = (opt.arch == "i386" or opt.arch == "x86_64") and "iPhoneSimulator" or "iPhoneOS"
- elseif opt.plat == "watchos" then
- platname = opt.arch == "i386" and "WatchSimulator" or "WatchOS"
- end
- local sdk_rootdir = format("%s/Contents/Developer/Platforms/%s.platform/Developer/SDKs/%s%s.sdk", xcode.sdkdir, platname, platname, xcode.sdkver)
-
- -- init include and link directories
- local linkdirs = {path.join(sdk_rootdir, "usr", "lib")}
- local includedirs = {path.join(sdk_rootdir, "usr", "include")}
-
- -- find library
- local result = nil
- for _, link in ipairs(links) do
- if find_file("lib" .. link .. ".tbd", linkdirs) then
- result = result or {}
- result.links = table.join(result.links or {}, link)
- end
- end
- if result then
- -- we don't need to add linkdirs again if we are building target on the current platform (with -isysroot)
- if config.plat() ~= opt.plat or config.arch() ~= opt.arch then
- result.linkdirs = linkdirs
- result.includedirs = includedirs
- end
- end
- return result
-end
-
--- find package from the system directories
+-- find package from system and compiler
+-- @see https://github.com/xmake-io/xmake/issues/4596
--
-- @param name the package name
--- @param opt the options, e.g. {verbose = true, version = "1.12.x")
+-- @param opt the options, e.g. {verbose = true, package = <package instance>, includes = "", sourcekind = "[cc|cxx|mm|mxx]",
+-- funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"},
+-- configs = {defines = "", links = "", cflags = ""}}
--
function main(name, opt)
-
- -- init options
opt = opt or {}
+ local configs = opt.configs or {}
- -- attempt to get links from pkg-config
- local pkginfo = nil
- local version = nil
- local links = table.wrap(opt.links)
- if #links == 0 then
- pkginfo = pkgconfig.libinfo(name)
- if pkginfo then
- links = table.wrap(pkginfo.links)
- version = pkginfo.version
- end
+ local items = _get_package_items()
+ local snippet_configs = {}
+ for _, name in ipairs(items) do
+ snippet_configs[name] = configs[name]
end
+ snippet_configs.links = snippet_configs.links or name
- -- uses name as links directly e.g. libname.a
- if #links == 0 then
- links = table.wrap(name)
- end
+ local snippet_opt = {
+ verbose = opt.verbose,
+ target = opt.package,
+ funcs = opt.funcs,
+ sourcekind = opt.sourcekind,
+ includes = opt.includes,
+ configs = snippet_configs}
- -- init finders
- local finders = {}
- if opt.plat == os.host() and opt.arch == os.arch() then
- if opt.plat ~= "windows" then
- table.insert(finders, _find_package_from_unixdirs)
- end
- table.insert(finders, _find_package_from_envs)
- end
- if opt.plat == "macosx" or opt.plat == "iphoneos" or opt.plat == "watchos" then
- table.insert(finders, _find_package_from_xcodedirs)
- end
-
- -- find package
- for _, finder in ipairs(finders) do
- local result = finder(name, links, opt)
- if result ~= nil then
- -- save version
- if version then
- result.version = version
- end
+ local snippetname = "find_package/" .. name
+ local snippets = opt.snippets or {[snippetname] = ""}
+ if check_cxsnippets(snippets, snippet_opt) then
+ local result = snippet_configs
+ if not table.empty(result) then
return result
end
end
-
- -- not found? only add links
- if not result and pkginfo and pkginfo.links then
- return {links = pkginfo.links}
- end
end