Пример #1
0
        CreateCollatedSymbolicLink(
            Bam.Core.Module sourceModule,
            Bam.Core.TokenizedString sourcePath,
            CollatedFile reference,
            Bam.Core.TokenizedString subDirectory)
        {
            if (null == reference)
            {
                throw new Bam.Core.Exception("Collating a symbolic link requires a collated file as reference");
            }

            var copySymlinkModule = Bam.Core.Module.Create <CollatedSymbolicLink>(preInitCallback: module =>
            {
                module.Macros["CopyDir"] = GenerateSymbolicLinkCopyDestination(
                    module,
                    reference.GeneratedPaths[CollatedObject.Key],
                    subDirectory);
            });

            this.Requires(copySymlinkModule);

            copySymlinkModule.SourceModule = sourceModule;
            copySymlinkModule.SourcePath   = sourcePath;
            copySymlinkModule.Reference    = reference;
            copySymlinkModule.SubDirectory = subDirectory;
            return(copySymlinkModule);
        }
Пример #2
0
        Include <DependentModule>(
            Bam.Core.PathKey key,
            string subDirectory,
            CollatedObject reference) where DependentModule : Bam.Core.Module, new()
        {
            var dependent = Bam.Core.Graph.Instance.FindReferencedModule <DependentModule>();

            this.Requires(dependent);
            this.Requires(dependent.Tool);

            var strippedInitialRef = this.RefMap[reference];

            var subDir         = Bam.Core.TokenizedString.CreateVerbatim(subDirectory);
            var copyFileModule = Bam.Core.Module.Create <CollatedFile>(preInitCallback: module =>
            {
                Bam.Core.TokenizedString referenceFilePath = strippedInitialRef.GeneratedPaths[this.ReferenceKey];
                this.RegisterGeneratedFile(Key, module.CreateTokenizedString("@dir($(0))", dependent.GeneratedPaths[key]));
                module.Macros["CopyDir"] = Collation.GenerateFileCopyDestination(
                    module,
                    referenceFilePath,
                    subDir,
                    this.GeneratedPaths[Key]);
            });

            this.Requires(copyFileModule);

            copyFileModule.SourceModule = dependent;
            copyFileModule.SourcePath   = dependent.GeneratedPaths[key];
            copyFileModule.Reference    = strippedInitialRef as CollatedFile;
            copyFileModule.SubDirectory = subDir;
            return(copyFileModule);
        }
Пример #3
0
        CreateCollatedSymbolicLink(
            Bam.Core.Module sourceModule,
            Bam.Core.TokenizedString sourcePath,
            CollatedFile reference,
            Bam.Core.TokenizedString subDirectory)
        {
            if (null == reference)
            {
                throw new Bam.Core.Exception("Collating a symbolic link requires a collated file as reference");
            }

            var copySymlinkModule = Bam.Core.Module.Create <CollatedSymbolicLink>(preInitCallback: module =>
            {
                module.Macros["CopyDir"] = GenerateSymbolicLinkCopyDestination(
                    module,
                    reference.GeneratedPaths[CollatedObject.Key],
                    subDirectory);
            });

            this.Requires(copySymlinkModule);
            if (null != reference.SourceModule &&
                null != sourceModule &&
                reference.SourceModule != sourceModule) // in case a different key from the same module is published
            {
                // ensuring that non-Native builders set up order-only dependencies for additional published only modules
                reference.SourceModule.Requires(sourceModule);
            }

            copySymlinkModule.SourceModule = sourceModule;
            copySymlinkModule.SourcePath   = sourcePath;
            copySymlinkModule.Reference    = reference;
            copySymlinkModule.SubDirectory = subDirectory;
            return(copySymlinkModule);
        }
Пример #4
0
        CreateCollatedFile(
            Bam.Core.Module sourceModule,
            Bam.Core.TokenizedString sourcePath,
            CollatedFile reference,
            Bam.Core.TokenizedString subDirectory)
        {
            var copyFileModule = Bam.Core.Module.Create <CollatedFile>(preInitCallback: module =>
            {
                Bam.Core.TokenizedString referenceFilePath = null;
                if (null != reference)
                {
                    referenceFilePath = reference.GeneratedPaths[CollatedObject.Key];
                }
                else
                {
                    if (!this.GeneratedPaths.ContainsKey(Key))
                    {
                        this.RegisterGeneratedFile(Key, module.CreateTokenizedString("@dir($(0))", sourcePath));
                    }
                }
                module.Macros["CopyDir"] = GenerateFileCopyDestination(
                    module,
                    referenceFilePath,
                    subDirectory,
                    this.GeneratedPaths[Key]);
            });

            this.Requires(copyFileModule);

            copyFileModule.SourceModule = sourceModule;
            copyFileModule.SourcePath   = sourcePath;
            copyFileModule.Reference    = reference;
            copyFileModule.SubDirectory = subDirectory;
            return(copyFileModule);
        }
Пример #5
0
 IncludeDirectory(
     Bam.Core.TokenizedString parameterizedPath,
     string subdir,
     CollatedFile reference)
 {
     return(this.CreateCollatedDirectory(null, parameterizedPath, reference, Bam.Core.TokenizedString.CreateVerbatim(subdir)));
 }
