diff options
| author | ruki <[email protected]> | 2024-01-11 23:13:39 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-01-11 23:13:39 +0800 |
| commit | 2d32603c5ed7811599517d10d47a73d192ecc4a2 (patch) | |
| tree | d7c8f611b77f2940135050d7058944af41d4b311 | |
| parent | caa2858df5409ec288006c81bd2fb981b236bbe1 (diff) | |
| parent | 7cfdda07ab460cac40ef42f74fe4430f34b559be (diff) | |
Merge pull request #4600 from xmake-io/system
improve system::find_package
| -rw-r--r-- | xmake/core/package/package.lua | 9 | ||||
| -rw-r--r-- | xmake/modules/package/manager/system/find_package.lua | 219 |
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 |
