public override void AddCompilerSettings(IDictionary <string, CompilerSettings> masterCompilerSettings, Project.Configuration conf) { var devEnv = conf.Target.GetFragment <DevEnv>(); var fastBuildSettings = PlatformRegistry.Get <IFastBuildCompilerSettings>(Platform.linux); var platform = conf.Target.GetFragment <Platform>(); string compilerName = $"Compiler-{Util.GetSimplePlatformString(platform)}-{devEnv}"; string CCompilerSettingsName = "C-" + compilerName + "-" + "Linux"; string CompilerSettingsName = compilerName + "-" + "Linux"; var projectRootPath = conf.Project.RootPath; CompilerSettings compilerSettings = GetMasterCompilerSettings(masterCompilerSettings, CompilerSettingsName, devEnv, projectRootPath, false); compilerSettings.PlatformFlags |= Platform.linux; CompilerSettings CcompilerSettings = GetMasterCompilerSettings(masterCompilerSettings, CCompilerSettingsName, devEnv, projectRootPath, true); CcompilerSettings.PlatformFlags |= Platform.linux; SetConfiguration(compilerSettings, CompilerSettingsName, projectRootPath, devEnv, false); SetConfiguration(CcompilerSettings, CCompilerSettingsName, projectRootPath, devEnv, true); }
public virtual bool HasPrecomp(IGenerationContext context) { Project.Configuration conf = context.Configuration; return(!string.IsNullOrEmpty(conf.PrecompSource) && !string.IsNullOrEmpty(conf.PrecompHeader)); }
public override void GenerateUserConfigurationFile(Project.Configuration conf, IFileGenerator generator) { generator.Write(_userFileConfigurationGeneralTemplate); }
internal void Link(Builder builder) { if (_dependenciesResolved) { return; } bool hasFastBuildProjectConf = false; foreach (Solution.Configuration solutionConfiguration in Configurations) { // Build SolutionFilesMapping string configurationFile = Path.Combine(solutionConfiguration.SolutionPath, solutionConfiguration.SolutionFileName); var fileConfigurationList = SolutionFilesMapping.GetValueOrAdd(configurationFile, new List <Solution.Configuration>()); fileConfigurationList.Add(solutionConfiguration); // solutionConfiguration.IncludedProjectInfos will be appended // while iterating, but with projects that we already have resolved, // so no need to parse them again int origCount = solutionConfiguration.IncludedProjectInfos.Count; for (int i = 0; i < origCount; ++i) { Configuration.IncludedProjectInfo configurationProject = solutionConfiguration.IncludedProjectInfos[i]; bool projectIsInactive = configurationProject.InactiveProject; Project project = builder.GetProject(configurationProject.Type); Project.Configuration projectConfiguration = project.GetConfiguration(configurationProject.Target); if (projectConfiguration == null) { throw new Error( "Solution {0} for target '{1}' contains project {2} with invalid target '{3}'", GetType().FullName, solutionConfiguration.Target, project.GetType().FullName, configurationProject.Target ); } if (configurationProject.Project == null) { configurationProject.Project = project; } else if (configurationProject.Project != project) { throw new Error("Tried to match more than one project to Project type."); } if (configurationProject.Configuration == null) { configurationProject.Configuration = projectConfiguration; } else if (configurationProject.Configuration != projectConfiguration) { throw new Error("Tried to match more than one Project Configuration to a solution configuration."); } hasFastBuildProjectConf |= projectConfiguration.IsFastBuild; bool build = !projectConfiguration.IsExcludedFromBuild && !configurationProject.InactiveProject; if (build && solutionConfiguration.IncludeOnlyFilterProject && (configurationProject.Project.SourceFilesFiltersCount == 0 || configurationProject.Project.SkipProjectWhenFiltersActive)) { build = false; } if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency) { if (build) { configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.Yes; } else if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.Yes) { configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.No; } } var dependenciesConfiguration = configurationProject.Configuration.GetRecursiveDependencies(); foreach (Project.Configuration dependencyConfiguration in dependenciesConfiguration) { Project dependencyProject = dependencyConfiguration.Project; Type dependencyProjectType = dependencyProject.GetType(); if (dependencyProjectType.IsDefined(typeof(Export), false)) { continue; } ITarget dependencyProjectTarget = dependencyConfiguration.Target; hasFastBuildProjectConf |= dependencyConfiguration.IsFastBuild; Configuration.IncludedProjectInfo configurationProjectDependency = solutionConfiguration.GetProject(dependencyProjectType); // if that project was not explicitely added to the solution configuration, add it ourselves, as it is needed if (configurationProjectDependency == null) { configurationProjectDependency = new Configuration.IncludedProjectInfo { Type = dependencyProjectType, Project = dependencyProject, Configuration = dependencyConfiguration, Target = dependencyProjectTarget, InactiveProject = projectIsInactive // inherit from the parent: no reason to mark dependencies for build if parent is inactive }; solutionConfiguration.IncludedProjectInfos.Add(configurationProjectDependency); } else if (!projectIsInactive && configurationProjectDependency.InactiveProject) { // if the project we found in the solutionConfiguration is inactive, and the current is not, replace its settings configurationProjectDependency.Type = dependencyProjectType; configurationProjectDependency.Project = dependencyProject; configurationProjectDependency.Configuration = dependencyConfiguration; configurationProjectDependency.Target = dependencyProjectTarget; configurationProjectDependency.InactiveProject = false; } else if (projectIsInactive) { // if the current project is inactive, ignore } else { if (!configurationProjectDependency.Target.IsEqualTo(dependencyProjectTarget)) { throw new Error("In solution configuration (solution: {3}, config: {4}) the parent project {5} generates multiple dependency targets for the same child project {0}: {1} and {2}. Look for all AddPublicDependency() and AddPrivateDependency() calls for the child project and follow the dependency chain.", configurationProjectDependency.Project?.GetType().ToString(), configurationProjectDependency.Target, dependencyProjectTarget, solutionConfiguration.SolutionFileName, solutionConfiguration.Target, project.Name); } if (configurationProjectDependency.Project == null) { configurationProjectDependency.Project = dependencyProject; } else if (configurationProjectDependency.Project != dependencyProject) { throw new Error("Tried to match more than one project to Project type."); } if (configurationProjectDependency.Configuration == null) { configurationProjectDependency.Configuration = dependencyConfiguration; } else if (configurationProjectDependency.Configuration != dependencyConfiguration) { throw new Error("Tried to match more than one Project Configuration to a solution configuration."); } } bool depBuild = !projectIsInactive && !dependencyConfiguration.IsExcludedFromBuild && !configurationProjectDependency.InactiveProject; if (depBuild && solutionConfiguration.IncludeOnlyFilterProject && (dependencyProject.SourceFilesFiltersCount == 0 || dependencyProject.SkipProjectWhenFiltersActive)) { depBuild = false; } if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency) { if (depBuild) { if (projectConfiguration.Output == Project.Configuration.OutputType.Dll || projectConfiguration.Output == Project.Configuration.OutputType.Exe) { configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.YesThroughDependency; } else { configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.Yes; } } else if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.Yes) { configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.No; } } } } } if (hasFastBuildProjectConf) { MakeFastBuildAllProjectIfNeeded(builder); } _dependenciesResolved = true; }
public virtual IEnumerable <Project.Configuration.BuildStepBase> GetExtraPostBuildEvents(Project.Configuration configuration, string fastBuildOutputFile) { return(Enumerable.Empty <Project.Configuration.BuildStepBase>()); }
public static void WriteConfigCustomBuildStepsAsGenericExecutable(string projectRoot, FileGenerator bffGenerator, Project project, Project.Configuration config, Func <string, bool> functor) { using (bffGenerator.Resolver.NewScopedParameter("project", project)) using (bffGenerator.Resolver.NewScopedParameter("config", config)) using (bffGenerator.Resolver.NewScopedParameter("target", config.Target)) { foreach (var customBuildStep in config.CustomFileBuildSteps) { if (customBuildStep.Filter == Project.Configuration.CustomFileBuildStep.ProjectFilter.ExcludeBFF) { continue; } UtilityMethods.WriteCustomBuildStepAsGenericExecutable(projectRoot, bffGenerator, customBuildStep, functor); } } }
private Options.ExplicitOptions GenerateOptions(AndroidPackageProject project, string projectPath, Project.Configuration conf) { Options.ExplicitOptions options = new Options.ExplicitOptions(); options["OutputFile"] = FileGeneratorUtilities.RemoveLineTag; if (_Project.AppLibType != null) { Project.Configuration appLibConf = conf.ConfigurationDependencies.FirstOrDefault(confDep => (confDep.Project.GetType() == _Project.AppLibType)); if (appLibConf != null) { // The lib name to first load from an AndroidActivity must be a dynamic library. if (appLibConf.Output != Project.Configuration.OutputType.Dll) { throw new Error("Cannot use configuration \"{0}\" as app lib for package configuration \"{1}\". Output type must be set to dynamic library.", appLibConf, conf); } options["OutputFile"] = appLibConf.TargetFileFullName; } else { throw new Error("Missing dependency of type \"{0}\" in configuration \"{1}\" dependencies.", _Project.AppLibType.ToNiceTypeName(), conf); } } //Options.Vc.General.UseDebugLibraries. // Disable WarnAsError="false" // Enable WarnAsError="true" /WX SelectOption ( Options.Option(Options.Vc.General.UseDebugLibraries.Disabled, () => { options["UseDebugLibraries"] = "false"; }), Options.Option(Options.Vc.General.UseDebugLibraries.Enabled, () => { options["UseDebugLibraries"] = "true"; }) ); SelectOption ( Options.Option(Options.Android.General.AndroidAPILevel.Default, () => { options["AndroidAPILevel"] = FileGeneratorUtilities.RemoveLineTag; }), Options.Option(Options.Android.General.AndroidAPILevel.Android19, () => { options["AndroidAPILevel"] = "android-19"; }), Options.Option(Options.Android.General.AndroidAPILevel.Android21, () => { options["AndroidAPILevel"] = "android-21"; }), Options.Option(Options.Android.General.AndroidAPILevel.Android22, () => { options["AndroidAPILevel"] = "android-22"; }), Options.Option(Options.Android.General.AndroidAPILevel.Android23, () => { options["AndroidAPILevel"] = "android-23"; }), Options.Option(Options.Android.General.AndroidAPILevel.Android24, () => { options["AndroidAPILevel"] = "android-24"; }) ); //OutputDirectory // The debugger need a rooted path to work properly. // So we root the relative output directory to $(ProjectDir) to work around this limitation. // Hopefully in a futur version of the cross platform tools will be able to remove this hack. string outputDirectoryRelative = Util.PathGetRelative(projectPath, conf.TargetPath); options["OutputDirectory"] = outputDirectoryRelative; //IntermediateDirectory string intermediateDirectoryRelative = Util.PathGetRelative(projectPath, conf.IntermediatePath); options["IntermediateDirectory"] = intermediateDirectoryRelative; return(options); }
private IEnumerable <IDictionary <string, object> > GetEntries(Builder builder, Project.Configuration projectConfiguration, CompileCommandFormat format) { var context = new CompileCommandGenerationContext(builder, projectConfiguration.Project, projectConfiguration); var resolverParams = new[] { new VariableAssignment("project", context.Project), new VariableAssignment("target", context.Configuration.Target), new VariableAssignment("conf", context.Configuration) }; context.EnvironmentVariableResolver = PlatformRegistry.Get <IPlatformDescriptor>(projectConfiguration.Platform).GetPlatformEnvironmentResolver(resolverParams); var factory = new CompileCommandFactory(context); var database = projectConfiguration.Project.GetSourceFilesForConfigurations(new[] { projectConfiguration }) .Except(projectConfiguration.ResolvedSourceFilesBuildExclude) .Where(f => projectConfiguration.Project.SourceFilesCPPExtensions.Contains(Path.GetExtension(f))) .Select(factory.CreateCompileCommand); foreach (var cc in database) { CompileCommandGenerated?.Invoke(context, cc); if (format == CompileCommandFormat.Arguments) { yield return(new Dictionary <string, object> { { "directory", cc.Directory }, { "arguments", cc.Arguments }, { "file", cc.File }, }); } else { yield return(new Dictionary <string, object> { { "directory", cc.Directory }, { "command", cc.Command }, { "file", cc.File }, }); } } }
private Options.ExplicitOptions GenerateOptions(Project.Configuration conf, FileInfo projectFileInfo) { Options.ExplicitOptions options = new Options.ExplicitOptions(); // CompilerToUse SelectOption(conf, Options.Option(Options.Makefile.General.PlatformToolset.Gcc, () => { options["CompilerToUse"] = "g++"; }), Options.Option(Options.Makefile.General.PlatformToolset.Clang, () => { options["CompilerToUse"] = "clang++"; }) ); // IntermediateDirectory options["IntermediateDirectory"] = PathMakeUnix(Util.PathGetRelative(projectFileInfo.DirectoryName, conf.IntermediatePath)); // OutputDirectory string outputDirectory = PathMakeUnix(GetOutputDirectory(conf, projectFileInfo)); options["OutputDirectory"] = outputDirectory; #region Compiler // Defines Strings defines = new Strings(); defines.AddRange(conf.Defines); defines.InsertPrefix("-D"); options["Defines"] = defines.JoinStrings(" "); // Includes OrderableStrings includePaths = new OrderableStrings(); includePaths.AddRange(Util.PathGetRelative(projectFileInfo.DirectoryName, Util.PathGetCapitalized(conf.IncludePrivatePaths))); includePaths.AddRange(Util.PathGetRelative(projectFileInfo.DirectoryName, Util.PathGetCapitalized(conf.IncludePaths))); includePaths.AddRange(Util.PathGetRelative(projectFileInfo.DirectoryName, Util.PathGetCapitalized(conf.DependenciesIncludePaths))); PathMakeUnix(includePaths); includePaths.InsertPrefix("-I"); options["Includes"] = includePaths.JoinStrings(" "); if (conf.ForcedIncludes.Count > 0) { OrderableStrings relativeForceIncludes = new OrderableStrings(Util.PathGetRelative(projectFileInfo.DirectoryName, conf.ForcedIncludes)); PathMakeUnix(relativeForceIncludes); relativeForceIncludes.InsertPrefix("-include "); options["Includes"] += " " + relativeForceIncludes.JoinStrings(" "); } // CFLAGS { StringBuilder cflags = new StringBuilder(); // ExtraWarnings SelectOption(conf, Options.Option(Options.Makefile.Compiler.ExtraWarnings.Enable, () => { cflags.Append("-Wextra "); }), Options.Option(Options.Makefile.Compiler.ExtraWarnings.Disable, () => { cflags.Append(""); }) ); // GenerateDebugInformation SelectOption(conf, Options.Option(Options.Makefile.Compiler.GenerateDebugInformation.Enable, () => { cflags.Append("-g "); }), Options.Option(Options.Makefile.Compiler.GenerateDebugInformation.Disable, () => { cflags.Append(""); }) ); // OptimizationLevel SelectOption(conf, Options.Option(Options.Makefile.Compiler.OptimizationLevel.Disable, () => { cflags.Append(""); }), Options.Option(Options.Makefile.Compiler.OptimizationLevel.Standard, () => { cflags.Append("-O1 "); }), Options.Option(Options.Makefile.Compiler.OptimizationLevel.Full, () => { cflags.Append("-O2 "); }), Options.Option(Options.Makefile.Compiler.OptimizationLevel.FullWithInlining, () => { cflags.Append("-O3 "); }), Options.Option(Options.Makefile.Compiler.OptimizationLevel.ForSize, () => { cflags.Append("-Os "); }) ); // Warnings SelectOption(conf, Options.Option(Options.Makefile.Compiler.Warnings.NormalWarnings, () => { cflags.Append(""); }), Options.Option(Options.Makefile.Compiler.Warnings.MoreWarnings, () => { cflags.Append("-Wall "); }), Options.Option(Options.Makefile.Compiler.Warnings.Disable, () => { cflags.Append("-w "); }) ); // WarningsAsErrors SelectOption(conf, Options.Option(Options.Makefile.Compiler.TreatWarningsAsErrors.Enable, () => { cflags.Append("-Werror "); }), Options.Option(Options.Makefile.Compiler.TreatWarningsAsErrors.Disable, () => { cflags.Append(""); }) ); // AdditionalCompilerOptions cflags.Append(conf.AdditionalCompilerOptions.JoinStrings(" ")); options["CFLAGS"] = cflags.ToString(); } // CXXFLAGS { StringBuilder cxxflags = new StringBuilder(); // CppLanguageStandard SelectOption(conf, Options.Option(Options.Makefile.Compiler.CppLanguageStandard.Cpp17, () => { cxxflags.Append("-std=c++17 "); }), Options.Option(Options.Makefile.Compiler.CppLanguageStandard.Cpp14, () => { cxxflags.Append("-std=c++14 "); }), Options.Option(Options.Makefile.Compiler.CppLanguageStandard.Cpp11, () => { cxxflags.Append("-std=c++11 "); }), Options.Option(Options.Makefile.Compiler.CppLanguageStandard.Cpp98, () => { cxxflags.Append("-std=c++98 "); }), Options.Option(Options.Makefile.Compiler.CppLanguageStandard.GnuCpp11, () => { cxxflags.Append("-std=gnu++11 "); }), Options.Option(Options.Makefile.Compiler.CppLanguageStandard.GnuCpp98, () => { cxxflags.Append("-std=gnu++98 "); }), Options.Option(Options.Makefile.Compiler.CppLanguageStandard.Default, () => { cxxflags.Append(""); }) ); // Exceptions SelectOption(conf, Options.Option(Options.Makefile.Compiler.Exceptions.Enable, () => { cxxflags.Append("-fexceptions "); }), Options.Option(Options.Makefile.Compiler.Exceptions.Disable, () => { cxxflags.Append("-fno-exceptions "); }) ); // RTTI SelectOption(conf, Options.Option(Options.Makefile.Compiler.Rtti.Enable, () => { cxxflags.Append("-frtti "); }), Options.Option(Options.Makefile.Compiler.Rtti.Disable, () => { cxxflags.Append("-fno-rtti "); }) ); options["CXXFLAGS"] = cxxflags.ToString(); } #endregion #region Linker // OutputFile options["OutputFile"] = FormatOutputFileName(conf); // DependenciesLibraryFiles OrderableStrings dependenciesLibraryFiles = new OrderableStrings(conf.DependenciesLibraryFiles); PathMakeUnix(dependenciesLibraryFiles); dependenciesLibraryFiles.InsertPrefix("-l"); options["DependenciesLibraryFiles"] = dependenciesLibraryFiles.JoinStrings(" "); // LibraryFiles OrderableStrings libraryFiles = new OrderableStrings(conf.LibraryFiles); libraryFiles.InsertPrefix("-l"); options["LibraryFiles"] = libraryFiles.JoinStrings(" "); // LibraryPaths OrderableStrings libraryPaths = new OrderableStrings(); libraryPaths.AddRange(Util.PathGetRelative(projectFileInfo.DirectoryName, conf.LibraryPaths)); libraryPaths.AddRange(Util.PathGetRelative(projectFileInfo.DirectoryName, conf.DependenciesOtherLibraryPaths)); libraryPaths.AddRange(Util.PathGetRelative(projectFileInfo.DirectoryName, conf.DependenciesBuiltTargetsLibraryPaths)); PathMakeUnix(libraryPaths); libraryPaths.InsertPrefix("-L"); options["LibraryPaths"] = libraryPaths.JoinStrings(" "); // Dependencies var deps = new OrderableStrings(); foreach (Project.Configuration depConf in conf.ResolvedDependencies) { switch (depConf.Output) { case Project.Configuration.OutputType.None: continue; case Project.Configuration.OutputType.Lib: case Project.Configuration.OutputType.Dll: case Project.Configuration.OutputType.DotNetClassLibrary: deps.Add(Path.Combine(depConf.TargetLibraryPath, FormatOutputFileName(depConf)), depConf.TargetFileOrderNumber); break; default: deps.Add(Path.Combine(depConf.TargetPath, FormatOutputFileName(depConf)), depConf.TargetFileOrderNumber); break; } } var depsRelative = Util.PathGetRelative(projectFileInfo.DirectoryName, deps); PathMakeUnix(depsRelative); options["LDDEPS"] = depsRelative.JoinStrings(" "); // LinkCommand if (conf.Output == Project.Configuration.OutputType.Lib) { options["LinkCommand"] = Template.Project.LinkCommandLib; } else { options["LinkCommand"] = Template.Project.LinkCommandExe; } string linkerAdditionalOptions = conf.AdditionalLinkerOptions.JoinStrings(" "); options["AdditionalLinkerOptions"] = linkerAdditionalOptions; // this is supported in both gcc and clang SelectOption(conf, Options.Option(Options.Makefile.Linker.LibGroup.Enable, () => { options["LibsStartGroup"] = " -Wl,--start-group "; options["LibsEndGroup"] = " -Wl,--end-group "; }), Options.Option(Options.Makefile.Linker.LibGroup.Disable, () => { options["LibsStartGroup"] = string.Empty; options["LibsEndGroup"] = string.Empty; }) ); #endregion return(options); }
/// <summary> /// Do custom configuration. /// </summary> /// <param name="configuration">The project configuration.</param> /// <param name="target">The project target.</param> public virtual void CustomConfigure( Project.Configuration configuration, Target target) { // Do nothing here, override to apply custom configurations. }
public void ConfigureAll( Project.Configuration configuration, Target target) { string mySourceRootPath = Util.NormalizePath(this.SourceRootPath, target.Platform); // Set configuration name with the default composition logic. configuration.Name = Util.ComposeConfigurationName(target); // Compose default project path. configuration.ProjectPath = string.Format( Util.NormalizePath("./projects/{0}/{1}", target.Platform), this.Name, Util.ComposeProjectPath(target)); // The output and intermediate paths is always the same by default. configuration.IntermediatePath = Util.NormalizePath(@"[conf.ProjectPath]\obj\$(PlatformTarget)\$(Configuration)", target.Platform); configuration.TargetPath = this.ComposeTargetPath(configuration, target); // Always add the project's source and header folders. configuration.IncludePrivatePaths.Add(Util.NormalizePath(@"[project.SourceRootPath]\src", target.Platform)); configuration.IncludePaths.Add(Util.NormalizePath(@"[project.SourceRootPath]\include", target.Platform)); // The pre-compiled header. if (this.UseDefaultPrecompiledHeader == true) { // Add the pre-compiled header with the default names. configuration.PrecompHeader = this.Name + "_PCH.h"; configuration.PrecompSource = this.Name + "_PCH.cpp"; } // Post build script. if (this.UseDefaultPostBuildScript == true) { string postBuildScriptPath = Util.NormalizePath($"../../../../{mySourceRootPath}/misc/PostBuild.", target.Platform); if (Util.IsMswinPlatform(target.Platform) == true) { postBuildScriptPath += "bat"; } else { postBuildScriptPath += "sh"; } string projectToSrcRootPath = Util.NormalizePath($"../../../../{mySourceRootPath}", target.Platform); string postBuildArgs = $"\"{configuration.TargetPath}\" \"{projectToSrcRootPath}\""; configuration.EventPostBuild.Add($"{postBuildScriptPath} {postBuildArgs} {this.DefaultPostBuildScriptArgs}"); } // Set the project output type according to the target's output type. if (this.IsApplication == true) { configuration.Output = Configuration.OutputType.Exe; } else { if (target.OutputType == OutputType.Dll) { configuration.Output = Configuration.OutputType.Dll; } else { configuration.Output = Configuration.OutputType.Lib; } } // Set default character set to Unicode. configuration.Options.Add(Options.Vc.General.CharacterSet.Unicode); // Do custom configurations. this.CustomConfigure(configuration, target); }
public void SetupDynamicLibraryPaths(Project.Configuration configuration, DependencySetting dependencySetting, Project.Configuration dependency) { // Not tested. We may need to root the path like we do in SetupStaticLibraryPaths. DefaultPlatform.SetupLibraryPaths(configuration, dependencySetting, dependency); }
public ProjectSettings(Project project, List <Project.Configuration> configurations, Resolver resolver) { Project.Configuration configurationDebug = configurations.FirstOrDefault(conf => conf.Target.GetFragment <Optimization>() == Optimization.Debug); Project.Configuration configurationRelease = configurations.FirstOrDefault(conf => conf.Target.GetFragment <Optimization>() == Optimization.Release); Project.Configuration configurationRetail = configurations.FirstOrDefault(conf => conf.Target.GetFragment <Optimization>() == Optimization.Retail); if (configurationDebug == null || configurationRelease == null || configurationRetail == null) { throw new Error("Android makefiles require a debug, release and final configuration. "); } configurationDebug.Defines.Add("_DEBUG"); configurationRelease.Defines.Add("NDEBUG"); configurationRetail.Defines.Add("NDEBUG"); _includePaths = ""; foreach (string includePath in configurationDebug.IncludePaths) { using (resolver.NewScopedParameter("Path", includePath)) { _includePaths += resolver.Resolve(Template.IncludePathTemplate) + "\r\n"; } } _sourcePaths = ""; Strings sourceFiles = project.GetSourceFilesForConfigurations(configurations); ResolveProjectPaths(project, sourceFiles); foreach (string sourcePath in sourceFiles) { string extension = sourcePath.Substring(sourcePath.LastIndexOf('.')); if (project.SourceFilesCompileExtensions.Contains(extension)) { if (!configurationDebug.ResolvedSourceFilesBuildExclude.Contains(sourcePath)) { using (resolver.NewScopedParameter("Path", sourcePath)) { _sourcePaths += resolver.Resolve(Template.SourceFileTemplate) + "\r\n"; } } } } _moduleName = project.Name; Options.SelectOption(configurationDebug, Options.Option(Options.AndroidMakefile.ArmMode.Thumb, () => _armMode = RemoveLineTag), Options.Option(Options.AndroidMakefile.ArmMode.Arm, () => _armMode = "arm") ); Options.SelectOption(configurationDebug, Options.Option(Options.AndroidMakefile.ShortCommands.Disable, () => _shortCommands = "false"), Options.Option(Options.AndroidMakefile.ShortCommands.Enable, () => _shortCommands = "true") ); Options.SelectOption(configurationDebug, Options.Option(Options.AndroidMakefile.GroupStaticLibraries.Disable, () => _groupStaticLibraries = "false"), Options.Option(Options.AndroidMakefile.GroupStaticLibraries.Enable, () => _groupStaticLibraries = "true") ); Strings compilerFlagsDebug = Options.GetStrings <Options.AndroidMakefile.CompilerFlags>(configurationDebug); Strings compilerFlagsRelease = Options.GetStrings <Options.AndroidMakefile.CompilerFlags>(configurationRelease); Strings compilerFlagsFinal = Options.GetStrings <Options.AndroidMakefile.CompilerFlags>(configurationRetail); _cFlagsDebug = configurationDebug.Defines.Select(define => "-D" + define).Union(compilerFlagsDebug).DefaultIfEmpty("").Aggregate((first, next) => first + " " + next); _cFlagsRelease = configurationRelease.Defines.Select(define => "-D" + define).Union(compilerFlagsRelease).DefaultIfEmpty("").Aggregate((first, next) => first + " " + next); _cFlagsFinal = configurationRetail.Defines.Select(define => "-D" + define).Union(compilerFlagsFinal).DefaultIfEmpty("").Aggregate((first, next) => first + " " + next); //Strings compilerExportedFlagsDebug = Options.GetStrings<Options.AndroidMakefile.CompilerExportedFlags>(configurationDebug); //Strings compilerExportedFlagsRelease = Options.GetStrings<Options.AndroidMakefile.CompilerExportedFlags>(configurationRelease); //Strings compilerExportedFlagsFinal = Options.GetStrings<Options.AndroidMakefile.CompilerExportedFlags>(configurationRetail); Strings exportedDefinesDebug = Options.GetStrings <Options.AndroidMakefile.ExportedDefines>(configurationDebug); Strings exportedDefinesRelease = Options.GetStrings <Options.AndroidMakefile.ExportedDefines>(configurationRelease); Strings exportedDefinesFinal = Options.GetStrings <Options.AndroidMakefile.ExportedDefines>(configurationRetail); _cFlagsExportedDebug = exportedDefinesDebug.Select(define => "-D" + define).Union(compilerFlagsDebug).DefaultIfEmpty("").Aggregate((first, next) => first + " " + next); _cFlagsExportedRelease = exportedDefinesRelease.Select(define => "-D" + define).Union(compilerFlagsRelease).DefaultIfEmpty("").Aggregate((first, next) => first + " " + next); _cFlagsExportedFinal = exportedDefinesFinal.Select(define => "-D" + define).Union(compilerFlagsFinal).DefaultIfEmpty("").Aggregate((first, next) => first + " " + next); List <PrebuiltStaticLibrary> allPrebuiltStaticLibrariesDebug = new List <PrebuiltStaticLibrary>(); List <PrebuiltStaticLibrary> allPrebuiltStaticLibrariesRelease = new List <PrebuiltStaticLibrary>(); List <PrebuiltStaticLibrary> allPrebuiltStaticLibrariesFinal = new List <PrebuiltStaticLibrary>(); foreach (var library in Options.GetObjects <Options.AndroidMakefile.PrebuiltStaticLibraries>(configurationDebug)) { PrebuiltStaticLibrary internalLibrary = new PrebuiltStaticLibrary(project, library); allPrebuiltStaticLibrariesDebug.Add(internalLibrary); } foreach (var library in Options.GetObjects <Options.AndroidMakefile.PrebuiltStaticLibraries>(configurationRelease)) { PrebuiltStaticLibrary internalLibrary = new PrebuiltStaticLibrary(project, library); allPrebuiltStaticLibrariesRelease.Add(internalLibrary); } foreach (var library in Options.GetObjects <Options.AndroidMakefile.PrebuiltStaticLibraries>(configurationRetail)) { PrebuiltStaticLibrary internalLibrary = new PrebuiltStaticLibrary(project, library); allPrebuiltStaticLibrariesFinal.Add(internalLibrary); } IEnumerable <PrebuiltStaticLibrary> prebuiltStaticLibraries = allPrebuiltStaticLibrariesDebug.Intersect(allPrebuiltStaticLibrariesRelease).Intersect(allPrebuiltStaticLibrariesFinal); IEnumerable <PrebuiltStaticLibrary> prebuiltStaticLibrariesDebug = allPrebuiltStaticLibrariesDebug.Except(prebuiltStaticLibraries); IEnumerable <PrebuiltStaticLibrary> prebuiltStaticLibrariesRelease = allPrebuiltStaticLibrariesRelease.Except(prebuiltStaticLibraries); IEnumerable <PrebuiltStaticLibrary> prebuiltStaticLibrariesFinal = allPrebuiltStaticLibrariesFinal.Except(prebuiltStaticLibraries); _prebuiltStaticLibraries = prebuiltStaticLibraries.Any() ? prebuiltStaticLibraries.Select(item => { using (resolver.NewScopedParameter("item", item)) return(resolver.Resolve(Template.PrebuiltStaticLibraryTemplate)); }).Aggregate((first, next) => first + "\r\n" + next) : ""; _prebuiltStaticLibrariesDebug = prebuiltStaticLibrariesDebug.Any() ? prebuiltStaticLibrariesDebug.Select(item => { using (resolver.NewScopedParameter("item", item)) return(resolver.Resolve(Template.PrebuiltStaticLibraryTemplate)); }).Aggregate((first, next) => first + "\r\n" + next) : ""; _prebuiltStaticLibrariesRelease = prebuiltStaticLibrariesRelease.Any() ? prebuiltStaticLibrariesRelease.Select(item => { using (resolver.NewScopedParameter("item", item)) return(resolver.Resolve(Template.PrebuiltStaticLibraryTemplate)); }).Aggregate((first, next) => first + "\r\n" + next) : ""; _prebuiltStaticLibrariesFinal = prebuiltStaticLibrariesFinal.Any() ? prebuiltStaticLibrariesFinal.Select(item => { using (resolver.NewScopedParameter("item", item)) return(resolver.Resolve(Template.PrebuiltStaticLibraryTemplate)); }).Aggregate((first, next) => first + "\r\n" + next) : ""; switch (configurationDebug.Output) { case Project.Configuration.OutputType.Lib: _buildType = Template.BuildStaticLibraryTemplate; break; case Project.Configuration.OutputType.Dll: _buildType = Template.BuildSharedLibraryTemplate; break; default: _buildType = RemoveLineTag; break; } }
private void SetConfiguration( Project.Configuration conf, IDictionary <string, CompilerSettings.Configuration> configurations, string configName, string projectRootPath, DevEnv devEnv, bool useCCompiler) { string linkerPathOverride = null; string linkerExeOverride = null; string librarianExeOverride = null; GetLinkerExecutableInfo(conf, out linkerPathOverride, out linkerExeOverride, out librarianExeOverride); if (!configurations.ContainsKey(configName)) { var fastBuildCompilerSettings = PlatformRegistry.Get <IWindowsFastBuildCompilerSettings>(Platform.win64); string binPath; if (!fastBuildCompilerSettings.BinPath.TryGetValue(devEnv, out binPath)) { binPath = devEnv.GetVisualStudioBinPath(Platform.win64); } string linkerPath; if (!string.IsNullOrEmpty(linkerPathOverride)) { linkerPath = linkerPathOverride; } else if (!fastBuildCompilerSettings.LinkerPath.TryGetValue(devEnv, out linkerPath)) { linkerPath = binPath; } string linkerExe; if (!string.IsNullOrEmpty(linkerExeOverride)) { linkerExe = linkerExeOverride; } else if (!fastBuildCompilerSettings.LinkerExe.TryGetValue(devEnv, out linkerExe)) { linkerExe = "link.exe"; } string librarianExe; if (!string.IsNullOrEmpty(librarianExeOverride)) { librarianExe = librarianExeOverride; } else if (!fastBuildCompilerSettings.LibrarianExe.TryGetValue(devEnv, out librarianExe)) { librarianExe = "lib.exe"; } string resCompiler; if (!fastBuildCompilerSettings.ResCompiler.TryGetValue(devEnv, out resCompiler)) { resCompiler = devEnv.GetWindowsResourceCompiler(Platform.win64); } configurations.Add( configName, new CompilerSettings.Configuration( Platform.win64, binPath: Util.GetCapitalizedPath(Util.PathGetAbsolute(projectRootPath, binPath)), linkerPath: Util.GetCapitalizedPath(Util.PathGetAbsolute(projectRootPath, linkerPath)), resourceCompiler: Util.GetCapitalizedPath(Util.PathGetAbsolute(projectRootPath, resCompiler)), librarian: Path.Combine(@"$LinkerPath$", librarianExe), linker: Path.Combine(@"$LinkerPath$", linkerExe) ) ); configurations.Add( configName + "Masm", new CompilerSettings.Configuration( Platform.win64, compiler: @"$BinPath$\ml64.exe", usingOtherConfiguration: configName ) ); } }
public static UniqueList <Project.Configuration> GetOrderedFlattenedProjectDependencies(Project.Configuration conf, bool allDependencies = true, bool fuDependencies = false) { var dependencies = new UniqueList <Project.Configuration>(); GetOrderedFlattenedProjectDependenciesInternal(conf, dependencies, allDependencies, fuDependencies); return(dependencies); }
private void SelectOption(Project.Configuration conf, params Options.OptionAction[] options) { Options.SelectOption(conf, options); }
internal static UniqueList <Project.Configuration> GetOrderedFlattenedBuildOnlyDependencies(Project.Configuration conf) { var dependencies = new UniqueList <Project.Configuration>(); GetOrderedFlattenedBuildOnlyDependenciesInternal(conf, dependencies); return(dependencies); }
public TrackedConfiguration FindConfiguration(Project.Configuration config) { return(Configurations[GetKeyFromConfiguration(config)]); }
private void GenerateProjectFile(object arg) { var pair = (KeyValuePair <string, List <Project.Configuration> >)arg; string projectFile = pair.Key; List <Project.Configuration> configurations = pair.Value; Project.Configuration firstConf = configurations.FirstOrDefault(); Project project = firstConf.Project; using (new Util.StopwatchProfiler(ms => { ProfileWriteLine(" |{0,5} ms| generate project file {1}", ms, firstConf.ProjectFileName); })) { GenerationOutput output = new GenerationOutput(); try { bool generateProject = false; DevEnv devEnv = configurations[0].Target.GetFragment <DevEnv>(); for (int i = 0; i < configurations.Count; ++i) { Project.Configuration conf = pair.Value[i]; if (devEnv != conf.Target.GetFragment <DevEnv>()) { throw new Error("Multiple generator cannot output to the same file:" + Environment.NewLine + "\tBoth {0} and {1} try to generate {2}", devEnv, conf.Target.GetFragment <DevEnv>(), projectFile); } if (!generateProject) { if (_usedProjectConfigurations == null || Arguments.TypesToGenerate.Contains(project.GetType()) || // generate the project if it was explicitly queried by the user-code _usedProjectConfigurations.Contains(conf)) { generateProject = true; } } } if (project.SourceFilesFilters == null || (project.SourceFilesFiltersCount != 0 && !project.SkipProjectWhenFiltersActive)) { if (generateProject) { _getGeneratorsManagerCallBack().Generate(this, project, configurations, projectFile, output.Generated, output.Skipped); } } } catch (Exception ex) { output.Exception = ex; } GenerationOutput allOutput = _generationReport.GetOrAdd(project.GetType(), output); if (allOutput != output) { lock (allOutput) allOutput.Merge(output); } } }
public void AddConfig(Project.Configuration config) { Configurations.Add(config.ToString().Substring(config.ToString().IndexOf(':') + 1), new TrackedConfiguration(this, config)); }
private void Generate( AndroidPackageProject project, List <Project.Configuration> unsortedConfigurations, string projectPath, string projectFile, List <string> generatedFiles, List <string> skipFiles) { // Need to sort by name and platform List <Project.Configuration> configurations = new List <Project.Configuration>(); configurations.AddRange(unsortedConfigurations.OrderBy(conf => conf.Name + conf.Platform)); // validate that 2 conf name in the same project don't have the same name Dictionary <string, Project.Configuration> configurationNameMapping = new Dictionary <string, Project.Configuration>(); string projectName = null; foreach (Project.Configuration conf in configurations) { if (projectName == null) { projectName = conf.ProjectName; } else if (projectName != conf.ProjectName) { throw new Error("Project configurations in the same project files must be the same: {0} != {1} in {2}", projectName, conf.ProjectName, projectFile); } Project.Configuration otherConf; string projectUniqueName = conf.Name + Util.GetPlatformString(conf.Platform, conf.Project); if (configurationNameMapping.TryGetValue(projectUniqueName, out otherConf)) { var differBy = Util.MakeDifferenceString(conf, otherConf); throw new Error( "Project {0} ({5} in {6}) has 2 configurations with the same name: \"{1}\" for {2} and {3}" + Environment.NewLine + "Nb: ps3 and win32 cannot have same conf name: {4}", project.Name, conf.Name, otherConf.Target, conf.Target, differBy, projectFile, projectPath); } configurationNameMapping[projectUniqueName] = conf; // set generator information switch (conf.Platform) { case Platform.android: conf.GeneratorSetGeneratedInformation("elf", "elf", "so", "pdb"); break; default: break; } } Resolver resolver = new Resolver(); _ProjectDirectoryCapitalized = Util.GetCapitalizedPath(projectPath); //_ProjectSourceCapitalized = Util.GetCapitalizedPath(project.SourceRootPath); _Project = project; _ProjectConfigurationList = configurations; MemoryStream memoryStream = new MemoryStream(); StreamWriter writer = new StreamWriter(memoryStream); // xml begin header DevEnvRange devEnvRange = new DevEnvRange(unsortedConfigurations); using (resolver.NewScopedParameter("toolsVersion", devEnvRange.MinDevEnv.GetVisualProjectToolsVersionString())) { Write(Template.Project.ProjectBegin, writer, resolver); } Write(Template.Project.ProjectBeginConfigurationDescription, writer, resolver); // xml header contain description of each target foreach (Project.Configuration conf in _ProjectConfigurationList) { using (resolver.NewScopedParameter("platformName", Util.GetPlatformString(conf.Platform, conf.Project))) using (resolver.NewScopedParameter("conf", conf)) { Write(Template.Project.ProjectConfigurationDescription, writer, resolver); } } Write(Template.Project.ProjectEndConfigurationDescription, writer, resolver); // xml end header var firstConf = _ProjectConfigurationList.First(); using (resolver.NewScopedParameter("projectName", projectName)) using (resolver.NewScopedParameter("guid", firstConf.ProjectGuid)) using (resolver.NewScopedParameter("toolsVersion", devEnvRange.MinDevEnv.GetVisualProjectToolsVersionString())) { Write(Template.Project.ProjectDescription, writer, resolver); } // generate all configuration options once... Dictionary <Project.Configuration, Options.ExplicitOptions> options = new Dictionary <Project.Configuration, Options.ExplicitOptions>(); foreach (Project.Configuration conf in _ProjectConfigurationList) { _ProjectConfiguration = conf; Options.ExplicitOptions option = GenerateOptions(project, projectPath, conf); _ProjectConfiguration = null; options.Add(conf, option); } // configuration general foreach (Project.Configuration conf in _ProjectConfigurationList) { using (resolver.NewScopedParameter("platformName", Util.GetPlatformString(conf.Platform, conf.Project))) using (resolver.NewScopedParameter("conf", conf)) using (resolver.NewScopedParameter("options", options[conf])) { Write(Template.Project.ProjectConfigurationsGeneral, writer, resolver); } } // .props files Write(Template.Project.ProjectAfterConfigurationsGeneral, writer, resolver); Write(Template.Project.ProjectAfterImportedProps, writer, resolver); string androidPackageDirectory = project.AntBuildRootDirectory; // configuration ItemDefinitionGroup foreach (Project.Configuration conf in _ProjectConfigurationList) { using (resolver.NewScopedParameter("platformName", Util.GetPlatformString(conf.Platform, conf.Project))) using (resolver.NewScopedParameter("conf", conf)) using (resolver.NewScopedParameter("options", options[conf])) using (resolver.NewScopedParameter("androidPackageDirectory", androidPackageDirectory)) { Write(Template.Project.ProjectConfigurationBeginItemDefinition, writer, resolver); { Write(Template.Project.AntPackage, writer, resolver); } Write(Template.Project.ProjectConfigurationEndItemDefinition, writer, resolver); } } GenerateFilesSection(project, writer, resolver, projectPath, projectFile, generatedFiles, skipFiles); GenerateProjectReferences(configurations, resolver, writer, options); // .targets Write(Template.Project.ProjectTargets, writer, resolver); Write(Template.Project.ProjectEnd, writer, resolver); // Write the project file writer.Flush(); // remove all line that contain RemoveLineTag MemoryStream cleanMemoryStream = Util.RemoveLineTags(memoryStream, FileGeneratorUtilities.RemoveLineTag); FileInfo projectFileInfo = new FileInfo(Path.Combine(projectPath, projectFile + ProjectExtension)); if (_Builder.Context.WriteGeneratedFile(project.GetType(), projectFileInfo, cleanMemoryStream)) { generatedFiles.Add(projectFileInfo.FullName); } else { skipFiles.Add(projectFileInfo.FullName); } writer.Close(); _Project = null; }
private string Generate( Solution solution, IReadOnlyList <Solution.Configuration> solutionConfigurations, string solutionPath, string solutionFile, bool addMasterBff, out bool updated ) { // reset current solution state _rootSolutionFolders.Clear(); _solutionFolders.Clear(); FileInfo solutionFileInfo = new FileInfo(Util.GetCapitalizedPath(solutionPath + Path.DirectorySeparatorChar + solutionFile + SolutionExtension)); string solutionGuid = Util.BuildGuid(solutionFileInfo.FullName, solution.SharpmakeCsPath); DevEnv devEnv = solutionConfigurations[0].Target.GetFragment <DevEnv>(); List <Solution.ResolvedProject> solutionProjects = ResolveSolutionProjects(solution, solutionConfigurations); if (solutionProjects.Count == 0) { updated = solutionFileInfo.Exists; if (updated) { Util.TryDeleteFile(solutionFileInfo.FullName); } return(solutionFileInfo.FullName); } List <Solution.ResolvedProject> resolvedPathReferences = ResolveReferencesByPath(solutionProjects, solutionConfigurations[0].ProjectReferencesByPath); var guidlist = solutionProjects.Select(p => p.UserData["Guid"]); resolvedPathReferences = resolvedPathReferences.Where(r => !guidlist.Contains(r.UserData["Guid"])).ToList(); var fileGenerator = new FileGenerator(); // write solution header switch (devEnv) { case DevEnv.vs2010: fileGenerator.Write(Template.Solution.HeaderBeginVs2010); break; case DevEnv.vs2012: fileGenerator.Write(Template.Solution.HeaderBeginVs2012); break; case DevEnv.vs2013: fileGenerator.Write(Template.Solution.HeaderBeginVs2013); break; case DevEnv.vs2015: fileGenerator.Write(Template.Solution.HeaderBeginVs2015); break; case DevEnv.vs2017: fileGenerator.Write(Template.Solution.HeaderBeginVs2017); break; case DevEnv.vs2019: fileGenerator.Write(Template.Solution.HeaderBeginVs2019); break; default: Console.WriteLine("Unsupported DevEnv for solution " + solutionConfigurations[0].Target.GetFragment <DevEnv>()); break; } SolutionFolder masterBffFolder = null; if (addMasterBff) { masterBffFolder = GetSolutionFolder(solution.FastBuildMasterBffSolutionFolder); if (masterBffFolder == null) { throw new Error("FastBuildMasterBffSolutionFolder needs to be set in solution " + solutionFile); } } // Write all needed folders before the projects to make sure the proper startup project is selected. // Ensure folders are always in the same order to avoid random shuffles _solutionFolders.Sort((a, b) => { int nameComparison = string.Compare(a.Name, b.Name, StringComparison.InvariantCultureIgnoreCase); if (nameComparison != 0) { return(nameComparison); } return(a.Guid.CompareTo(b.Guid)); }); foreach (SolutionFolder folder in _solutionFolders) { using (fileGenerator.Declare("folderName", folder.Name)) using (fileGenerator.Declare("folderGuid", folder.Guid.ToString().ToUpper())) { fileGenerator.Write(Template.Solution.ProjectFolder); if (masterBffFolder == folder) { var bffFilesPaths = new SortedSet <string>(new FileSystemStringComparer()); foreach (var conf in solutionConfigurations) { string masterBffFilePath = conf.MasterBffFilePath + FastBuildSettings.FastBuildConfigFileExtension; bffFilesPaths.Add(Util.PathGetRelative(solutionPath, masterBffFilePath)); bffFilesPaths.Add(Util.PathGetRelative(solutionPath, FastBuild.MasterBff.GetGlobalBffConfigFileName(masterBffFilePath))); } // This always needs to be created so make sure it's there. bffFilesPaths.Add(solutionFile + FastBuildSettings.FastBuildConfigFileExtension); fileGenerator.Write(Template.Solution.SolutionItemBegin); { foreach (var path in bffFilesPaths) { using (fileGenerator.Declare("solutionItemPath", path)) fileGenerator.Write(Template.Solution.SolutionItem); } } fileGenerator.Write(Template.Solution.ProjectSectionEnd); } fileGenerator.Write(Template.Solution.ProjectEnd); } } Solution.ResolvedProject fastBuildAllProjectForSolutionDependency = null; if (solution.FastBuildAllSlnDependencyFromExe) { var fastBuildAllProjects = solutionProjects.Where(p => p.Project.IsFastBuildAll).ToArray(); if (fastBuildAllProjects.Length > 1) { throw new Error("More than one FastBuildAll project"); } if (fastBuildAllProjects.Length == 1) { fastBuildAllProjectForSolutionDependency = fastBuildAllProjects[0]; } } using (fileGenerator.Declare("solution", solution)) using (fileGenerator.Declare("solutionGuid", solutionGuid)) { foreach (Solution.ResolvedProject resolvedProject in solutionProjects.Concat(resolvedPathReferences).Distinct(new Solution.ResolvedProjectGuidComparer())) { FileInfo projectFileInfo = new FileInfo(resolvedProject.ProjectFile); using (fileGenerator.Declare("project", resolvedProject.Project)) using (fileGenerator.Declare("projectName", resolvedProject.ProjectName)) using (fileGenerator.Declare("projectFile", Util.PathGetRelative(solutionFileInfo.Directory.FullName, projectFileInfo.FullName))) using (fileGenerator.Declare("projectGuid", resolvedProject.UserData["Guid"])) using (fileGenerator.Declare("projectTypeGuid", resolvedProject.UserData["TypeGuid"])) { fileGenerator.Write(Template.Solution.ProjectBegin); Strings buildDepsGuids = new Strings(resolvedProject.Configurations.SelectMany( c => c.GenericBuildDependencies.Where( p => (p.Project is FastBuildAllProject) == false || fastBuildAllProjectForSolutionDependency == null || p.Project == fastBuildAllProjectForSolutionDependency.Project ).Select( p => p.ProjectGuid ?? ReadGuidFromProjectFile(p.ProjectFullFileNameWithExtension) ) )); if (fastBuildAllProjectForSolutionDependency != null) { bool writeDependencyToFastBuildAll = resolvedProject.Configurations.Any(conf => conf.IsFastBuild && conf.Output == Project.Configuration.OutputType.Exe); if (writeDependencyToFastBuildAll) { buildDepsGuids.Add(fastBuildAllProjectForSolutionDependency.UserData["Guid"] as string); } } if (buildDepsGuids.Any()) { fileGenerator.Write(Template.Solution.ProjectDependencyBegin); foreach (string guid in buildDepsGuids) { using (fileGenerator.Declare("projectDependencyGuid", guid)) fileGenerator.Write(Template.Solution.ProjectDependency); } fileGenerator.Write(Template.Solution.ProjectSectionEnd); } fileGenerator.Write(Template.Solution.ProjectEnd); } } } // Write extra solution items // TODO: What happens if we define an existing folder? foreach (var items in solution.ExtraItems) { using (fileGenerator.Declare("folderName", items.Key)) using (fileGenerator.Declare("folderGuid", Util.BuildGuid(items.Key))) using (fileGenerator.Declare("solution", solution)) { fileGenerator.Write(Template.Solution.ProjectFolder); { fileGenerator.Write(Template.Solution.SolutionItemBegin); foreach (string file in items.Value) { using (fileGenerator.Declare("solutionItemPath", Util.PathGetRelative(solutionPath, file))) fileGenerator.Write(Template.Solution.SolutionItem); } fileGenerator.Write(Template.Solution.ProjectSectionEnd); } fileGenerator.Write(Template.Solution.ProjectEnd); } } fileGenerator.Write(Template.Solution.GlobalBegin); // Write source code control informations if (solution.PerforceRootPath != null) { List <Solution.ResolvedProject> sccProjects = new List <Solution.ResolvedProject>(); foreach (Solution.ResolvedProject resolvedProject in solutionProjects) { if (resolvedProject.Project.PerforceRootPath != null) { sccProjects.Add(resolvedProject); } else { _builder.LogWriteLine(@"warning: cannot bind solution {0} to perforce, PerforceRootPath for project '{1}' is not set.", solutionFileInfo.Name, resolvedProject.Project.ClassName); } } if (sccProjects.Count == solutionProjects.Count) { using (fileGenerator.Declare("sccNumberOfProjects", sccProjects.Count)) { fileGenerator.Write(Template.Solution.GlobalSectionSolutionSourceCodeControlBegin); } for (int i = 0; i < sccProjects.Count; ++i) { Solution.ResolvedProject resolvedProject = sccProjects[i]; FileInfo projectFileInfo = new FileInfo(resolvedProject.ProjectFile); //SccProjectUniqueName7 = ..\\..\\extern\\techgroup\\framework\\gear\\private\\compilers\\win32\\vc9\\gear_win32_compile.vcproj string sccProjectUniqueName = Util.PathGetRelative(solutionFileInfo.Directory.FullName, projectFileInfo.FullName).Replace("\\", "\\\\"); //SccProjectTopLevelParentUniqueName7 = guildlib.sln string sccProjectTopLevelParentUniqueName = solutionFileInfo.Name; // sln to perforce file //SccLocalPath7 = ..\\..\\extern\\techgroup\\framework\\gear string sccLocalPath = Util.PathGetRelative(solutionPath, resolvedProject.Project.PerforceRootPath).Replace("\\", "\\\\"); //SccProjectFilePathRelativizedFromConnection7 = private\\compilers\\win32\\vc9\\ string sccProjectFilePathRelativizedFromConnection = Util.PathGetRelative(resolvedProject.Project.PerforceRootPath, projectFileInfo.DirectoryName).Trim('.', '\\').Replace("\\", "\\\\"); using (fileGenerator.Declare("i", i)) using (fileGenerator.Declare("sccProjectUniqueName", sccProjectUniqueName)) using (fileGenerator.Declare("sccProjectTopLevelParentUniqueName", sccProjectTopLevelParentUniqueName)) using (fileGenerator.Declare("sccLocalPath", sccLocalPath)) using (fileGenerator.Declare("sccProjectFilePathRelativizedFromConnection", sccProjectFilePathRelativizedFromConnection)) { fileGenerator.Write(Template.Solution.GlobalSectionSolutionSourceCodeControlProject); } } fileGenerator.Write(Template.Solution.GlobalSectionSolutionSourceCodeControlEnd); } } // write solution configurations string visualStudioExe = GetVisualStudioIdePath(devEnv) + Util.WindowsSeparator + "devenv.com"; List <string> configurationSectionNames = new List <string>(); fileGenerator.Write(Template.Solution.GlobalSectionSolutionConfigurationBegin); foreach (Solution.Configuration solutionConfiguration in solutionConfigurations) { string configurationName; string category; if (solution.MergePlatformConfiguration) { configurationName = solutionConfiguration.PlatformName + "-" + solutionConfiguration.Name; category = "All Platforms"; } else { configurationName = solutionConfiguration.Name; category = solutionConfiguration.PlatformName; } using (fileGenerator.Declare("configurationName", configurationName)) using (fileGenerator.Declare("category", category)) { configurationSectionNames.Add(fileGenerator.Resolver.Resolve(Template.Solution.GlobalSectionSolutionConfiguration)); } // set the compile command line if (File.Exists(visualStudioExe)) { solutionConfiguration.CompileCommandLine = string.Format(@"""{0}"" ""{1}"" /build ""{2}|{3}""", visualStudioExe, solutionFileInfo.FullName, configurationName, category); } } configurationSectionNames.Sort(); foreach (string configurationSectionName in configurationSectionNames) { fileGenerator.Write(configurationSectionName); } fileGenerator.Write(Template.Solution.GlobalSectionSolutionConfigurationEnd); // write all project target and match then to a solution target fileGenerator.Write(Template.Solution.GlobalSectionProjectConfigurationBegin); var solutionConfigurationFastBuildBuilt = new Dictionary <Solution.Configuration, List <string> >(); foreach (Solution.ResolvedProject solutionProject in solutionProjects) { foreach (Solution.Configuration solutionConfiguration in solutionConfigurations) { ITarget solutionTarget = solutionConfiguration.Target; ITarget projectTarget = null; Solution.Configuration.IncludedProjectInfo includedProject = solutionConfiguration.GetProject(solutionProject.Project.GetType()); bool perfectMatch = includedProject != null && solutionProject.Configurations.Contains(includedProject.Configuration); if (perfectMatch) { projectTarget = includedProject.Target; } else { // try to find the target in the project that is the closest match from the solution one int maxEqualFragments = 0; int[] solutionTargetValues = solutionTarget.GetFragmentsValue(); Platform previousPlatform = Platform._reserved1; foreach (var conf in solutionProject.Configurations) { Platform currentTargetPlatform = conf.Target.GetPlatform(); int[] candidateTargetValues = conf.Target.GetFragmentsValue(); if (solutionTargetValues.Length != candidateTargetValues.Length) { continue; } int equalFragments = 0; for (int i = 0; i < solutionTargetValues.Length; ++i) { if ((solutionTargetValues[i] & candidateTargetValues[i]) != 0) { equalFragments++; } } if ((equalFragments == maxEqualFragments && currentTargetPlatform < previousPlatform) || equalFragments > maxEqualFragments) { projectTarget = conf.Target; maxEqualFragments = equalFragments; previousPlatform = currentTargetPlatform; } } // last resort: if we didn't find a good enough match, fallback to TargetDefault if (projectTarget == null) { projectTarget = solutionProject.TargetDefault; } } Project.Configuration projectConf = solutionProject.Project.GetConfiguration(projectTarget); if (includedProject != null && includedProject.Configuration.IsFastBuild) { solutionConfigurationFastBuildBuilt.GetValueOrAdd(solutionConfiguration, new List <string>()); } Platform projectPlatform = projectTarget.GetPlatform(); string configurationName; string category; if (solution.MergePlatformConfiguration) { configurationName = solutionConfiguration.PlatformName + "-" + solutionConfiguration.Name; category = "All Platforms"; } else { configurationName = solutionConfiguration.Name; category = solutionConfiguration.PlatformName; } using (fileGenerator.Declare("solutionConf", solutionConfiguration)) using (fileGenerator.Declare("projectGuid", solutionProject.UserData["Guid"])) using (fileGenerator.Declare("projectConf", projectConf)) using (fileGenerator.Declare("projectPlatform", Util.GetPlatformString(projectPlatform, solutionProject.Project, true))) using (fileGenerator.Declare("category", category)) using (fileGenerator.Declare("configurationName", configurationName)) { bool build = false; if (solution is PythonSolution) { // nothing is built in python solutions } else if (perfectMatch) { build = includedProject.ToBuild == Solution.Configuration.IncludedProjectInfo.Build.Yes; // for fastbuild, only build the projects that cannot be built through dependency chain if (!projectConf.IsFastBuild) { build |= includedProject.ToBuild == Solution.Configuration.IncludedProjectInfo.Build.YesThroughDependency; } else { if (build) { solutionConfigurationFastBuildBuilt[solutionConfiguration].Add(projectConf.Project.Name + " " + projectConf.Name); } } } fileGenerator.Write(Template.Solution.GlobalSectionProjectConfigurationActive); if (build) { fileGenerator.Write(Template.Solution.GlobalSectionProjectConfigurationBuild); bool deployProject = includedProject.Project.DeployProject || includedProject.Configuration.DeployProject; if (deployProject) { fileGenerator.Write(Template.Solution.GlobalSectionProjectConfigurationDeploy); } } } } } foreach (var fb in solutionConfigurationFastBuildBuilt) { var solutionConfiguration = fb.Key; if (fb.Value.Count == 0) { Builder.Instance.LogErrorLine($"{solutionFile} - {solutionConfiguration.Name}|{solutionConfiguration.PlatformName} - has no FastBuild projects to build."); } else if (fb.Value.Count > 1) { Builder.Instance.LogErrorLine($"{solutionFile} - {solutionConfiguration.Name}|{solutionConfiguration.PlatformName} - has more than one FastBuild project to build ({string.Join(";", fb.Value)})."); } } fileGenerator.Write(Template.Solution.GlobalSectionProjectConfigurationEnd); fileGenerator.Write(Template.Solution.SolutionProperties); // Write nested folders if (_solutionFolders.Count != 0) { fileGenerator.Write(Template.Solution.NestedProjectBegin); foreach (SolutionFolder folder in _solutionFolders) { if (folder.Parent != null) { using (fileGenerator.Declare("nestedChildGuid", folder.Guid.ToString().ToUpper())) using (fileGenerator.Declare("nestedParentGuid", folder.Parent.Guid.ToString().ToUpper())) { fileGenerator.Write(Template.Solution.NestedProjectItem); } } } foreach (Solution.ResolvedProject resolvedProject in solutionProjects.Concat(resolvedPathReferences)) { SolutionFolder folder = resolvedProject.UserData["Folder"] as SolutionFolder; if (folder != null) { using (fileGenerator.Declare("nestedChildGuid", resolvedProject.UserData["Guid"].ToString().ToUpper())) using (fileGenerator.Declare("nestedParentGuid", folder.Guid.ToString().ToUpper())) { fileGenerator.Write(Template.Solution.NestedProjectItem); } } } fileGenerator.Write(Template.Solution.NestedProjectEnd); } fileGenerator.Write(Template.Solution.GlobalEnd); // Write the solution file updated = _builder.Context.WriteGeneratedFile(solution.GetType(), solutionFileInfo, fileGenerator.ToMemoryStream()); solution.PostGenerationCallback?.Invoke(solutionPath, solutionFile, SolutionExtension); return(solutionFileInfo.FullName); }
public virtual void SetupExtraLinkerSettings(IFileGenerator fileGenerator, Project.Configuration configuration, string fastBuildOutputFile) { SetupExtraLinkerSettings(fileGenerator, configuration.Output); }
private List <Solution.ResolvedProject> ResolveSolutionProjects(Solution solution, IReadOnlyList <Solution.Configuration> solutionConfigurations) { bool projectsWereFiltered; List <Solution.ResolvedProject> solutionProjects = solution.GetResolvedProjects(solutionConfigurations, out projectsWereFiltered).ToList(); // Ensure all projects are always in the same order to avoid random shuffles solutionProjects.Sort((a, b) => { int nameComparison = string.Compare(a.ProjectName, b.ProjectName, StringComparison.InvariantCultureIgnoreCase); if (nameComparison != 0) { return(nameComparison); } return(string.Compare(a.ProjectFile, b.ProjectFile, StringComparison.InvariantCultureIgnoreCase)); }); // Validate and handle startup project. IEnumerable <Solution.Configuration> confWithStartupProjects = solutionConfigurations.Where(conf => conf.StartupProject != null); var startupProjectGroups = confWithStartupProjects.GroupBy(conf => conf.StartupProject.Configuration.ProjectFullFileName).ToArray(); if (startupProjectGroups.Length > 1) { throw new Error("Solution {0} contains multiple startup projects; this is not supported. Startup projects: {1}", Path.Combine(solutionConfigurations[0].SolutionPath, solutionConfigurations[0].SolutionFileName), string.Join(", ", startupProjectGroups.Select(group => group.Key))); } Solution.Configuration.IncludedProjectInfo startupProject = startupProjectGroups.Select(group => group.First().StartupProject).FirstOrDefault(); if (startupProject == null) { startupProject = ResolveStartupProject(solution, solutionConfigurations); } if (startupProject != null) { //put the startup project at the top of the project list. Visual Studio will put it as the default startup project. Solution.ResolvedProject resolvedStartupProject = solutionProjects.FirstOrDefault(x => x.OriginalProjectFile == startupProject.Configuration.ProjectFullFileName); if (resolvedStartupProject != null) { solutionProjects.Remove(resolvedStartupProject); solutionProjects.Insert(0, resolvedStartupProject); } } // Read project Guid and append project extension foreach (Solution.ResolvedProject resolvedProject in solutionProjects) { Project.Configuration firstConf = resolvedProject.Configurations.First(); if (firstConf.ProjectGuid == null) { if (!firstConf.Project.GetType().IsDefined(typeof(Compile), false)) { throw new Error("cannot read guid from existing project, project must have Compile attribute: {0}", resolvedProject.ProjectFile); } firstConf.ProjectGuid = ReadGuidFromProjectFile(resolvedProject.ProjectFile); } resolvedProject.UserData["Guid"] = firstConf.ProjectGuid; resolvedProject.UserData["TypeGuid"] = ReadTypeGuidFromProjectFile(resolvedProject.ProjectFile); resolvedProject.UserData["Folder"] = GetSolutionFolder(resolvedProject.SolutionFolder); } return(solutionProjects); }
public virtual void AddCompilerSettings(IDictionary <string, CompilerSettings> masterCompilerSettings, Project.Configuration conf) { }
public void SetupStaticLibraryPaths(Project.Configuration configuration, DependencySetting dependencySetting, Project.Configuration dependency) { DefaultPlatform.SetupLibraryPaths(configuration, dependencySetting, dependency); }
internal void Link(Builder builder) { if (_dependenciesResolved) { return; } bool hasFastBuildProjectConf = false; var unlinkedConfigurations = new Dictionary <Solution.Configuration, List <Project.Configuration> >(); // This will hold MSBuild -> Fastbuild refs using (builder.CreateProfilingScope("Solution.Link:confs", Configurations.Count)) { foreach (Solution.Configuration solutionConfiguration in Configurations) { // Build SolutionFilesMapping string configurationFile = Path.Combine(solutionConfiguration.SolutionPath, solutionConfiguration.SolutionFileName); var fileConfigurationList = SolutionFilesMapping.GetValueOrAdd(configurationFile, new List <Solution.Configuration>()); fileConfigurationList.Add(solutionConfiguration); var unlinkedList = unlinkedConfigurations.GetValueOrAdd(solutionConfiguration, new List <Project.Configuration>()); // solutionConfiguration.IncludedProjectInfos will be appended // while iterating, but with projects that we already have resolved, // so no need to parse them again int origCount = solutionConfiguration.IncludedProjectInfos.Count; for (int i = 0; i < origCount; ++i) { Configuration.IncludedProjectInfo configurationProject = solutionConfiguration.IncludedProjectInfos[i]; bool projectIsInactive = configurationProject.InactiveProject; Project project = builder.GetProject(configurationProject.Type); Project.Configuration projectConfiguration = project.GetConfiguration(configurationProject.Target); if (projectConfiguration == null) { var messageBuilder = new System.Text.StringBuilder(); messageBuilder.AppendFormat("Resolving dependencies for solution {0}, target '{1}': cannot find target '{3}' in project {2}", GetType().FullName, solutionConfiguration.Target, project.GetType().FullName, configurationProject.Target); messageBuilder.AppendLine(); if (project.Configurations.Any()) { messageBuilder.AppendLine("Project configurations are:"); int confNum = 0; foreach (var conf in project.Configurations) { messageBuilder.AppendLine(++confNum + "/" + project.Configurations.Count + " " + conf.ToString()); } } else { messageBuilder.AppendLine("The project does not contain any configurations!"); } Trace.WriteLine(messageBuilder.ToString()); Debugger.Break(); throw new Error(messageBuilder.ToString()); } if (configurationProject.Project == null) { configurationProject.Project = project; } else if (configurationProject.Project != project) { throw new Error("Tried to match more than one project to Project type."); } if (configurationProject.Configuration == null) { configurationProject.Configuration = projectConfiguration; } else if (configurationProject.Configuration != projectConfiguration) { throw new Error("Tried to match more than one Project Configuration to a solution configuration."); } hasFastBuildProjectConf |= projectConfiguration.IsFastBuild; if (projectConfiguration.IsFastBuild) { projectConfiguration.AddMasterBff(solutionConfiguration.MasterBffFilePath); } bool build = !projectConfiguration.IsExcludedFromBuild && !configurationProject.InactiveProject; if (build && solutionConfiguration.IncludeOnlyFilterProject && (configurationProject.Project.SourceFilesFiltersCount == 0 || configurationProject.Project.SkipProjectWhenFiltersActive)) { build = false; } if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency) { if (build) { configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.Yes; } else if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.Yes) { configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.No; } } var dependenciesConfiguration = configurationProject.Configuration.GetRecursiveDependencies(); // TODO: Slow LINQ? May be better to create this list as part of GetRecursiveDependencies if (!configurationProject.Configuration.IsFastBuild && configurationProject.Configuration.ResolvedDependencies.Any(d => d.IsFastBuild)) { unlinkedList.Add(configurationProject.Configuration); } unlinkedList.AddRange(dependenciesConfiguration.Where(c => !c.IsFastBuild && c.ResolvedDependencies.Any(d => d.IsFastBuild))); foreach (Project.Configuration dependencyConfiguration in dependenciesConfiguration) { Project dependencyProject = dependencyConfiguration.Project; if (dependencyProject.SharpmakeProjectType == Project.ProjectTypeAttribute.Export) { continue; } Type dependencyProjectType = dependencyProject.GetType(); ITarget dependencyProjectTarget = dependencyConfiguration.Target; hasFastBuildProjectConf |= dependencyConfiguration.IsFastBuild; if (dependencyConfiguration.IsFastBuild) { dependencyConfiguration.AddMasterBff(solutionConfiguration.MasterBffFilePath); } Configuration.IncludedProjectInfo configurationProjectDependency = solutionConfiguration.GetProject(dependencyProjectType); // if that project was not explicitly added to the solution configuration, add it ourselves, as it is needed if (configurationProjectDependency == null) { configurationProjectDependency = new Configuration.IncludedProjectInfo { Type = dependencyProjectType, Project = dependencyProject, Configuration = dependencyConfiguration, Target = dependencyProjectTarget, InactiveProject = projectIsInactive // inherit from the parent: no reason to mark dependencies for build if parent is inactive }; solutionConfiguration.IncludedProjectInfos.Add(configurationProjectDependency); } else if (!projectIsInactive && configurationProjectDependency.InactiveProject) { // if the project we found in the solutionConfiguration is inactive, and the current is not, replace its settings configurationProjectDependency.Type = dependencyProjectType; configurationProjectDependency.Project = dependencyProject; configurationProjectDependency.Configuration = dependencyConfiguration; configurationProjectDependency.Target = dependencyProjectTarget; configurationProjectDependency.InactiveProject = false; } else if (projectIsInactive) { // if the current project is inactive, ignore } else { if (!configurationProjectDependency.Target.IsEqualTo(dependencyProjectTarget)) { throw new Error("In solution configuration (solution: {3}, config: {4}) the parent project {5} generates multiple dependency targets for the same child project {0}: {1} and {2}. Look for all AddPublicDependency() and AddPrivateDependency() calls for the child project and follow the dependency chain.", configurationProjectDependency.Project?.GetType().ToString(), configurationProjectDependency.Target, dependencyProjectTarget, solutionConfiguration.SolutionFileName, solutionConfiguration.Target, project.Name ); } if (configurationProjectDependency.Project == null) { configurationProjectDependency.Project = dependencyProject; } else if (configurationProjectDependency.Project != dependencyProject) { throw new Error("Tried to match more than one project to Project type."); } if (configurationProjectDependency.Configuration == null) { configurationProjectDependency.Configuration = dependencyConfiguration; } else if (configurationProjectDependency.Configuration != dependencyConfiguration) { throw new Error("Tried to match more than one Project Configuration to a solution configuration."); } } if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency) { // If we're finding a Fastbuild dependency of an MSBuild project, we know that it'll need re-linking if the All project is generated. var needsFastbuildRelink = (dependencyConfiguration.IsFastBuild && !configurationProject.Configuration.IsFastBuild && GenerateFastBuildAllProject); var isExcludedSinceNoFilter = solutionConfiguration.IncludeOnlyFilterProject && (configurationProjectDependency.Project.SourceFilesFiltersCount == 0 || configurationProjectDependency.Project.SkipProjectWhenFiltersActive); var skipBuild = dependencyConfiguration.IsExcludedFromBuild || projectIsInactive || configurationProjectDependency.InactiveProject || needsFastbuildRelink || isExcludedSinceNoFilter; if (!skipBuild) { if (projectConfiguration.Output == Project.Configuration.OutputType.Dll || projectConfiguration.Output == Project.Configuration.OutputType.Exe) { configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.YesThroughDependency; } else { configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.Yes; } } else if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.Yes) { configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.No; } } } } } if (hasFastBuildProjectConf) { MakeFastBuildAllProjectIfNeeded(builder, unlinkedConfigurations); } _dependenciesResolved = true; } }
public IEnumerable <string> GetPlatformLibraryPaths(Project.Configuration configuration) { yield break; }
internal static bool IsFastBuildEnabledProjectConfig(this Project.Configuration conf) { return(conf.IsFastBuild && conf.Platform.IsSupportedFastBuildPlatform() && !conf.DoNotGenerateFastBuild); }
public override void SetupExtraLinkerSettings(IFileGenerator fileGenerator, Project.Configuration configuration, string fastBuildOutputFile) { string sharedOption = string.Empty; if (configuration.Output == Project.Configuration.OutputType.Dll) { sharedOption = " -shared"; } using (fileGenerator.Resolver.NewScopedParameter("sharedOption", sharedOption)) { fileGenerator.Write(_linkerOptionsTemplate); } }