in Sharpmake/Builder.cs [999:1142]
private void LogUnusedProjectConfigurations(List<Project> projects, List<Solution> solutions)
{
Trace.Assert(_usedProjectConfigurations != null);
foreach (Project p in projects)
{
if (p.SharpmakeProjectType == Project.ProjectTypeAttribute.Export)
continue;
var dic = new Dictionary<FieldInfo, DiagHelper>();
List<ITarget> uselessTargets = null;
var debugList = new List<string>();
bool foundUnusedConfInProject = false;
foreach (var conf in p.Configurations)
{
bool confWasUsed = _usedProjectConfigurations.Contains(conf);
var target = conf.Target;
if (!confWasUsed)
{
foundUnusedConfInProject = true;
debugList.ForEach(d => LogWriteLine(d));
LogWriteLine(conf.Project.SharpmakeCsFileName + ": Config not used during generation: " + conf.Owner.GetType().ToNiceTypeName() + ":" + conf.Target);
if (uselessTargets == null)
uselessTargets = new List<ITarget>(p.Configurations.Count);
uselessTargets.Add(target);
}
else if (s_logUsedConfigurations)
{
if (!foundUnusedConfInProject)
debugList.Add(conf.Project.SharpmakeCsFileName + ": Config WAS used during generation: " + conf.Owner.GetType().ToNiceTypeName() + ":" + conf.Target);
else
LogWriteLine(conf.Project.SharpmakeCsFileName + ": Config WAS used during generation: " + conf.Owner.GetType().ToNiceTypeName() + ":" + conf.Target);
}
FieldInfo[] fragmentFields = target.GetFragmentFieldInfo();
int[] fragmentValues = new int[fragmentFields.Length];
for (int i = 0; i < fragmentValues.Length; ++i)
{
FieldInfo fieldInfo = fragmentFields[i];
int fragmentValue = (int)fieldInfo.GetValue(target);
if (!dic.ContainsKey(fieldInfo))
dic[fieldInfo] = new DiagHelper(fieldInfo);
if (confWasUsed)
dic[fieldInfo].AddUsedConf(fragmentValue, conf);
else
dic[fieldInfo].AddUnusedConf(fragmentValue, conf);
}
}
if (uselessTargets != null && uselessTargets.Count > 1)
{
foreach (var tuple in dic)
{
var fieldInfo = tuple.Key;
var diagHelper = tuple.Value;
diagHelper.LogAllFragmentValuesThatAreAllUnused();
}
List<ITarget> mergeCandidateTargets = uselessTargets;
List<ITarget> doneTargets = new List<ITarget>(uselessTargets.Count);
int currentDepth = 0;
while (mergeCandidateTargets.Count > 0)
{
ITarget previousTarget = null;
int[] previousFragmentValues = null;
int previousDiffIndex = -1;
List<ITarget> nextMergeCandidateTargets = new List<ITarget>(mergeCandidateTargets.Count);
foreach (var target in mergeCandidateTargets)
{
int[] fragmentValues = target.GetFragmentsValue();
if (previousTarget == null)
{
previousTarget = target;
previousFragmentValues = fragmentValues;
continue;
}
int firstDiffIndex = -1;
for (int i = 0; i < fragmentValues.Length; ++i)
{
if (fragmentValues[i] != previousFragmentValues[i])
{
if (firstDiffIndex == -1)
firstDiffIndex = i;
else
{
firstDiffIndex = -1;
break; // can't accept more than one difference
}
}
}
if (firstDiffIndex != -1)
{
ITarget mergedTarget = target.Clone();
previousFragmentValues[firstDiffIndex] = fragmentValues[firstDiffIndex] | previousFragmentValues[firstDiffIndex];
mergedTarget.GetFragmentFieldInfo()[firstDiffIndex].SetValue(mergedTarget, previousFragmentValues[firstDiffIndex]);
previousTarget = mergedTarget;
previousDiffIndex = firstDiffIndex;
continue;
}
if (previousDiffIndex != -1)
{
nextMergeCandidateTargets.Add(previousTarget);
previousDiffIndex = -1;
}
else
{
doneTargets.Add(previousTarget);
}
previousTarget = target;
previousFragmentValues = fragmentValues;
}
if (previousDiffIndex != -1)
{
nextMergeCandidateTargets.Add(previousTarget);
}
else
{
doneTargets.Add(previousTarget);
}
mergeCandidateTargets = nextMergeCandidateTargets;
++currentDepth;
}
if (doneTargets.Count < uselessTargets.Count)
{
LogWarningLine("Previously mentioned useless Configs in compact format:");
foreach (ITarget target in doneTargets)
{
LogWarningLine("Target: " + target.ToString().Replace(", ", "|"));
}
}
}
}
}