In any event, a key to successful automation here is to have other best practices in place that ensure peer reviews of each update and unit testing of each update (by the developer) is done before the developer signals that the update is "ready". Your CM Plan must mandate these (and/or other) quality assurance practices before code reaches the Build Team.
Given that you have identified what will go into the build, any half-decent CM tool should allow you to retrieve exactly that source code in a simple operation. If it doesn't, you're going to have quality problems. One note here, except for builds done in a developer's own workspace, never copy files into the "build" directory (or tree) - always retrieve them using an automated process from the repository. It doesn't matter if you retrieve all of them or just an incremental set, as long as the process for doing so is automated. If the process has errors, correct the process, not the result.
Generally "make" files or similar build directions are used both to run the build operation and to package up the deliverables. These are process description files - they say how to operate on the files retreived for the build operation. In some cases, these files can be automatically generated from the CM and/or IDE tools - a great feature as they are typically complex in format and semantics.
So many projects start out as a one of, and then split off into dozens, if not hundreds, of variants of a product. Managing large numbers of baselines, builds, etc. is not only tedious and resource intensive, but it's risky. Sooner or later you're going to reach a point where you cannot cope. I've seen it more than often enough.
Your CM Plan has to specify Design Criteria which will make CM manageable. CM does not solve software engineering problems - it helps you to identify them, and variant handling is one area where software engineering needs to take the lead.
It is not at all difficult to avoid dozens of variants. In fact, it's actually easier than not doing so. But it needs some simple rules up front. A variant will not be a build time variant, or a load time variant, if it can be a run-time variant. You need Big, Medium and Small sizes - you can create separate images that support each of these. But you can just as easily add a requirement to the design team that says, the size will be configured at run time by setting a Size parameter. Similary for language, optional components, etc. There will be a run-time parameter governing each of these.
Your CM Plan must explicitly state this - because it's not going to get stated otherwise. And presto, all of the software design steps have this as a requirements and so instead of allocating a fixed number of resources, they make the allocation parameter a variable that can be adjusted prior to the resources being allocated. That was easy. It may help to have someone work on a user interface or database table that tracks and manages system parameters. But other than that, most of your variant problems are solved. There's still one, for the moment (but not too much longer) that's hard to get around - different builds for different platforms. One day this will disappear into a run-time switch as well (and Java is just one approach to this).
Your CM Plan should specify a number of levels of testing. Some might have more levels than others,