[Scons-users] SCons fails to create symlinks (SHLIBVERSION)

Mats Wichmann mats at wichmann.us
Fri Feb 23 10:58:29 EST 2024


On 2/22/24 23:01, Cristian Farcas via Scons-users wrote:
> It works after I cleaned the old lib, built without SHLIBVERSION. Thanks!
> 
> It’s really ugly to switch from normal to versioned lib. I cannot 
> request the whole team to do a clean everytime they checkout over my 
> commit. So I have to ensure at each build that libabc.so is deleted if 
> it’s not a symlink. Also, when increasing the version, untracked old 
> version libs remain on the disk. These require special deletion as well...

This situation arises due to the design of SCons, for better or for 
worse: when it starts up, it reads the build configuration from the 
sconscripts, constructs the dependency graph, and then makes decisions 
from that.  At this point it doesn't know anything about what that graph 
may have looked like before.  There may be saved information in the 
signature database from the previous run, but (a) it's not consulted for 
nodes not in the current tree (and will simply be lost next time the 
database is updated - that is, when *this* run finishes) and (b) there's 
no filetype information, so it can't detect changes (like "used to be a 
dir, now a file"; "used to be a file, now a symlink", etc.).

Case (a) applies if you change the version:  if the library name 
previously was libfoo.so.3 and now it's libfoo.so.4 then the former will 
be unknown this time, and won't even be picked up by a "clean". But at 
least the fresh build should work, you'll just be left with that 
dangling build artifact from earlier.

Case (b) is the one from your original posting: libfoo.so was the target 
library before, now it's libfoo.3, because the "base" library always 
includes the version if it's defined. This goes wrong because the shared 
library logic sees it should make a symbolic link (or two if you had a 
dot in the version specifier), but because the existing file by that 
name isn't a symlink it just leaves it alone - this is commented as a 
safety measure in the code, whether or not that's well considered - and 
then the actual link operation fails.  At least in this case since the 
symlink will be a tracked target, it will be removed on a clean and you 
can then recover by rebuilding.

This is the aforementioned safety rail in the code:

         # Delete the (previously created) symlink if exists. Let only 
symlinks
         # to be deleted to prevent accidental deletion of source 
files...
         if env.fs.islink(link): 

             env.fs.unlink(link)


Don't know what to tell you about mitigations... you've pretty much 
listed the obvious ones, which is to provide some cleanup code (perhaps 
in site_scons?) when you know you've made a structural change. Maybe 
someone else listening here has some better suggestions - I know there 
are some experts particularly on the shared libs topics.


More information about the Scons-users mailing list