summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaikari <[email protected]>2026-02-01 12:19:49 +0300
committerGitHub <[email protected]>2026-02-01 12:19:49 +0300
commit9fce99ffc77bdd8c77cb0e3d4c129eaa012246f1 (patch)
treedc636b1925aaa56d81501529b6b2330e6ea6058c
parent336fce6edf7a4a2932b8ac0881cd10b2d62d3ecc (diff)
parentd7bdbc99bcc5b64a3fa257c5835014f5d8878150 (diff)
Merge branch 'xmake-io:dev' into stdin
-rw-r--r--core/src/xmake/engine.c2
-rw-r--r--core/src/xmake/os/processes.c86
-rw-r--r--tests/projects/nim/link_library/headers/test_header.h10
-rw-r--r--tests/projects/nim/link_library/inc/test.h11
-rw-r--r--tests/projects/nim/link_library/maindll.nim16
-rw-r--r--tests/projects/nim/link_library/mainlib.nim30
-rw-r--r--tests/projects/nim/link_library/shared.nim29
-rw-r--r--tests/projects/nim/link_library/static.nim26
-rw-r--r--tests/projects/nim/link_library/xmake.lua47
-rw-r--r--tests/projects/policy/compile_commands/src/main.c3
-rw-r--r--tests/projects/policy/compile_commands/xmake.lua10
-rw-r--r--xmake/core/base/tty.lua94
-rw-r--r--xmake/core/base/winos.lua5
-rw-r--r--xmake/core/project/policy.lua2
-rw-r--r--xmake/core/sandbox/modules/winos.lua1
-rw-r--r--xmake/languages/nim/xmake.lua13
-rw-r--r--xmake/modules/core/tools/gcc/has_flags.lua2
-rw-r--r--xmake/modules/core/tools/nim.lua111
-rw-r--r--xmake/modules/detect/sdks/find_cuda.lua6
-rw-r--r--xmake/modules/detect/sdks/find_vstudio.lua44
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua5
21 files changed, 522 insertions, 31 deletions
diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c
index eb07fe2b5..df5ae06be 100644
--- a/core/src/xmake/engine.c
+++ b/core/src/xmake/engine.c
@@ -278,6 +278,7 @@ tb_int_t xm_winos_registry_query(lua_State *lua);
tb_int_t xm_winos_registry_keys(lua_State *lua);
tb_int_t xm_winos_registry_values(lua_State *lua);
tb_int_t xm_winos_short_path(lua_State *lua);
+tb_int_t xm_winos_processes(lua_State* lua);
#endif
// the utf8 functions
@@ -483,6 +484,7 @@ static luaL_Reg const g_winos_functions[] = {
{ "registry_keys", xm_winos_registry_keys },
{ "registry_values", xm_winos_registry_values },
{ "short_path", xm_winos_short_path },
+ { "processes", xm_winos_processes },
{ tb_null, tb_null },
};
#endif
diff --git a/core/src/xmake/os/processes.c b/core/src/xmake/os/processes.c
new file mode 100644
index 000000000..8dbb92aa2
--- /dev/null
+++ b/core/src/xmake/os/processes.c
@@ -0,0 +1,86 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed 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-present, Xmake Open Source Community.
+ *
+ * @author ruki
+ * @file processes.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "processes"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+#ifdef TB_CONFIG_OS_WINDOWS
+#include <windows.h>
+#include <tlhelp32.h>
+#endif
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+tb_int_t xm_winos_processes(lua_State* lua) {
+#ifdef TB_CONFIG_OS_WINDOWS
+ // init result table
+ lua_newtable(lua);
+
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (hSnapshot != INVALID_HANDLE_VALUE) {
+ PROCESSENTRY32W pe32;
+ pe32.dwSize = sizeof(PROCESSENTRY32W);
+
+ if (Process32FirstW(hSnapshot, &pe32)) {
+ tb_int_t i = 1;
+ do {
+ // new process entry table
+ lua_newtable(lua);
+
+ // name
+ tb_char_t name[MAX_PATH * 4];
+ tb_size_t size = tb_wtoa(name, pe32.szExeFile, sizeof(name));
+ if (size != -1) {
+ lua_pushlstring(lua, name, size);
+ } else {
+ lua_pushstring(lua, "");
+ }
+ lua_setfield(lua, -2, "name");
+
+ // pid
+ lua_pushinteger(lua, (tb_int_t)pe32.th32ProcessID);
+ lua_setfield(lua, -2, "pid");
+
+ // ppid
+ lua_pushinteger(lua, (tb_int_t)pe32.th32ParentProcessID);
+ lua_setfield(lua, -2, "parent_pid");
+
+ // result[i++] = entry
+ lua_rawseti(lua, -2, i++);
+
+ } while (Process32NextW(hSnapshot, &pe32));
+ }
+ CloseHandle(hSnapshot);
+ }
+ return 1;
+#else
+ return 0;
+#endif
+}
diff --git a/tests/projects/nim/link_library/headers/test_header.h b/tests/projects/nim/link_library/headers/test_header.h
new file mode 100644
index 000000000..4b71d3173
--- /dev/null
+++ b/tests/projects/nim/link_library/headers/test_header.h
@@ -0,0 +1,10 @@
+#ifndef TEST_HEADER_H
+#define TEST_HEADER_H
+
+#define TEST_HEADER_VAL 123
+
+static int test_add_five(int x) {
+ return x + 5;
+}
+
+#endif
diff --git a/tests/projects/nim/link_library/inc/test.h b/tests/projects/nim/link_library/inc/test.h
new file mode 100644
index 000000000..f7d68cac8
--- /dev/null
+++ b/tests/projects/nim/link_library/inc/test.h
@@ -0,0 +1,11 @@
+
+#ifndef TEST_H
+#define TEST_H
+
+#ifdef TEST_STATIC
+ #define TEST_MSG "Hello from Static Lib!"
+#else
+ #define TEST_MSG "Hello from Shared Lib!"
+#endif
+
+#endif
diff --git a/tests/projects/nim/link_library/maindll.nim b/tests/projects/nim/link_library/maindll.nim
new file mode 100644
index 000000000..b13fe1caf
--- /dev/null
+++ b/tests/projects/nim/link_library/maindll.nim
@@ -0,0 +1,16 @@
+import shared
+
+echo "Calling shared lib mulTwo(10): ", mulTwo(10)
+echo "Calling shared lib countWords('hello, world, hello'): ", countWords("hello, world, hello")
+echo "Calling shared lib getMsg('test'): ", getMsg()
+
+{.emit: """
+#include <test_header.h>
+""".}
+
+var testHeaderVal {.importc: "TEST_HEADER_VAL", nodecl.}: cint
+echo "TEST_HEADER_VAL: ", testHeaderVal
+
+proc test_add_five(x: cint): cint {.importc: "test_add_five", nodecl.}
+echo "test_add_five(80): ", test_add_five(80)
+
diff --git a/tests/projects/nim/link_library/mainlib.nim b/tests/projects/nim/link_library/mainlib.nim
new file mode 100644
index 000000000..1a1fae06c
--- /dev/null
+++ b/tests/projects/nim/link_library/mainlib.nim
@@ -0,0 +1,30 @@
+import static
+
+{.emit: """
+#include <zlib.h>
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb_image.h>
+""".}
+
+proc zlibVersion(): cstring {.importc: "zlibVersion", nodecl.}
+proc stbi_set_flip_vertically_on_load(flag_true_if_should_flip: cint) {.importc: "stbi_set_flip_vertically_on_load", nodecl.}
+
+echo "Zlib Version: ", zlibVersion()
+
+stbi_set_flip_vertically_on_load(1)
+echo "STB Image: Flip vertically on load set to 1"
+
+echo "Calling static lib addTwo(10): ", addTwo(10)
+echo "Calling static lib getAlphabet(): ", getAlphabet()
+echo "Calling static lib getMsg('test'): ", getMsg()
+
+{.emit: """
+#include <test_header.h>
+""".}
+
+var testHeaderVal {.importc: "TEST_HEADER_VAL", nodecl.}: cint
+echo "TEST_HEADER_VAL: ", testHeaderVal
+
+proc test_add_five(x: cint): cint {.importc: "test_add_five", nodecl.}
+echo "test_add_five(55): ", test_add_five(55)
+
diff --git a/tests/projects/nim/link_library/shared.nim b/tests/projects/nim/link_library/shared.nim
new file mode 100644
index 000000000..58dacc6df
--- /dev/null
+++ b/tests/projects/nim/link_library/shared.nim
@@ -0,0 +1,29 @@
+proc mulTwo*(x: int): int =
+ return x * 2
+
+import tables, strutils
+
+proc countWords*(input: string): string =
+ var wordFrequencies = initCountTable[string]()
+ for word in input.split(", "):
+ wordFrequencies.inc(word)
+ return "The most frequent word is '" & $wordFrequencies.largest & "'"
+
+{.emit: """
+#include "test.h"
+""".}
+
+proc getMsg*(): cstring {.exportc, dynlib.} =
+ var msg: cstring
+ {.emit: "`msg` = TEST_MSG;".}
+ return msg
+
+{.emit: """
+#include <test_header.h>
+""".}
+
+var testHeaderVal {.importc: "TEST_HEADER_VAL", nodecl.}: cint
+echo "TEST_HEADER_VAL: ", testHeaderVal
+
+proc test_add_five(x: cint): cint {.importc: "test_add_five", nodecl.}
+echo "test_add_five(10): ", test_add_five(10)
diff --git a/tests/projects/nim/link_library/static.nim b/tests/projects/nim/link_library/static.nim
new file mode 100644
index 000000000..6808d5895
--- /dev/null
+++ b/tests/projects/nim/link_library/static.nim
@@ -0,0 +1,26 @@
+proc addTwo*(x: int): int =
+ return x + 2
+
+proc getAlphabet*(): string =
+ for letter in 'a'..'z':
+ result.add(letter)
+
+{.emit: """
+#define TEST_STATIC
+#include "test.h"
+""".}
+
+proc getMsg*(): cstring {.exportc, dynlib.} =
+ var msg: cstring
+ {.emit: "`msg` = TEST_MSG;".}
+ return msg
+
+{.emit: """
+#include <test_header.h>
+""".}
+
+var testHeaderVal {.importc: "TEST_HEADER_VAL", nodecl.}: cint
+echo "TEST_HEADER_VAL: ", testHeaderVal
+
+proc test_add_five(x: cint): cint {.importc: "test_add_five", nodecl.}
+echo "test_add_five(60): ", test_add_five(60)
diff --git a/tests/projects/nim/link_library/xmake.lua b/tests/projects/nim/link_library/xmake.lua
new file mode 100644
index 000000000..ba56fcbf2
--- /dev/null
+++ b/tests/projects/nim/link_library/xmake.lua
@@ -0,0 +1,47 @@
+set_project("link_libs")
+add_rules("mode.debug", "mode.release")
+
+add_requires("zlib", {system = false, configs = {shared = true}})
+add_requires("stb", {system = false})
+
+target("headers")
+ set_kind("headeronly")
+ add_headerfiles("headers/*.h")
+ add_includedirs("headers", {public = true})
+
+target("executablestatic")
+ set_kind("binary")
+ add_files("mainlib.nim")
+ add_deps("staticlib")
+ add_packages("zlib", "stb", {public = true})
+ if is_plat("linux") then
+ add_syslinks("pthread", "m")
+ end
+
+target("executableshared")
+ set_kind("binary")
+ add_files("maindll.nim")
+ add_deps("sharedlib")
+ if is_plat("linux") then
+ add_syslinks("pthread", "m")
+ end
+
+target("staticlib")
+ set_kind("static")
+ add_files("static.nim")
+ add_includedirs("inc", {public = true})
+ add_headerfiles("inc/*.h")
+ if is_plat("linux") then
+ add_syslinks("pthread", "m")
+ end
+ add_deps("headers")
+
+target("sharedlib")
+ set_kind("shared")
+ add_files("shared.nim")
+ add_includedirs("inc", {public = true})
+ add_headerfiles("inc/*.h")
+ if is_plat("linux") then
+ add_syslinks("pthread", "m")
+ end
+ add_deps("headers")
diff --git a/tests/projects/policy/compile_commands/src/main.c b/tests/projects/policy/compile_commands/src/main.c
new file mode 100644
index 000000000..9b130982d
--- /dev/null
+++ b/tests/projects/policy/compile_commands/src/main.c
@@ -0,0 +1,3 @@
+int main(int argc, char** argv) {
+ return 0;
+}
diff --git a/tests/projects/policy/compile_commands/xmake.lua b/tests/projects/policy/compile_commands/xmake.lua
new file mode 100644
index 000000000..1ccf48af6
--- /dev/null
+++ b/tests/projects/policy/compile_commands/xmake.lua
@@ -0,0 +1,10 @@
+add_rules("mode.debug", "mode.release")
+
+target("enabled")
+ set_kind("binary")
+ add_files("src/main.c")
+
+target("disabled")
+ set_kind("binary")
+ add_files("src/main.c")
+ set_policy("generator.compile_commands", false)
diff --git a/xmake/core/base/tty.lua b/xmake/core/base/tty.lua
index b3ac35b2b..c3681cdd3 100644
--- a/xmake/core/base/tty.lua
+++ b/xmake/core/base/tty.lua
@@ -235,15 +235,68 @@ function tty.flush()
return tty
end
--- find the shell from the parent process (linux)
-function tty._find_shell_from_parent()
- if os.host() ~= "linux" or not os.isfile("/proc/self/stat") then
- return
+function tty._find_shell_from_parent_on_windows()
+ local shell
+ local winos = require("base/winos")
+ if winos.processes then
+ local processes = winos.processes()
+ if processes then
+ local pid = os.getpid()
+ local processes_map = {}
+ for _, process in ipairs(processes) do
+ processes_map[process.pid] = process
+ end
+ local count = 0
+ while pid and pid ~= 0 and count < 10 do
+ count = count + 1
+ local process = processes_map[pid]
+ if not process then
+ break
+ end
+ local name = process.name
+ if name then
+ name = name:lower()
+ if name:sub(-4) == ".exe" then
+ name = name:sub(1, #name - 4)
+ end
+ for _, shellname in ipairs({"zsh", "bash", "fish", "nu", "elvish", "pwsh", "powershell", "cmd", "sh"}) do
+ if name == shellname then
+ shell = shellname
+ break
+ end
+ end
+ end
+ if shell then
+ break
+ end
+ pid = process.parent_pid or process.ppid -- for backward compatibility
+ end
+ end
end
- local shell
+ if not shell then
+ local subhost = xmake._SUBHOST
+ if subhost == "windows" then
+ if os.getenv("PROMPT") then
+ shell = "cmd"
+ else
+ local ok, result = os.iorun("pwsh -v")
+ if ok then
+ shell = "pwsh"
+ else
+ shell = "powershell"
+ end
+ end
+ end
+ end
+ return shell
+end
+
+
+function tty._find_shell_from_parent_on_linux()
local pid = os.getpid()
local count = 0
+ local shell
while pid ~= 0 and count < 4 do
count = count + 1
local shell_name = nil
@@ -288,6 +341,20 @@ function tty._find_shell_from_parent()
return shell
end
+-- find the shell from the parent process
+function tty._find_shell_from_parent()
+
+ -- for windows
+ if os.host() == "windows" then
+ return tty._find_shell_from_parent_on_windows()
+ end
+
+ -- for linux
+ if os.host() == "linux" and os.isfile("/proc/self/stat") then
+ return tty._find_shell_from_parent_on_linux()
+ end
+end
+
-- get shell name
function tty.shell()
local shell = tty._SHELL
@@ -295,22 +362,7 @@ function tty.shell()
if os.getenv("NU_VERSION") then
shell = "nu"
end
- if not shell then
- local subhost = xmake._SUBHOST
- if subhost == "windows" then
- if os.getenv("PROMPT") then
- shell = "cmd"
- else
- local ok, result = os.iorun("pwsh -v")
- if ok then
- shell = "pwsh"
- else
- shell = "powershell"
- end
- end
- end
- end
- -- try to find the shell from the parent process (linux)
+ -- try to find the shell from the parent process
if not shell then
shell = tty._find_shell_from_parent()
end
diff --git a/xmake/core/base/winos.lua b/xmake/core/base/winos.lua
index 73657662e..9d786fdfc 100644
--- a/xmake/core/base/winos.lua
+++ b/xmake/core/base/winos.lua
@@ -31,6 +31,7 @@ winos._oem_cp = winos._oem_cp or winos.oem_cp
winos._registry_query = winos._registry_query or winos.registry_query
winos._registry_keys = winos._registry_keys or winos.registry_keys
winos._registry_values = winos._registry_values or winos.registry_values
+winos._processes = winos._processes or winos.processes
function winos.ansi_cp()
if not winos._ANSI_CP then
@@ -46,6 +47,10 @@ function winos.oem_cp()
return winos._OEM_CP
end
+if not winos.processes then
+ winos.processes = winos._processes
+end
+
-- get windows version from name
function winos._version_from_name(name)
winos._VERSIONS = winos._VERSIONS or {
diff --git a/xmake/core/project/policy.lua b/xmake/core/project/policy.lua
index 1cecfd01a..5123f0a5c 100644
--- a/xmake/core/project/policy.lua
+++ b/xmake/core/project/policy.lua
@@ -192,6 +192,8 @@ function policy.policies()
["network.mode"] = {description = "Set the network mode", type = "string"},
-- Set the compatibility version, e.g. 2.0, 3.0
["compatibility.version"] = {description = "Set the compatibility version", type = "string", default = "3.0", values = {"2.0", "3.0"}},
+ -- Enable compile_commands
+ ["generator.compile_commands"] = {description = "Enable compile_commands.", default = true, type = "boolean"},
-- Generate the solution file in root output directory
-- @see https://github.com/xmake-io/xmake/issues/6519
["generator.vsxmake.root_sln"] = {description = "Generate the solution file in root output directory", default = false, type = "boolean"}
diff --git a/xmake/core/sandbox/modules/winos.lua b/xmake/core/sandbox/modules/winos.lua
index fec1d07df..eddcf91d4 100644
--- a/xmake/core/sandbox/modules/winos.lua
+++ b/xmake/core/sandbox/modules/winos.lua
@@ -33,6 +33,7 @@ sandbox_winos.console_cp = winos.console_cp
sandbox_winos.console_output_cp = winos.console_output_cp
sandbox_winos.logical_drives = winos.logical_drives
sandbox_winos.cmdargv = winos.cmdargv
+sandbox_winos.processes = winos.processes
sandbox_winos.inherit_handles_safely = winos.inherit_handles_safely
-- get windows system version
diff --git a/xmake/languages/nim/xmake.lua b/xmake/languages/nim/xmake.lua
index 65ad6429b..458cd1d33 100644
--- a/xmake/languages/nim/xmake.lua
+++ b/xmake/languages/nim/xmake.lua
@@ -39,10 +39,13 @@ language("nim")
, "target.optimize:check"
, "target.vectorexts:check"
, "target.includedirs"
+ , "target.sysincludedirs"
, "toolchain.includedirs"
}
, binary = {
"config.linkdirs"
+ , "target.includedirs"
+ , "target.sysincludedirs"
, "target.linkdirs"
, "target.rpathdirs"
, "target.strip"
@@ -52,9 +55,14 @@ language("nim")
, "config.links"
, "target.links"
, "toolchain.links"
+ , "config.syslinks"
+ , "target.syslinks"
+ , "toolchain.syslinks"
}
, shared = {
"config.linkdirs"
+ , "target.includedirs"
+ , "target.sysincludedirs"
, "target.linkdirs"
, "target.strip"
, "target.symbols"
@@ -62,10 +70,15 @@ language("nim")
, "config.links"
, "target.links"
, "toolchain.links"
+ , "config.syslinks"
+ , "target.syslinks"
+ , "toolchain.syslinks"
}
, static = {
"target.strip"
, "target.symbols"
+ , "target.includedirs"
+ , "target.sysincludedirs"
}
}
diff --git a/xmake/modules/core/tools/gcc/has_flags.lua b/xmake/modules/core/tools/gcc/has_flags.lua
index c743f91fb..5539fc0f4 100644
--- a/xmake/modules/core/tools/gcc/has_flags.lua
+++ b/xmake/modules/core/tools/gcc/has_flags.lua
@@ -125,7 +125,7 @@ function _check_try_running(flags, opt, islinker)
if not cuda_gpu_flags then
local cuda = get_config("cuda")
local cuda_sdk = find_cuda(cuda)
- local cuda_sdkver = cuda_sdk and cuda_sdk.sdkver or "7.0"
+ local cuda_sdkver = cuda_sdk and cuda_sdk.version or "7.0"
if cuda_sdkver and semver.compare(cuda_sdkver, "12.0") >= 0 then
table.insert(args, 1, "--cuda-gpu-arch=sm_80")
end
diff --git a/xmake/modules/core/tools/nim.lua b/xmake/modules/core/tools/nim.lua
index 94cc0645c..415d102f2 100644
--- a/xmake/modules/core/tools/nim.lua
+++ b/xmake/modules/core/tools/nim.lua
@@ -34,6 +34,23 @@ function init(self)
-- init shflags
self:set("ncshflags", "--app:lib", "--noMain")
+
+ -- init arch flags
+ local arch = self:arch()
+ if arch then
+ if self:is_arch("x86", "i386") then
+ self:add("ncflags", "--cpu:i386", "--define:bit32")
+ if self:is_plat("linux", "macosx", "bsd", "mingw") then
+ self:add("ncflags", '--passC:"-m32"', '--passL:"-m32"')
+ end
+ elseif self:is_arch("x64", "x86_64") then
+ self:add("ncflags", "--cpu:amd64", "--define:bit64")
+ elseif self:is_arch("arm64.*") then
+ self:add("ncflags", "--cpu:arm64", "--define:bit64")
+ elseif self:is_arch("arm.*") then
+ self:add("ncflags", "--cpu:arm", "--define:bit32")
+ end
+ end
end
-- make the warning flag
@@ -92,31 +109,113 @@ end
function nf_strip(self, level)
if self:is_plat("linux", "macosx", "bsd") then
if level == "debug" or level == "all" then
- return "--passL:-s"
+ return '--passL:"-s"'
end
end
end
-- make the includedir flag
function nf_includedir(self, dir)
- return {"--passC:-I" .. path.translate(dir)}
+ return {string.format('--passC:"-I%s"', path.translate(dir))}
+end
+
+-- make the sysincludedir flag
+function nf_sysincludedir(self, dir)
+ return nf_includedir(self, dir)
end
-- make the link flag
function nf_link(self, lib)
if self:is_plat("windows") then
- return "--passL:" .. lib .. ".lib"
+ return string.format('--passL:"%s.lib"', lib)
+ else
+ return string.format('--passL:"-l%s"', lib)
+ end
+end
+
+-- make the syslink flag
+function nf_syslink(self, lib)
+ if self:is_plat("windows") then
+ return string.format('--passL:"%s.lib"', lib)
else
- return "--passL:-l" .. lib
+ if lib == "pthread" then
+ return {"--threads:on", string.format('--passL:"-l%s"', lib), '--dynlibOverride:"pthread"'}
+ else
+ return string.format('--passL:"-l%s"', lib)
+ end
end
end
-- make the linkdir flag
function nf_linkdir(self, dir)
if self:is_plat("windows") then
- return {"--passL:-libpath:" .. path.translate(dir)}
+ return {string.format('--passL:"-libpath:%s"', path.translate(dir))}
else
- return {"--passL:-L" .. path.translate(dir)}
+ return {string.format('--passL:"-L%s"', path.translate(dir))}
+ end
+end
+
+-- make the rpathdir flag
+function nf_rpathdir(self, dir, opt)
+ if self:is_plat("windows") then
+ return
+ end
+ opt = opt or {}
+ local extra = opt.extra
+ if extra and extra.installonly then
+ return
+ end
+ dir = path.translate(dir)
+
+ -- Use --passL:"-Wl,-rpath=<dir>" to pass rpath to the linker
+ -- We use standard -Wl,-rpath for gcc/clang on linux/macosx/bsd without check mainly.
+ if self:is_plat("macosx", "iphoneos") then
+ dir = dir:gsub("([@$][%w_]+)", function (name)
+ if name == "$ORIGIN" then
+ return "@loader_path"
+ end
+ return name
+ end)
+ local rpath = string.format("-Wl,-rpath,%s", dir)
+ return {string.format('--passL:"%s"', rpath)}
+ elseif self:is_plat("linux", "bsd", "android") then
+ dir = dir:gsub("([@$][%w_]+)", function (name)
+ if name == "@loader_path" or name == "@executable_path" then
+ return "\\$ORIGIN"
+ elseif name == "$ORIGIN" then
+ return "\\$ORIGIN"
+ end
+ return name
+ end)
+ local rpath = string.format("-Wl,-rpath=%s", dir)
+ local flags = {string.format('--passL:"%s"', rpath)}
+ if extra then
+ if extra.runpath == false and self:has_flags(string.format('--passL:"%s,--disable-new-dtags"', rpath), "ldflags") then
+ flags[1] = string.format('--passL:"%s,--disable-new-dtags"', rpath)
+ elseif extra.runpath == true and self:has_flags(string.format('--passL:"%s,--enable-new-dtags"', rpath), "ldflags") then
+ flags[1] = string.format('--passL:"%s,--enable-new-dtags"', rpath)
+ end
+ end
+ return flags
+ end
+
+ -- fallback
+ if self:has_flags(string.format('--passL:"-Wl,-rpath=%s"', dir), "ldflags") then
+ local flags = {string.format('--passL:"-Wl,-rpath=%s"', (dir:gsub("@[%w_]+", function (name)
+ local maps = { ["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN" }
+ return maps[name]
+ end)))}
+ -- add_rpathdirs("...", {runpath = false})
+ if extra then
+ if extra.runpath == false and self:has_flags(string.format('--passL:"-Wl,-rpath=%s,--disable-new-dtags"', dir), "ldflags") then
+ flags[1] = string.format('--passL:"-Wl,-rpath=%s,--disable-new-dtags"', dir)
+ elseif extra.runpath == true and self:has_flags(string.format('--passL:"-Wl,-rpath=%s,--enable-new-dtags"', dir), "ldflags") then
+ flags[1] = string.format('--passL:"-Wl,-rpath=%s,--enable-new-dtags"', dir)
+ end
+ end
+ return flags
+ elseif self:has_flags('--passL:"-Xlinker" --passL:"-rpath" --passL:"-Xlinker" ' .. string.format('--passL:"%s"', dir), "ldflags") then
+ return {'--passL:"-Xlinker"', '--passL:"-rpath"', '--passL:"-Xlinker"', string.format('--passL:"%s"', (dir:gsub("%$ORIGIN", "@loader_path")))}
end
end
diff --git a/xmake/modules/detect/sdks/find_cuda.lua b/xmake/modules/detect/sdks/find_cuda.lua
index b767e8e34..5a90cc581 100644
--- a/xmake/modules/detect/sdks/find_cuda.lua
+++ b/xmake/modules/detect/sdks/find_cuda.lua
@@ -131,7 +131,7 @@ function _find_cuda(sdkdir, sdkver)
local includedirs = {path.join(sdkdir, "include")}
-- get version
- local sdkver = find_programver(path.join(bindir, "nvcc"), {parse = "release (%d+%.%d+),"})
+ local version = find_programver(path.join(bindir, "nvcc"), {parse = "release (%d+%.%d+),"})
-- find msbuildextensionsdir on windows
local msbuildextensionsdir
@@ -140,7 +140,7 @@ function _find_cuda(sdkdir, sdkver)
end
-- get toolchains
- return {sdkdir = sdkdir, bindir = bindir, sdkver = sdkver, linkdirs = linkdirs, includedirs = includedirs, msbuildextensionsdir = msbuildextensionsdir}
+ return {sdkdir = sdkdir, bindir = bindir, version = version, linkdirs = linkdirs, includedirs = includedirs, msbuildextensionsdir = msbuildextensionsdir}
end
-- find cuda sdk toolchains
@@ -176,7 +176,7 @@ function main(sdkdir, opt)
-- save to config
config.set("cuda", cuda.sdkdir, {force = true, readonly = true})
- config.set("cuda_sdkver", cuda.sdkver, {force = true, readonly = true})
+ config.set("cuda_sdkver", cuda.version, {force = true, readonly = true})
-- trace
if opt.verbose or option.get("verbose") then
diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua
index cf56fcca9..22f5dea6b 100644
--- a/xmake/modules/detect/sdks/find_vstudio.lua
+++ b/xmake/modules/detect/sdks/find_vstudio.lua
@@ -21,6 +21,7 @@
-- imports
import("core.base.option")
import("core.base.semver")
+import("core.base.hashset")
import("core.project.config")
import("lib.detect.find_file")
import("lib.detect.find_tool")
@@ -93,6 +94,9 @@ local vsenvs =
, ["4.2"] = "VS42COMNTOOLS"
}
+-- the original environment variables
+local _env_orgs = {}
+
-- get all known Visual Studio environment variables
function get_vcvars()
local realvcvars = vcvars
@@ -310,6 +314,9 @@ function _load_vcvarsall_impl(vcvarsall, vsver, arch, opt)
variables[name] = value
end
end
+
+ -- check if the environment variables are truncated
+ _check_vcvarsall_env(variables)
if not variables.path then
return
end
@@ -381,6 +388,40 @@ function _strip_toolset_ver(vs_toolset)
return vs_toolset
end
+-- check if the environment variables are truncated
+-- https://github.com/xmake-io/xmake/issues/7281
+function _check_vcvarsall_env(vars)
+ if not option.get("diagnosis") then
+ return
+ end
+ local check_vars = {"PATH", "INCLUDE", "LIB", "LIBPATH"}
+ for _, name in ipairs(check_vars) do
+ local value_org = _env_orgs[name]
+ if value_org == nil then
+ local value_str = os.getenv(name)
+ if value_str then
+ _env_orgs[name] = path.splitenv(value_str)
+ else
+ _env_orgs[name] = false
+ end
+ value_org = _env_orgs[name]
+ end
+ local value_new = vars[name] or vars[name:lower()]
+ if value_org and value_new and #value_org > 0 then
+ local values_new = hashset.from(path.splitenv(value_new))
+ for _, p in ipairs(value_org) do
+ if not values_new:has(p) then
+ if #p > 256 then
+ p = p:sub(1, 256) .. "..."
+ end
+ wprint("%%%s%% is too long and truncated, msvc detection may fail, please clear some unused variables!\n > %s", name, p)
+ break
+ end
+ end
+ end
+ end
+end
+
function _load_vcvarsall(vcvarsall, vsver, arch, opt)
opt = opt or {}
local vs_toolset = opt.toolset or opt.vcvars_ver
@@ -414,6 +455,9 @@ end
function _find_vstudio(opt)
opt = opt or {}
+ -- clear local cache of environment variables
+ _env_orgs = {}
+
-- find the single current MSVC/VS from environment variables
local VCInstallDir = os.getenv("VCInstallDir")
if VCInstallDir and (VCInstallDir ~= "") then
diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua
index 4f01354fa..909184800 100644
--- a/xmake/plugins/project/clang/compile_commands.lua
+++ b/xmake/plugins/project/clang/compile_commands.lua
@@ -266,6 +266,11 @@ function _add_target(jsonfile, target)
-- https://github.com/xmake-io/xmake/issues/2337
target:data_set("plugin.project.kind", "compile_commands")
+ -- disable compile_commands?
+ if target:policy("generator.compile_commands") == false then
+ return
+ end
+
-- enter package environments
local oldenvs = os.addenvs(target:pkgenvs())