// determine the eventual linker configuration
// (may be null) and collect any explicit
// object files or libraries
Vector<File> objectFiles = new Vector<File>();
Vector<File> sysObjectFiles = new Vector<File>();
LinkerConfiguration linkerConfig = collectExplicitObjectFiles(
objectFiles, sysObjectFiles, versionInfo);
//
// Assemble hashtable of all files
// that we know how to compile (keyed by output file name)
//
Map<String, TargetInfo> targets = getTargets(linkerConfig, objectFiles, versionInfo, _outfile);
TargetInfo linkTarget = null;
//
// if output file is not specified,
// then skip link step
//
if (_outfile != null) {
linkTarget = getLinkTarget(linkerConfig, objectFiles,
sysObjectFiles, targets, versionInfo);
}
if (projects.size() > 0) {
List<File> files = new ArrayList<File>();
ProjectFileCollector matcher = new ProjectFileCollector(files);
for (int i = 0; i < _compilers.size(); i++) {
CompilerDef currentCompilerDef = (CompilerDef) _compilers
.elementAt(i);
if (currentCompilerDef.isActive()) {
if (currentCompilerDef.hasFileSets()) {
currentCompilerDef.visitFiles(matcher);
}
}
}
compilerDef.visitFiles(matcher);
Enumeration<ProjectDef> iter = projects.elements();
while (iter.hasMoreElements()) {
ProjectDef projectDef = iter.nextElement();
if (projectDef.isActive()) {
projectDef.execute(this, files, targets, linkTarget);
}
}
}
if (projectsOnly) return;
//
// mark targets that don't have a history record or
// whose source last modification time is not
// the same as the history to be rebuilt
//
objHistory.markForRebuild(targets);
CCTaskProgressMonitor monitor = new CCTaskProgressMonitor(objHistory, versionInfo);
//
// check for changed include files
//
int rebuildCount = checkForChangedIncludeFiles(targets);
if (rebuildCount > 0) {
BuildException compileException = null;
//
// compile all targets with getRebuild() == true
//
Map<ProcessorConfiguration, Vector<TargetInfo>> targetsByConfig =
getTargetsToBuildByConfiguration(targets);
//
// build array containing Vectors with precompiled generation
// steps going first
//
Vector<TargetInfo>[] targetVectors = new Vector[targetsByConfig.size()];
int index = 0;
Iterator<Vector<TargetInfo>> targetVectorEnum = targetsByConfig.values().iterator();
while (targetVectorEnum.hasNext()) {
Vector<TargetInfo> targetsForConfig = targetVectorEnum.next();
//
// get the configuration from the first entry
//
CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig
.elementAt(0)).getConfiguration();
if (config.isPrecompileGeneration()) {
targetVectors[index++] = targetsForConfig;
}
}
targetVectorEnum = targetsByConfig.values().iterator();
while (targetVectorEnum.hasNext()) {
Vector<TargetInfo> targetsForConfig = targetVectorEnum.next();
for (int i = 0; i < targetVectors.length; i++) {
if (targetVectors[i] == targetsForConfig) {
break;
}
if (targetVectors[i] == null) {
targetVectors[i] = targetsForConfig;
break;
}
}
}
// BEGINFREEHEP
Progress progress = new Progress(getObjdir(), rebuildCount);
progress.start();
// ENDFREEHEP
for (int i = 0; i < targetVectors.length; i++) {
//
// get the targets for this configuration
//
Vector<TargetInfo> targetsForConfig = targetVectors[i];
//
// get the configuration from the first entry
//
CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig
.elementAt(0)).getConfiguration();
//
// prepare the list of source files
//
// BEGINFREEHEP
int noOfCores = Runtime.getRuntime().availableProcessors();
log("Found "+noOfCores+" processors available");
if (maxCores > 0) {
noOfCores = Math.min(maxCores, noOfCores);
log("Limited processors to "+noOfCores);
}
int noOfFiles = targetsForConfig.size();
if (noOfFiles < noOfCores) {
noOfCores = noOfFiles;
log("Limited used processors to "+noOfCores);
}
if (ordered) {
noOfCores = 1;
log("Limited processors to 1 due to ordering of source files");
}
List<String>[] sourceFiles = new List[noOfCores];
for (int j = 0; j < sourceFiles.length; j++) {
sourceFiles[j] = new ArrayList<String>(noOfFiles / sourceFiles.length);
}
Enumeration<TargetInfo> targetsEnum = targetsForConfig.elements();
index = 0;
while (targetsEnum.hasMoreElements()) {
TargetInfo targetInfo = targetsEnum.nextElement();
sourceFiles[index++].add(targetInfo.getSources()[0]
.toString());
index %= sourceFiles.length;
}
// setup cores/cpus
Core[] cores = new Core[noOfCores];
for (int j = 0; j < cores.length; j++) {
cores[j] = new Core(this, j, config, _objDir, sourceFiles[j],
relentless, monitor);
log("\nStarting Core " + j + " with "
+ sourceFiles[j].size() + " source files...");
}
// starting cores
for (int j = 0; j < cores.length; j++) {
cores[j].start();
}
// checking cores
boolean alive = false;
try {
do {
alive = false;
for (int j = 0; j < cores.length; j++) {
if (cores[j] != null) {
if (cores[j].isAlive()) {
alive = true;
} else {
Exception exception = cores[j].getException();
if (exception != null) {
if ((compileException == null) && (exception instanceof BuildException)) {
compileException = (BuildException)exception;
} else {
log(cores[j].getName()+" "+exception+" ", Project.MSG_ERR);
}
if (!relentless) {
cores[j] = null;
alive = false;
break;
}
}
cores[j] = null;
}
}
}
if (alive) {
// wait for a maximum of 5 seconds or #files*2 seconds.
Thread.sleep(Math.min(5000, sourceFiles[0].size()*2000));
}
} while (alive);
} catch (InterruptedException e) {
break;
}
// killing leftovers
for (int j = 0; j < cores.length; j++) {
if (cores[j] != null) {
cores[j].interrupt();
log(cores[j].getName()+" interrupted ");
}
}
if ((!relentless) && (compileException != null)) {
break;
}
// ENDFREEHEP
/* OLD CODE
String[] sourceFiles = new String[targetsForConfig.size()];
Enumeration targetsEnum = targetsForConfig.elements();
index = 0;
while (targetsEnum.hasMoreElements()) {
TargetInfo targetInfo = ((TargetInfo) targetsEnum
.nextElement());
sourceFiles[index++] = targetInfo.getSources()[0]
.toString();
}
try {
config.compile(this, _objDir, sourceFiles, relentless,
monitor);
} catch (BuildException ex) {
if (compileException == null) {
compileException = ex;
}
if (!relentless)
break;
}
*/
}
// BEGINFREEHEP
progress.exit();
try {
progress.join();
} catch (InterruptedException ex) {
}
// ENDFREEHEP
//
// save the details of the object file compilation
// settings to disk for dependency analysis
//
try {
objHistory.commit();
} catch (IOException ex) {
this.log("Error writing history.xml: " + ex.toString());
}
//
// if we threw a compile exception and
// didn't throw it at the time because
// we were relentless then
// save the history and
// throw the exception
//
if (compileException != null) {
if (failOnError) {
throw compileException;
} else {
log(compileException.getMessage(), Project.MSG_ERR);
return;
}
}
}
//
// if the dependency tree was not fully
// evaluated, then throw an exception
// since we really didn't do what we
// should have done
//
//
if (dependencyDepth >= 0) {
throw new BuildException(
"All files at depth "
+ Integer.toString(dependencyDepth)
+ " from changes successfully compiled.\n"
+ "Remove or change dependencyDepth to -1 to perform full compilation.");
}
//
// if no link target then
// commit the history for the object files
// and leave the task
if (linkTarget != null) {
//
// get the history for the link target (may be the same
// as the object history)
TargetHistoryTable linkHistory = getLinkHistory(objHistory);
//
// see if it needs to be rebuilt
//
linkHistory.markForRebuild(linkTarget);
//
// if it needs to be rebuilt, rebuild it
//
File output = linkTarget.getOutput();
if (linkTarget.getRebuild()) {
LinkerConfiguration linkConfig = (LinkerConfiguration) linkTarget
.getConfiguration();
// BEGINFREEHEP
log("Linking...");
log("Starting link {" + linkConfig.getIdentifier() + "}");
// ENDFREEHEP
if (failOnError) {
linkConfig.link(this, linkTarget);
} else {
try {
linkConfig.link(this, linkTarget);
} catch(BuildException ex) {
log(ex.getMessage(), Project.MSG_ERR);
return;
}
}