Пример #6
0
 GenerateFileCopyDestination(
     Bam.Core.Module module,
     Bam.Core.TokenizedString referenceFilePath,
     Bam.Core.TokenizedString subDirectory,
     Bam.Core.TokenizedString unReferencedRoot)
 {
     if (referenceFilePath != null)
     {
         if (null != subDirectory)
         {
             return(module.CreateTokenizedString("@normalize(@dir($(0))/$(1)/)",
                                                 referenceFilePath,
                                                 subDirectory));
         }
         else
         {
             return(module.CreateTokenizedString("@normalize(@dir($(0))/)",
                                                 referenceFilePath));
         }
     }
     else
     {
         if (null != subDirectory)
         {
             return(module.CreateTokenizedString("@normalize($(0)/$(1)/)",
                                                 unReferencedRoot,
                                                 subDirectory));
         }
         else
         {
             return(module.CreateTokenizedString("@normalize($(0)/)",
                                                 unReferencedRoot));
         }
     }
 }
Пример #7
0
        CreateInternal(
            string tokenizedString,
            Module macroSource,
            bool verbatim,
            TokenizedStringArray positionalTokens,
            EFlags flags)
        {
            if (null == tokenizedString)
            {
                return(null);
            }

            // strings can be created during the multithreaded phase
            lock (Cache)
            {
                if (0 == (flags & EFlags.NoCache))
                {
                    var search = Cache.Where((ts) =>
                    {
                        // first check the simple states for equivalence
                        if (ts.OriginalString == tokenizedString && ts.ModuleWithMacros == macroSource && ts.Verbatim == verbatim)
                        {
                            // and then check the positional tokens, if they exist
                            var samePosTokenCount = ((null != positionalTokens) && (positionalTokens.Count() == ts.PositionalTokens.Count())) ||
                                                    ((null == positionalTokens) && (0 == ts.PositionalTokens.Count()));
                            if (!samePosTokenCount)
                            {
                                return(false);
                            }
                            for (int i = 0; i < ts.PositionalTokens.Count(); ++i)
                            {
                                // because positional tokens are TokenizedStrings, they will refer to the same object
                                if (ts.PositionalTokens[i] != positionalTokens[i])
                                {
                                    return(false);
                                }
                            }
                            return(true);
                        }
                        else
                        {
                            return(false);
                        }
                    });
                    var foundTS = search.FirstOrDefault();
                    if (null != foundTS)
                    {
                        ++foundTS.RefCount;
                        return(foundTS);
                    }
                }
                var newTS = new TokenizedString(tokenizedString, macroSource, verbatim, positionalTokens, flags);
                Cache.Add(newTS);
                return(newTS);
            }
        }
Пример #8
0
 Aliased(
     TokenizedString alias)
 {
     if (this.IsAliased)
     {
         throw new Exception("TokenizedString is already aliased");
     }
     this.Alias = alias;
     ++alias.RefCount;
 }
Пример #9
0
 RegisterGeneratedFile(
     PathKey key,
     TokenizedString path)
 {
     if (this.GeneratedPaths.ContainsKey(key))
     {
         Log.DebugMessage("Key '{0}' already exists", key);
         return;
     }
     this.GeneratedPaths.Add(key, path);
 }
Пример #10
0
        CreateTokenizedString(
            string format,
            params TokenizedString[] argv)
        {
            if (0 == argv.Length)
            {
                return(TokenizedString.Create(format, this));
            }
            var positionalTokens = new TokenizedStringArray(argv);

            return(TokenizedString.Create(format, this, positionalTokens));
        }
Пример #11
0
        IncludeFile(
            Bam.Core.TokenizedString parameterizedFilePath,
            string subdir)
        {
            var copyFileModule = this.CreateCollatedFile(
                this,
                parameterizedFilePath,
                null,
                Bam.Core.TokenizedString.CreateVerbatim(subdir));

            return(copyFileModule);
        }
Пример #12
0
 SetPublishingDirectory(
     string original,
     params Bam.Core.TokenizedString[] positional)
 {
     if (null == this.publishingDirectory)
     {
         this.publishingDirectory = this.CreateTokenizedString(original, positional);
     }
     else
     {
         this.publishingDirectory.Set(original, positional);
     }
 }
Пример #13
0
        ISharedObjectSymbolicLinkPolicy.Symlink(
            ConsoleApplication sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.PreBuiltTool tool,
            Bam.Core.TokenizedString linkname,
            Bam.Core.TokenizedString target)
        {
            var commandLine = new Bam.Core.StringArray();

            commandLine.Add("-s");
            commandLine.Add("-f");
            commandLine.Add(sender.CreateTokenizedString("@filename($(0))", target).Parse());
            commandLine.Add(sender.CreateTokenizedString("@dir($(0))/$(1)", target, linkname).Parse());
            CommandLineProcessor.Processor.Execute(context, tool, commandLine);
        }
