lewissbaker/cake

Allow building a subset of individual targets defined in a build script

lewissbaker opened this issue · 2 comments

Sometimes you will have a build script that builds an entire library potentially consisting of many source files. In addition it might also be a shared library (DLL) that requires linking with other libraries built in other build scripts. In the case of a top-level program build script it might end up building every source file.

Currently if you ask Cake to build a build script it builds everything in that build script and recursively builds everything required to build those things.

What would be nice is having a way to specify that you only want to build a certain target within a build script rather than having it implicitly build everything in that script. eg. only build an individual source file within a library or build all object files but skip any link step that might require building other libraries.

Imagine extending the command-line to allow specifying an optional list of target names after each build script. eg.

$ cake src/build.cake:foo.obj    # Just build foo.obj
$ cake src/build.cake:foo.obj,bar.obj,baz.obj    # Build multiple named targets

Build scripts (or tools called by build scripts) could register named targets with the current root script using an API that looks something like the following:

from cake.tools import script, sometool

# Tool may automatically register the returned target under the name 'sometarget'.
someTarget = sometool.build(target='sometarget')

# Script could manually register the target under a different name
script.addTarget('anothername', someTarget)

Build scripts could refer to named targets from other build scripts to indicate some dependency or to republish the other build script's targets under a name in the current build script.

from cake.tools import script

otherScript = script.get(script.cwd('other.cake')

# Get a reference to a named target from another script.
# Note this would not cause other.cake to be executed unless the returned target
# was used by something.
otherObjects = otherScript.getTarget('objects')

# Could republish the other script's named targets as our own so that when
# this script is asked to build 'objects' it would result in building 'objects'
# target from other.cake.
script.addTarget('objects', otherObjects)

In terms of implementation, we'd need to introduce the concept of a lazy task or lazy target so that a script can execute, define how to build a bunch of targets but not actually build any of them unless those targets have been requested to be built.

If the user just asks for a build script to be built without specifying a named target (as is currently supported) then the behaviour should be as per the current behaviour. ie. build all targets defined in that build script.

Some groundwork towards this has been added in 2b8580d which added support for lazy-tasks.

Main outstanding work is updating the command-line arg parsing to support specifying named targets of a script from the command-line. eg. to allow something like "cake path/to/build.cake@target1,target2"

Support for specifying named targets on command-line is implented in 1240b6d

Also added -l and --list-targets option for listing named targets defined in the scripts specified on command-line.