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

_______________________________________________
Scons-dev mailing list
[email protected]
http://two.pairlist.net/mailman/listinfo/scons-dev

Reply via email to