Пример #14
0
        FindReferencedModule <T>() where T : Module, new()
        {
            if (null == this.BuildEnvironmentInternal)
            {
                var message = new System.Text.StringBuilder();
                message.AppendLine("Unable to find a module either within a patch or after the build has started.");
                message.AppendLine("If called within a patch function, please modify the calling code to invoke this call within the module's Init method.");
                message.AppendLine("If it must called elsewhere, please use the overloaded version accepting an Environment argument.");
                throw new Exception(message.ToString());
            }
            var referencedModules = this.ReferencedModules[this.BuildEnvironmentInternal];
            var matchedModule     = referencedModules.FirstOrDefault(item => item.GetType() == typeof(T));

            if (null != matchedModule)
            {
                return(matchedModule as T);
            }
            this.CommonModuleType.Push(typeof(T));
            try
            {
                var newModule = Module.Create <T>(preInitCallback: module =>
                {
                    if (null != module)
                    {
                        referencedModules.Add(module);
                    }
                });
                return(newModule);
            }
            catch (UnableToBuildModuleException)
            {
                // remove the failed to create module from the referenced list
                // and also any modules and strings created in its Init function, potentially
                // of child module types
                var moduleTypeToRemove = this.CommonModuleType.Peek();
                TokenizedString.RemoveEncapsulatedStrings(moduleTypeToRemove);
                Module.RemoveEncapsulatedModules(moduleTypeToRemove);
                referencedModules.Remove(referencedModules.First(item => item.GetType() == typeof(T)));
                var moduleEnvList = this.Modules[this.BuildEnvironmentInternal];
                moduleEnvList.Remove(moduleEnvList.First(item => item.GetType() == typeof(T)));
                throw;
            }
            finally
            {
                this.CommonModuleType.Pop();
            }
        }
Пример #15
0
 GenerateSymbolicLinkCopyDestination(
     Bam.Core.Module module,
     Bam.Core.TokenizedString referenceFilePath,
     Bam.Core.TokenizedString subDirectory)
 {
     if (null != subDirectory)
     {
         return(module.CreateTokenizedString("@normalize(@dir($(0))/$(1)/)",
                                             referenceFilePath,
                                             subDirectory));
     }
     else
     {
         return(module.CreateTokenizedString("@normalize(@dir($(0))/)",
                                             referenceFilePath));
     }
 }
Пример #16
0
        AssignLinkTarget(
            TokenizedString path = null)
        {
#if __MonoCS__
            if (path == null)
            {
                var symlink = new Mono.Unix.UnixSymbolicLinkInfo(this.SourcePath.Parse());
                this.Macros["LinkTarget"] = Bam.Core.TokenizedString.CreateVerbatim(symlink.ContentsPath);
            }
            else
            {
                this.Macros["LinkTarget"] = path;
            }
#else
            throw new System.NotSupportedException("Unable to get symbolic link target on Windows");
#endif
        }
Пример #17
0
        CreateCollatedFile(
            Bam.Core.Module sourceModule,
            Bam.Core.TokenizedString sourcePath,
            CollatedFile reference,
            Bam.Core.TokenizedString subDirectory)
        {
            var copyFileModule = Bam.Core.Module.Create <CollatedFile>(preInitCallback: module =>
            {
                Bam.Core.TokenizedString referenceFilePath = null;
                if (null != reference)
                {
                    referenceFilePath = reference.GeneratedPaths[CollatedObject.Key];
                }
                else
                {
                    if (!this.GeneratedPaths.ContainsKey(Key))
                    {
                        this.RegisterGeneratedFile(Key, module.CreateTokenizedString("@dir($(0))", sourcePath));
                    }
                }
                module.Macros["CopyDir"] = GenerateFileCopyDestination(
                    module,
                    referenceFilePath,
                    subDirectory,
                    this.GeneratedPaths[Key]);
            });

            this.Requires(copyFileModule);
            if (null != reference &&
                null != reference.SourceModule &&
                null != sourceModule &&
                reference.SourceModule != sourceModule) // in case a different key (e.g. import library) is published from the same module
            {
                // ensuring that non-Native builders set up order-only dependencies for additional published only modules
                reference.SourceModule.Requires(sourceModule);
            }

            copyFileModule.SourceModule = sourceModule;
            copyFileModule.SourcePath   = sourcePath;
            copyFileModule.Reference    = reference;
            copyFileModule.SubDirectory = subDirectory;
            return(copyFileModule);
        }
Пример #18
0
        Init(
            Bam.Core.Module parent)
        {
            base.Init(parent);

            if (this.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows))
            {
                this.Tool = Bam.Core.Graph.Instance.FindReferencedModule <ZipWin>();
            }
            else
            {
                this.Tool = Bam.Core.Graph.Instance.FindReferencedModule <ZipPosix>();
            }
            this.RegisterGeneratedFile(
                Key,
                this.CreateTokenizedString("$(packagebuilddir)/$(moduleoutputdir)/$(zipoutputbasename).zip")
                );

            this.InputPath = this.Macros["pathtozip"];
        }
        ISharedObjectSymbolicLinkPolicy.Symlink(
            ConsoleApplication sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.PreBuiltTool tool,
            Bam.Core.TokenizedString linkname,
            Bam.Core.TokenizedString target)
        {
            var makeMeta = sender.MetaData as MakeFileBuilder.MakeFileMeta;
            var rule     = makeMeta.Rules[0];

            var commandLineArgs = new Bam.Core.StringArray();

            commandLineArgs.Add("-s");
            commandLineArgs.Add("-f");

            rule.AddShellCommand(System.String.Format(@"{0} {1} $(notdir $@) $(dir $@)/{2} {3}",
                                                      CommandLineProcessor.Processor.StringifyTool(tool),
                                                      commandLineArgs.ToString(' '),
                                                      linkname.Parse(),
                                                      CommandLineProcessor.Processor.TerminatingArgs(tool)));
        }
