[Scons-dev] Something looks wrong to me in Node.changed(). Your opinion?

alexandre.feblot at gmail.com alexandre.feblot at gmail.com
Sun Sep 15 09:30:25 EDT 2013


Hi list,

I'm a new joiner here and have ben using Scons since about a year on a quite large project (around 15 billion code lines).

I was investigating a Scons 2.3.0 regression caused by the added support of versioned libraries ( http://scons.tigris.org/issues/show_bug.cgi?id=2903 ), and while I found the issue and the right way to retrieve the 2.2 behavior (I'll submit a pull request for it), I still have the feeling something is missing even in Scons 2.2, and that's where I'd like your opinion:

Basically, the Node.changed() method does not take into account names of a node dependencies, but only its number of dependencies, their timestamps, md5 and sizes, and its build function/string signature.

Let's show it on a small example: I build libmyshared.so against liba.so or libb.so

SharedLibrary("myshared", ["main.c"], LIBS = ["a"], LIBPATH=["."])
scons -> builds libmyshared.so against liba.so
I modify the SConstruct:
SharedLibrary("myshared", ["main.c"], LIBS = ["b"], LIBPATH=["."])
scons -> builds libmyshared.so against libb.so

Here, libmyshread.so is rebuilt because:
1) the build command has changed (gcc -la --> gcc -lb)
2) "some dependency changes" have been detected based on timestamp or md5.

Now, let's trigger the issue:

1) I hack the default SharedLib builder in SCons/Tool/__init__.py in order to set a build command which does not change when LIBS changes:
action_list = [ SCons.Defaults.SharedCheck, SCons.Defaults.Touch("$TARGET") ]
shared_lib = SCons.Builder.Builder(action = action_list, ..... snip..... )
env['BUILDERS']['SharedLibrary'] = shared_lib
2) I manage so that liba.so and libb.so have the same md5 and the same timestamp (i.e. also not rely on soname to detect if a shared lib is different)

SharedLibrary("myshared", ["main.c"], LIBS = ["a"], LIBPATH=["."])
scons -> builds libmyshared.so against liba.so
I modify the SConstruct:
SharedLibrary("myshared", ["main.c"], LIBS = ["b"], LIBPATH=["."])
scons -> nothing is rebuilt, libmyshared is considered up to date.

Here, nothing is rebuilt because Node.changed()
1) finds the same number of dependencies: 2 (main.os and liba.so/libb.so)
2) decides (wrongly) libb.so has not changed because the recorded dependency in the previous build had the same timestamp and md5, although its name was different. But the name doesn't seem to be recorded, as prev_ni only has csig, timestamp, and size attributes.
3) decides the command line signature has not changed

While is general, building with 2 differently named files having the exact same content would produce the same result, this is wrong when building a shared lib which records the names of the libs it depends on.

Do you agree the behavior is wrong?
If you do, do you see an easy way to fix it, as dependency names are not available in prev_ni (other than relying on the command signature)? Or do you think this use case is too special to deserve being fixed (a real use case would be creating a shared lib builder which would store all lib dependencies in a file and pass that file to the linker, I guess) ?

Thanks

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://two.pairlist.net/pipermail/scons-dev/attachments/20130915/ed53bc72/attachment.html>


More information about the Scons-dev mailing list