Re: finding out which env causes this error: Two different environments were specified for target
Dominic Binks <[email protected]>
| Newsgroups | gmane.comp.programming.tools.scons.user |
|---|---|
| Message-ID | <[email protected]> |
Hi Dagg On 27/03/2022 08:58, daggs wrote: > Greetings Dominic, > >> Sent: Friday, March 25, 2022 at 9:18 PM >> From: "Dominic Binks" <[email protected]> >> To: [email protected] >> Cc: [email protected] >> Subject: Re: [Scons-users] finding out which env causes this error: Two different environments were specified for target >> >> Hi Dagg, >> >> I've found the biggest problem with this issue is trying to find out >> where the duplication is arriving from. >> >> To this end, I've created a small function: >> >> def check_for_problem_file(env, scons_nodes, needle_re): >> nodes = env.Flatten([scons_nodes]) >> for n in nodes: >> if re.match(needle_re, str(n)): >> print("Filename match {} against {}".format(n, needle_re)) >> print_stack() >> >> needle_re is a regular expression and a stack trace is printed whenever >> the regular expression matches the name of a file that is passed in via >> the scons_nodes. >> >> The other part to this is to have a replacement for the function that >> seems to be giving rise to the duplicate entries. You've identified >> that InstallAs does this, so if you wrap the real InstallAs inside a >> MyInstallAs method, then you can call check_for_problem_file with the >> name of the file that is seeing the duplicate environment to figure out >> where the two environments are originating from. >> >> It's then not too difficult (usually) to eliminate the duplication. >> >> While it's a bit crude, it's proved quite good at helping to eliminate >> (most) of our duplicate environment warnings. >> >> Dominic > > I've tried your func, the trace shows only one SConscript, the problematic on. > should I put it in all SConscript files called in the tree? > > Dagg. This will depend a little on your layout of SConstruct/SConscript, or rather more environments. You don't need this function in every SConscript, you need to make sure the MyInstallAs method is present in every environment. You said your sconscript was something like this: for folder in [ a, b, c ]: for modes in [ y. z ]: export('mode') sconscript("src/" + folder + "/SConscript", variant_dir = "out/" + folder + "." + mode, duplicate = 0. export('env')) If, earlier in that file, you include check_for_problem_file() and then add def MyInstallAs(env, *nargs, **kwargs): objs = env.InstallAs(*nargs, **kwargs) check_for_problem_file(env, objs, "duplicate-env-warning-file-name") return objs env.AddMethod(MyInstallAs, "MyInstallAs") Then, as long as you don't create new environments from scratch in the sub sconscripts MyInstallAs will report each time the filename matching the regex is amongst the generated files. If you add the InstallAs method as say "RealInstallAs" like this: env["BUILDERS"]["RealInstallAs"] = env["BUILDERS"]["InstallAs"] then you can override InstallAs with MyInstallAs and call RealInstallAs in the MyInstallAs method which wiil ensure that every call to InstallAs gets checked, which may be helpful is you've got a lot of InstallAs targets. That'd look something like this: env["BUILDERS"]["RealInstalAs"] = env["BUILDERS"]["InstallAs"] def MyInstallAs(env, *nargs, **kwargs): objs = env.RealInstallAs(*nargs, **kwargs) check_for_problem_file(env, objs, "duplicate-env-warning-file-name") return objs # You may need to check this, I'm doing it from memory and I may have # misremembered something about this. env["BUILDERS"]["InstallAs"] = SCons.Builder.Builder(action=MyInstallAs) I don't think you can use AddMethod because I don't think it will replace the existing InstallAs. Hope this helps. Dominic