Пример #1
0
        Convert(
            this IStripToolSettings settings,
            Bam.Core.StringArray commandLine)
        {
            var module = (settings as Bam.Core.Settings).Module;

            if (settings.Verbose && !module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.OSX))
            {
                commandLine.Add("-v");
            }

            if (settings.PreserveTimestamp && !module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.OSX))
            {
                commandLine.Add("-p");
            }

            if (settings.StripDebugSymbols)
            {
                commandLine.Add("-S");
            }

            if (settings.StripLocalSymbols)
            {
                commandLine.Add("-x");
            }
        }
Пример #2
0
        Convert(
            this IObjCopyToolSettings settings,
            Bam.Core.StringArray commandLine)
        {
            var objCopy = (settings as Bam.Core.Settings).Module as ObjCopyModule;

            switch (settings.Mode)
            {
            case EObjCopyToolMode.OnlyKeepDebug:
                commandLine.Add(System.String.Format("--only-keep-debug {0} {1}",
                                                     objCopy.SourceModule.GeneratedPaths[objCopy.SourceKey].Parse(),
                                                     objCopy.GeneratedPaths[ObjCopyModule.Key].Parse()));
                break;

            case EObjCopyToolMode.AddGNUDebugLink:
                commandLine.Add(System.String.Format("--add-gnu-debuglink={0} {1}",
                                                     objCopy.GeneratedPaths[ObjCopyModule.Key].Parse(),
                                                     objCopy.SourceModule.GeneratedPaths[objCopy.SourceKey].Parse()));
                break;

            default:
                throw new Bam.Core.Exception("Unrecognized objcopy mode, {0}", settings.Mode.ToString());
            }
            if (settings.Verbose)
            {
                commandLine.Add("-v");
            }
        }
Пример #3
0
        GetPackageHash(
            StringArray sourceCode,
            StringArray definitions,
            Array <BamAssemblyDescription> bamAssemblies)
        {
            int hashCode = 0;

            foreach (var source in sourceCode)
            {
                hashCode ^= source.GetHashCode();
            }
            foreach (var define in definitions)
            {
                hashCode ^= define.GetHashCode();
            }
            foreach (var assembly in bamAssemblies)
            {
                var assemblyPath     = System.IO.Path.Combine(Graph.Instance.ProcessState.ExecutableDirectory, assembly.Name) + ".dll";
                var lastModifiedDate = System.IO.File.GetLastWriteTime(assemblyPath);
                hashCode ^= lastModifiedDate.GetHashCode();
            }
            var hash = hashCode.ToString();

            return(hash);
        }
Пример #4
0
 protected DynamicExtensionModule(
     string moduleName,
     Bam.Core.StringArray sourceFiles)
     :
     this(moduleName, sourceFiles, null, null, null, null, null)
 {
 }
Пример #5
0
        ISharedObjectSymbolicLinkPolicy.Symlink(
            SharedObjectSymbolicLink sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.PreBuiltTool tool,
            ConsoleApplication target)
        {
            var commandLine = new Bam.Core.StringArray();

            commandLine.Add("-s");
            commandLine.Add("-f");
            var sourceFile = sender.CreateTokenizedString("@filename($(0))", target.GeneratedPaths[ConsoleApplication.Key]);

            lock (sourceFile)
            {
                if (!sourceFile.IsParsed)
                {
                    sourceFile.Parse();
                }
            }
            commandLine.Add(sourceFile.ToStringQuoteIfNecessary());
            var destination = sender.CreateTokenizedString("@dir($(0))/$(1)", target.GeneratedPaths[ConsoleApplication.Key], target.Macros[sender.Macros["SymlinkUsage"].ToString()]);

            lock (destination)
            {
                if (!destination.IsParsed)
                {
                    destination.Parse();
                }
            }
            commandLine.Add(destination.ToStringQuoteIfNecessary());
            CommandLineProcessor.Processor.Execute(context, tool, commandLine);
        }
