in Sharpmake.Generators/Generic/Makefile.cs [244:369]
private string GenerateProject(
Builder builder,
Project project,
List<Project.Configuration> unsortedConfigurations,
FileInfo projectFileInfo,
out bool updated)
{
// Need to sort by name and platform
List<Project.Configuration> configurations = new List<Project.Configuration>();
configurations.AddRange(unsortedConfigurations.OrderBy(conf => conf.Name + conf.Platform));
// Build source files list.
List<ProjectFile> sourceFiles = GetSourceFiles(project, configurations, projectFileInfo);
// Generate options.
Dictionary<Project.Configuration, Options.ExplicitOptions> options = new Dictionary<Project.Configuration, Options.ExplicitOptions>();
foreach (Project.Configuration conf in configurations)
{
Options.ExplicitOptions option = GenerateOptions(conf, projectFileInfo);
options.Add(conf, option);
}
var fileGenerator = new FileGenerator();
{
fileGenerator.Write(Template.Project.Header);
// Configurations variables.
foreach (Project.Configuration conf in configurations)
{
string precompHeader = "";
string precompHeaderOut = "";
string precompIntermediate = "";
string precompCommand = "";
string precompPreBuildCmds = "";
string precompPreLinkCmds = "";
string precompPostBuildCmds = "";
if (!string.IsNullOrEmpty(conf.PrecompHeader))
{
// Support pch files in sub folders
var pchFile = PathMakeUnix(conf.PrecompHeader);
// Don't make additional subfolder in temp directory
var pchObj = Path.GetFileName(conf.PrecompHeader);
var fileName = Path.Combine(PathMakeUnix(project.SourceRootPath), pchFile);
precompHeader = PathMakeUnix(Util.PathGetRelative(projectFileInfo.DirectoryName, fileName, true));
precompHeaderOut = $"$(OBJDIR)/{pchObj}";
precompIntermediate = $"$(OBJDIR)/{pchObj}.gch";
precompCommand = "-include $(PCHOUT)";
}
if (conf.EventPreBuild.Any())
precompPreBuildCmds = conf.EventPreBuild.Aggregate((curr, next) => $"{curr} && {next}");
if (conf.EventPreLink.Any())
precompPreLinkCmds = conf.EventPreLink.Aggregate((curr, next) => $"{curr} && {next}");
if (conf.EventPostBuild.Any())
precompPostBuildCmds = conf.EventPostBuild.Aggregate((curr, next) => $"{curr} && {next}");
using (fileGenerator.Declare("name", conf.Name.ToLower()))
using (fileGenerator.Declare("options", options[conf]))
using (fileGenerator.Declare("precompHeader", precompHeader))
using (fileGenerator.Declare("precompHeaderOut", precompHeaderOut))
using (fileGenerator.Declare("precompIntermediate", precompIntermediate))
using (fileGenerator.Declare("precompCommand", precompCommand))
using (fileGenerator.Declare("precompPreBuildCmds", precompPreBuildCmds))
using (fileGenerator.Declare("precompPreLinkCmds", precompPreLinkCmds))
using (fileGenerator.Declare("precompPostBuildCmds", precompPostBuildCmds))
{
fileGenerator.Write(Template.Project.ProjectConfigurationVariables);
}
}
// Objects variables
foreach (Project.Configuration conf in configurations)
{
using (fileGenerator.Declare("name", conf.Name.ToLower()))
{
fileGenerator.Write(Template.Project.ObjectsVariableBegin);
foreach (ProjectFile file in sourceFiles)
{
// Excluded source files are written to the makefile but are commented out.
// This support the use case where you have a huge unit tests suite that take too long to compile.
// In this case, you just exclude all unit tests from the build and manually uncomment only the unit tests you want to build.
using (fileGenerator.Declare("excludeChar", conf.ResolvedSourceFilesBuildExclude.Contains(file.FileName) ? "#" : ""))
using (fileGenerator.Declare("objectFile", file.GetObjectFileName()))
{
fileGenerator.Write(Template.Project.ObjectsVariableElement);
}
}
fileGenerator.Write(Template.Project.ObjectsVariableEnd);
}
}
// General rules
using (fileGenerator.Declare("projectName", project.Name))
{
fileGenerator.Write(Template.Project.ProjectRulesGeneral);
}
// Source file rules
// Since we write excluded source files commented. Here we write rules for all files
// in case one of the commented out object file is manually uncomment.
foreach (ProjectFile file in sourceFiles)
{
using (fileGenerator.Declare("objectFile", file.GetObjectFileName()))
using (fileGenerator.Declare("sourceFile", PathMakeUnix(file.FileNameProjectRelative)))
{
if (!project.SourceFilesCPPExtensions.Contains(file.FileExtensionLower))
{
fileGenerator.Write(Template.Project.ObjectRuleC);
}
else
{
fileGenerator.Write(Template.Project.ObjectRuleCxx);
}
}
}
fileGenerator.Write(Template.Project.Footer);
// Write the project file
updated = builder.Context.WriteGeneratedFile(project.GetType(), projectFileInfo, fileGenerator);
}
return projectFileInfo.FullName;
}