Пример #20
0
        CopyPDB(
            CollatedObject collatedFile,
            System.Collections.Generic.Dictionary <CollatedObject, Bam.Core.Module> referenceMap)
        {
            var copyPDBModule = Bam.Core.Module.Create <CollatedFile>(preInitCallback: module =>
            {
                Bam.Core.TokenizedString referenceFilePath = null;
                if (collatedFile.Reference != null)
                {
                    if (!referenceMap.ContainsKey(collatedFile.Reference))
                    {
                        throw new Bam.Core.Exception("Unable to find CollatedFile reference to {0} in the reference map", collatedFile.Reference.SourceModule.ToString());
                    }

                    var newRef        = referenceMap[collatedFile.Reference];
                    referenceFilePath = newRef.GeneratedPaths[CollatedObject.Key];
                }

                module.Macros["CopyDir"] = Collation.GenerateFileCopyDestination(
                    this,
                    referenceFilePath,
                    collatedFile.SubDirectory,
                    this.GeneratedPaths[Key]);
            });

            this.DependsOn(copyPDBModule);

            copyPDBModule.SourceModule = collatedFile.SourceModule;
            // TODO: there has not been a check whether this is a valid path or not (i.e. were debug symbols enabled for link?)
            copyPDBModule.SourcePath   = collatedFile.SourceModule.GeneratedPaths[C.ConsoleApplication.PDBKey];
            copyPDBModule.SubDirectory = collatedFile.SubDirectory;

            // since PDBs aren't guaranteed to exist as it depends on build settings, allow missing files to go through
            copyPDBModule.FailWhenSourceDoesNotExist = false;

            if (collatedFile.Reference == null)
            {
                referenceMap.Add(collatedFile, copyPDBModule);
            }
        }
Пример #21
0
        ILinkingPolicy.Link(
            ConsoleApplication sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString executablePath,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> headers,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> libraries,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> frameworks)
        {
            // any libraries added prior to here, need to be moved to the end
            // they are external dependencies, and thus all built modules (to be added now) may have
            // a dependency on them (and not vice versa)
            var linker = sender.Settings as C.ICommonLinkerSettings;
            var externalLibs = linker.Libraries;
            linker.Libraries = new Bam.Core.StringArray();
            foreach (var library in libraries)
            {
                (sender.Tool as C.LinkerTool).ProcessLibraryDependency(sender as CModule, library as CModule);
            }
            linker.Libraries.AddRange(externalLibs);

            var executableDir = System.IO.Path.GetDirectoryName(executablePath.ToString());
            if (!System.IO.Directory.Exists(executableDir))
            {
                System.IO.Directory.CreateDirectory(executableDir);
            }

            var commandLine = new Bam.Core.StringArray();

            // first object files
            foreach (var input in objectFiles)
            {
                commandLine.Add(input.GeneratedPaths[C.ObjectFile.Key].ToString());
            }

            // then all options
            (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine);

            CommandLineProcessor.Processor.Execute(context, sender.Tool as Bam.Core.ICommandLineTool, commandLine);
        }
Пример #22
0
        IncludeFile(
            Bam.Core.TokenizedString parameterizedFilePath,
            string subdir,
            CollatedFile reference,
            bool isExecutable = false)
        {
            var copyFileModule = this.CreateCollatedFile(
                null,
                parameterizedFilePath,
                reference,
                Bam.Core.TokenizedString.CreateVerbatim(subdir));

            if (isExecutable)
            {
                if (this.IsReferenceAWindowedApp(reference))
                {
                    this.AddOSXChangeIDNameForBinary(copyFileModule);
                }
            }

            return(copyFileModule);
        }
Пример #23
0
 GenerateDirectoryCopyDestination(
     Bam.Core.Module module,
     Bam.Core.TokenizedString referenceFilePath,
     Bam.Core.TokenizedString subDirectory,
     Bam.Core.TokenizedString sourcePath)
 {
     // Windows XCOPY requires the directory name to be added to the destination, while Posix cp does not
     if (null != subDirectory)
     {
         if (module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows))
         {
             return(module.CreateTokenizedString("@normalize(@dir($(0))/$(1)/@ifnotempty($(CopiedFilename),$(CopiedFilename),@filename($(2)))/)",
                                                 referenceFilePath,
                                                 subDirectory,
                                                 sourcePath));
         }
         else
         {
             return(module.CreateTokenizedString("@normalize(@dir($(0))/$(1)/@ifnotempty($(CopiedFilename),$(CopiedFilename),))",
                                                 referenceFilePath,
                                                 subDirectory));
         }
     }
     else
     {
         if (module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows))
         {
             return(module.CreateTokenizedString("@normalize(@dir($(0))/@ifnotempty($(CopiedFilename),$(CopiedFilename),@filename($(1)))/)",
                                                 referenceFilePath,
                                                 sourcePath));
         }
         else
         {
             return(module.CreateTokenizedString("@normalize(@dir($(0))/@ifnotempty($(CopiedFilename),$(CopiedFilename),))",
                                                 referenceFilePath));
         }
     }
 }