Пример #6
0
        ISharedObjectSymbolicLinkPolicy.Symlink(
            SharedObjectSymbolicLink sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.PreBuiltTool tool,
            ConsoleApplication target)
        {
            var meta = new MakeFileBuilder.MakeFileMeta(sender);
            var rule = meta.AddRule();

            // since this is not a referenced type, need to specify a variable name for the MakeFile
            var variableName = new System.Text.StringBuilder();

            variableName.Append(target.GetType().Name);                    // this is what it's building the symlink for
            variableName.Append("_");
            variableName.Append(sender.Macros["SymlinkUsage"].ToString()); // intended usage

            rule.AddTarget(sender.GeneratedPaths[SharedObjectSymbolicLink.Key], variableName: variableName.ToString());
            rule.AddPrerequisite(target, C.ConsoleApplication.Key);

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

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

            var command = new System.Text.StringBuilder();

            command.AppendFormat("{0} {1} $(notdir $<) $@ {2}",
                                 CommandLineProcessor.Processor.StringifyTool(tool),
                                 commandLineArgs.ToString(' '),
                                 CommandLineProcessor.Processor.TerminatingArgs(tool));
            rule.AddShellCommand(command.ToString());
        }
Пример #7
0
        Init()
        {
            base.Init();

            var publishRoot = this.CreateTokenizedString("$(packagebuilddir)/$(config)/PublicHeaders");

            this.PublicPatch((settings, appliedTo) =>
            {
                if (settings is C.ICommonPreprocessorSettings preprocessor)
                {
                    preprocessor.IncludePaths.AddUnique(publishRoot);
                }
            });

            var headerPaths = new Bam.Core.StringArray
            {
                "src/x86/ffitarget.h",
                "include/ffi_common.h"
            };

            foreach (var header in headerPaths)
            {
                this.IncludeFiles <CopyNonPublicHeadersToPublic>("$(packagedir)/Modules/_ctypes/libffi/" + header, publishRoot, null);
            }
        }
Пример #8
0
 protected DynamicExtensionModule(
     string moduleName,
     Bam.Core.StringArray sourceFiles,
     Bam.Core.Module.PrivatePatchDelegate compilationPatch)
     :
     this(moduleName, sourceFiles, null, compilationPatch, null, null, null)
 {
 }
 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);
 }
Пример #10
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);
        }
        Convert(
            this IInstallNameToolSettings settings,
            Bam.Core.StringArray commandLine)
        {
            switch (settings.Mode)
            {
            case EInstallNameToolMode.UpdateIDName:
                commandLine.Add("-id");
                break;

            case EInstallNameToolMode.ChangeIDName:
                commandLine.Add("-change");
                break;
            }
        }
Пример #12
0
        Convert(
            this ICopyFileSettings settings,
            Bam.Core.StringArray commandLine)
        {
            var module = (settings as Bam.Core.Settings).Module;

            if (module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows))
            {
                if (settings.Force)
                {
                    commandLine.Add("/Y");
                }
                if (settings.Verbose)
                {
                    commandLine.Add("/F");
                }
                if (settings.Recursive)
                {
                    commandLine.Add("/S");
                }
                if (settings.PreserveAllAttributes)
                {
                    commandLine.Add("/K"); // copy attributes
                    // TODO: this causes 'access denied' errors, although not clear why
                    //commandLine.Add("/O"); // copy ownership and ACL
                    commandLine.Add("/B"); // copy symbolic link itself, not the target
                }
            }
            else
            {
                if (settings.Force)
                {
                    commandLine.Add("-f");
                }
                if (settings.Verbose)
                {
                    commandLine.Add("-v");
                }
                if (settings.Recursive)
                {
                    commandLine.Add("-R");
                }
                if (settings.PreserveAllAttributes)
                {
                    commandLine.Add("-a");
                }
            }
        }
