summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-08-21 00:46:07 +0800
committerruki <[email protected]>2021-08-21 00:46:07 +0800
commita226ce07d85f3aab66b6dacf6f91e85f7296a490 (patch)
tree7aead5aa3cccab016e06175eddf040fb40b7de89
parentc95fdc3f443b3dee83708b42bc34383a47601e13 (diff)
improve to copy symlink for installation
-rw-r--r--CHANGELOG.md2
-rw-r--r--xmake/core/base/os.lua24
-rw-r--r--xmake/modules/target/action/install/unix.lua12
3 files changed, 29 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0967c52e5..1f1ffbd65 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
* [#1540](https://github.com/xmake-io/xmake/issues/1540): Better support for compilation of automatically generated code
* [#1578](https://github.com/xmake-io/xmake/issues/1578): Improve add_repositories to support relative path better
+* [#1582](https://github.com/xmake-io/xmake/issues/1582): Improve installation and os.cp to reserve symlink
### Bugs fixed
@@ -1067,6 +1068,7 @@
* [#1540](https://github.com/xmake-io/xmake/issues/1540): 更好更方便地编译自动生成的代码
* [#1578](https://github.com/xmake-io/xmake/issues/1578): 改进 add_repositories 去更好地支持相对路径
+* [#1582](https://github.com/xmake-io/xmake/issues/1582): 改进安装和 os.cp 支持符号链接
### Bugs 修复
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index e9f403d92..ea913b977 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -49,7 +49,7 @@ os.SYSERR_NOT_PERM = 1
os.SYSERR_NOT_FILEDIR = 2
-- copy single file or directory
-function os._cp(src, dst, rootdir)
+function os._cp(src, dst, rootdir, opt)
-- check
assert(src and dst)
@@ -65,7 +65,7 @@ function os._cp(src, dst, rootdir)
end
-- is file?
- if os.isfile(src) then
+ if os.isfile(src) or os.islink(src) then
-- the destination is directory? append the filename
if os.isdir(dst) or path.islastsep(dst) then
@@ -76,9 +76,17 @@ function os._cp(src, dst, rootdir)
end
end
- -- copy file
- if not os.cpfile(src, dst) then
- return false, string.format("cannot copy file %s to %s, %s", src, dst, os.strerror())
+ -- link file if reserve symlink
+ if opt and opt.symlink and os.islink(src) then
+ local reallink = os.readlink(src)
+ if not os.link(reallink, dst) then
+ return false, string.format("cannot link %s(%s) to %s, %s", src, reallink, dst, os.strerror())
+ end
+ else
+ -- copy file
+ if not os.cpfile(src, dst) then
+ return false, string.format("cannot copy file %s to %s, %s", src, dst, os.strerror())
+ end
end
-- is directory?
elseif os.isdir(src) then
@@ -386,7 +394,7 @@ function os.filedirs(pattern, callback)
end
-- copy files or directories and we can reserve the source directory structure
--- e.g. os.cp("src/**.h", "/tmp/", {rootdir = "src"})
+-- e.g. os.cp("src/**.h", "/tmp/", {rootdir = "src", symlink = true})
function os.cp(srcpath, dstpath, opt)
-- check arguments
@@ -405,10 +413,10 @@ function os.cp(srcpath, dstpath, opt)
-- copy files or directories
local srcpathes = os._match_wildcard_pathes(srcpath)
if type(srcpathes) == "string" then
- return os._cp(srcpathes, dstpath, rootdir)
+ return os._cp(srcpathes, dstpath, rootdir, opt)
else
for _, _srcpath in ipairs(srcpathes) do
- local ok, errors = os._cp(_srcpath, dstpath, rootdir)
+ local ok, errors = os._cp(_srcpath, dstpath, rootdir, opt)
if not ok then
return false, errors
end
diff --git a/xmake/modules/target/action/install/unix.lua b/xmake/modules/target/action/install/unix.lua
index bd2a1cdb1..2f55dbd3b 100644
--- a/xmake/modules/target/action/install/unix.lua
+++ b/xmake/modules/target/action/install/unix.lua
@@ -43,7 +43,17 @@ function _install_shared_for_package(target, pkg, outputdir)
if os.isfile(path.join(outputdir, soname)) then
wprint("'%s' already exists in install dir, overwriting it from package(%s).", soname, pkg:name())
end
- os.vcp(sopath, outputdir)
+ -- we need reserve symlink
+ -- @see https://github.com/xmake-io/xmake/issues/1582
+ os.vcp(sopath, outputdir, {symlink = true})
+ -- copy real file of symlink
+ if os.islink(sopath) then
+ local realpath = os.readlink(sopath)
+ if not path.is_absolute(realpath) then
+ realpath = path.absolute(realpath, path.directory(sopath))
+ end
+ os.vcp(realpath, outputdir)
+ end
end
end
end