summaryrefslogtreecommitdiff
path: root/xmake
diff options
context:
space:
mode:
authorruki <[email protected]>2026-01-31 08:38:32 +0800
committerGitHub <[email protected]>2026-01-31 08:38:32 +0800
commit09a670d2fef977f1494135b4146631dbf81a4446 (patch)
tree1abc2bd2d2ee867d55a6c377c8e0f755d0b719d7 /xmake
parent51a68ee33918b95811420beb6a56673a83abe6cc (diff)
parent62b7806dd006540fda8c8c85d173973ae2479fbf (diff)
Merge pull request #7272 from luadebug/nimlib
enhance Nim support for shared libraries and rpath handling
Diffstat (limited to 'xmake')
-rw-r--r--xmake/languages/nim/xmake.lua13
-rw-r--r--xmake/modules/core/tools/nim.lua111
2 files changed, 118 insertions, 6 deletions
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/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