diff options
| author | ruki <[email protected]> | 2026-01-31 08:38:32 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-31 08:38:32 +0800 |
| commit | 09a670d2fef977f1494135b4146631dbf81a4446 (patch) | |
| tree | 1abc2bd2d2ee867d55a6c377c8e0f755d0b719d7 /xmake | |
| parent | 51a68ee33918b95811420beb6a56673a83abe6cc (diff) | |
| parent | 62b7806dd006540fda8c8c85d173973ae2479fbf (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.lua | 13 | ||||
| -rw-r--r-- | xmake/modules/core/tools/nim.lua | 111 |
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 |