Пример #13
0
 protected DynamicExtensionModule(
     string moduleName,
     Bam.Core.StringArray sourceFiles,
     Bam.Core.StringArray libraries,
     Bam.Core.Module.PrivatePatchDelegate compilationPatch,
     Bam.Core.Module.PrivatePatchDelegate linkerPatch,
     Bam.Core.StringArray assemblerFiles,
     Bam.Core.Module.PrivatePatchDelegate assemberPatch)
 {
     this.ModuleName       = moduleName;
     this.SourceFiles      = sourceFiles;
     this.LibsToLink       = libraries;
     this.CompilationPatch = compilationPatch;
     this.LinkerPatch      = linkerPatch;
     this.AssemblerFiles   = (null != assemblerFiles) ? assemblerFiles : null;
     this.AssemblerPatch   = assemberPatch;
 }
        Convert(
            this IMakeLinkSettings settings,
            Bam.Core.StringArray commandLine)
        {
            var module = (settings as Bam.Core.Settings).Module;

            if (module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows))
            {
                if (settings.Force)
                {
                    // no switch
                }
                if (settings.Verbose)
                {
                    // no switch
                }
                if (settings.SymbolicLink)
                {
                    // no switch
                }
                if (settings.DoNotDereferenceTarget)
                {
                    // no switch
                }
            }
            else
            {
                if (settings.Force)
                {
                    commandLine.Add("-f");
                }
                if (settings.Verbose)
                {
                    commandLine.Add("-v");
                }
                if (settings.SymbolicLink)
                {
                    commandLine.Add("-s");
                }
                if (settings.DoNotDereferenceTarget)
                {
                    commandLine.Add("-n");
                }
            }
        }
        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)));
        }
        IProceduralHeaderFromToolOutputPolicy.HeaderFromToolOutput(
            ProceduralHeaderFileFromToolOutput sender,
            ExecutionContext context,
            TokenizedString outputPath,
            ICommandLineTool tool)
        {
            var toolProject = (tool as Bam.Core.Module).MetaData as VSSolutionBuilder.VSProject;
            var toolConfig  = toolProject.GetConfiguration(tool as Bam.Core.Module);

            var output = outputPath.Parse();

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

            commands.Add(System.String.Format("IF NOT EXIST {0} MKDIR {0}", System.IO.Path.GetDirectoryName(output)));
            commands.Add(System.String.Format("{0} > {1}", CommandLineProcessor.Processor.StringifyTool(tool), output));
            toolConfig.AddPostBuildCommands(commands);

            // alias the tool's project so that inter-project dependencies can be set up
            sender.MetaData = toolProject;
        }
        IProceduralHeaderFromToolOutputPolicy.HeaderFromToolOutput(
            ProceduralHeaderFileFromToolOutput sender,
            ExecutionContext context,
            TokenizedString outputPath,
            ICommandLineTool tool)
        {
            var toolTarget        = (tool as Bam.Core.Module).MetaData as XcodeBuilder.Target;
            var toolConfiguration = toolTarget.GetConfiguration(tool as Bam.Core.Module);

            var output = outputPath.Parse();

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

            commands.Add(System.String.Format("[[ ! -d {0} ]] && mkdir -p {0}", System.IO.Path.GetDirectoryName(output)));
            commands.Add(System.String.Format("{0} > {1}", CommandLineProcessor.Processor.StringifyTool(tool), output));
            toolTarget.AddPostBuildCommands(commands, toolConfiguration);

            // alias the tool's target so that inter-target dependencies can be set up
            sender.MetaData = toolTarget;
        }
