summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaikari <[email protected]>2026-01-28 22:49:00 +0300
committerSaikari <[email protected]>2026-01-28 22:49:00 +0300
commitfdc2242b8aca146cf963ec5c1214d4da17f921cf (patch)
treeea33b786ed9089cee0dba1fbdc06711de984429b
parenta45f1db67258d65543be7f6272e7fe994a3c354c (diff)
Enhance os.isexec function to include .exe extension checks and streamline PE header validation for Windows executables
-rw-r--r--tests/modules/io/test.lua48
-rw-r--r--xmake/core/base/os.lua62
2 files changed, 50 insertions, 60 deletions
diff --git a/tests/modules/io/test.lua b/tests/modules/io/test.lua
index 2b8bad8bf..341908a4e 100644
--- a/tests/modules/io/test.lua
+++ b/tests/modules/io/test.lua
@@ -160,3 +160,51 @@ function test_convert(t)
os.tryrm("temp")
end
+
+function test_parse_pe(t)
+ local workdir = path.join(os.tmpdir(), "xmake_test_parse_pe")
+ os.tryrm(workdir)
+ os.mkdir(workdir)
+
+ -- create a local repository
+ local repodir = path.join(workdir, "repo")
+ local pkgdir = path.join(repodir, "packages", "p", "putty_test")
+ os.mkdir(pkgdir)
+
+ io.writefile(path.join(pkgdir, "xmake.lua"), [[
+package("putty_test")
+ set_kind("binary")
+ add_urls("https://the.earth.li/~sgtatham/putty/$(version)/w64/putty.zip")
+ add_versions("0.83", "9a4376156971c17896fdb80b550b6f1c1dffd7bac40de5d7b16e774bad49cf76")
+ on_install(function (package)
+ os.cp("PUTTY.EXE", package:installdir("bin"))
+ end)
+]])
+
+ -- create a project to install it
+ local projdir = path.join(workdir, "proj")
+ os.mkdir(projdir)
+ io.writefile(path.join(projdir, "xmake.lua"), string.format([[
+add_repositories("myrepo %s")
+add_requires("putty_test")
+target("test")
+ set_kind("phony")
+]], repodir:gsub("\\", "/")))
+
+ -- install package using a custom install directory
+ local installdir = path.join(workdir, "packages")
+ local envs = {XMAKE_PKG_INSTALLDIR = installdir}
+ local out, err = os.iorunv("xmake", {"require", "-y", "putty_test"}, {curdir = projdir, envs = envs})
+
+ -- find the installed executable
+ local files = os.files(path.join(installdir, "p", "putty_test", "*", "*", "bin", "PUTTY.EXE"))
+ if #files > 0 then
+ local file_x64 = files[1]
+ local info = io.parse_pe(file_x64)
+ t:are_equal(info.arch, "x64")
+ else
+ t:fail("putty_test not installed. output:\n" .. out .. "\n" .. err)
+ end
+
+ os.tryrm(workdir)
+end
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 28e9ad968..3ea77c9a9 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -1158,77 +1158,19 @@ function os.isexec(filepath)
if os.isfile(filepath) then
if os.host() == "windows" then
local ext = path.extension(filepath):lower()
- if ext == ".cmd" or ext == ".bat" or ext == ".ps1" then
+ if ext == ".exe" or ext == ".cmd" or ext == ".bat" or ext == ".ps1" then
return true
end
- -- check for PE header
- local peinfo = io.parse_pe(filepath)
- if peinfo then
- local pe_arch = peinfo.arch
- -- x86
- if pe_arch == "x86" and os.is_arch("x86_64", "i686") then
- return true
- else
- return false
- end
- -- x64
- if pe_arch == "x64" and os.is_arch("x86_64") then
- return true
- else
- return false
- end
- -- arm64
- if pe_arch == "arm64" and os.is_arch("arm64") then
- return true
- else
- return false
- end
- -- arm32
- if pe_arch == "arm" and os.is_arch("arm.*") then
- return true
- else
- return false
- end
- end
else
return os._access(filepath, "x")
end
end
if os.host() == "windows" then
- for _, suffix in ipairs({".cmd", ".bat", ".ps1"}) do
+ for _, suffix in ipairs({".exe", ".cmd", ".bat", ".ps1"}) do
if os.isfile(filepath .. suffix) then
return true
end
end
- -- check for PE header
- local peinfo = io.parse_pe(filepath .. ".exe")
- if peinfo then
- local pe_arch = peinfo.arch
- -- x86
- if pe_arch == "x86" and os.is_arch("x86_64", "i686") then
- return true
- else
- return false
- end
- -- x64
- if pe_arch == "x64" and os.is_arch("x86_64") then
- return true
- else
- return false
- end
- -- arm64
- if pe_arch == "arm64" and os.is_arch("arm64") then
- return true
- else
- return false
- end
- -- arm32
- if pe_arch == "arm" and os.is_arch("arm.*") then
- return true
- else
- return false
- end
- end
end
return false
end