diff options
| author | ruki <[email protected]> | 2017-07-17 23:24:16 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-07-17 23:24:34 +0800 |
| commit | 7cac00bb9cace801c6db9758d2a01d2711738926 (patch) | |
| tree | 40831686913090534c1e2b5ddb54399aa5b6bf11 | |
| parent | 33144e73eae59ee7d934fd77673aac5a5a5cb0d1 (diff) | |
add add_moduledirs api and improve import
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | xmake/core/project/project.lua | 11 | ||||
| -rw-r--r-- | xmake/core/project/task.lua | 6 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import.lua | 375 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/sandbox/module.lua | 461 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/lib/detect/find_package.lua | 8 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/inherit.lua | 22 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/features.lua | 8 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/find_tool.lua | 12 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/find_toolname.lua | 12 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/has_flags.lua | 8 |
11 files changed, 497 insertions, 428 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 86ad4c726..9c1011af7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * Add `target.on_load` api * [#132](https://github.com/tboox/xmake/issues/132): Add `add_frameworkdirs` api * Add `lib.detect.has_xxx` and `lib.detect.find_xxx` apis. +* Add `add_moduledirs` api ### Changes @@ -323,6 +324,7 @@ * 添加`target.on_load`接口 * [#132](https://github.com/tboox/xmake/issues/132): 添加`add_frameworkdirs`接口 * 添加`lib.detect.has_xxx`和`lib.detect.find_xxx`接口 +* 添加`add_moduledirs`接口在工程中定义和加载扩展模块 ### 改进 diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua index 692d504b3..d31322345 100644 --- a/xmake/core/project/project.lua +++ b/xmake/core/project/project.lua @@ -44,6 +44,7 @@ local platform = require("platform/platform") local environment = require("platform/environment") local language = require("language/language") local sandbox_os = require("sandbox/modules/os") +local sandbox_module = require("sandbox/modules/import/core/sandbox/module") -- the current os is belong to the given os? function project._api_is_os(interp, ...) @@ -146,7 +147,12 @@ function project._api_is_option(interp, ...) end end --- load all plugins from the given directories +-- add module directories +function project._api_add_moduledirs(interp, ...) + sandbox_module.add_directories(...) +end + +-- add plugin directories load all plugins from the given directories function project._api_add_plugindirs(interp, ...) -- get all directories @@ -160,7 +166,7 @@ function project._api_add_plugindirs(interp, ...) interp:api_builtin_add_subdirs(plugindirs) end --- load all packages from the given directories +-- add package directories and load all packages from the given directories function project._api_add_packagedirs(interp, ...) -- get all directories @@ -287,6 +293,7 @@ function project._interpreter() , {"is_arch", project._api_is_arch } , {"is_option", project._api_is_option } -- add_xxx + , {"add_moduledirs", project._api_add_moduledirs } , {"add_plugindirs", project._api_add_plugindirs } , {"add_packagedirs", project._api_add_packagedirs } } diff --git a/xmake/core/project/task.lua b/xmake/core/project/task.lua index 1f7770881..b32352b7e 100644 --- a/xmake/core/project/task.lua +++ b/xmake/core/project/task.lua @@ -30,9 +30,9 @@ local os = require("base/os") local table = require("base/table") local utils = require("base/utils") local string = require("base/string") +local global = require("base/global") local interpreter = require("base/interpreter") local sandbox = require("sandbox/sandbox") -local global = require("base/global") local config = require("project/config") local project = require("project/project") local package = require("project/package") @@ -42,8 +42,8 @@ local sandbox_os = require("sandbox/modules/os") function task._directories() return { path.join(global.directory(), "plugins") - , path.join(xmake._PROGRAM_DIR, "plugins") - , path.join(xmake._PROGRAM_DIR, "actions") + , path.join(os.programdir(), "plugins") + , path.join(os.programdir(), "actions") } end diff --git a/xmake/core/sandbox/modules/import.lua b/xmake/core/sandbox/modules/import.lua index 7f19159df..9cb99dbcd 100644 --- a/xmake/core/sandbox/modules/import.lua +++ b/xmake/core/sandbox/modules/import.lua @@ -22,379 +22,6 @@ -- @file import.lua -- --- define module -local sandbox_import = sandbox_import or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local global = require("base/global") -local sandbox = require("sandbox/sandbox") -local raise = require("sandbox/modules/raise") - --- get module name -function sandbox_import._modulename(name) - - -- check - assert(name) - - -- find modulename - local i = name:find_last(".", true) - if i then - name = name:sub(i + 1) - end - - -- get it - return name -end - --- get module path from name -function sandbox_import._modulepath(name) - - -- translate module path - -- - -- "package.module" => "package/module" - -- "..package.module" => "../../package/module" - -- - local startdots = true - local modulepath = name:gsub(".", function(c) - if c == '.' then - if startdots then - return ".." .. path.seperator() - else - return path.seperator() - end - else - startdots = false - return c - end - end) - - -- return module path - return modulepath -end - --- load module from file -function sandbox_import._loadfile(filepath, instance) - - -- check - assert(filepath) - - -- load module script - local script, errors = loadfile(filepath) - if not script then - return nil, errors - end - - -- with sandbox? - if instance then - - -- fork a new sandbox for this script - instance, errors = instance:fork(script, path.directory(filepath)) - if not instance then - return nil, errors - end - - -- import module - local result, errors = instance:import() - if not result then - return nil, errors - end - - -- ok - return result, instance:script() - end - - -- load module without sandbox - local ok, result = xpcall(script, debug.traceback) - if not ok then - return nil, result - end - - -- ok? - return result, script -end - --- find module -function sandbox_import._find(dir, name) - - -- check - assert(dir and name) - - -- get module path - name = sandbox_import._modulepath(name) - assert(name) - - -- get module key - local key = path.join(dir, name) - - -- the single module? - if os.isfile(key .. ".lua") then - return path.absolute(key) - -- modules? - elseif os.isdir(key) then - return path.absolute(key) - end -end - --- load module -function sandbox_import._load(dir, name, instance) - - -- check - assert(dir and name) - - -- get module path - name = sandbox_import._modulepath(name) - assert(name) - - -- load the single module? - local module = nil - local script = nil - if os.isfile(path.join(dir, name .. ".lua")) then - - -- load module - local result, errors = sandbox_import._loadfile(path.join(dir, name .. ".lua"), instance) - if not result then - return nil, errors - end - - -- save module - module = result - - -- save script - script = errors - - -- load modules - elseif os.isdir(path.join(dir, name)) then - - -- get modulefiles - local moduleroot = path.join(path.join(dir, name)) - local modulefiles = os.match(path.join(moduleroot, "**.lua")) - if modulefiles then - for _, modulefile in ipairs(modulefiles) do - - -- load module - local result, errors = sandbox_import._loadfile(modulefile, instance) - if not result then - return nil, errors - end - - -- bind main entry - if result.main then - setmetatable(result, { __call = function (_, ...) return result.main(...) end}) - end - - -- get the module path - local modulepath = path.relative(modulefile, moduleroot) - if not modulepath then - return nil, string.format("cannot get the path for module: %s", name) - end - - -- init the root module - module = module or {} - - -- save script - script = errors - - -- save module - local scope = module - for _, modulename in ipairs(path.split(modulepath)) do - - -- is end? - local pos = modulename:find(".lua", 1, true) - if pos then - - -- get the module name - modulename = modulename:sub(1, pos - 1) - assert(modulename) - - -- save module - scope[modulename] = result - - -- is scope? - else - - -- enter submodule - scope[modulename] = scope[modulename] or {} - scope = scope[modulename] - end - end - end - end - end - - -- this module not found? - if not module then - return nil, string.format("module: %s not found!", name) - end - - -- return it - return module, script -end - --- import module --- --- @param name the module name, .e.g core.platform --- @param args the arguments, .e.g {alias = "", rootdir = "", inherit = false, anonymous = false, nocache = false} --- --- @return the module instance --- --- .e.g --- --- import("core.platform") --- => platform --- --- import("core.platform", {alias = "p"}) --- => p --- --- import("core") --- => core --- => core.platform ---- --- import("core", {rootdir = "/scripts"}) --- => core --- => core.platform --- --- import("core.platform", {inherit = true}) --- => inherit the all interfaces of core.platform to the current scope --- --- local test = import("test", {rootdir = "/tmp/xxx", anonymous = true}) --- => only return imported module --- --- @note the polymiorphism is not supported for import.inherit mode now. --- -function sandbox_import.import(name, args) - - -- check - assert(name) - - -- the arguments - args = args or {} - - -- init module cache - sandbox_import._MODULES = sandbox_import._MODULES or {} - local modules = sandbox_import._MODULES - - -- get the parent scope - local scope_parent = getfenv(2) - assert(scope_parent) - - -- get module name - local modulename = sandbox_import._modulename(name) - if not modulename then - raise("cannot get module name for %s", name) - end - - -- the imported name - local imported_name = args.alias or modulename - - -- get the current sandbox instance - local instance = sandbox.instance() - assert(instance) - - -- the root directory for this sandbox script - local rootdir = args.rootdir or instance:rootdir() - assert(rootdir) - - -- the global modules directory of users - local modules_global_dir = path.join(global.directory(), "modules") - - -- the program modules directory - local modules_program_dir = path.join(os.programdir(), "modules") - - -- the sandbox modules directory - local modules_sandbox_dir = path.join(os.programdir(), "core/sandbox/modules/import") - - -- init module directories - local modules_directories = table.join(rootdir, modules_global_dir, modules_program_dir, modules_sandbox_dir) - - -- load module - local errors = nil - local module = nil - local modulekey = nil - for idx, moduledir in ipairs(modules_directories) do - - -- find module and key - modulekey = sandbox_import._find(moduledir, name) - if modulekey then - - -- load it from cache first - local moduleinfo = modules[modulekey] - if moduleinfo and not args.nocache and not args.inherit then - module = moduleinfo[1] - errors = moduleinfo[2] - else - -- load it from the script file - module, errors = sandbox_import._load(moduledir, name, utils.ifelse(idx < #modules_directories, instance, nil)) -- last modules need not fork sandbox - - -- cache this module - if not args.nocache then - modules[modulekey] = {module, errors} - end - end - - -- end - break - end - end - - -- check - if not module then - raise("cannot import module: %s, %s", name, errors) - end - - -- get module script - local script = errors - - -- inherit? - if args.inherit then - - -- inherit this module into the parent scope - table.inherit2(scope_parent, module) - - -- import as super module - imported_name = "_super" - - -- public the script scope for the super module - -- - -- we can access the all scope members of _super in the child module - -- - -- .e.g - -- - -- import("core.platform.xxx", {inherit = true}) - -- - -- print(_super._g) - -- - if script ~= nil then - setmetatable(module, { __index = function (tbl, key) - local val = rawget(tbl, key) - if val == nil then - val = rawget(getfenv(script), key) - end - return val - end}) - - end - - end - - -- bind main entry - if module.main then - setmetatable(module, { __call = function (_, ...) return module.main(...) end}) - end - - -- import this module into the parent scope - if not args.anonymous then - scope_parent[imported_name] = module - end - - -- return it - return module -end - -- load module -return sandbox_import.import +return require("sandbox/modules/import/core/sandbox/module").import diff --git a/xmake/core/sandbox/modules/import/core/sandbox/module.lua b/xmake/core/sandbox/modules/import/core/sandbox/module.lua new file mode 100644 index 000000000..53b814218 --- /dev/null +++ b/xmake/core/sandbox/modules/import/core/sandbox/module.lua @@ -0,0 +1,461 @@ +--!The Make-like 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 - 2017, TBOOX Open Source Group. +-- +-- @author ruki +-- @file module.lua +-- + +-- define module +local core_sandbox_module = core_sandbox_module or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local global = require("base/global") +local sandbox = require("sandbox/sandbox") +local raise = require("sandbox/modules/raise") + +-- get module name +function core_sandbox_module._modulename(name) + + -- check + assert(name) + + -- find modulename + local i = name:find_last(".", true) + if i then + name = name:sub(i + 1) + end + + -- get it + return name +end + +-- get module path from name +function core_sandbox_module._modulepath(name) + + -- translate module path + -- + -- "package.module" => "package/module" + -- "..package.module" => "../../package/module" + -- + local startdots = true + local modulepath = name:gsub(".", function(c) + if c == '.' then + if startdots then + return ".." .. path.seperator() + else + return path.seperator() + end + else + startdots = false + return c + end + end) + + -- return module path + return modulepath +end + +-- load module from file +function core_sandbox_module._loadfile(filepath, instance) + + -- check + assert(filepath) + + -- load module script + local script, errors = loadfile(filepath) + if not script then + return nil, errors + end + + -- with sandbox? + if instance then + + -- fork a new sandbox for this script + instance, errors = instance:fork(script, path.directory(filepath)) + if not instance then + return nil, errors + end + + -- import module + local result, errors = instance:import() + if not result then + return nil, errors + end + + -- ok + return result, instance:script() + end + + -- load module without sandbox + local ok, result = xpcall(script, debug.traceback) + if not ok then + return nil, result + end + + -- ok? + return result, script +end + +-- find module +function core_sandbox_module._find(dir, name) + + -- check + assert(dir and name) + + -- get module path + name = core_sandbox_module._modulepath(name) + assert(name) + + -- get module key + local key = path.join(dir, name) + + -- the single module? + if os.isfile(key .. ".lua") then + return path.absolute(key) + -- modules? + elseif os.isdir(key) then + return path.absolute(key) + end +end + +-- load module +function core_sandbox_module._load(dir, name, instance) + + -- check + assert(dir and name) + + -- get module path + name = core_sandbox_module._modulepath(name) + assert(name) + + -- load the single module? + local module = nil + local script = nil + if os.isfile(path.join(dir, name .. ".lua")) then + + -- load module + local result, errors = core_sandbox_module._loadfile(path.join(dir, name .. ".lua"), instance) + if not result then + return nil, errors + end + + -- save module + module = result + + -- save script + script = errors + + -- load modules + elseif os.isdir(path.join(dir, name)) then + + -- get modulefiles + local moduleroot = path.join(path.join(dir, name)) + local modulefiles = os.match(path.join(moduleroot, "**.lua")) + if modulefiles then + for _, modulefile in ipairs(modulefiles) do + + -- load module + local result, errors = core_sandbox_module._loadfile(modulefile, instance) + if not result then + return nil, errors + end + + -- bind main entry + if result.main then + setmetatable(result, { __call = function (_, ...) return result.main(...) end}) + end + + -- get the module path + local modulepath = path.relative(modulefile, moduleroot) + if not modulepath then + return nil, string.format("cannot get the path for module: %s", name) + end + + -- init the root module + module = module or {} + + -- save script + script = errors + + -- save module + local scope = module + for _, modulename in ipairs(path.split(modulepath)) do + + -- is end? + local pos = modulename:find(".lua", 1, true) + if pos then + + -- get the module name + modulename = modulename:sub(1, pos - 1) + assert(modulename) + + -- save module + scope[modulename] = result + + -- is scope? + else + + -- enter submodule + scope[modulename] = scope[modulename] or {} + scope = scope[modulename] + end + end + end + end + end + + -- this module not found? + if not module then + return nil, string.format("module: %s not found!", name) + end + + -- return it + return module, script +end + +-- get module directories +function core_sandbox_module.directories() + + -- init directories + local directories = core_sandbox_module._DIRS or { path.join(global.directory(), "modules") + , path.join(os.programdir(), "modules") + , path.join(os.programdir(), "core/sandbox/modules/import") + } + + -- save directories to cache + core_sandbox_module._DIRS = directories + return directories +end + +-- add module directories +function core_sandbox_module.add_directories(...) + + -- add directories + local moduledirs = core_sandbox_module.directories() + for _, dir in ipairs({...}) do + table.insert(moduledirs, 1, dir) + end + + -- remove unique directories + core_sandbox_module._DIRS = table.unique(moduledirs) +end + +-- find module +function core_sandbox_module.find(name) + + -- find it from the module directories + for _, moduledir in ipairs(core_sandbox_module.directories()) do + if core_sandbox_module._find(moduledir, name) then + return true + end + end +end + +-- import module +-- +-- @param name the module name, .e.g core.platform +-- @param opt the argument options, .e.g {alias = "", rootdir = "", try = false, inherit = false, anonymous = false, nocache = false} +-- +-- @return the module instance +-- +-- .e.g +-- +-- import("core.platform") +-- => platform +-- +-- import("core.platform", {alias = "p"}) +-- => p +-- +-- import("core") +-- => core +-- => core.platform +--- +-- import("core", {rootdir = "/scripts"}) +-- => core +-- => core.platform +-- +-- import("core.platform", {inherit = true}) +-- => inherit the all interfaces of core.platform to the current scope +-- +-- local test = import("test", {rootdir = "/tmp/xxx", anonymous = true}) +-- => only return imported module +-- +-- import("core.project.config", {try = true}) +-- => cannot raise errors if the imported module not found +-- +-- @note the polymiorphism is not supported for import.inherit mode now. +-- +function core_sandbox_module.import(name, opt) + + -- check + assert(name) + + -- the argument options + opt = opt or {} + + -- init module cache + core_sandbox_module._MODULES = core_sandbox_module._MODULES or {} + local modules = core_sandbox_module._MODULES + + -- get the parent scope + local scope_parent = getfenv(2) + assert(scope_parent) + + -- get module name + local modulename = core_sandbox_module._modulename(name) + if not modulename then + raise("cannot get module name for %s", name) + end + + -- the imported name + local imported_name = opt.alias or modulename + + -- get the current sandbox instance + local instance = sandbox.instance() + assert(instance) + + -- the root directory for this sandbox script + local rootdir = opt.rootdir or instance:rootdir() + assert(rootdir) + + -- init module directories + local modules_directories = table.join(rootdir, core_sandbox_module.directories()) + + -- load module + local found = false + local errors = nil + local module = nil + local modulekey = nil + for idx, moduledir in ipairs(modules_directories) do + + -- find module and key + modulekey = core_sandbox_module._find(moduledir, name) + if modulekey then + + -- load it from cache first + local moduleinfo = modules[modulekey] + if moduleinfo and not opt.nocache and not opt.inherit then + module = moduleinfo[1] + errors = moduleinfo[2] + else + -- load it from the script file + module, errors = core_sandbox_module._load(moduledir, name, utils.ifelse(idx < #modules_directories, instance, nil)) -- last modules need not fork sandbox + + -- cache this module + if not opt.nocache then + modules[modulekey] = {module, errors} + end + end + + -- end + found = true + break + end + end + + -- not found? + if not found then + if opt.try then + return nil + else + raise("cannot import module: %s, not found!", name) + end + end + + -- check + if not module then + raise("cannot import module: %s, %s", name, errors) + end + + -- get module script + local script = errors + + -- inherit? + if opt.inherit then + + -- inherit this module into the parent scope + table.inherit2(scope_parent, module) + + -- import as super module + imported_name = "_super" + + -- public the script scope for the super module + -- + -- we can access the all scope members of _super in the child module + -- + -- .e.g + -- + -- import("core.platform.xxx", {inherit = true}) + -- + -- print(_super._g) + -- + if script ~= nil then + setmetatable(module, { __index = function (tbl, key) + local val = rawget(tbl, key) + if val == nil then + val = rawget(getfenv(script), key) + end + return val + end}) + + end + + end + + -- bind main entry + if module.main then + setmetatable(module, { __call = function (_, ...) return module.main(...) end}) + end + + -- import this module into the parent scope + if not opt.anonymous then + scope_parent[imported_name] = module + end + + -- return it + return module +end + +-- inherit module +-- +-- we can access all super interfaces by _super +-- +-- @note the polymiorphism is not supported for import.inherit mode now. +-- +function core_sandbox_module.inherit(name, opt) + + -- init opt + opt = opt or {} + + -- mark as inherit + opt.inherit = true + + -- import and inherit it + return core_sandbox_module.import(name, opt) +end + +-- load module +return core_sandbox_module + 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 17d3f319d..001bffb20 100644 --- a/xmake/core/sandbox/modules/import/lib/detect/find_package.lua +++ b/xmake/core/sandbox/modules/import/lib/detect/find_package.lua @@ -54,11 +54,9 @@ end function sandbox_lib_detect_find_package._find_from_modules(name, opt) -- "detect.packages.find_xxx" exists? - if os.isfile(path.join(os.programdir(), "modules", "detect", "packages", "find_" .. name .. ".lua")) then - local find_package = import("detect.packages.find_" .. name) - if find_package then - return find_package(opt) - end + local find_package = import("detect.packages.find_" .. name, {try = true}) + if find_package then + return find_package(opt) end end diff --git a/xmake/core/sandbox/modules/inherit.lua b/xmake/core/sandbox/modules/inherit.lua index 2ec1e2e29..659a5fa05 100644 --- a/xmake/core/sandbox/modules/inherit.lua +++ b/xmake/core/sandbox/modules/inherit.lua @@ -23,25 +23,5 @@ -- -- load modules -local import = require("sandbox/modules/import") - --- inherit module --- --- we can access all super interfaces by _super --- --- @note the polymiorphism is not supported for import.inherit mode now. -function sandbox_inherit(name, args) - - -- init args - args = args or {} - - -- mark as inherit - args.inherit = true - - -- import and inherit it - return import(name, args) -end - --- load module -return sandbox_inherit +return require("sandbox/modules/import/core/sandbox/module").inherit diff --git a/xmake/modules/lib/detect/features.lua b/xmake/modules/lib/detect/features.lua index be1974a20..3992e52d5 100644 --- a/xmake/modules/lib/detect/features.lua +++ b/xmake/modules/lib/detect/features.lua @@ -76,11 +76,9 @@ function main(name, opt) -- detect.tools.xxx.features(opt)? _g._checking = ifelse(coroutine_running, key, nil) - if os.isfile(path.join(os.programdir(), "modules", "detect", "tools", tool.name, "features.lua")) then - local features = import("detect.tools." .. tool.name .. ".features") - if features then - result = features(opt) - end + local features = import("detect.tools." .. tool.name .. ".features", {try = true}) + if features then + result = features(opt) end _g._checking = nil diff --git a/xmake/modules/lib/detect/find_tool.lua b/xmake/modules/lib/detect/find_tool.lua index 58289b0dc..6d74a7804 100644 --- a/xmake/modules/lib/detect/find_tool.lua +++ b/xmake/modules/lib/detect/find_tool.lua @@ -30,13 +30,11 @@ import("lib.detect.find_toolname") -- find tool from modules function _find_from_modules(name, opt) - -- "detect.tools.find_xxx" exists? - if os.isfile(path.join(os.programdir(), "modules", "detect", "tools", "find_" .. name .. ".lua")) then - local find_tool = import("detect.tools.find_" .. name) - if find_tool then - local program, version, toolname = find_tool(opt) - return {name = toolname or name, program = program, version = version} - end + -- attempt to import "detect.tools.find_xxx" + local find_tool = import("detect.tools.find_" .. name, {try = true}) + if find_tool then + local program, version, toolname = find_tool(opt) + return {name = toolname or name, program = program, version = version} end end diff --git a/xmake/modules/lib/detect/find_toolname.lua b/xmake/modules/lib/detect/find_toolname.lua index ce3b4f1f1..d997eb879 100644 --- a/xmake/modules/lib/detect/find_toolname.lua +++ b/xmake/modules/lib/detect/find_toolname.lua @@ -22,14 +22,14 @@ -- @file find_toolname.lua -- +-- imports +import("core.sandbox.module") + -- find tool name from the given program function _find(program) - -- get tool directory - local tooldir = path.join(os.programdir(), "modules", "detect", "tools") - -- attempt to find it directly first - if os.isfile(path.join(tooldir, "find_" .. program .. ".lua")) then + if module.find("detect.tools.find_" .. program) then return program end @@ -50,7 +50,7 @@ function _find(program) -- find_toolname.lua exists? found local toolname = name:gsub("[%+%-]", function (ch) return ifelse(ch == "+", "x", "_") end) - if os.isfile(path.join(tooldir, "find_" .. toolname .. ".lua")) then + if module.find("detect.tools.find_" .. toolname) then return toolname end @@ -65,7 +65,7 @@ function _find(program) -- find_toolname.lua exists? found toolname = name:gsub("%+", "x") - if os.isfile(path.join(tooldir, "find_" .. toolname .. ".lua")) then + if module.find("detect.tools.find_" .. toolname) then return toolname end end diff --git a/xmake/modules/lib/detect/has_flags.lua b/xmake/modules/lib/detect/has_flags.lua index 614049821..68069b3db 100644 --- a/xmake/modules/lib/detect/has_flags.lua +++ b/xmake/modules/lib/detect/has_flags.lua @@ -103,11 +103,9 @@ function main(name, flags, opt) -- detect.tools.xxx.has_flags(flags, opt)? _g._checking = ifelse(coroutine_running, key, nil) - if os.isfile(path.join(os.programdir(), "modules", "detect", "tools", tool.name, "has_flags.lua")) then - local hasflags = import("detect.tools." .. tool.name .. ".has_flags") - if hasflags then - result = hasflags(flags, opt) - end + local hasflags = import("detect.tools." .. tool.name .. ".has_flags", {try = true}) + if hasflags then + result = hasflags(flags, opt) else result = try { function () os.runv(tool.program, flags); return true end } end |