Пример #24
0
        CreateCollatedDirectory(
            Bam.Core.Module sourceModule,
            Bam.Core.TokenizedString sourcePath,
            CollatedFile reference,
            Bam.Core.TokenizedString subDirectory)
        {
            if (null == reference)
            {
                throw new Bam.Core.Exception("Collating a directory requires a collated file as reference");
            }

            // copying a directory must not have a trailing slash on the source directory path
            // otherwise the leafname ends up being duplicated
            var fixedSourcePath     = this.CreateTokenizedString("@removetrailingseparator($(0))", sourcePath);
            var copyDirectoryModule = Bam.Core.Module.Create <CollatedDirectory>(preInitCallback: module =>
            {
                module.Macros["CopyDir"] = GenerateDirectoryCopyDestination(
                    module,
                    reference.GeneratedPaths[CollatedObject.Key],
                    subDirectory,
                    fixedSourcePath);
            });

            this.Requires(copyDirectoryModule);
            if (null != reference.SourceModule &&
                null != sourceModule &&
                reference.SourceModule != sourceModule) // in case a different key from the same module is published
            {
                // ensuring that non-Native builders set up order-only dependencies for additional published only modules
                reference.SourceModule.Requires(sourceModule);
            }

            copyDirectoryModule.SourceModule = sourceModule;
            copyDirectoryModule.SourcePath   = fixedSourcePath;
            copyDirectoryModule.Reference    = reference;
            copyDirectoryModule.SubDirectory = subDirectory;
            return(copyDirectoryModule);
        }
Пример #25
0
        CloneFile(
            CollatedObject collatedFile,
            System.Collections.Generic.Dictionary <CollatedObject, Bam.Core.Module> referenceMap)
        {
            var clonedFile = Bam.Core.Module.Create <CollatedFile>(preInitCallback: module =>
            {
                Bam.Core.TokenizedString referenceFilePath = null;
                if (collatedFile.Reference != null)
                {
                    if (!referenceMap.ContainsKey(collatedFile.Reference))
                    {
                        throw new Bam.Core.Exception("Unable to find CollatedFile reference to {0} in the reference map", collatedFile.Reference.SourceModule.ToString());
                    }

                    var newRef = referenceMap[collatedFile.Reference];
                    // the PathKey depends on whether the reference came straight as a clone, or after being stripped
                    referenceFilePath = newRef.GeneratedPaths[this.ReferenceKey];
                }

                module.Macros["CopyDir"] = Collation.GenerateFileCopyDestination(
                    this,
                    referenceFilePath,
                    collatedFile.SubDirectory,
                    this.GeneratedPaths[Key]);
            });

            this.DependsOn(clonedFile);

            clonedFile.SourceModule = collatedFile;
            clonedFile.SourcePath   = collatedFile.GeneratedPaths[CollatedObject.Key];
            clonedFile.SubDirectory = collatedFile.SubDirectory;

            if (collatedFile.Reference == null)
            {
                referenceMap.Add(collatedFile, clonedFile);
                this.ReferenceKey = CollatedObject.Key;
            }
        }
Пример #26
0
 Display()
 {
     Log.Info("\nBuildAMation Statistics");
     Log.Info("Memory Usage");
     Log.Info("Peak working set size : {0:N2}MB", BytesToMegaBytes(System.Diagnostics.Process.GetCurrentProcess().PeakWorkingSet64));
     Log.Info("Peak virtual size     : {0:N2}MB", BytesToMegaBytes(System.Diagnostics.Process.GetCurrentProcess().PeakVirtualMemorySize64));
     Log.Info("GC total memory       : {0:N2}MB (after GC, {1:N2}MB)", BytesToMegaBytes(System.GC.GetTotalMemory(false)), BytesToMegaBytes(System.GC.GetTotalMemory(true)));
     Log.Info("\nObject counts");
     Log.Info("Tokenized strings     : {0} ({1} unshared)", TokenizedString.Count, TokenizedString.UnsharedCount);
     TokenizedString.DumpCache();
     Log.Info("Modules               : {0}", Module.Count);
     Log.Info("\nModule creation times");
     foreach (var env in Graph.Instance.BuildEnvironments)
     {
         var encapsulatingModules = Graph.Instance.EncapsulatingModules(env);
         Log.Info("Configuration {0} has {1} named/encapsulating modules, with the following creation times (ms):", env.Configuration.ToString(), encapsulatingModules.Count);
         foreach (var module in encapsulatingModules.OrderByDescending(item => item.CreationTime))
         {
             Log.Info("\t{0}\t{1}", module, module.CreationTime.TotalMilliseconds);
         }
     }
     TimingProfileUtilities.DumpProfiles();
 }
