[Scons-users] Per target env variables

Jonathon Reinhart jonathon.reinhart at gmail.com
Thu Sep 6 12:30:07 EDT 2018


Hi Bill,

I've responded inline:

> Why so many clones? Are the environment's being modified?

Sometimes we clone out of safety (see blow), and sometimes we clone
out of necessity.

In the case of Pseudo-builders, we had some (arguably poorly-written)
that would first Clone the environment, and then make target-specific
modifications to it. These would be better off as overrides when
calling lower-level builders (e.g. env.Object). But sometimes the
changes apply to multiple sub-builders, so it made more sense to
modify the environment. Hence the reason that oenv = env.Override()
works so well here.

> Are you seeing that the # of clones is actually causing you issues?

Hard to say. There's a pretty long delay before SCons starts building,
and we're continuously seeking to improve that.

> Are you Clone'ing as a form of write protection on the original env?

Yes, we tend to follow this pattern for safety:

    env.SConscript(
       dirs = 'somechild',
       variant_dir = '$BUILD_DIR/somechild',
       duplicate = False,
       exports = dict(env = env.Clone()),
    )

> How many objects does "--debug=count" output for your build?

Object counts:
       pre-   post-    pre-   post-
       read   read    build   build   Class
          0   1745     1745   32256   Action.CommandAction
          0     53       53      53   Action.CommandGeneratorAction
          0    185      185     185   Action.FunctionAction
          0    117      117     117   Action.LazyAction
          0    107      107     107   Action.ListAction
          0   1505     1505    1505   Builder.BuilderBase
          0     43       43      43   Builder.CompositeBuilder
          0   6343     6343    6343   Builder.OverrideWarner
          0      7        7       7   Environment.Base
          0   2177     2177    2177   Environment.EnvironmentClone
          0   1666     1666   17571   Environment.OverrideEnvironment
          0  17869    17869   18825   Executor.Executor
          0      8        8   12220   Executor.Null
          0  29711    29711   32204   Node.FS.Base
          0   4254     4254    5100   Node.FS.Dir
          0  12621    12621   13353   Node.FS.File
          0  29843    29843   32336   Node.Node

> There are supported ways to create override environments.

Not ones that you can have a reference to, for the purpose of calling
multiple builders upon.

> Once again, unless you are creating large # of Environment's via Clone(), it's unlikely this is really a performance issue.

I have a colleague that once tested this. Sorry I don't have access to
the code right now, but it basically created about 1000 clones. I do
have these numbers we noted:

Full build:
  Without clone: 1m 9s
  With clone: 2m 11s

With -n (dry-run) and >/dev/null:
  Without clone: 14.1s
  With clone: 17.5s  (+3.4s)

Only invoking SConscript: no actual building
  Without clone: 2.3s
  With clone: 4.7s  (+2.4s)

No Sonscript invocation:
  Without clone: 0.4s
  With clone: 2.6s  (+2.2s)

With SConscript call but without env.Program() call (not actually
building anything):
  env = OverrideEnvironment(local_env); env.Append(COUNTER=counter):    2.05s  *
  env.Clone(COUNTER=counter):
                      4.80s  (+2.75s)

[*] I realize that this test was wrong -- you can't Append() to an
OverrideEnvironment without modifying the original env.


> That said a lighter weight copy on write and/or read-only Clone could be a useful addition.

I agree. Being able to simply call one efficient API would be ideal.


More information about the Scons-users mailing list