From a8c60009ba4b17694e13b45b733819c2fc3dce8b Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 1 Sep 2024 22:25:27 +0800 Subject: [PATCH 1/4] improve cosmocc for windows --- tests/projects/c/cosmocc/console/xmake.lua | 6 ++++++ .../core/sandbox/modules/import/lib/detect/find_program.lua | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/projects/c/cosmocc/console/xmake.lua b/tests/projects/c/cosmocc/console/xmake.lua index babd520a25e..1327045c134 100644 --- a/tests/projects/c/cosmocc/console/xmake.lua +++ b/tests/projects/c/cosmocc/console/xmake.lua @@ -2,6 +2,12 @@ add_rules("mode.debug", "mode.release") add_requires("cosmocc") +-- TODO, we should add envs to toolchains/cosmocc +if is_subhost("windoows") then + add_requires("msys2") + add_packages("msys2") +end + target("test") set_kind("binary") add_files("src/*.c") diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua index 3923916d902..3b20eb9387c 100644 --- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua +++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua @@ -74,9 +74,10 @@ end -- check program function sandbox_lib_detect_find_program._check(program, opt) + opt = opt or {} local findname = program if os.subhost() == "windows" then - if not program:endswith(".exe") and not program:endswith(".cmd") and not program:endswith(".bat") then + if not opt.shell and not program:endswith(".exe") and not program:endswith(".cmd") and not program:endswith(".bat") then findname = program .. ".exe" end elseif os.subhost() == "msys" and os.isfile(program) and os.filesize(program) < 256 then From 87252889ffb913043721dd332456c186588a5ee7 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 2 Sep 2024 22:47:58 +0800 Subject: [PATCH 2/4] rename package envs --- tests/projects/c/cosmocc/console/xmake.lua | 6 ------ xmake/core/project/package.lua | 5 +++++ xmake/core/project/target.lua | 2 +- xmake/toolchains/emcc/xmake.lua | 2 +- xmake/toolchains/iverilog/xmake.lua | 2 +- xmake/toolchains/nim/xmake.lua | 2 +- xmake/toolchains/verilator/xmake.lua | 4 ++-- xmake/toolchains/zig/xmake.lua | 2 +- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/tests/projects/c/cosmocc/console/xmake.lua b/tests/projects/c/cosmocc/console/xmake.lua index 1327045c134..babd520a25e 100644 --- a/tests/projects/c/cosmocc/console/xmake.lua +++ b/tests/projects/c/cosmocc/console/xmake.lua @@ -2,12 +2,6 @@ add_rules("mode.debug", "mode.release") add_requires("cosmocc") --- TODO, we should add envs to toolchains/cosmocc -if is_subhost("windoows") then - add_requires("msys2") - add_packages("msys2") -end - target("test") set_kind("binary") add_files("src/*.c") diff --git a/xmake/core/project/package.lua b/xmake/core/project/package.lua index 63267a04e57..c253ee0a2a2 100644 --- a/xmake/core/project/package.lua +++ b/xmake/core/project/package.lua @@ -271,6 +271,11 @@ function _instance:enable(enabled) self:set("__enabled", enabled) end +-- get environments +function _instance:envs() + return self:get("envs") +end + -- get the given rule function _instance:rule(name) return self:rules()[name] diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index c84e6fbcbee..ace54441c0e 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -1335,7 +1335,7 @@ function _instance:pkgenvs() end end for _, pkg in pkgs:orderkeys() do - local envs = pkg:get("envs") + local envs = pkg:envs() if envs then for name, values in table.orderpairs(envs) do if type(values) == "table" then diff --git a/xmake/toolchains/emcc/xmake.lua b/xmake/toolchains/emcc/xmake.lua index b95e6714570..2282afe93d7 100644 --- a/xmake/toolchains/emcc/xmake.lua +++ b/xmake/toolchains/emcc/xmake.lua @@ -58,7 +58,7 @@ toolchain("emcc") toolchain:add("ldflags", "") toolchain:add("shflags", "") for _, package in ipairs(toolchain:packages()) do - local envs = package:get("envs") + local envs = package:envs() if envs then for _, name in ipairs({"EMSDK", "EMSDK_NODE", "EMSDK_PYTHON", "JAVA_HOME"}) do local values = envs[name] diff --git a/xmake/toolchains/iverilog/xmake.lua b/xmake/toolchains/iverilog/xmake.lua index 30f83fabce8..659922441ea 100644 --- a/xmake/toolchains/iverilog/xmake.lua +++ b/xmake/toolchains/iverilog/xmake.lua @@ -28,7 +28,7 @@ toolchain("iverilog") import("lib.detect.find_tool") local paths = {} for _, package in ipairs(toolchain:packages()) do - local envs = package:get("envs") + local envs = package:envs() if envs then table.join2(paths, envs.PATH) end diff --git a/xmake/toolchains/nim/xmake.lua b/xmake/toolchains/nim/xmake.lua index 9afd491daec..826f3196e7b 100644 --- a/xmake/toolchains/nim/xmake.lua +++ b/xmake/toolchains/nim/xmake.lua @@ -26,7 +26,7 @@ toolchain("nim") import("lib.detect.find_tool") local paths = {} for _, package in ipairs(toolchain:packages()) do - local envs = package:get("envs") + local envs = package:envs() if envs then table.join2(paths, envs.PATH) end diff --git a/xmake/toolchains/verilator/xmake.lua b/xmake/toolchains/verilator/xmake.lua index 59edcf6db0b..5bb38b3875a 100644 --- a/xmake/toolchains/verilator/xmake.lua +++ b/xmake/toolchains/verilator/xmake.lua @@ -26,7 +26,7 @@ toolchain("verilator") import("lib.detect.find_tool") local paths = {} for _, package in ipairs(toolchain:packages()) do - local envs = package:get("envs") + local envs = package:envs() if envs then table.join2(paths, envs.PATH) end @@ -46,7 +46,7 @@ toolchain("verilator") on_load(function (toolchain) if is_host("windows") then for _, package in ipairs(toolchain:packages()) do - local envs = package:get("envs") + local envs = package:envs() if envs then local verilator_root = envs.VERILATOR_ROOT if verilator_root then diff --git a/xmake/toolchains/zig/xmake.lua b/xmake/toolchains/zig/xmake.lua index 082dcba329b..71133476271 100644 --- a/xmake/toolchains/zig/xmake.lua +++ b/xmake/toolchains/zig/xmake.lua @@ -30,7 +30,7 @@ toolchain("zig") import("lib.detect.find_tool") local paths = {} for _, package in ipairs(toolchain:packages()) do - local envs = package:get("envs") + local envs = package:envs() if envs then table.join2(paths, envs.PATH) end From 4e9459eca8abe50b31f498541173948f2153f7b4 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 2 Sep 2024 22:52:18 +0800 Subject: [PATCH 3/4] load cosmocc envs --- xmake/modules/detect/tools/find_cosmoar.lua | 1 + xmake/modules/detect/tools/find_cosmocc.lua | 2 +- xmake/modules/detect/tools/find_cosmocxx.lua | 1 + xmake/toolchains/cosmocc/check.lua | 10 ++++++++++ xmake/toolchains/cosmocc/xmake.lua | 8 ++++++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/xmake/modules/detect/tools/find_cosmoar.lua b/xmake/modules/detect/tools/find_cosmoar.lua index 01c9232cecb..b293c9b570b 100644 --- a/xmake/modules/detect/tools/find_cosmoar.lua +++ b/xmake/modules/detect/tools/find_cosmoar.lua @@ -36,6 +36,7 @@ import("lib.detect.find_program") function main(opt) opt = opt or {} opt.shell = true + opt.envs = opt.envs or {PATH = os.getenv("PATH")} local program = find_program(opt.program or "cosmoar", opt) if program and is_host("windows") then program = program:gsub("\\", "/") diff --git a/xmake/modules/detect/tools/find_cosmocc.lua b/xmake/modules/detect/tools/find_cosmocc.lua index 91064362633..14d14d1be76 100644 --- a/xmake/modules/detect/tools/find_cosmocc.lua +++ b/xmake/modules/detect/tools/find_cosmocc.lua @@ -37,7 +37,7 @@ import("lib.detect.find_programver") function main(opt) opt = opt or {} opt.shell = true - opt.envs = {PATH = os.getenv("PATH")} + opt.envs = opt.envs or {PATH = os.getenv("PATH")} local program = find_program(opt.program or "cosmocc", opt) if program and is_host("windows") then program = program:gsub("\\", "/") diff --git a/xmake/modules/detect/tools/find_cosmocxx.lua b/xmake/modules/detect/tools/find_cosmocxx.lua index 06ce69aac21..d09bac5101d 100644 --- a/xmake/modules/detect/tools/find_cosmocxx.lua +++ b/xmake/modules/detect/tools/find_cosmocxx.lua @@ -37,6 +37,7 @@ import("lib.detect.find_programver") function main(opt) opt = opt or {} opt.shell = true + opt.envs = opt.envs or {PATH = os.getenv("PATH")} local program = find_program(opt.program or "cosmoc++", opt) if program and is_host("windows") then program = program:gsub("\\", "/") diff --git a/xmake/toolchains/cosmocc/check.lua b/xmake/toolchains/cosmocc/check.lua index d193cceb2fb..5876db68f76 100644 --- a/xmake/toolchains/cosmocc/check.lua +++ b/xmake/toolchains/cosmocc/check.lua @@ -32,6 +32,7 @@ function main(toolchain) local bindir = toolchain:bindir() -- find cross toolchain from external envirnoment + local envs local cross_toolchain = find_cross_toolchain(sdkdir, {bindir = bindir}) if not cross_toolchain then -- find it from packages @@ -40,6 +41,11 @@ function main(toolchain) if installdir and os.isdir(installdir) then cross_toolchain = find_cross_toolchain(installdir) if cross_toolchain then + -- we need to bind msys2 shell envirnoments for calling cosmocc, + -- @see https://github.com/xmake-io/xmake/issues/5552 + if is_subhost("windows") then + envs = package:envs() + end break end end @@ -57,9 +63,13 @@ function main(toolchain) toolchain:config_set("cross", cross_toolchain.cross) toolchain:config_set("bindir", cross_toolchain.bindir) toolchain:config_set("sdkdir", cross_toolchain.sdkdir) + if envs then + toolchain:config_set("envs", envs) + end toolchain:configs_save() else raise("cosmocc toolchain not found!") end return cross_toolchain end + diff --git a/xmake/toolchains/cosmocc/xmake.lua b/xmake/toolchains/cosmocc/xmake.lua index 0b19ad16c82..17d217a6cdf 100644 --- a/xmake/toolchains/cosmocc/xmake.lua +++ b/xmake/toolchains/cosmocc/xmake.lua @@ -45,4 +45,12 @@ toolchain("cosmocc") toolchain:set("toolset", "ranlib", "aarch64-linux-cosmo-ranlib") toolchain:set("toolset", "strip", "aarch64-linux-cosmo-strip") end + -- @see https://github.com/xmake-io/xmake/issues/5552 + local envs = toolchain:config("envs") + if envs then + for k, v in pairs(envs) do + toolchain:add("runenvs", k, v) + end + end end) + From b7dbf58d81a5731ec404afe57b2af4fa783d6b72 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 2 Sep 2024 22:54:15 +0800 Subject: [PATCH 4/4] improve to get shell path --- xmake/core/base/os.lua | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index 9160aa53472..2dba50509c4 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -288,6 +288,36 @@ function os._run_exit_cbs(ok, errors) end end +-- get shell path, e.g. sh, bash +function os._get_shell_path(opt) + opt = opt or {} + local setenvs = opt.setenvs or opt.envs or {} + local addenvs = opt.addenvs or {} + local paths = {} + local p = setenvs.PATH + if type(p) == "string" then + p = path.splitenv(p) + end + if p then + table.join2(paths, p) + end + p = addenvs.PATH + if type(p) == "string" then + p = path.splitenv(p) + end + if p then + table.join2(paths, p) + end + for _, p in ipairs(paths) do + for _, name in ipairs({"sh", "bash"}) do + local filepath = path.join(p, name) + if os.isexec(filepath) then + return filepath + end + end + end +end + -- match files or directories -- -- @param pattern the search pattern @@ -808,7 +838,7 @@ function os.execv(program, argv, opt) -- because `/bin/sh` is not real file path, maybe we need to convert it. local host = os.host() if host == "windows" then - filename = "sh" + filename = os._get_shell_path(opt) or "sh" argv = table.join(shellfile, argv) else line = line:sub(3)