diff options
| author | SineStriker <[email protected]> | 2025-04-18 23:29:50 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-04-23 11:30:30 +0800 |
| commit | 6551ed38c1250c0c41eada6db14f8601bf3ddb64 (patch) | |
| tree | f8e7525fc8bc74b54f077c82148c0ae79df35d87 | |
| parent | a5c510f35e861b0ff71a2af0781359bc881ea3af (diff) | |
Support customizing `implib` path of MinGW/MSVC
| -rw-r--r-- | xmake/actions/package/oldpkg/main.lua | 18 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 20 | ||||
| -rw-r--r-- | xmake/modules/core/tools/gcc.lua | 14 | ||||
| -rw-r--r-- | xmake/modules/core/tools/link.lua | 8 | ||||
| -rw-r--r-- | xmake/modules/core/tools/nvcc.lua | 18 | ||||
| -rw-r--r-- | xmake/modules/target/action/clean/main.lua | 19 | ||||
| -rw-r--r-- | xmake/modules/target/action/install/main.lua | 4 | ||||
| -rw-r--r-- | xmake/plugins/pack/batchcmds.lua | 12 |
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) |
