summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSineStriker <[email protected]>2025-04-18 23:29:50 +0800
committerruki <[email protected]>2025-04-23 11:30:30 +0800
commit6551ed38c1250c0c41eada6db14f8601bf3ddb64 (patch)
treef8e7525fc8bc74b54f077c82148c0ae79df35d87
parenta5c510f35e861b0ff71a2af0781359bc881ea3af (diff)
Support customizing `implib` path of MinGW/MSVC
-rw-r--r--xmake/actions/package/oldpkg/main.lua18
-rw-r--r--xmake/core/project/target.lua20
-rw-r--r--xmake/modules/core/tools/gcc.lua14
-rw-r--r--xmake/modules/core/tools/link.lua8
-rw-r--r--xmake/modules/core/tools/nvcc.lua18
-rw-r--r--xmake/modules/target/action/clean/main.lua19
-rw-r--r--xmake/modules/target/action/install/main.lua4
-rw-r--r--xmake/plugins/pack/batchcmds.lua12
8 files changed, 89 insertions, 24 deletions
diff --git a/xmake/actions/package/oldpkg/main.lua b/xmake/actions/package/oldpkg/main.lua
index d0854635f..983f187a9 100644
--- a/xmake/actions/package/oldpkg/main.lua
+++ b/xmake/actions/package/oldpkg/main.lua
@@ -48,11 +48,19 @@ function _package_library(target)
-- copy *.lib for shared/windows (*.dll) target
-- @see https://github.com/xmake-io/xmake/issues/787
- if target:is_shared() and target:is_plat("windows", "mingw") then
- local targetfile = target:targetfile()
- local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib")
- if os.isfile(targetfile_lib) then
- os.vcp(targetfile_lib, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/", outputdir, targetname))
+ if target:is_shared() then
+ if target:is_plat("windows") then
+ local targetfile = target:targetfile()
+ local targetfile_lib = path.join(target:implibdir(), path.basename(targetfile) .. ".lib")
+ if os.isfile(targetfile_lib) then
+ os.vcp(targetfile_lib, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/", outputdir, targetname))
+ end
+ elseif target:is_plat("mingw") then
+ local targetfile = target:targetfile()
+ local targetfile_lib = path.join(target:implibdir(), path.basename(targetfile) .. ".dll.a")
+ if os.isfile(targetfile_lib) then
+ os.vcp(targetfile_lib, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/", outputdir, targetname))
+ end
end
end
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 089fd1e3c..411822fcb 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -1605,6 +1605,26 @@ function _instance:targetdir()
return targetdir
end
+-- get the imp-lib directory (only on windows)
+function _instance:implibdir()
+ if not ((self:is_plat("windows", "mingw")) and self:is_shared()) then
+ return nil
+ end
+
+ local targetdir = self:extraconf("targetdir") or {}
+ local implibdir = nil
+ for _, v in pairs(targetdir) do
+ if type(v) == "table" then
+ implibdir = v["implibdir"]
+ end
+ break
+ end
+ if not implibdir then
+ return self:targetdir()
+ end
+ return implibdir
+end
+
-- get the target file name
function _instance:filename()
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index ed6bbcf22..09a5b589e 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -575,7 +575,11 @@ function linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
-- add `-Wl,--out-implib,outputdir/libxxx.a` for xxx.dll on mingw/gcc
if targetkind == "shared" and self:is_plat("mingw") then
- table.insert(flags_extra, "-Wl,--out-implib," .. path.join(path.directory(targetfile), path.basename(targetfile) .. ".dll.a"))
+ local implibdir = path.directory(targetfile)
+ if opt.target then
+ implibdir = opt.target:implibdir()
+ end
+ table.insert(flags_extra, "-Wl,--out-implib," .. path.join(implibdir, path.basename(targetfile) .. ".dll.a"))
end
-- init arguments
@@ -595,7 +599,13 @@ end
function link(self, objectfiles, targetkind, targetfile, flags, opt)
opt = opt or {}
os.mkdir(path.directory(targetfile))
- local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags)
+
+ -- ensure the implib directory
+ if opt and opt.target and opt.target:implibdir() then
+ os.mkdir(opt.target:implibdir())
+ end
+
+ local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
if option.get("verbose") then
os.execv(program, argv, {envs = self:runenvs(), shell = opt.shell})
else
diff --git a/xmake/modules/core/tools/link.lua b/xmake/modules/core/tools/link.lua
index 3e51ad40a..fb533eb92 100644
--- a/xmake/modules/core/tools/link.lua
+++ b/xmake/modules/core/tools/link.lua
@@ -137,6 +137,9 @@ function linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
table.insert(argv, 1, "-lib")
elseif targetkind == "shared" then
table.insert(argv, 1, "-dll")
+ if opt.target then
+ table.insert(argv, "/IMPLIB:" .. path.join(opt.target:implibdir(), path.basename(targetfile) .. ".lib"))
+ end
end
return self:program(), argv
end
@@ -147,6 +150,11 @@ function link(self, objectfiles, targetkind, targetfile, flags, opt)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
+ -- ensure the implib directory
+ if opt and opt.target and opt.target:implibdir() then
+ os.mkdir(opt.target:implibdir())
+ end
+
try
{
function ()
diff --git a/xmake/modules/core/tools/nvcc.lua b/xmake/modules/core/tools/nvcc.lua
index ea8c8704a..b68ed570e 100644
--- a/xmake/modules/core/tools/nvcc.lua
+++ b/xmake/modules/core/tools/nvcc.lua
@@ -274,7 +274,7 @@ function nf_pcxxheader(self, pcheaderfile)
end
-- make the link arguments list
-function linkargv(self, objectfiles, targetkind, targetfile, flags)
+function linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
-- add rpath for dylib (macho), e.g. -install_name @rpath/file.dylib
local flags_extra = {}
@@ -287,8 +287,12 @@ function linkargv(self, objectfiles, targetkind, targetfile, flags)
-- add `-Wl,--out-implib,outputdir/libxxx.a` for xxx.dll on mingw/gcc
if targetkind == "shared" and self:is_plat("mingw") then
+ local implibdir = path.directory(targetfile)
+ if opt.target then
+ implibdir = opt.target:implibdir()
+ end
table.insert(flags_extra, "-Xlinker")
- table.insert(flags_extra, "-Wl,--out-implib," .. path.join(path.directory(targetfile), path.basename(targetfile) .. ".dll.a"))
+ table.insert(flags_extra, "-Wl,--out-implib," .. path.join(implibdir, path.basename(targetfile) .. ".dll.a"))
end
-- make link args
@@ -296,9 +300,15 @@ function linkargv(self, objectfiles, targetkind, targetfile, flags)
end
-- link the target file
-function link(self, objectfiles, targetkind, targetfile, flags)
+function link(self, objectfiles, targetkind, targetfile, flags, opt)
os.mkdir(path.directory(targetfile))
- local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags)
+
+ -- ensure the implib directory
+ if opt and opt.target and opt.target:implibdir() then
+ os.mkdir(opt.target:implibdir())
+ end
+
+ local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
os.runv(program, argv, {envs = self:runenvs()})
end
diff --git a/xmake/modules/target/action/clean/main.lua b/xmake/modules/target/action/clean/main.lua
index 06bd39f70..911fbe17e 100644
--- a/xmake/modules/target/action/clean/main.lua
+++ b/xmake/modules/target/action/clean/main.lua
@@ -37,12 +37,19 @@ function main(target)
-- remove import library of the target file
-- @see https://github.com/xmake-io/xmake/issues/3052
- if target:is_plat("windows") and target:is_shared() then
- local expfile = path.join(path.directory(targetfile), path.basename(targetfile) .. ".exp")
- local libfile = path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib")
- if os.isfile(expfile) then
- remove_files(libfile)
- remove_files(expfile)
+ if target:is_shared() then
+ if target:is_plat("windows") then
+ local expfile = path.join(target:implibdir(), path.basename(targetfile) .. ".exp")
+ local libfile = path.join(target:implibdir(), path.basename(targetfile) .. ".lib")
+ if os.isfile(expfile) then
+ remove_files(libfile)
+ remove_files(expfile)
+ end
+ elseif target:is_plat("mingw") then
+ local libfile = path.join(target:implibdir(), path.basename(targetfile) .. ".dll.a")
+ if os.isfile(libfile) then
+ remove_files(libfile)
+ end
end
end
diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua
index 48e97e4cc..d60426b0a 100644
--- a/xmake/modules/target/action/install/main.lua
+++ b/xmake/modules/target/action/install/main.lua
@@ -232,12 +232,12 @@ function _install_shared(target, opt)
os.mkdir(bindir)
local targetfile = target:targetfile()
- if target:is_plat("windows", "mingw") then
+ if target:is_plat("windows", "mingw") and target:is_shared() then
-- install *.lib for shared/windows (*.dll) target
-- @see https://github.com/xmake-io/xmake/issues/714
os.vcp(target:targetfile(), bindir)
local libdir = _get_target_libdir(target, opt)
- local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))
+ local targetfile_lib = path.join(target:implibdir(), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))
if os.isfile(targetfile_lib) then
os.mkdir(libdir)
os.vcp(targetfile_lib, libdir)
diff --git a/xmake/plugins/pack/batchcmds.lua b/xmake/plugins/pack/batchcmds.lua
index 9ed38e970..aeb1b842e 100644
--- a/xmake/plugins/pack/batchcmds.lua
+++ b/xmake/plugins/pack/batchcmds.lua
@@ -303,11 +303,13 @@ function _on_target_installcmd_shared(target, batchcmds_, opt)
-- install *.lib for shared/windows (*.dll) target
-- @see https://github.com/xmake-io/xmake/issues/714
- local targetfile = target:targetfile()
- local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))
- if os.isfile(targetfile_lib) then
- batchcmds_:mkdir(libdir)
- batchcmds_:cp(targetfile_lib, path.join(libdir, path.filename(targetfile_lib)))
+ if target:is_plat("windows", "mingw") and target:is_shared() then
+ local targetfile = target:targetfile()
+ local targetfile_lib = path.join(target:implibdir(), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))
+ if os.isfile(targetfile_lib) then
+ batchcmds_:mkdir(libdir)
+ batchcmds_:cp(targetfile_lib, path.join(libdir, path.filename(targetfile_lib)))
+ end
end
_install_target_headers(target, batchcmds_, opt)