Пример #27
0
        CreateInternal(
            string tokenizedString,
            Module macroSource,
            bool verbatim,
            TokenizedStringArray positionalTokens,
            EFlags flags)
        {
            if (null == tokenizedString)
            {
                return null;
            }

            // strings can be created during the multithreaded phase
            lock (Cache)
            {
                if (0 == (flags & EFlags.NoCache))
                {
                    var search = Cache.Where((ts) =>
                    {
                        // first check the simple states for equivalence
                        if (ts.OriginalString == tokenizedString && ts.ModuleWithMacros == macroSource && ts.Verbatim == verbatim)
                        {
                            // and then check the positional tokens, if they exist
                            var samePosTokenCount = ((null != positionalTokens) && (positionalTokens.Count() == ts.PositionalTokens.Count())) ||
                                                    ((null == positionalTokens) && (0 == ts.PositionalTokens.Count()));
                            if (!samePosTokenCount)
                            {
                                return false;
                            }
                            for (int i = 0; i < ts.PositionalTokens.Count(); ++i)
                            {
                                // because positional tokens are TokenizedStrings, they will refer to the same object
                                if (ts.PositionalTokens[i] != positionalTokens[i])
                                {
                                    return false;
                                }
                            }
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    });
                    var foundTS = search.FirstOrDefault();
                    if (null != foundTS)
                    {
                        ++foundTS.RefCount;
                        return foundTS;
                    }
                }
                var newTS = new TokenizedString(tokenizedString, macroSource, verbatim, positionalTokens, flags);
                Cache.Add(newTS);
                return newTS;
            }
        }
Пример #28
0
        ILinkingPolicy.Link(
            ConsoleApplication sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString executablePath,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> headers,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> libraries,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> frameworks)
        {
            // any libraries added prior to here, need to be moved to the end
            // they are external dependencies, and thus all built modules (to be added now) may have
            // a dependency on them (and not vice versa)
            var linker       = sender.Settings as C.ICommonLinkerSettings;
            var externalLibs = linker.Libraries;

            linker.Libraries = new Bam.Core.StringArray();
            foreach (var library in libraries)
            {
                (sender.Tool as C.LinkerTool).ProcessLibraryDependency(sender as CModule, library as CModule);
            }
            linker.Libraries.AddRange(externalLibs);

            var commandLineArgs = new Bam.Core.StringArray();

            (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLineArgs);

            var meta = new MakeFileBuilder.MakeFileMeta(sender);
            var rule = meta.AddRule();

            rule.AddTarget(executablePath);
            foreach (var module in objectFiles)
            {
                rule.AddPrerequisite(module, C.ObjectFile.Key);
            }
            foreach (var module in libraries)
            {
                if (module is StaticLibrary)
                {
                    rule.AddPrerequisite(module, C.StaticLibrary.Key);
                }
                else if (module is IDynamicLibrary)
                {
                    if (module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows))
                    {
                        rule.AddPrerequisite(module, C.DynamicLibrary.ImportLibraryKey);
                    }
                    else
                    {
                        rule.AddPrerequisite(module, C.DynamicLibrary.Key);
                    }
                }
                else if (module is CSDKModule)
                {
                    continue;
                }
                else if (module is OSXFramework)
                {
                    continue;
                }
                else
                {
                    throw new Bam.Core.Exception("Unknown module library type: {0}", module.GetType());
                }
            }

            var tool     = sender.Tool as Bam.Core.ICommandLineTool;
            var commands = new System.Text.StringBuilder();

            commands.AppendFormat("{0} $^ {1} {2}",
                                  CommandLineProcessor.Processor.StringifyTool(tool),
                                  commandLineArgs.ToString(' '),
                                  CommandLineProcessor.Processor.TerminatingArgs(tool));
            rule.AddShellCommand(commands.ToString());

            var executableDir = System.IO.Path.GetDirectoryName(executablePath.ToString());

            meta.CommonMetaData.Directories.AddUnique(executableDir);
            meta.CommonMetaData.ExtendEnvironmentVariables(tool.EnvironmentVariables);
        }
Пример #29
0
 public CollatedObject()
 {
     this.RealSourcePath = this.MakePlaceholderPath();
     this.Macros.Add("CopiedFilename", this.MakePlaceholderPath());
 }
