Add symbolic link support to Install
This issue was originally created at: 2012-05-08 09:55:01.
This issue was reported by: mortoray.
mortoray said at 2012-05-08 09:55:01
Install should be able to copy symbolic links as symbolic links, for example:
That is, given a source directory like this:
src/library.so -> library.so.1.0.0
src/library.so.1 -> library.so.1.0.0
src/library.so.1.0.0
I need the destination directory to maintain the links as:
dst/library.so -> library.so.1.0.0
dst/library.so.1 -> library.so.1.0.0
dst/library.so.1.0.0
This can be done via an optional parameter to Install called "symLink" with the following enum options:
PreserveInTreeSymLinks
Just those at or down from the source directory.
PreserveRelativeSymLinks
Any relative sym link.
PreserveAllSymLinks
Any symlink including absolute paths.
DoNotPreserveSymLinks
mortoray said at 2012-05-08 09:56:03
The default and current behaviour would be DoNotPreserveSymLink.
wblevins001 said at 2013-08-29 12:35:14
This should probably be a defect.
As described below, this problem greatly degrades the SHLIBVERSION functionality.
wblevins001 said at 2013-08-29 13:01:46
Looks like this can be fixed by adding an install option which allows symlink support. The function already exists as part of shutil.copytree and was added to SCons as:
SCons.Tool.install:scons_copytree(src, dst, symlinks=False)
Votes for this issue: 2.
How does this relate to InstallVersionedLib?
I beleive the example was such, but the intent was it would preserve any symlinks.
Hey Matts and William! So I needed this one today.... The use case was that I'm redistributing some gcc/g++/gfortran libraries with my project and I would like to maintain these symbolic links when I install the file into my packaging area:
lrwxrwxrwx 1 dnwillia dev 19 Oct 12 11:57 libstdc++.so -> libstdc++.so.6.0.25*
lrwxrwxrwx 1 dnwillia dev 19 Oct 12 11:57 libstdc++.so.6 -> libstdc++.so.6.0.25*
-rwxr-xr-x 1 dnwillia dev 12135712 Oct 12 11:57 libstdc++.so.6.0.25*
My SCons code looks like this:
gccDir = os.path.join(conan_packages["gcc"]["LIBPATH"][0])
gccLibFiles = (
Glob(os.path.join(gccDir, "libstdc++.so*"))
+ Glob(os.path.join(gccDir, "libgcc*.so*"))
+ Glob(os.path.join(gccDir, "libgfortran.so*"))
+ Glob(os.path.join(gccDir, "libquadmath.so*"))
)
libCompilerGnu = env.Install(installDir, gccLibFiles)
Default(libCompilerGnu)
It copies perfectly, but maintaining the sym links with a flag to do that like keep_links=True would be nice.
Hmmm, the underlying functions used by Install - shutil.copy2 for individual files, and a modified copy of shutil.copytree named scons_copytree - do understand symbolic links, and have suitable keyword arguments for them. There's just no way to pass the information through, and as Install is a Builder instance (actually BuilderBase), not sure it's easy to add such. Will take a bit of thought.
Meanwhile, you might be able to use the Copy factory to do the installation - that is, calling Command with an appropriate Copy as the action, along these lines:
env.Command('bar.out', 'bar.in', Copy('$TARGET', '$SOURCE'))
Copy does take a symlinks boolean flag which says whether to try to recreate a symlink at the destination, which we helpfully don't document (sigh):
https://scons.org/doc/production/HTML/scons-man.html#miscellaneous_action_functions
The internal function that's actually used is in the API docs here:
https://scons.org/doc/production/HTML/scons-api/SCons/#SCons.Defaults.copy_func
@mwichmann - we'd likely have to add an envar, something like INSTALL_COPY_SYMLINKS or such?
The other possibility is to write an alternate copy function, and set it as env['INSTALL'] - which I had forgotten existed.
Windows-specific note for symlinks.
Creating symbolic links in Windows requires the SeCreateSymbolicLinkPrivilege privilege. By default, this is administrators.
Hardlinks (files) and junctions (directories) do not require any "special" permissions in Windows.
Windows 10 in Developer Mode may allow symbolic links to be created by a user without the privilege. Unsure about developer mode in Windows 11.
The location for creating symbolic links via the local security policy (secpol.msc) is:
Security Settings\Local Policies\User Rights Assignment\Create symbolic links.