Пример #18
0
        Convert(
            this IZipSettings settings,
            Bam.Core.StringArray commandLine)
        {
            var module = (settings as Bam.Core.Settings).Module;

            if (module.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows))
            {
                if (settings.Verbose)
                {
                    commandLine.Add("-bb3");
                }
                if (settings.RecursivePaths)
                {
                    commandLine.Add("-r");
                }
                if (settings.Update)
                {
                    commandLine.Add("u");
                }
                else
                {
                    commandLine.Add("a");
                }
            }
            else
            {
                if (settings.Verbose)
                {
                    commandLine.Add("-v");
                }
                if (settings.RecursivePaths)
                {
                    commandLine.Add("-r");
                }
                if (settings.Update)
                {
                    commandLine.Add("-u");
                }
            }
        }
        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
        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);
        }
        IProceduralHeaderFromToolOutputPolicy.HeaderFromToolOutput(
            ProceduralHeaderFileFromToolOutput sender,
            ExecutionContext context,
            TokenizedString outputPath,
            ICommandLineTool tool)
        {
            var meta = new MakeFileBuilder.MakeFileMeta(sender);
            var rule = meta.AddRule();

            rule.AddTarget(outputPath);

            rule.AddPrerequisite(tool.Executable);

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

            args.Add("$< > $@");
            rule.AddShellCommand(args.ToString(' '));

            var outputDir = System.IO.Path.GetDirectoryName(outputPath.Parse());

            meta.CommonMetaData.AddDirectory(outputDir);
        }
Пример #22
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);
        }