Пример #30
0
        ILinkingPolicy.Link(
            ConsoleApplication sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString executablePath,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> headers,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> libraries)
        {
            // any libraries added prior to here, need to be moved to the end
            // they are external dependencies, and thus all built modules (to be added now) may have
            // a dependency on them (and not vice versa)
            var linker       = sender.Settings as C.ICommonLinkerSettings;
            var externalLibs = linker.Libraries;

            linker.Libraries = new Bam.Core.StringArray();
            foreach (var library in libraries)
            {
                (sender.Tool as C.LinkerTool).ProcessLibraryDependency(sender as CModule, library as CModule);
            }
            linker.Libraries.AddRange(externalLibs);

            var commandLineArgs = new Bam.Core.StringArray();

            (sender.Settings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLineArgs);

            var meta = new MakeFileBuilder.MakeFileMeta(sender);
            var rule = meta.AddRule();

            rule.AddTarget(executablePath);
            string objExt = null; // try to get the object file extension from a compiled source file

            foreach (var module in objectFiles)
            {
                if (null == objExt)
                {
                    objExt = module.Tool.Macros["objext"].ToString();
                }
                if (!(module as C.ObjectFileBase).PerformCompilation)
                {
                    continue;
                }
                rule.AddPrerequisite(module, C.ObjectFile.Key);
            }
            foreach (var module in libraries)
            {
                if (module is StaticLibrary)
                {
                    rule.AddPrerequisite(module, C.StaticLibrary.Key);
                }
                else if (module is IDynamicLibrary)
                {
                    var dynLib = module as IDynamicLibrary;
                    if (dynLib.LinkerNameSymbolicLink != null)
                    {
                        var linkerNameSymLink = dynLib.LinkerNameSymbolicLink;
                        rule.AddPrerequisite(linkerNameSymLink, C.SharedObjectSymbolicLink.Key);
                    }
                    else
                    {
                        rule.AddPrerequisite(module, C.DynamicLibrary.Key);
                    }
                }
                else if (module is CSDKModule)
                {
                    continue;
                }
                else if (module is OSXFramework)
                {
                    continue;
                }
                else if (module is HeaderLibrary)
                {
                    continue;
                }
                else
                {
                    throw new Bam.Core.Exception("Unknown module library type: {0}", module.GetType());
                }
            }

            var tool     = sender.Tool as Bam.Core.ICommandLineTool;
            var commands = new System.Text.StringBuilder();
            // if there were no object files, you probably intended to use all prerequisites anyway
            var filter = (null != objExt) ? System.String.Format("$(filter %{0},$^)", objExt) : "$^";

            commands.AppendFormat("{0} {1} {2} {3}",
                                  CommandLineProcessor.Processor.StringifyTool(tool),
                                  filter,
                                  commandLineArgs.ToString(' '),
                                  CommandLineProcessor.Processor.TerminatingArgs(tool));
            rule.AddShellCommand(commands.ToString());

            var executableDir = System.IO.Path.GetDirectoryName(executablePath.ToString());

            meta.CommonMetaData.AddDirectory(executableDir);
            meta.CommonMetaData.ExtendEnvironmentVariables(tool.EnvironmentVariables);
        }
Пример #31
0
 MakePlaceholderPath()
 {
     return(TokenizedString.CreateUncached(string.Empty, this));
 }
Пример #32
0
 Aliased(
     TokenizedString alias)
 {
     if (this.IsAliased)
     {
         throw new Exception("TokenizedString is already aliased");
     }
     this.Alias = alias;
     ++alias.RefCount;
 }
Пример #33
0
 public CollatedObject()
 {
     this.RealSourcePath = this.MakePlaceholderPath();
     this.Macros.Add("CopiedFilename", this.MakePlaceholderPath());
 }
