lionelmessi
lionelmessi

Reputation: 1144

Skip folders to build using scons after full build

I have large number of source files ~10,000 and they are scattered across several folders.

I wanted to know if there is a way to skip certain folders, I know that havent changed.

For ex, consider the following folder structure

A (Sconstruct is here)
|
->B (unchanged 1000 files)
->C (unchanged 1000 files)
->D (changed 1 file)

Once I do a complete build for the first time, I want it to compile everything (B, C, D) but when I modify a file in D (I know that), I would like to build folder D only, skip B and C and finally link them all together to form the final binary (B, C and new D).

I have been looking for quite some time now but not able to figure it out. Is it even possible? Can I specify only to look into a particular folder for changes?

Upvotes: 0

Views: 555

Answers (2)

Robᵩ
Robᵩ

Reputation: 168876

First, I'd investigate using Decider('timestamp-match') or even building a custom Decider function. That should speed up your dependency-checking time.

But to answer your specific question, yes it is possible to not build the targets in B and C. If you don't invoke a builder for the targets in those subdirectories, you just won't build them. Just have an if that selectively chooses which env.Object() (or similar) functions to invoke.

When I fleshed out your example, I chose to have each subdirectory create a library that would be linked into the main executable, and to only invoke env.SConscript() for the directories that the user chooses. Here is one way to implement that:

A/SConstruct:

subdirs = ['B','C','D']
AddOption('--exclude', default=[], action='append', choices=subdirs)
env = Environment(EXCLUDES = GetOption('exclude'))

env.SConscript(
    dirs=[subdir for subdir in subdirs
          if subdir not in env['EXCLUDES']],
    exports='env')

env2 = env.Clone()
env2.PrependUnique(LIBPATH=subdirs,
                   LIBS=subdirs)
env2.Program('main.c')

B/SConscript:

Import('env')
env.Library('B', env.Glob('*.c'))

C/SConscript:

Import('env')
env.Library('C', env.Glob('*.c'))

D/SConscript:

Import('env')
env.Library('D', env.Glob('*.c'))

To do a global build: scons

To do a build after modifying a single file in D: scons --exclude=B --exclude=C

EDIT

Similarly, you can add a whitelist option to your SConstruct. The idea is the same: only invoke builders for certain objects.

Here is a SConstruct similar to above, but with a whitelist option:

subdirs = ['B','C','D']
AddOption('--only', default=[], action='append', choices=subdirs)
env = Environment(ONLY = GetOption('only') or subdirs)

env.SConscript(
    dirs=env['ONLY'],
    exports='env')

env2 = env.Clone()
env2.PrependUnique(LIBPATH=subdirs,
                   LIBS=subdirs)
env2.Program('main.c')

To build everything: scons

To rebuild D and relink main program: scons --only=D

Upvotes: 1

dirkbaechle
dirkbaechle

Reputation: 4052

If D is independent of B and C just specify your target in D (program/library), or the whole directory, as target explicitly on the command line like scons D/myprog.exe. SCons will expand the required dependencies automatically, and such doesn't traverse the unrelated folders B and C.

Note how you can specify an arbitrary number of targets, so

scons D/myprog.exe B

is allowed too.

Upvotes: 0

Related Questions