Пример #23
0
        IdentifyAllPackages(
            bool allowDuplicates            = false,
            bool enforceBamAssemblyVersions = true)
        {
            var packageRepos = new System.Collections.Generic.LinkedList <System.Tuple <string, PackageDefinition> >();
            int reposHWM     = 0;

            foreach (var repo in Graph.Instance.PackageRepositories)
            {
                EnqueuePackageRepositoryToVisit(packageRepos, ref reposHWM, repo, null);
            }

            var masterDefinitionFile = GetMasterPackage();

            foreach (var repo in masterDefinitionFile.PackageRepositories)
            {
                EnqueuePackageRepositoryToVisit(packageRepos, ref reposHWM, repo, masterDefinitionFile);
            }

            // read the definition files of any package found in the package roots
            var candidatePackageDefinitions = new Array <PackageDefinition>();

            candidatePackageDefinitions.Add(masterDefinitionFile);
            var packageReposVisited = 0;

            Log.Detail("Querying package repositories...");
            while (packageRepos.Count > 0)
            {
                var repoTuple = packageRepos.First();
                packageRepos.RemoveFirst();
                var repo = repoTuple.Item1;
                if (!System.IO.Directory.Exists(repo))
                {
                    var message = new System.Text.StringBuilder();
                    message.AppendFormat("Package repository directory {0} does not exist.", repo);
                    message.AppendLine();
                    message.AppendFormat("Repository requested from {0}", repoTuple.Item2.XMLFilename);
                    message.AppendLine();
                    throw new Exception(message.ToString());
                }

                // faster than System.IO.Directory.GetDirectories(repo, BamSubFolder, System.IO.SearchOption.AllDirectories);
                // when there are deep directories
                StringArray candidatePackageDirs = new StringArray();
                var         possiblePackages     = System.IO.Directory.GetDirectories(repo, "*", System.IO.SearchOption.TopDirectoryOnly);
                foreach (var packageDir in possiblePackages)
                {
                    var possibleBamFolder = System.IO.Path.Combine(packageDir, BamSubFolder);
                    if (System.IO.Directory.Exists(possibleBamFolder))
                    {
                        candidatePackageDirs.Add(packageDir);
                    }
                }

                Graph.Instance.PackageRepositories.Add(repo);

                foreach (var packageDir in candidatePackageDirs)
                {
                    var packageDefinitionPath = GetPackageDefinitionPathname(packageDir);

                    // ignore any duplicates (can be found due to nested repositories)
                    if (null != candidatePackageDefinitions.FirstOrDefault(item => item.XMLFilename == packageDefinitionPath))
                    {
                        continue;
                    }

                    var definitionFile = new PackageDefinition(packageDefinitionPath);
                    definitionFile.Read();
                    candidatePackageDefinitions.Add(definitionFile);

                    foreach (var newRepo in definitionFile.PackageRepositories)
                    {
                        EnqueuePackageRepositoryToVisit(packageRepos, ref reposHWM, newRepo, definitionFile);
                    }
                }

                ++packageReposVisited;
                Log.DetailProgress("{0,3}%", (int)(100 * ((float)packageReposVisited / reposHWM)));
            }
#if DEBUG
            if (packageReposVisited != reposHWM)
            {
                throw new Exception("Inconsistent package repository count: {0} added, {1} visited", reposHWM, packageReposVisited);
            }
#endif

            // defaults come from
            // - the master definition file
            // - command line args (these trump the mdf)
            // and only requires resolving when referenced
            var packageDefinitions = new Array <PackageDefinition>();
            PackageDefinition.ResolveDependencies(masterDefinitionFile, packageDefinitions, candidatePackageDefinitions);

            // now resolve any duplicate names using defaults
            // unless duplicates are allowed
            var duplicatePackageNames    = packageDefinitions.GroupBy(item => item.Name).Where(item => item.Count() > 1).Select(item => item.Key);
            var uniquePackageNames       = packageDefinitions.GroupBy(item => item.Name).Where(item => item.Count() == 1).Select(item => item.Key);
            var versionSpeciferArgs      = new Options.PackageDefaultVersion();
            var packageVersionSpecifiers = CommandLineProcessor.Evaluate(versionSpeciferArgs);
            if ((duplicatePackageNames.Count() > 0) && !allowDuplicates)
            {
                var toRemove = new Array <PackageDefinition>();

                foreach (var dupName in duplicatePackageNames)
                {
                    var duplicates        = packageDefinitions.Where(item => item.Name == dupName);
                    var resolvedDuplicate = TryToResolveDuplicate(masterDefinitionFile, dupName, duplicates, packageDefinitions, packageVersionSpecifiers, toRemove);
                    if (null != resolvedDuplicate)
                    {
                        continue;
                    }

                    // try removing any packages that have already been resolved
                    // which can remove additional packages (recursive check) because they had been added solely by those we are just about to remove
                    packageDefinitions.RemoveAll(PackagesToRemove(toRemove, packageDefinitions, masterDefinitionFile));
                    packageDefinitions.RemoveAll(toRemove);

                    // and if that has reduced the duplicates for this package down to a single version, we're good to carry on
                    var numDuplicates = duplicates.Count();
                    if (1 == numDuplicates)
                    {
                        toRemove.Clear();
                        continue;
                    }

                    // otherwise, error
                    var resolveErrorMessage = new System.Text.StringBuilder();
                    if (numDuplicates > 0)
                    {
                        resolveErrorMessage.AppendFormat("Unable to resolve to a single version of package {0}. Use --{0}.version=<version> to resolve.", dupName);
                        resolveErrorMessage.AppendLine();
                        resolveErrorMessage.AppendLine("Available versions of the package are:");
                        foreach (var dup in duplicates)
                        {
                            resolveErrorMessage.AppendFormat("\t{0}", dup.Version);
                            resolveErrorMessage.AppendLine();
                        }
                    }
                    else
                    {
                        resolveErrorMessage.AppendFormat("No version of package {0} has been determined to be available.", dupName);
                        resolveErrorMessage.AppendLine();
                        if (toRemove.Count() > 0)
                        {
                            resolveErrorMessage.AppendFormat("If there were any references to {0}, they may have been removed from consideration by the following packages being discarded:", dupName);
                            resolveErrorMessage.AppendLine();
                            foreach (var removed in toRemove)
                            {
                                resolveErrorMessage.AppendFormat("\t{0}", removed.FullName);
                                resolveErrorMessage.AppendLine();
                            }
                        }
                        resolveErrorMessage.AppendFormat("Please add an explicit dependency to (a version of) the {0} package either in your master package or one of its dependencies.", dupName);
                        resolveErrorMessage.AppendLine();
                    }
                    throw new Exception(resolveErrorMessage.ToString());
                }

                // finally, clean up the package definition list to use, with all those that need to be deleted
                packageDefinitions.RemoveAll(toRemove);
            }

            // ensure that all packages with a single version in the definition files, does not have a command line override
            // that refers to a completely different version
            foreach (var uniquePkgName in uniquePackageNames)
            {
                foreach (var versionSpecifier in packageVersionSpecifiers)
                {
                    if (!versionSpecifier.Contains(uniquePkgName))
                    {
                        continue;
                    }

                    var versionFromDefinition = packageDefinitions.First(item => item.Name == uniquePkgName).Version;
                    if (versionSpecifier[1] != versionFromDefinition)
                    {
                        var noMatchMessage = new System.Text.StringBuilder();
                        noMatchMessage.AppendFormat("Command line version specified, {0}, could not resolve to one of the available versions of package {1}:", versionSpecifier[1], uniquePkgName);
                        noMatchMessage.AppendLine();
                        noMatchMessage.AppendFormat("\t{0}", versionFromDefinition);
                        noMatchMessage.AppendLine();
                        throw new Exception(noMatchMessage.ToString());
                    }
                }
            }

            if (enforceBamAssemblyVersions)
            {
                // for all packages that make up this assembly, ensure that their requirements on the version of the Bam
                // assemblies are upheld, prior to compiling the code
                foreach (var pkgDefn in packageDefinitions)
                {
                    pkgDefn.ValidateBamAssemblyRequirements();
                }
            }

            Graph.Instance.SetPackageDefinitions(packageDefinitions);
        }
