public void ShouldBindToNullWhenNoTargetIsResolved() { var target = new ResolvedTarget(typeof(string)); var context = GetCompileContext(target); Assert.Null(target.Bind(context)); }
/// <summary> /// Registers an alias for one type to another type. /// /// The created entry will effectively represent a second Resolve call into the container for the aliased type. /// </summary> /// <param name="targetContainer">The builder in which the alias is to be registered</param> /// <param name="aliasType">The type to be registered as an alias</param> /// <param name="originalType">The type being aliased.</param> /// <remarks>Use this when it's important that a given target type is always served through the same compiled target, even when the consumer /// expects it to be of a different type. A very common scenario is when you have a singleton instance of the <paramref name="originalType" />, /// and need to serve that same instance for <paramref name="aliasType"/>. If you register the same singleton for both types, you get two /// separate singletons for each type, whereas if you create an alias, both will be served by the same alias. /// </remarks> public static void RegisterAlias(this ITargetContainer targetContainer, Type aliasType, Type originalType) { if (targetContainer == null) { throw new ArgumentNullException(nameof(targetContainer)); } if (aliasType == originalType) { throw new ArgumentException("The aliased type and its alias must be different", nameof(aliasType)); } ITarget target = new ResolvedTarget(originalType); // if there's no implicit conversion to our alias type from the aliased type, but there is // the other way around, then we need to stick in an explicit change of type, otherwise the registration will // fail. This does, unfortunately, give rise to the situation where we could be performing an invalid cast - but that // will come out in the wash at runtime. if (!aliasType.IsAssignableFrom(originalType) && originalType.IsAssignableFrom(aliasType)) { target = new ChangeTypeTarget(target, aliasType); } targetContainer.Register(target, aliasType); }
public static void EmitExecutable( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { // Executable( alias ) ; (optional) Alias // { // .Linker ; Linker executable to use // .LinkerOutput ; Output from linker // .LinkerOptions ; Options to pass to linker // .Libraries ; Libraries to link into executable // .LinkerLinkObjects ; (optional) Link objects used to make libs instead of libs (default false) // .LinkerAssemblyResources ; (optional) List of assembly resources to use with %3 // // .LinkerStampExe ; (optional) Executable to run post-link to "stamp" executable in-place // .LinkerStampExeArgs ; (optional) Arguments to pass to LinkerStampExe // .LinkerType ; (optional) Specify the linker type. Valid options include: // ; auto, msvc, gcc, snc-ps3, clang-orbis, greenhills-exlr, codewarrior-ld // ; Default is 'auto' (use the linker executable name to detect) // .LinkerAllowResponseFile ; (optional) Allow response files to be used if not auto-detected (default: false) // .LinkerForceResponseFile ; (optional) Force use of response files (default: false) // // ; Additional options // .PreBuildDependencies ; (optional) Force targets to be built before this Executable (Rarely needed, // ; but useful when Executable relies on externally generated files). // // .Environment ; (optional) Environment variables to use for local build // ; If set, linker uses this environment // ; If not set, linker uses .Environment from your Settings node // } }
public static void EmitTest( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { // Test( alias ) // (optional) Alias // { // // Options // .TestExecutable // The executable file to run that will execute the tests // .TestOutput // Output file for captured test output // // // Additional inputs // .TestInput // (optional) Input file(s) to pass to executable // .TestInputPath // (optional) Path to find files in // .TestInputPattern // (optional) Pattern(s) to use when finding files (default *.*) // .TestInputPathRecurse // (optional) Recurse into dirs when finding files (default true) // .TestInputExcludePath // (optional) Path(s) to exclude // .TestInputExcludedFiles // (optional) File(s) to exclude from compilation (partial, root-relative of full path) // .TestInputExcludePattern // (optional) Pattern(s) to exclude // // // Other // .TestArguments // (optional) Arguments to pass to test executable // .TestWorkingDir // (optional) Working dir for test execution // .TestTimeOut // (optional) TimeOut (in seconds) for test (default: 0, no timeout) // .TestAlwaysShowOutput // (optional) Show output of tests even when they don't fail (default: false) // // // Additional options // .PreBuildDependencies // (optional) Force targets to be built before this Test (Rarely needed, // // but useful when Test relies on externally generated files). // // .Environment // (optional) Environment variables to use for local build // // If set, linker uses this environment // // If not set, linker uses .Environment from your Settings node // } }
public void ShouldSetAllPropertiesIfProvided() { var fallback = new TestTarget(supportsType: true); var target = new ResolvedTarget(typeof(string), fallback); Assert.Equal(typeof(string), target.DeclaredType); Assert.Same(fallback, target.FallbackTarget); }
private static void EmitSources( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { var platform = solution.Platform; var toolchain = solution.Toolchain; var variablePrefix = $@"{toolchain.ToolchainType}_{toolchain.ArchitectureType}_{platform.PlatformType}"; var configurationPart = (target.SourceTarget.ConfigurationFlavour == ConfigurationFlavour.None) ? target.SourceTarget.ConfigurationType.ToString() : $@"{target.SourceTarget.ConfigurationType}{target.SourceTarget.ConfigurationFlavour}"; var sourcePath = target.SourceTarget.Project.ProjectRootPath; output.WriteLine($@"Unity('Unity-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}') {{"); output.WriteLine($@" .UnityInputPath = '{sourcePath}'"); output.WriteLine($@" .UnityInputPattern = {{ '*.cxx' }}"); output.WriteLine($@" .UnityOutputPath = 'unity/{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}'"); output.WriteLine($@" .UnityOutputPattern = '{target.Name}-unity-*.cxx'"); output.WriteLine($@" .UnityNumFiles = 1"); output.WriteLine($@" .UnityInputExcludePattern = {{"); output.WriteLine($@" '*Linux.*.cxx'"); output.WriteLine($@" '*Android.*.cxx'"); output.WriteLine($@" '*Posix.*.cxx'"); output.WriteLine($@" '*UWP.*.cxx'"); output.WriteLine($@" }}"); output.WriteLine($@"}}"); output.WriteLine($@"ObjectList('Obj-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}') {{"); output.WriteLine($@" Using(.{variablePrefix}_CommonPlatformToolchain)"); output.WriteLine($@" .CompilerOutputPath = 'obj/{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}'"); output.WriteLine($@" .CompilerOptions = ''"); output.WriteLine($@" + ' {toolchain.FormatCompilerInputFile("%1")}'"); output.WriteLine($@" + ' {toolchain.FormatCompilerOutputFile("%2")}'"); output.WriteLine($@" + .{variablePrefix}_PlatformIncludePaths"); output.WriteLine($@" + .{variablePrefix}_ToolchainIncludePaths"); foreach (var item in toolchain.GetCompilerCommandLine(target.SourceTarget)) { output.WriteLine($@" + ' {item}'"); } foreach (var path in target.PrivateIncludePaths) { output.WriteLine($@" + ' {toolchain.FormatIncludePath(path)}'"); } foreach (var path in target.PrivateDefines) { output.WriteLine($@" + ' {toolchain.FormatDefine(path)}'"); } output.WriteLine($@" .CompilerInputUnity = 'Unity-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}'"); output.WriteLine($@"}}"); }
public void ShouldUseFallbackWhenContextContainerFails() { var container = new Container(); var fallback = new TestTarget(typeof(string), useFallBack: false, supportsType: true); var target = new ResolvedTarget(typeof(string), fallback); var context = GetCompileContext(target, container); var result = target.Bind(context); Assert.NotNull(result); Assert.Same(fallback, result); }
public void ShouldBindToTargetFromContextContainer() { var container = new Container(); container.Register(new TestTarget(typeof(string), useFallBack: false, supportsType: true)); var target = new ResolvedTarget(typeof(string)); var context = GetCompileContext(target, container); var result = target.Bind(context); Assert.NotNull(result); Assert.IsType <TestTarget>(result); }
public static void EmitObjectList( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { // ObjectList( alias ) ; Alias // { // ; options for compilation // .Compiler ; Compiler to use // .CompilerOptions ; Options for compiler // .CompilerOutputPath ; Path to store intermediate objects // .CompilerOutputExtension ; (optional) Specify the file extension for generated objects (default .obj or .o) // .CompilerOutputKeepBaseExtension ; (optional) Append extension instead of replacing it (default: false) // .CompilerOutputPrefix ; (optional) Specify a prefix for generated objects (default none) // // ; Specify inputs for compilation // .CompilerInputPath ; (optional) Path to find files in // .CompilerInputPattern ; (optional) Pattern(s) to use when finding files (default *.cpp) // .CompilerInputPathRecurse ; (optional) Recurse into dirs when finding files (default true) // .CompilerInputExcludePath ; (optional) Path(s) to exclude from compilation // .CompilerInputExcludedFiles ; (optional) File(s) to exclude from compilation (partial, root-relative of full path) // .CompilerInputExcludePattern ; (optional) Pattern(s) to exclude from compilation // .CompilerInputFiles ; (optional) Explicit array of files to build // .CompilerInputFilesRoot ; (optional) Root path to use for .obj path generation for explicitly listed files // .CompilerInputUnity ; (optional) Unity to build (or Unities) // .CompilerInputAllowNoFiles ; (optional) Don't fail if no inputs are found // .CompilerInputObjectLists ; (optional) ObjectList(s) whos output should be used as an input // // ; Cache & Distributed compilation control // .AllowCaching ; (optional) Allow caching of compiled objects if available (default true) // .AllowDistribution ; (optional) Allow distributed compilation if available (default true) // // ; Custom preprocessor support // .Preprocessor ; (optional) Compiler to use for preprocessing // .PreprocessorOptions ; (optional) Args to pass to compiler if using custom preprocessor // // ; Additional compiler options // .CompilerForceUsing ; (optional) List of objects to be used with /FU // // ; (optional) Properties to control precompiled header use // .PCHInputFile ; (optional) Precompiled header (.cpp) file to compile // .PCHOutputFile ; (optional) Precompiled header compilation output // .PCHOptions ; (optional) Options for compiler for precompiled header // // ; Additional options // .PreBuildDependencies ; (optional) Force targets to be built before this ObjectList (Rarely needed, // ; but useful when a ObjectList relies on generated code). // .Hidden ; (optional) Hide a target from -showtargets (default false) // } }
public static void EmitUnity( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { var platform = solution.Platform; var toolchain = solution.Toolchain; var variablePrefix = $@"{toolchain.ToolchainType}_{toolchain.ArchitectureType}_{platform.PlatformType}"; var configurationPart = (target.SourceTarget.ConfigurationFlavour == ConfigurationFlavour.None) ? target.SourceTarget.ConfigurationType.ToString() : $@"{target.SourceTarget.ConfigurationType}{target.SourceTarget.ConfigurationFlavour}"; var targetName = $@"{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}"; output.WriteLine($@"Unity('Unity-{targetName}') {{"); // { // .UnityInputPath ; (optional) Path (or paths) to find files // .UnityInputExcludePath ; (optional) Path (or paths) in which to ignore files // .UnityInputExcludePattern; (optional) Wildcard pattern(s) of files/folders to exclude // .UnityInputPattern ; (optional) Pattern(s) of files to find (default *.cpp) // .UnityInputPathRecurse ; (optional) Recurse when searching for files (default true) // .UnityInputFiles ; (optional) Explicit list of files to include // .UnityInputExcludedFiles ; (optional) Explicit list of excluded files (partial, root-relative or full path) // .UnityInputIsolatedFiles ; (optional) List of files to exclude from unity, but still compile (partial end or root-relative) // .UnityInputObjectLists ; (optional) ObjectList(s) to use as input // .UnityInputIsolateWritableFiles ; (optional) Build writable files individually (default false) // .UnityInputIsolateWritableFilesLimit ; (optional) Disable isolation when many files are writable (default 0) // .UnityInputIsolateListFile ; (optional) Text file containing list of files to isolate // .UnityOutputPath ; Path to output generated Unity files // .UnityOutputPattern ; (optional) Pattern of output Unity file names (default Unity*.cpp) // .UnityNumFiles ; (optional) Number of Unity files to generate (default 1) // .UnityPCH ; (optional) Precompiled Header file to add to generated Unity files // .PreBuildDependencies ; (optional) Force targets to be built before this Unity (Rarely needed, // ; but useful when a Unity should contain generated code) // .Hidden ; (optional) Hide a target from -showtargets (default false) // .UseRelativePaths_Experimental ; (optional) Use relative paths for generated Unity files // } output.WriteLine($@"}}"); }
public static void EmitTarget( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { var targetType = target.SourceTarget.TargetType; if (targetType == TargetType.SharedLibrary) { EmitSharedLibrary(output, solution, target); } else if (targetType == TargetType.StaticLibrary) { EmitStaticLibrary(output, solution, target); } else if (targetType == TargetType.HeaderLibrary) { ; } else if (targetType == TargetType.Application) { EmitExecutable(output, solution, target); } }
private static void EmitProjectDefinition( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { FastbuildTemplate.EmitTarget(output, solution, target); #if false var platform = solution.Platform; var toolchain = solution.Toolchain; var targetCompileCommands = toolchain.GetCompilerCommandLine(target.SourceTarget); var variablePrefix = $@"{toolchain.ToolchainType}_{toolchain.ArchitectureType}_{platform.PlatformType}"; var configurationPart = (target.SourceTarget.ConfigurationFlavour == ConfigurationFlavour.None) ? target.SourceTarget.ConfigurationType.ToString() : $@"{target.SourceTarget.ConfigurationType}{target.SourceTarget.ConfigurationFlavour}"; var targetFileName = platform.AdjustTargetName(target.Name, target.SourceTarget.TargetType); EmitSources(output, solution, target); var functionType = MapToFunctionType(target.SourceTarget.TargetType); output.WriteLine($@"; Location: {target.SourceTarget.Project.ProjectRootPath}"); output.WriteLine($@"{functionType}('Target-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}') {{"); output.WriteLine($@" Using(.{variablePrefix}_CommonPlatformToolchain)"); output.WriteLine($@" .CompilerOutputPath = 'obj-1/{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}'"); output.WriteLine($@" .CompilerOptions = ''"); output.WriteLine($@" + ' {toolchain.FormatCompilerInputFile("%1")}'"); output.WriteLine($@" + ' {toolchain.FormatCompilerOutputFile("%2")}'"); output.WriteLine($@" + .{variablePrefix}_PlatformIncludePaths"); output.WriteLine($@" + .{variablePrefix}_ToolchainIncludePaths"); foreach (var item in targetCompileCommands) { output.WriteLine($@" + ' {item}'"); } foreach (var path in target.PrivateIncludePaths) { output.WriteLine($@" + ' {toolchain.FormatIncludePath(path)}'"); } foreach (var path in target.PrivateDefines) { output.WriteLine($@" + ' {toolchain.FormatDefine(path)}'"); } if (target.SourceTarget.TargetType == TargetType.StaticLibrary) { output.WriteLine($@" .CompilerInputObjectLists = {{"); output.WriteLine($@" 'Obj-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}'"); output.WriteLine($@" }}"); } var linker = (target.SourceTarget.TargetType == TargetType.SharedLibrary) ? "Linker" : "Librarian"; output.WriteLine($@" .{linker}Output = '.generated/bin/{variablePrefix}{configurationPart}/{targetFileName}'"); output.WriteLine($@" .{linker}Options = ''"); output.WriteLine($@" + ' /NOLOGO'"); output.WriteLine($@" + ' /MACHINE:X64'"); output.WriteLine($@" + .{variablePrefix}_ToolchainLibraryPaths"); output.WriteLine($@" + .{variablePrefix}_PlatformLibraryPaths"); output.WriteLine($@" + ' {toolchain.FormatLinkerGroupStart}{toolchain.FormatLinkerInputFile("%1")}{toolchain.FormatLinkerGroupEnd}'"); output.WriteLine($@" + ' {toolchain.FormatLinkerOutputFile("%2")}'"); if (target.SourceTarget.TargetType == TargetType.SharedLibrary) { output.WriteLine($@" + ' /DLL'"); } foreach (var path in target.PrivateLibraryPaths) { output.WriteLine($@" + ' {toolchain.FormatLibraryPath(path)}'"); } foreach (var lib in target.PrivateLibraries) { output.WriteLine($@" + ' {toolchain.FormatLink(lib)}'"); } output.WriteLine($@" .Libraries = {{"); foreach (var dep in target.PrivateDependencies) { output.WriteLine($@" 'Target-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{dep.Name}-{configurationPart}'"); } output.WriteLine($@" 'Obj-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}'"); output.WriteLine($@" }}"); output.WriteLine($@"}}"); #endif }
public static void EmitStaticLibrary( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target) { var platform = solution.Platform; var toolchain = solution.Toolchain; var variablePrefix = $@"{toolchain.ToolchainType}_{toolchain.ArchitectureType}_{platform.PlatformType}"; var configurationPart = (target.SourceTarget.ConfigurationFlavour == ConfigurationFlavour.None) ? target.SourceTarget.ConfigurationType.ToString() : $@"{target.SourceTarget.ConfigurationType}{target.SourceTarget.ConfigurationFlavour}"; var sourcePath = target.SourceTarget.Project.ProjectRootPath; for (var i = 0; i < target.SourceTarget.Sources.Count; ++i) { var source = target.SourceTarget.Sources[i]; EmitSourceList(output, solution, target, source, $@"Source-{i}"); } if (target.SourceTarget.Sources.Count == 0) { // Otherwise, add default source list EmitSourceList(output, solution, target, new SourceList() { MergeFiles = 1, InputPaths = new[] { sourcePath, }, InputPattern = "*.cxx", }, $@"Source"); } // Library( alias ) ; (optional) Alias // { // ; options for compilation // .Compiler ; Compiler to use // .CompilerOptions ; Options for compiler // .CompilerOutputPath ; Path to store intermediate objects // .CompilerOutputExtension ; (optional) Specify the file extension for generated objects (default .obj or .o) // .CompilerOutputPrefix ; (optional) Specify a prefix for generated objects (default none) // // ; Options for librarian // .Librarian ; Librarian to collect intermediate objects // .LibrarianOptions ; Options for librarian // .LibrarianType ; (optional) Specify the librarian type. Valid options include: // ; auto, msvc, ar, ar-orbis, greenhills-ax // ; Default is 'auto' (use the librarian executable name to detect) // .LibrarianOutput ; Output path for lib file // .LibrarianAdditionalInputs; (optional) Additional inputs to merge into library // .LibrarianAllowResponseFile ; (optional) Allow response files to be used if not auto-detected (default: false) // .LibrarianForceResponseFile ; (optional) Force use of response files (default: false) // // ; Specify inputs for compilation // .CompilerInputPath ; (optional) Path to find files in // .CompilerInputPattern ; (optional) Pattern(s) to use when finding files (default *.cpp) // .CompilerInputPathRecurse ; (optional) Recurse into dirs when finding files (default true) // .CompilerInputExcludePath ; (optional) Path(s) to exclude from compilation // .CompilerInputExcludedFiles ; (optional) File(s) to exclude from compilation (partial, root-relative of full path) // .CompilerInputExcludePattern ; (optional) Pattern(s) to exclude from compilation // .CompilerInputFiles ; (optional) Explicit array of files to build // .CompilerInputFilesRoot ; (optional) Root path to use for .obj path generation for explicitly listed files // .CompilerInputUnity ; (optional) Unity to build (or Unities) // .CompilerInputObjectLists ; (optional) ObjectList(s) whos output should be used as an input // // ; Cache & Distributed compilation control // .AllowCaching ; (optional) Allow caching of compiled objects if available (default true) // .AllowDistribution ; (optional) Allow distributed compilation if available (default true) // // ; Custom preprocessor support // .Preprocessor ; (optional) Compiler to use for preprocessing // .PreprocessorOptions ; (optional) Args to pass to compiler if using custom preprocessor // // ; Additional compiler options // .CompilerForceUsing ; (optional) List of objects to be used with /FU // // ; (optional) Properties to control precompiled header use // .PCHInputFile ; (optional) Precompiled header (.cpp) file to compile // .PCHOutputFile ; (optional) Precompiled header compilation output // .PCHOptions ; (optional) Options for compiler for precompiled header // // ; Additional options // .PreBuildDependencies ; (optional) Force targets to be built before this library (Rarely needed, // ; but useful when a library relies on generated code). // // .Environment ; (optional) Environment variables to use for local build // ; If set, librarian uses this environment // ; If not set, librarian uses .Environment from your Settings node // .Hidden ; (optional) Hide a target from -showtargets (default false) // } }
public static void EmitSourceList( StreamWriter output, EvaluatedSolution solution, ResolvedTarget target, SourceList source, string name) { var platform = solution.Platform; var toolchain = solution.Toolchain; var variablePrefix = $@"{toolchain.ToolchainType}_{toolchain.ArchitectureType}_{platform.PlatformType}"; var configurationPart = (target.SourceTarget.ConfigurationFlavour == ConfigurationFlavour.None) ? target.SourceTarget.ConfigurationType.ToString() : $@"{target.SourceTarget.ConfigurationType}{target.SourceTarget.ConfigurationFlavour}"; var targetName = $@"{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}-{target.Name}-{configurationPart}"; if (source.MergeFiles == 0) { output.WriteLine($@"; Emit-explicit-sources: {targetName}-{name}"); // Emit ObjectList output.WriteLine($@"ObjectList('Objects-{targetName}-{name}') {{"); output.WriteLine($@" .Compiler = 'Compiler-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}'"); output.WriteLine($@" .CompilerOptions = '{toolchain.FormatCompilerInputFile("%1")} {toolchain.FormatCompilerOutputFile("%2")}'"); output.WriteLine($@" .CompilerOutputPath = 'build/obj/{targetName}'"); output.WriteLine($@" .CompilerInputFiles = {{"); foreach (var file in source.Files) { output.WriteLine($@" '{target.SourceTarget.Project.ProjectRootPath}/{file}'"); } output.WriteLine($@" }}"); output.WriteLine($@" .CompilerInputFilesRoot = '{target.SourceTarget.Project.ProjectRootPath}'"); output.WriteLine($@"}}"); } else { output.WriteLine($@"Unity('Unity-{targetName}-{name}') {{"); output.WriteLine($@" .UnityNumFiles = {source.MergeFiles}"); if (source.InputPaths != null) { output.WriteLine($@" .UnityInputPath = {{"); foreach (var path in source.InputPaths) { output.WriteLine($@" '{path}'"); } output.WriteLine($@" }}"); } if (source.InputPattern != null) { output.WriteLine($@" .UnityInputPattern = {{ '{source.InputPattern}' }}"); } if (source.ExcludePaths != null) { output.WriteLine($@" .UnityInputExcludePath = {{"); foreach (var path in source.ExcludePaths) { output.WriteLine($@" '{path}'"); } output.WriteLine($@"}}"); } if (source.ExcludePattern != null) { output.WriteLine($@" .UnityInputExcludePattern = '{source.ExcludePattern}'"); } output.WriteLine($@" .UnityOutputPath = 'build/unity/{targetName}'"); output.WriteLine($@" .UnityOutputPattern = '{target.Name}-unity-*.cxx'"); // .UnityInputPath ; (optional) Path (or paths) to find files // .UnityInputExcludePath ; (optional) Path (or paths) in which to ignore files // .UnityInputExcludePattern; (optional) Wildcard pattern(s) of files/folders to exclude // .UnityInputPattern ; (optional) Pattern(s) of files to find (default *.cpp) // .UnityInputPathRecurse ; (optional) Recurse when searching for files (default true) // .UnityInputFiles ; (optional) Explicit list of files to include // .UnityInputExcludedFiles ; (optional) Explicit list of excluded files (partial, root-relative or full path) // .UnityInputIsolatedFiles ; (optional) List of files to exclude from unity, but still compile (partial end or root-relative) // .UnityInputObjectLists ; (optional) ObjectList(s) to use as input // .UnityOutputPath ; Path to output generated Unity files // .UnityOutputPattern ; (optional) Pattern of output Unity file names (default Unity*.cpp) // .UnityPCH ; (optional) Precompiled Header file to add to generated Unity files // } output.WriteLine($@"}}"); output.WriteLine($@"ObjectList('Objects-{targetName}-{name}') {{"); output.WriteLine($@" .Compiler = 'Compiler-{toolchain.ToolchainType}-{toolchain.ArchitectureType}-{platform.PlatformType}'"); output.WriteLine($@" .CompilerOptions = '{toolchain.FormatCompilerInputFile("%1")} {toolchain.FormatCompilerOutputFile("%2")}'"); output.WriteLine($@" .CompilerOutputPath = 'build/obj/{targetName}'"); output.WriteLine($@" .CompilerInputUnity = 'Unity-{targetName}-{name}'"); output.WriteLine($@"}}"); } }