Пример #34
0
        Execute(
            Array <Environment> environments,
            System.Reflection.Assembly packageAssembly = null)
        {
            PrintVersion();

            if (0 == environments.Count)
            {
                throw new Exception("No build configurations were specified");
            }

            var graph = Graph.Instance;

            if (null != packageAssembly)
            {
                PackageUtilities.IdentifyAllPackages();
                graph.ScriptAssembly         = packageAssembly;
                graph.ScriptAssemblyPathname = packageAssembly.Location;
            }
            else
            {
                PackageUtilities.CompilePackageAssembly();
                PackageUtilities.LoadPackageAssembly();
            }

            var packageMetaDataProfile = new TimeProfile(ETimingProfiles.PackageMetaData);

            packageMetaDataProfile.StartProfile();

            // validate that there is at most one local policy
            // if test mode is enabled, then the '.tests' sub-namespaces are also checked
            {
                var localPolicies = graph.ScriptAssembly.GetTypes().Where(t => typeof(ISitePolicy).IsAssignableFrom(t));
                var includeTests  = CommandLineProcessor.Evaluate(new Options.UseTests());
                if (!includeTests)
                {
                    localPolicies = localPolicies.Where(item => !item.Namespace.EndsWith(".tests"));
                }
                var numLocalPolicies = localPolicies.Count();
                if (numLocalPolicies > 0)
                {
                    if (numLocalPolicies > 1)
                    {
                        var message = new System.Text.StringBuilder();
                        message.AppendLine("Too many site policies exist in the package assembly:");
                        foreach (var policy in localPolicies)
                        {
                            message.AppendFormat("\t{0}", policy.ToString());
                            message.AppendLine();
                        }
                        throw new Exception(message.ToString());
                    }

                    Settings.LocalPolicy = System.Activator.CreateInstance(localPolicies.First()) as ISitePolicy;
                }
            }

            // find a product definition
            {
                var productDefinitions    = graph.ScriptAssembly.GetTypes().Where(t => typeof(IProductDefinition).IsAssignableFrom(t));
                var numProductDefinitions = productDefinitions.Count();
                if (numProductDefinitions > 0)
                {
                    if (numProductDefinitions > 1)
                    {
                        var message = new System.Text.StringBuilder();
                        message.AppendLine("Too many product definitions exist in the package assembly:");
                        foreach (var def in productDefinitions)
                        {
                            message.AppendFormat("\t{0}", def.ToString());
                            message.AppendLine();
                        }
                        throw new Exception(message.ToString());
                    }

                    graph.ProductDefinition = System.Activator.CreateInstance(productDefinitions.First()) as IProductDefinition;
                }
            }

            // get the metadata from the build mode package
            var metaName     = System.String.Format("{0}Builder.{0}Meta", graph.Mode);
            var metaDataType = graph.ScriptAssembly.GetType(metaName);

            if (null == metaDataType)
            {
                throw new Exception("No build mode {0} meta data type {1}", graph.Mode, metaName);
            }

            if (!typeof(IBuildModeMetaData).IsAssignableFrom(metaDataType))
            {
                throw new Exception("Build mode package meta data type {0} does not implement the interface {1}", metaDataType.ToString(), typeof(IBuildModeMetaData).ToString());
            }
            graph.BuildModeMetaData = System.Activator.CreateInstance(metaDataType) as IBuildModeMetaData;

            // packages can have meta data - instantiate where they exist
            foreach (var package in graph.Packages)
            {
                var ns       = package.Name;
                var metaType = graph.ScriptAssembly.GetTypes().FirstOrDefault(item => item.Namespace == ns && typeof(PackageMetaData).IsAssignableFrom(item));
                if (null == metaType)
                {
                    continue;
                }

                try
                {
                    package.MetaData = System.Activator.CreateInstance(metaType) as PackageMetaData;
                }
                catch (Exception exception)
                {
                    throw exception;
                }
                catch (System.Reflection.TargetInvocationException exception)
                {
                    throw new Exception(exception, "Failed to create package metadata");
                }
            }

            packageMetaDataProfile.StopProfile();

            var topLevelNamespace = graph.MasterPackage.Name;

            var findBuildableModulesProfile = new TimeProfile(ETimingProfiles.IdentifyBuildableModules);

            findBuildableModulesProfile.StartProfile();

            // Phase 1: Instantiate all modules in the namespace of the package in which the tool was invoked
            Log.Detail("Creating modules");
            foreach (var env in environments)
            {
                graph.CreateTopLevelModules(graph.ScriptAssembly, env, topLevelNamespace);
            }

            findBuildableModulesProfile.StopProfile();

            var populateGraphProfile = new TimeProfile(ETimingProfiles.PopulateGraph);

            populateGraphProfile.StartProfile();
            // Phase 2: Graph now has a linear list of modules; create a dependency graph
            // NB: all those modules with 0 dependees are the top-level modules
            // NB: default settings have already been defined here
            // not only does this generate the dependency graph, but also creates the default settings for each module, and completes them
            graph.SortDependencies();
            populateGraphProfile.StopProfile();

            // TODO: make validation optional, if it starts showing on profiles
            var validateGraphProfile = new TimeProfile(ETimingProfiles.ValidateGraph);

            validateGraphProfile.StartProfile();
            graph.Validate();
            validateGraphProfile.StopProfile();

            // Phase 3: (Create default settings, and ) apply patches (build + shared) to each module
            // NB: some builders can use the patch directly for child objects, so this may be dependent upon the builder
            // Toolchains for modules need to be set here, as they might append macros into each module in order to evaluate paths
            // TODO: a parallel thread can be spawned here, that can check whether command lines have changed
            // the Settings object can be inspected, and a hash generated. This hash can be written to disk, and compared.
            // If a 'verbose' mode is enabled, then more work can be done to figure out what has changed. This would also require
            // serializing the binary Settings object
            var createPatchesProfile = new TimeProfile(ETimingProfiles.CreatePatches);

            createPatchesProfile.StartProfile();
            graph.ApplySettingsPatches();
            createPatchesProfile.StopProfile();

            // expand paths after patching settings, because some of the patches may contain tokenized strings
            // TODO: a thread can be spawned, to check for whether files were in date or not, which will
            // be ready in time for graph execution
            var parseStringsProfile = new TimeProfile(ETimingProfiles.ParseTokenizedStrings);

            parseStringsProfile.StartProfile();
            TokenizedString.ParseAll();
            parseStringsProfile.StopProfile();

            if (CommandLineProcessor.Evaluate(new Options.ViewDependencyGraph()))
            {
                // must come after all strings are parsed, in order to display useful paths
                graph.Dump();
            }

            // Phase 4: Execute dependency graph
            // N.B. all paths (including those with macros) have been delayed expansion until now
            var graphExecutionProfile = new TimeProfile(ETimingProfiles.GraphExecution);

            graphExecutionProfile.StartProfile();
            var executor = new Executor();

            executor.Run();
            graphExecutionProfile.StopProfile();
        }