Пример #24
0
        CompilePackageAssembly(
            bool enforceBamAssemblyVersions = true,
            bool enableClean = true)
        {
            // validate build root
            if (null == Graph.Instance.BuildRoot)
            {
                throw new Exception("Build root has not been specified");
            }

            var gatherSourceProfile = new TimeProfile(ETimingProfiles.GatherSource);

            gatherSourceProfile.StartProfile();

            IdentifyAllPackages(enforceBamAssemblyVersions: enforceBamAssemblyVersions);

            var cleanFirst = CommandLineProcessor.Evaluate(new Options.CleanFirst());

            if (enableClean && cleanFirst && System.IO.Directory.Exists(Graph.Instance.BuildRoot))
            {
                Log.Info("Deleting build root '{0}'", Graph.Instance.BuildRoot);
                try
                {
                    // make sure no files are read-only, which may have happened as part of collation preserving file attributes
                    var dirInfo = new System.IO.DirectoryInfo(Graph.Instance.BuildRoot);
                    foreach (var file in dirInfo.EnumerateFiles("*", System.IO.SearchOption.AllDirectories))
                    {
                        file.Attributes &= ~System.IO.FileAttributes.ReadOnly;
                    }

                    System.IO.Directory.Delete(Graph.Instance.BuildRoot, true);
                }
                catch (System.IO.IOException ex)
                {
                    Log.Info("Failed to delete build root, because {0}. Continuing", ex.Message);
                }
            }

            BuildModeUtilities.ValidateBuildModePackage();

            var definitions = new StringArray();

            // gather source files
            var sourceCode   = new StringArray();
            int packageIndex = 0;

            foreach (var package in Graph.Instance.Packages)
            {
                Log.DebugMessage("{0}: '{1}' @ '{2}'", packageIndex, package.Version, (package.PackageRepositories.Count > 0) ? package.PackageRepositories[0] : "Not in a repository");

                // to compile with debug information, you must compile the files
                // to compile without, we need to file contents to hash the source
                if (Graph.Instance.CompileWithDebugSymbols)
                {
                    var scripts = package.GetScriptFiles();
                    sourceCode.AddRange(scripts);
                    Log.DebugMessage(scripts.ToString("\n\t"));
                }
                else
                {
                    foreach (var scriptFile in package.GetScriptFiles())
                    {
                        using (var reader = new System.IO.StreamReader(scriptFile))
                        {
                            sourceCode.Add(reader.ReadToEnd());
                        }
                        Log.DebugMessage("\t'{0}'", scriptFile);
                    }
                }

                foreach (var define in package.Definitions)
                {
                    if (!definitions.Contains(define))
                    {
                        definitions.Add(define);
                    }
                }

                ++packageIndex;
            }

            // add/remove other definitions
            definitions.Add(VersionDefineForCompiler);
            definitions.Add(HostPlatformDefineForCompiler);
            definitions.Sort();

            gatherSourceProfile.StopProfile();

            var assemblyCompileProfile = new TimeProfile(ETimingProfiles.AssemblyCompilation);

            assemblyCompileProfile.StartProfile();

            // assembly is written to the build root
            var cachedAssemblyPathname = System.IO.Path.Combine(Graph.Instance.BuildRoot, ".CachedPackageAssembly");

            cachedAssemblyPathname = System.IO.Path.Combine(cachedAssemblyPathname, Graph.Instance.MasterPackage.Name) + ".dll";
            var    hashPathName = System.IO.Path.ChangeExtension(cachedAssemblyPathname, "hash");
            string thisHashCode = null;

            var cacheAssembly = !CommandLineProcessor.Evaluate(new Options.DisableCacheAssembly());

            string compileReason = null;

            if (Graph.Instance.CompileWithDebugSymbols)
            {
                compileReason = "debug symbols were enabled";
            }
            else
            {
                // can an existing assembly be reused?
                thisHashCode = GetPackageHash(sourceCode, definitions, Graph.Instance.MasterPackage.BamAssemblies);
                if (cacheAssembly)
                {
                    if (System.IO.File.Exists(hashPathName))
                    {
                        using (var reader = new System.IO.StreamReader(hashPathName))
                        {
                            var diskHashCode = reader.ReadLine();
                            if (diskHashCode.Equals(thisHashCode))
                            {
                                Log.DebugMessage("Cached assembly used '{0}', with hash {1}", cachedAssemblyPathname, diskHashCode);
                                Log.Detail("Re-using existing package assembly");
                                Graph.Instance.ScriptAssemblyPathname = cachedAssemblyPathname;

                                assemblyCompileProfile.StopProfile();
                                return;
                            }
                            else
                            {
                                compileReason = "package source has changed since the last compile";
                            }
                        }
                    }
                    else
                    {
                        compileReason = "no previously compiled package assembly exists";
                    }
                }
                else
                {
                    compileReason = "user has disabled package assembly caching";
                }
            }

            // use the compiler in the current runtime version to build the assembly of packages
            var clrVersion      = System.Environment.Version;
            var compilerVersion = System.String.Format("v{0}.{1}", clrVersion.Major, clrVersion.Minor);

            Log.Detail("Compiling package assembly (C# compiler {0}{1}), because {2}.",
                       compilerVersion,
                       Graph.Instance.ProcessState.TargetFrameworkVersion != null ? (", targetting " + Graph.Instance.ProcessState.TargetFrameworkVersion) : string.Empty,
                       compileReason);

            var providerOptions = new System.Collections.Generic.Dictionary <string, string>();

            providerOptions.Add("CompilerVersion", compilerVersion);

            if (Graph.Instance.ProcessState.RunningMono)
            {
                Log.DebugMessage("Compiling assembly for Mono");
            }

            using (var provider = new Microsoft.CSharp.CSharpCodeProvider(providerOptions))
            {
                var compilerParameters = new System.CodeDom.Compiler.CompilerParameters();
                compilerParameters.TreatWarningsAsErrors = true;
                compilerParameters.WarningLevel          = 4;
                compilerParameters.GenerateExecutable    = false;
                compilerParameters.GenerateInMemory      = false;

                if (Graph.Instance.CompileWithDebugSymbols)
                {
                    compilerParameters.OutputAssembly = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Graph.Instance.MasterPackage.Name) + ".dll";
                }
                else
                {
                    compilerParameters.OutputAssembly = cachedAssemblyPathname;
                }

                var compilerOptions = "/checked+ /unsafe-";
                if (Graph.Instance.CompileWithDebugSymbols)
                {
                    compilerParameters.IncludeDebugInformation = true;
                    compilerOptions += " /optimize-";
                }
                else
                {
                    compilerOptions += " /optimize+";
                }
                compilerOptions += " /platform:anycpu";

                // define strings
                compilerOptions += " /define:" + definitions.ToString(';');

                compilerParameters.CompilerOptions = compilerOptions;

                if (provider.Supports(System.CodeDom.Compiler.GeneratorSupport.Resources))
                {
                    // Bam assembly
                    // TODO: Q: why is it only for the master package? Why not all of them, which may have additional dependencies?
                    foreach (var assembly in Graph.Instance.MasterPackage.BamAssemblies)
                    {
                        var assemblyFileName = System.String.Format("{0}.dll", assembly.Name);
                        var assemblyPathName = System.IO.Path.Combine(Graph.Instance.ProcessState.ExecutableDirectory, assemblyFileName);
                        compilerParameters.ReferencedAssemblies.Add(assemblyPathName);
                    }

                    // DotNet assembly
                    foreach (var desc in Graph.Instance.MasterPackage.DotNetAssemblies)
                    {
                        var assemblyFileName = System.String.Format("{0}.dll", desc.Name);
                        compilerParameters.ReferencedAssemblies.Add(assemblyFileName);
                    }

                    if (Graph.Instance.ProcessState.RunningMono)
                    {
                        compilerParameters.ReferencedAssemblies.Add("Mono.Posix.dll");
                    }
                }
                else
                {
                    throw new Exception("C# compiler does not support Resources");
                }

                // this will create the build root directory as necessary
                IOWrapper.CreateDirectory(System.IO.Path.GetDirectoryName(compilerParameters.OutputAssembly));

                var results = Graph.Instance.CompileWithDebugSymbols ?
                              provider.CompileAssemblyFromFile(compilerParameters, sourceCode.ToArray()) :
                              provider.CompileAssemblyFromSource(compilerParameters, sourceCode.ToArray());

                if (results.Errors.HasErrors || results.Errors.HasWarnings)
                {
                    var message = new System.Text.StringBuilder();
                    message.AppendFormat("Failed to compile package '{0}'. There are {1} errors.", Graph.Instance.MasterPackage.FullName, results.Errors.Count);
                    message.AppendLine();
                    foreach (System.CodeDom.Compiler.CompilerError error in results.Errors)
                    {
                        message.AppendFormat("\t{0}({1}): {2} {3}", error.FileName, error.Line, error.ErrorNumber, error.ErrorText);
                        message.AppendLine();
                    }
                    if (!Graph.Instance.CompileWithDebugSymbols)
                    {
                        message.AppendLine();
                        ICommandLineArgument debugOption = new Options.UseDebugSymbols();
                        message.AppendFormat("Use the {0}/{1} command line option with bam for more accurate error messages.", debugOption.LongName, debugOption.ShortName);
                        message.AppendLine();
                    }
                    message.AppendLine();
                    ICommandLineArgument createDebugProjectOption = new Options.CreateDebugProject();
                    message.AppendFormat("Use the {0}/{1} command line option with bam to create an editable IDE project containing the build scripts.", createDebugProjectOption.LongName, createDebugProjectOption.ShortName);
                    message.AppendLine();
                    throw new Exception(message.ToString());
                }

                if (!Graph.Instance.CompileWithDebugSymbols)
                {
                    if (cacheAssembly)
                    {
                        using (var writer = new System.IO.StreamWriter(hashPathName))
                        {
                            writer.WriteLine(thisHashCode);
                        }
                    }
                    else
                    {
                        // will not throw if the file doesn't exist
                        System.IO.File.Delete(hashPathName);
                    }
                }

                Log.DebugMessage("Written assembly to '{0}'", compilerParameters.OutputAssembly);
                Graph.Instance.ScriptAssemblyPathname = compilerParameters.OutputAssembly;
            }

            assemblyCompileProfile.StopProfile();
        }
Пример #25
0
 CommandLineProcessor.IConvertToCommandLine.Convert(
     Bam.Core.StringArray commandLine)
 {
     CommandLineProcessor.Conversion.Convert(typeof(CommandLineImplementation), this, commandLine);
 }
Пример #26
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);
        }
 Convert(
     this IDSymUtilToolSettings settings,
     Bam.Core.StringArray commandLine)
 {
 }
Пример #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);
        }