summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-02-15 00:50:59 +0800
committerruki <[email protected]>2024-02-15 00:50:59 +0800
commit3a105891797c66149cbb291d4b92285b96be66ae (patch)
tree5a3292fa268f7fab336d65a0fd2af64761c5915d
parente5f3c0b6221b26a2c65384131f74dc0c23960f0b (diff)
support exclude pattern
-rw-r--r--tests/apis/xxx_script/xmake.lua14
-rw-r--r--xmake/core/base/private/select_script.lua71
2 files changed, 74 insertions, 11 deletions
diff --git a/tests/apis/xxx_script/xmake.lua b/tests/apis/xxx_script/xmake.lua
index 5c33fccc7..9bfb456b0 100644
--- a/tests/apis/xxx_script/xmake.lua
+++ b/tests/apis/xxx_script/xmake.lua
@@ -16,6 +16,18 @@ target("test")
print("after_build")
end)
- after_build("linux|.*", function (target)
+ after_build("!macosx", function (target)
+ print("after_build !macosx")
+ end)
+
+ after_build("!linux", function (target)
+ print("after_build !linux")
+ end)
+
+ after_build("!iphoneos", function (target)
+ print("after_build !iphoneos")
+ end)
+
+ after_build("linux|*", function (target)
assert(target:is_plat("linux"))
end)
diff --git a/xmake/core/base/private/select_script.lua b/xmake/core/base/private/select_script.lua
index b0c3900dc..f1fdfe1a7 100644
--- a/xmake/core/base/private/select_script.lua
+++ b/xmake/core/base/private/select_script.lua
@@ -18,15 +18,26 @@
-- @file select_script.lua
--
--- match pattern, plat|arch
-function _match_pattern(pattern, plat, arch)
- return (plat .. '|' .. arch):match('^' .. pattern .. '$') or plat:match('^' .. pattern .. '$')
+-- load modules
+local table = require("base/table")
+local utils = require("base/utils")
+
+-- match pattern, matched mode: plat|arch, excluded mode: !plat|arch
+function _match_pattern(pattern, plat, arch, excluded)
+ local is_excluded_pattern = pattern:find('!', 1, true)
+ if excluded and is_excluded_pattern then
+ return not ('!' .. plat .. '|' .. arch):match('^' .. pattern .. '$') and
+ not (plat .. '|!' .. arch):match('^' .. pattern .. '$') and
+ not ('!' .. plat):match('^' .. pattern .. '$')
+ elseif not is_excluded_pattern then
+ return (plat .. '|' .. arch):match('^' .. pattern .. '$') or plat:match('^' .. pattern .. '$')
+ end
end
-- match patterns
-function _match_patterns(patterns, plat, arch)
+function _match_patterns(patterns, plat, arch, excluded)
for _, pattern in ipairs(patterns) do
- if _match_pattern(pattern, plat, arch) then
+ if _match_pattern(pattern, plat, arch, excluded) then
return true
end
end
@@ -34,10 +45,13 @@ end
-- mattch the script pattern
--
--- the supported pattern:
+-- @note interpreter has converted pattern to a lua pattern ('*' => '.*')
+--
+-- matched pattern:
-- plat|arch@subhost|subarch
--
-- e.g.
+--
-- `@linux`
-- `@linux|x86_64`
-- `@macosx,linux`
@@ -45,9 +59,23 @@ end
-- `android|armeabi-v7a@macosx,linux`
-- `android|armeabi-v7a,iphoneos@macosx,linux|x86_64`
-- `android|armeabi-v7a@linux|x86_64`
--- 'linux|.*'
+-- 'linux|*'
+--
+-- excluded pattern:
+-- !plat|!arch@!subhost|!subarch
--
-function _match_script(pattern, plat, arch)
+-- e.g.
+--
+-- `@!linux`
+-- `@!linux|x86_64`
+-- `@!macosx,!linux`
+-- `!android@macosx,!linux`
+-- `android|!armeabi-v7a@macosx,!linux`
+-- `android|armeabi-v7a,!iphoneos@macosx,!linux|x86_64`
+-- `!android|armeabi-v7a@!linux|!x86_64`
+-- '!linux|*'
+--
+function _match_script(pattern, plat, arch, excluded)
local splitinfo = pattern:split("@", {plain = true})
local plat_part = splitinfo[1]
local host_part = splitinfo[2]
@@ -56,9 +84,9 @@ function _match_script(pattern, plat, arch)
if host_part then
host_patterns = host_part:split(",", {plain = true})
end
- if _match_patterns(plat_patterns, plat, arch) then
+ if _match_patterns(plat_patterns, plat, arch, excluded) then
if host_patterns and #host_patterns > 0 and
- not _match_patterns(host_patterns, os.subhost(), os.subarch()) then
+ not _match_patterns(host_patterns, os.subhost(), os.subarch(), excluded) then
return false
end
return true
@@ -81,6 +109,29 @@ function select_script(scripts, opt)
break
end
end
+ if not script_matched then
+ local scripts_fallback = {}
+ local patterns_fallback = {}
+ for pattern, script in pairs(scripts) do
+ if not pattern:startswith("__") and _match_script(pattern, plat, arch, true) then
+ table.insert(scripts_fallback, script)
+ table.insert(patterns_fallback, pattern)
+ end
+ end
+ script_matched = scripts_fallback[1]
+ if script_matched and #scripts_fallback > 0 then
+ local conflict_patterns = {patterns_fallback[1]}
+ for idx, script in ipairs(scripts_fallback) do
+ local pattern = patterns_fallback[idx]
+ if script ~= script_matched then
+ table.insert(conflict_patterns, pattern)
+ end
+ end
+ if #conflict_patterns > 1 then
+ utils.warning("multiple script patterns are matched, %s", table.concat(conflict_patterns, ", "))
+ end
+ end
+ end
result = script_matched or scripts["__generic__"]
end
return result