コード例 #1
0
        FindTools <AttributeType, ToolType>(
            System.Collections.Generic.Dictionary <EBit, Bam.Core.TypeArray> collection)
            where AttributeType : ToolRegistrationAttribute
            where ToolType : Bam.Core.PreBuiltTool
        {
            var graph = Bam.Core.Graph.Instance;

            foreach (var toolData in GetToolsFromMetaData <AttributeType>())
            {
                var bits = toolData.Item2.BitDepth;
                if (!collection.ContainsKey(bits))
                {
                    collection[bits] = new Bam.Core.TypeArray(toolData.Item1);
                }
                else
                {
                    collection[bits].AddUnique(toolData.Item1);
                }
            }
        }
コード例 #2
0
        IArchivingPolicy.Archive(
            StaticLibrary sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString libraryPath,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> headers)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta;
            var target    = workspace.EnsureTargetExists(sender);

            target.EnsureOutputFileReferenceExists(
                sender.CreateTokenizedString("@filename($(0))", libraryPath),
                XcodeBuilder.FileReference.EFileType.Archive,
                XcodeBuilder.Target.EProductType.StaticLibrary);
            var configuration = target.GetConfiguration(sender);

            if (sender.Macros["OutputName"].Equals(sender.Macros["modulename"]))
            {
                configuration.SetProductName(Bam.Core.TokenizedString.CreateVerbatim("${TARGET_NAME}"));
            }
            else
            {
                configuration.SetProductName(sender.Macros["OutputName"]);
            }

            foreach (var header in headers)
            {
                target.EnsureHeaderFileExists((header as HeaderFile).InputPath);
            }

            var excludedSource  = new XcodeBuilder.MultiConfigurationValue();
            var realObjectFiles = objectFiles.Where(item => !(item is AssembledObjectFile)); // C,C++,ObjC,ObjC++

            if (realObjectFiles.Any())
            {
                var xcodeConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(XcodeBuilder.Configuration)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    realObjectFiles,
                    typeof(ClangCommon.XcodeCompilerImplementation),
                    typeof(XcodeProjectProcessor.IConvertToProject),
                    xcodeConvertParameterTypes);
                (sharedSettings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

                foreach (var objFile in realObjectFiles)
                {
                    if (!(objFile as C.ObjectFileBase).PerformCompilation)
                    {
                        var fullPath = (objFile as C.ObjectFileBase).InputPath.Parse();
                        var filename = System.IO.Path.GetFileName(fullPath);
                        excludedSource.Add(filename);
                    }

                    var buildFile     = objFile.MetaData as XcodeBuilder.BuildFile;
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    if (null != deltaSettings)
                    {
                        var commandLine = new Bam.Core.StringArray();
                        (deltaSettings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine);
                        if (commandLine.Count > 0)
                        {
                            // Cannot set per-file-per-configuration settings, so blend them together
                            if (null == buildFile.Settings)
                            {
                                buildFile.Settings = commandLine;
                            }
                            else
                            {
                                buildFile.Settings.AddRangeUnique(commandLine);
                            }
                        }
                    }
                    configuration.BuildFiles.Add(buildFile);
                }

                // now deal with other object file types
                var assembledObjectFiles = objectFiles.Where(item => item is AssembledObjectFile);
                foreach (var asmObj in assembledObjectFiles)
                {
                    var buildFile = asmObj.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }
            else
            {
                (objectFiles[0].Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
                foreach (var objFile in objectFiles)
                {
                    if (!(objFile as C.ObjectFileBase).PerformCompilation)
                    {
                        var fullPath = (objFile as C.ObjectFileBase).InputPath.Parse();
                        var filename = System.IO.Path.GetFileName(fullPath);
                        excludedSource.Add(filename);
                    }

                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }

            configuration["EXCLUDED_SOURCE_FILE_NAMES"] = excludedSource;

            // convert librarian settings to the Xcode project
            if (sender.Settings is XcodeProjectProcessor.IConvertToProject)
            {
                (sender.Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
            }

            // order only dependents
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }
                if (required is HeaderLibrary)
                {
                    // the target for a HeaderLibrary has no FileReference output, and thus cannot be an order only dependency
                    continue;
                }

                var requiredTarget = required.MetaData as XcodeBuilder.Target;
                if (null != requiredTarget)
                {
                    target.Requires(requiredTarget);
                }
            }
            // any non-C module targets should be order-only dependencies
            // note: this is unlikely to happen, as StaticLibraries don't have hard 'dependencies'
            // because there is no fixed 'link' action at the end
            foreach (var dependent in sender.Dependents)
            {
                if (null == dependent.MetaData)
                {
                    continue;
                }
                if (dependent is C.CModule)
                {
                    continue;
                }
                var dependentTarget = dependent.MetaData as XcodeBuilder.Target;
                if (null != dependentTarget)
                {
                    target.Requires(dependentTarget);
                }
            }
            // however, there may be forwarded libraries, and these are useful order only dependents
            foreach (var dependent in (sender as IForwardedLibraries).ForwardedLibraries)
            {
                if (null == dependent.MetaData)
                {
                    continue;
                }
                var dependentTarget = dependent.MetaData as XcodeBuilder.Target;
                if (null != dependentTarget)
                {
                    target.Requires(dependentTarget);
                }
            }
        }
コード例 #3
0
        IArchivingPolicy.Archive(
            StaticLibrary sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString libraryPath,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> headers)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution;
            var project  = solution.EnsureProjectExists(sender);
            var config   = project.GetConfiguration(sender);

            config.SetType(VSSolutionBuilder.VSProjectConfiguration.EType.StaticLibrary);
            config.SetOutputPath(libraryPath);
            config.EnableIntermediatePath();

            foreach (var header in headers)
            {
                config.AddHeaderFile(header as HeaderFile);
            }

            var compilerGroup = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.Compiler);

            var realObjectFiles = objectFiles.Where(item => !((item is WinResource) || (item is AssembledObjectFile)));

            if (realObjectFiles.Any())
            {
                var vsConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(VSSolutionBuilder.VSSettingsGroup),
                    typeof(string)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    realObjectFiles,
                    typeof(VisualCCommon.VSSolutionImplementation),
                    typeof(VisualStudioProcessor.IConvertToProject),
                    vsConvertParameterTypes);
                (sharedSettings as VisualStudioProcessor.IConvertToProject).Convert(sender, compilerGroup);

                foreach (var objFile in realObjectFiles)
                {
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    config.AddSourceFile(objFile, deltaSettings);
                }
            }

            // now handle the other object file types

            // TODO: if there were many resource files, this could also have a common settings group? Not sure if VS supports this
            // and it's not as likely to have many resource files, as it would have many source files
            var resourceObjectFiles = objectFiles.Where(item => item is WinResource);

            foreach (var resObj in resourceObjectFiles)
            {
                config.AddResourceFile(resObj as WinResource, resObj.Settings);
            }

            var assembledObjectFiles = objectFiles.Where(item => item is AssembledObjectFile);

            foreach (var asmObj in assembledObjectFiles)
            {
                config.AddAssemblyFile(asmObj as AssembledObjectFile, asmObj.Settings);
            }

            var vsSettingsGroup = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.Librarian);

            (sender.Settings as VisualStudioProcessor.IConvertToProject).Convert(sender, vsSettingsGroup);

            // order only dependencies
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }

                var requiredProject = required.MetaData as VSSolutionBuilder.VSProject;
                if (null != requiredProject)
                {
                    config.RequiresProject(requiredProject);
                }
            }
            // any non-C module projects should be order-only dependencies
            // note: this is unlikely to happen, as StaticLibraries don't have hard 'dependencies'
            // because there is no fixed 'link' action at the end
            foreach (var dependent in sender.Dependents)
            {
                if (null == dependent.MetaData)
                {
                    continue;
                }
                if (dependent is C.CModule)
                {
                    continue;
                }
                var dependentProject = dependent.MetaData as VSSolutionBuilder.VSProject;
                if (null != dependentProject)
                {
                    config.RequiresProject(dependentProject);
                }
            }
            // however, there may be forwarded libraries, and these are useful order only dependents
            foreach (var dependent in (sender as IForwardedLibraries).ForwardedLibraries)
            {
                if (null == dependent.MetaData)
                {
                    continue;
                }
                var dependentProject = dependent.MetaData as VSSolutionBuilder.VSProject;
                if (null != dependentProject)
                {
                    config.RequiresProject(dependentProject);
                }
            }
        }
コード例 #4
0
ファイル: SettingsBase.cs プロジェクト: knocte/BuildAMation
        SharedSettings(
            System.Collections.Generic.IEnumerable<Bam.Core.Module> objectFiles,
            System.Type convertExtensionClassType,
            System.Type conversionInterfaceType,
            Bam.Core.TypeArray convertParameterTypes)
        {
            var sharedInterfaces = SharedInterfaces(objectFiles);
            var implementedInterfaces = new Bam.Core.TypeArray(sharedInterfaces);
            implementedInterfaces.Add(conversionInterfaceType);

            // define a new type, that contains just the shared interfaces between all object files
            // (any interface not shared, must be cloned later)
            var typeSignature = "IDESharedSettings";
            var assemblyName = new System.Reflection.AssemblyName(typeSignature);
            var assemblyBuilder = System.AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, System.Reflection.Emit.AssemblyBuilderAccess.Run);
            var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule", true);
            var sharedSettingsTypeDefn = moduleBuilder.DefineType(typeSignature,
                System.Reflection.TypeAttributes.Public |
                System.Reflection.TypeAttributes.Class |
                System.Reflection.TypeAttributes.AutoClass |
                System.Reflection.TypeAttributes.AnsiClass |
                System.Reflection.TypeAttributes.BeforeFieldInit |
                System.Reflection.TypeAttributes.AutoLayout,
                typeof(C.SettingsBase),
                implementedInterfaces.ToArray());

                // TODO: is this necessary?
#if false
            sharedSettingsTypeDefn.DefineDefaultConstructor(
                System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName);
#endif

            // implement 'automatic property' setter and getters for each property in each interface
            foreach (var i in sharedInterfaces)
            {
                var properties = i.GetProperties();
                foreach (var prop in properties)
                {
                    var dynamicProperty = sharedSettingsTypeDefn.DefineProperty(prop.Name,
                        System.Reflection.PropertyAttributes.None,
                        prop.PropertyType,
                        System.Type.EmptyTypes);
                    var field = sharedSettingsTypeDefn.DefineField("m" + prop.Name,
                        prop.PropertyType,
                        System.Reflection.FieldAttributes.Private);
                    var methodAttrs = System.Reflection.MethodAttributes.Public |
                        System.Reflection.MethodAttributes.HideBySig |
                        System.Reflection.MethodAttributes.Virtual;
                    if (prop.IsSpecialName)
                    {
                        methodAttrs |= System.Reflection.MethodAttributes.SpecialName;
                    }
                    var getter = sharedSettingsTypeDefn.DefineMethod("get_" + prop.Name,
                        methodAttrs,
                        prop.PropertyType,
                        System.Type.EmptyTypes);
                    var setter = sharedSettingsTypeDefn.DefineMethod("set_" + prop.Name,
                        methodAttrs,
                        null,
                        new[] { prop.PropertyType });
                    var getIL = getter.GetILGenerator();
                    getIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                    getIL.Emit(System.Reflection.Emit.OpCodes.Ldfld, field);
                    getIL.Emit(System.Reflection.Emit.OpCodes.Ret);
                    dynamicProperty.SetGetMethod(getter);
                    var setIL = setter.GetILGenerator();
                    setIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                    setIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                    setIL.Emit(System.Reflection.Emit.OpCodes.Stfld, field);
                    setIL.Emit(System.Reflection.Emit.OpCodes.Ret);
                    dynamicProperty.SetSetMethod(setter);
                }
            }

            var projectSettingsConvertMethod = sharedSettingsTypeDefn.DefineMethod("Convert",
                System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Final | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.Virtual,
                null,
                convertParameterTypes.ToArray());
            var convertIL = projectSettingsConvertMethod.GetILGenerator();
            foreach (var i in sharedInterfaces)
            {
                var extConvertParameterTypes = new Bam.Core.TypeArray(i);
                extConvertParameterTypes.AddRange(convertParameterTypes);
                var methInfo = convertExtensionClassType.GetMethod("Convert", extConvertParameterTypes.ToArray());
                if (null == methInfo)
                {
                        throw new Bam.Core.Exception("Unable to locate the function {0}.{1}(this {2})", convertExtensionClassType.FullName, "Convert", i.Name);
                }
                // TODO: can this be simplified, using the ldarg opcode? a simple loop would suffice
                convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                if (extConvertParameterTypes.Count > 1)
                {
                    convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                }
                if (extConvertParameterTypes.Count > 2)
                {
                    convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_2);
                }
                if (extConvertParameterTypes.Count > 3)
                {
                    convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_3);
                }
                convertIL.Emit(System.Reflection.Emit.OpCodes.Call, methInfo);
            }
            convertIL.Emit(System.Reflection.Emit.OpCodes.Ret);

            var sharedSettingsType = sharedSettingsTypeDefn.CreateType();
            var attributeType = typeof(Bam.Core.SettingsExtensionsAttribute);

            // now that we have an instance of the shared settings type, calculate the values of the individual settings across all object files
            // for all shared interfaces
            var commonSettings = System.Activator.CreateInstance(sharedSettingsType) as SettingsBase;
            commonSettings.InitializeAllInterfaces(objectFiles.First(), true, false);
            foreach (var i in sharedInterfaces)
            {
                var attributeArray = i.GetCustomAttributes(attributeType, false);
                if (0 == attributeArray.Length)
                {
                    throw new Bam.Core.Exception("Settings interface {0} is missing attribute {1}", i.ToString(), attributeType.ToString());
                }

                var attribute = attributeArray[0] as Bam.Core.SettingsExtensionsAttribute;

                var cloneSettingsMethod = attribute.GetMethod("Clone", new[] { i, i });
                if (null == cloneSettingsMethod)
                {
                    throw new Bam.Core.Exception("Unable to find extension method {0}.SharedSettings(this {1}, {1}, {1}, {1})",
                        attribute.ExtensionsClassName,
                        i.ToString());
                }

                var intersectSettingsMethod = attribute.GetMethod("Intersect", new[] { i, i });
                if (null == intersectSettingsMethod)
                {
                    throw new Bam.Core.Exception("Unable to find extension method {0}.Intersect(this {1}, {1})",
                        attribute.ExtensionsClassName,
                        i.ToString());
                }

                var objectFileCount = objectFiles.Count();
                cloneSettingsMethod.Invoke(null, new[] { commonSettings, objectFiles.First().Settings });
                for (int objIndex = 1; objIndex < objectFileCount; ++objIndex)
                {
                    intersectSettingsMethod.Invoke(null, new[] { commonSettings, objectFiles.ElementAt(objIndex).Settings });
                }
            }
            return commonSettings;
        }
コード例 #5
0
        IArchivingPolicy.Archive(
            StaticLibrary sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString libraryPath,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> headers)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution;
            var project = solution.EnsureProjectExists(sender);
            var config = project.GetConfiguration(sender);

            config.SetType(VSSolutionBuilder.VSProjectConfiguration.EType.StaticLibrary);
            config.SetOutputPath(libraryPath);
            config.EnableIntermediatePath();

            foreach (var header in headers)
            {
                config.AddHeaderFile(header as HeaderFile);
            }

            var compilerGroup = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.Compiler);
            if (objectFiles.Count > 1)
            {
                var vsConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(VSSolutionBuilder.VSSettingsGroup),
                    typeof(string)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    objectFiles,
                    typeof(VisualCCommon.VSSolutionImplementation),
                    typeof(VisualStudioProcessor.IConvertToProject),
                    vsConvertParameterTypes);
                (sharedSettings as VisualStudioProcessor.IConvertToProject).Convert(sender, compilerGroup);

                foreach (var objFile in objectFiles)
                {
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    config.AddSourceFile(objFile, deltaSettings);
                }
            }
            else
            {
                (objectFiles[0].Settings as VisualStudioProcessor.IConvertToProject).Convert(sender, compilerGroup);
                foreach (var objFile in objectFiles)
                {
                    config.AddSourceFile(objFile, null);
                }
            }

            var vsSettingsGroup = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.Librarian);
            (sender.Settings as VisualStudioProcessor.IConvertToProject).Convert(sender, vsSettingsGroup);

            // order only dependencies
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }

                var requiredProject = required.MetaData as VSSolutionBuilder.VSProject;
                if (null != requiredProject)
                {
                    project.RequiresProject(requiredProject);
                }
            }
        }
コード例 #6
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)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var workspace   = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta;
            var target      = workspace.EnsureTargetExists(sender);
            var exeFilename = sender.CreateTokenizedString("@filename($(0))", executablePath);

            exeFilename.Parse();
            target.EnsureOutputFileReferenceExists(
                exeFilename,
                (sender is IDynamicLibrary) ? XcodeBuilder.FileReference.EFileType.DynamicLibrary : XcodeBuilder.FileReference.EFileType.Executable,
                (sender is IDynamicLibrary) ? XcodeBuilder.Target.EProductType.DynamicLibrary : XcodeBuilder.Target.EProductType.Executable);
            var configuration = target.GetConfiguration(sender);

            if (sender is IDynamicLibrary && !((sender is Plugin) || (sender is C.Cxx.Plugin)))
            {
                var productName = sender.Macros["OutputName"].ToString().Equals(sender.Macros["modulename"].ToString()) ?
                                  sender.CreateTokenizedString("${TARGET_NAME}.$(MajorVersion)") :
                                  sender.CreateTokenizedString("$(OutputName).$(MajorVersion)");
                lock (productName)
                {
                    if (!productName.IsParsed)
                    {
                        productName.Parse();
                    }
                }
                configuration.SetProductName(productName);
            }
            else
            {
                if (sender.Macros["OutputName"].ToString().Equals(sender.Macros["modulename"].ToString()))
                {
                    configuration.SetProductName(Bam.Core.TokenizedString.CreateVerbatim("${TARGET_NAME}"));
                }
                else
                {
                    configuration.SetProductName(sender.Macros["OutputName"]);
                }
            }

            foreach (var header in headers)
            {
                target.EnsureHeaderFileExists((header as HeaderFile).InputPath);
            }

            var excludedSource  = new XcodeBuilder.MultiConfigurationValue();
            var realObjectFiles = objectFiles.Where(item => !((item is WinResource) || (item is AssembledObjectFile)));

            if (realObjectFiles.Any())
            {
                var xcodeConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(XcodeBuilder.Configuration)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    realObjectFiles,
                    typeof(ClangCommon.XcodeCompilerImplementation),
                    typeof(XcodeProjectProcessor.IConvertToProject),
                    xcodeConvertParameterTypes);
                XcodeSharedSettings.Tweak(sharedSettings);
                (sharedSettings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

                foreach (var objFile in realObjectFiles)
                {
                    var asObjFileBase = objFile as C.ObjectFileBase;
                    if (!asObjFileBase.PerformCompilation)
                    {
                        var fullPath = asObjFileBase.InputPath.ToString();
                        var filename = System.IO.Path.GetFileName(fullPath);
                        excludedSource.Add(filename);
                    }

                    var buildFile     = objFile.MetaData as XcodeBuilder.BuildFile;
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    if (null != deltaSettings)
                    {
                        var commandLine = new Bam.Core.StringArray();
                        (deltaSettings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine);
                        if (commandLine.Count > 0)
                        {
                            // Cannot set per-file-per-configuration settings, so blend them together
                            if (null == buildFile.Settings)
                            {
                                buildFile.Settings = commandLine;
                            }
                            else
                            {
                                buildFile.Settings.AddRangeUnique(commandLine);
                            }
                        }
                    }
                    configuration.BuildFiles.Add(buildFile);
                }

                // now deal with other object file types
                var assembledObjectFiles = objectFiles.Where(item => item is AssembledObjectFile);
                foreach (var asmObj in assembledObjectFiles)
                {
                    var buildFile = asmObj.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }
            else
            {
                (objectFiles[0].Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
                foreach (var objFile in objectFiles)
                {
                    var asObjFileBase = objFile as C.ObjectFileBase;
                    if (!asObjFileBase.PerformCompilation)
                    {
                        var fullPath = asObjFileBase.InputPath.ToString();
                        var filename = System.IO.Path.GetFileName(fullPath);
                        excludedSource.Add(filename);
                    }

                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }

            configuration["EXCLUDED_SOURCE_FILE_NAMES"] = excludedSource;

            // add library search paths prior to converting linker settings
            var linker = sender.Settings as C.ICommonLinkerSettings;

            foreach (var library in libraries)
            {
                if (library is C.StaticLibrary)
                {
                    var libDir = library.CreateTokenizedString("@dir($(0))", library.GeneratedPaths[C.StaticLibrary.Key]);
                    lock (libDir)
                    {
                        if (!libDir.IsParsed)
                        {
                            libDir.Parse();
                        }
                    }
                    linker.LibraryPaths.Add(libDir);
                }
                else if (library is C.IDynamicLibrary)
                {
                    var libDir = library.CreateTokenizedString("@dir($(0))", library.GeneratedPaths[C.DynamicLibrary.Key]);
                    lock (libDir)
                    {
                        if (!libDir.IsParsed)
                        {
                            libDir.Parse();
                        }
                    }
                    linker.LibraryPaths.Add(libDir);
                }
                else if (library is C.CSDKModule)
                {
                    // SDK modules are collections of libraries, not one in particular
                    // thus do nothing as they are undefined at this point, and may yet be pulled in automatically
                }
                else if (library is C.HeaderLibrary)
                {
                    // no library
                }
                else if (library is OSXFramework)
                {
                    // frameworks are dealt with elsewhere
                }
                else
                {
                    throw new Bam.Core.Exception("Don't know how to handle this module type, {0}", library.ToString());
                }
            }

            foreach (var library in libraries)
            {
                var libAsCModule = library as C.CModule;
                if (null == libAsCModule)
                {
                    throw new Bam.Core.Exception("Don't know how to handle library module of type '{0}'", library.GetType().ToString());
                }
                if (libAsCModule.IsPrebuilt)
                {
                    if (library is OSXFramework)
                    {
                        // frameworks are dealt with elsewhere
                    }
                    else if (library is C.StaticLibrary)
                    {
                        (sender.Tool as C.LinkerTool).ProcessLibraryDependency(sender as CModule, libAsCModule);
                    }
                    else
                    {
                        throw new Bam.Core.Exception("Don't know how to handle this prebuilt module dependency, '{0}'", library.GetType().ToString());
                    }
                }
                else
                {
                    if (library is C.StaticLibrary)
                    {
                        target.DependsOn(library.MetaData as XcodeBuilder.Target);
                    }
                    else if (library is C.IDynamicLibrary)
                    {
                        target.DependsOn(library.MetaData as XcodeBuilder.Target);
                    }
                    else if (library is C.CSDKModule)
                    {
                        // do nothing, just an area for external
                    }
                    else if (library is C.HeaderLibrary)
                    {
                        // no library
                    }
                    else if (library is OSXFramework)
                    {
                        // frameworks are dealt with elsewhere
                    }
                    else
                    {
                        throw new Bam.Core.Exception("Don't know how to handle this module type");
                    }
                }
            }

            // convert link settings to the Xcode project
            (sender.Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

            var required_targets = new System.Collections.Generic.HashSet <XcodeBuilder.Target>();
            // order only dependencies - recurse into each, so that all layers
            // of order only dependencies are included
            var queue = new System.Collections.Generic.Queue <Bam.Core.Module>(sender.Requirements);

            while (queue.Count > 0)
            {
                var required = queue.Dequeue();
                foreach (var additional in required.Requirements)
                {
                    queue.Enqueue(additional);
                }

                if (null == required.MetaData)
                {
                    continue;
                }
                if (required is HeaderLibrary)
                {
                    // the target for a HeaderLibrary has no FileReference output, and thus cannot be an order only dependency
                    continue;
                }

                var requiredTarget = required.MetaData as XcodeBuilder.Target;
                if (null != requiredTarget)
                {
                    required_targets.Add(requiredTarget);
                }
            }
            // any non-C module projects should be order-only dependencies
            foreach (var dependent in sender.Dependents)
            {
                if (null == dependent.MetaData)
                {
                    continue;
                }
                if (dependent is C.CModule)
                {
                    continue;
                }
                var dependentTarget = dependent.MetaData as XcodeBuilder.Target;
                if (null != dependentTarget)
                {
                    required_targets.Add(dependentTarget);
                }
            }
            foreach (var reqTarget in required_targets)
            {
                target.Requires(reqTarget);
            }
        }
コード例 #7
0
        IArchivingPolicy.Archive(
            StaticLibrary sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString libraryPath,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> headers)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta;
            var target    = workspace.EnsureTargetExists(sender);

            target.EnsureOutputFileReferenceExists(
                sender.CreateTokenizedString("@filename($(0))", libraryPath),
                XcodeBuilder.FileReference.EFileType.Archive,
                XcodeBuilder.Target.EProductType.StaticLibrary);
            var configuration = target.GetConfiguration(sender);

            if (sender.Macros["OutputName"].Equals(sender.Macros["modulename"]))
            {
                configuration.SetProductName(Bam.Core.TokenizedString.CreateVerbatim("${TARGET_NAME}"));
            }
            else
            {
                configuration.SetProductName(sender.Macros["OutputName"]);
            }

            foreach (var header in headers)
            {
                target.EnsureHeaderFileExists((header as HeaderFile).InputPath);
            }

            if (objectFiles.Count > 1)
            {
                var xcodeConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(XcodeBuilder.Configuration)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    objectFiles,
                    typeof(ClangCommon.XcodeCompilerImplementation),
                    typeof(XcodeProjectProcessor.IConvertToProject),
                    xcodeConvertParameterTypes);
                (sharedSettings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

                foreach (var objFile in objectFiles)
                {
                    var buildFile     = objFile.MetaData as XcodeBuilder.BuildFile;
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    if (null != deltaSettings)
                    {
                        var commandLine = new Bam.Core.StringArray();
                        (deltaSettings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine);
                        if (commandLine.Count > 0)
                        {
                            // Cannot set per-file-per-configuration settings, so blend them together
                            if (null == buildFile.Settings)
                            {
                                buildFile.Settings = commandLine;
                            }
                            else
                            {
                                buildFile.Settings.AddRangeUnique(commandLine);
                            }
                        }
                    }
                    configuration.BuildFiles.Add(buildFile);
                }
            }
            else
            {
                (objectFiles[0].Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
                foreach (var objFile in objectFiles)
                {
                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }

            // convert librarian settings to the Xcode project
            if (sender.Settings is XcodeProjectProcessor.IConvertToProject)
            {
                (sender.Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
            }

            // order only dependents
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }
                if (required is HeaderLibrary)
                {
                    // the target for a HeaderLibrary has no FileReference output, and thus cannot be an order only dependency
                    continue;
                }

                var requiredTarget = required.MetaData as XcodeBuilder.Target;
                if (null != requiredTarget)
                {
                    target.Requires(requiredTarget);
                }
            }
        }
コード例 #8
0
        IArchivingPolicy.Archive(
            StaticLibrary sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString libraryPath,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection <Bam.Core.Module> headers)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var solution = Bam.Core.Graph.Instance.MetaData as VSSolutionBuilder.VSSolution;
            var project  = solution.EnsureProjectExists(sender);
            var config   = project.GetConfiguration(sender);

            config.SetType(VSSolutionBuilder.VSProjectConfiguration.EType.StaticLibrary);
            config.SetOutputPath(libraryPath);
            config.EnableIntermediatePath();

            foreach (var header in headers)
            {
                config.AddHeaderFile(header as HeaderFile);
            }

            var compilerGroup = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.Compiler);

            if (objectFiles.Count > 1)
            {
                var vsConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(VSSolutionBuilder.VSSettingsGroup),
                    typeof(string)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    objectFiles,
                    typeof(VisualCCommon.VSSolutionImplementation),
                    typeof(VisualStudioProcessor.IConvertToProject),
                    vsConvertParameterTypes);
                (sharedSettings as VisualStudioProcessor.IConvertToProject).Convert(sender, compilerGroup);

                foreach (var objFile in objectFiles)
                {
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    config.AddSourceFile(objFile, deltaSettings);
                }
            }
            else
            {
                (objectFiles[0].Settings as VisualStudioProcessor.IConvertToProject).Convert(sender, compilerGroup);
                foreach (var objFile in objectFiles)
                {
                    config.AddSourceFile(objFile, null);
                }
            }

            var vsSettingsGroup = config.GetSettingsGroup(VSSolutionBuilder.VSSettingsGroup.ESettingsGroup.Librarian);

            (sender.Settings as VisualStudioProcessor.IConvertToProject).Convert(sender, vsSettingsGroup);

            // order only dependencies
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }

                var requiredProject = required.MetaData as VSSolutionBuilder.VSProject;
                if (null != requiredProject)
                {
                    project.RequiresProject(requiredProject);
                }
            }
            // any non-C module projects should be order-only dependencies
            foreach (var dependent in sender.Dependents)
            {
                if (null == dependent.MetaData)
                {
                    continue;
                }
                if (dependent is C.CModule)
                {
                    continue;
                }
                var dependentProject = dependent.MetaData as VSSolutionBuilder.VSProject;
                if (null != dependentProject)
                {
                    project.RequiresProject(dependentProject);
                }
            }
        }
コード例 #9
0
ファイル: XcodeArchiving.cs プロジェクト: knocte/BuildAMation
        IArchivingPolicy.Archive(
            StaticLibrary sender,
            Bam.Core.ExecutionContext context,
            Bam.Core.TokenizedString libraryPath,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> objectFiles,
            System.Collections.ObjectModel.ReadOnlyCollection<Bam.Core.Module> headers)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta;
            var target = workspace.EnsureTargetExists(sender);
            target.EnsureOutputFileReferenceExists(
                sender.CreateTokenizedString("@filename($(0))", libraryPath),
                XcodeBuilder.FileReference.EFileType.Archive,
                XcodeBuilder.Target.EProductType.StaticLibrary);
            var configuration = target.GetConfiguration(sender);
            if (sender.Macros["OutputName"].Equals(sender.Macros["modulename"]))
            {
                configuration.SetProductName(Bam.Core.TokenizedString.CreateVerbatim("${TARGET_NAME}"));
            }
            else
            {
                configuration.SetProductName(sender.Macros["OutputName"]);
            }

            foreach (var header in headers)
            {
                target.EnsureHeaderFileExists((header as HeaderFile).InputPath);
            }

            if (objectFiles.Count > 1)
            {
                var xcodeConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(XcodeBuilder.Configuration)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    objectFiles,
                    typeof(ClangCommon.XcodeCompilerImplementation),
                    typeof(XcodeProjectProcessor.IConvertToProject),
                    xcodeConvertParameterTypes);
                (sharedSettings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

                foreach (var objFile in objectFiles)
                {
                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    if (null != deltaSettings)
                    {
                        var commandLine = new Bam.Core.StringArray();
                        (deltaSettings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine);
                        if (commandLine.Count > 0)
                        {
                            // Cannot set per-file-per-configuration settings, so blend them together
                            if (null == buildFile.Settings)
                            {
                                buildFile.Settings = commandLine;
                            }
                            else
                            {
                                buildFile.Settings.AddRangeUnique(commandLine);
                            }
                        }
                    }
                    configuration.BuildFiles.Add(buildFile);
                }
            }
            else
            {
                (objectFiles[0].Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
                foreach (var objFile in objectFiles)
                {
                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }

            // convert librarian settings to the Xcode project
            if (sender.Settings is XcodeProjectProcessor.IConvertToProject)
            {
                (sender.Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
            }

            // order only dependents
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }
                if (required is HeaderLibrary)
                {
                    // the target for a HeaderLibrary has no FileReference output, and thus cannot be an order only dependency
                    continue;
                }

                var requiredTarget = required.MetaData as XcodeBuilder.Target;
                if (null != requiredTarget)
                {
                    target.Requires(requiredTarget);
                }
            }
        }
コード例 #10
0
ファイル: XcodeLinker.cs プロジェクト: knocte/BuildAMation
        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)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta;
            var target    = workspace.EnsureTargetExists(sender);

            target.EnsureOutputFileReferenceExists(
                sender.CreateTokenizedString("@filename($(0))", executablePath),
                (sender is IDynamicLibrary) ? XcodeBuilder.FileReference.EFileType.DynamicLibrary : XcodeBuilder.FileReference.EFileType.Executable,
                (sender is IDynamicLibrary) ? XcodeBuilder.Target.EProductType.DynamicLibrary : XcodeBuilder.Target.EProductType.Executable);
            var configuration = target.GetConfiguration(sender);

            if (sender is IDynamicLibrary && !((sender is Plugin) || (sender is C.Cxx.Plugin)))
            {
                if (sender.Macros["OutputName"].Equals(sender.Macros["modulename"]))
                {
                    configuration.SetProductName(sender.CreateTokenizedString("${TARGET_NAME}.$(MajorVersion)"));
                }
                else
                {
                    configuration.SetProductName(sender.CreateTokenizedString("$(OutputName).$(MajorVersion)"));
                }
            }
            else
            {
                if (sender.Macros["OutputName"].Equals(sender.Macros["modulename"]))
                {
                    configuration.SetProductName(Bam.Core.TokenizedString.CreateVerbatim("${TARGET_NAME}"));
                }
                else
                {
                    configuration.SetProductName(sender.Macros["OutputName"]);
                }
            }

            foreach (var header in headers)
            {
                target.EnsureHeaderFileExists((header as HeaderFile).InputPath);
            }

            if (objectFiles.Count > 1)
            {
                var xcodeConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(XcodeBuilder.Configuration)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    objectFiles,
                    typeof(ClangCommon.XcodeCompilerImplementation),
                    typeof(XcodeProjectProcessor.IConvertToProject),
                    xcodeConvertParameterTypes);
                (sharedSettings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

                foreach (var objFile in objectFiles)
                {
                    var buildFile     = objFile.MetaData as XcodeBuilder.BuildFile;
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    if (null != deltaSettings)
                    {
                        var commandLine = new Bam.Core.StringArray();
                        (deltaSettings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine);
                        if (commandLine.Count > 0)
                        {
                            // Cannot set per-file-per-configuration settings, so blend them together
                            if (null == buildFile.Settings)
                            {
                                buildFile.Settings = commandLine;
                            }
                            else
                            {
                                buildFile.Settings.AddRangeUnique(commandLine);
                            }
                        }
                    }
                    configuration.BuildFiles.Add(buildFile);
                }
            }
            else
            {
                (objectFiles[0].Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
                foreach (var objFile in objectFiles)
                {
                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }

            // add library search paths prior to converting linker settings
            var linker = sender.Settings as C.ICommonLinkerSettings;

            foreach (var library in libraries)
            {
                if (library is C.StaticLibrary)
                {
                    linker.LibraryPaths.Add(library.CreateTokenizedString("@dir($(0))", library.GeneratedPaths[C.StaticLibrary.Key]));
                }
                else if (library is C.IDynamicLibrary)
                {
                    linker.LibraryPaths.Add(library.CreateTokenizedString("@dir($(0))", library.GeneratedPaths[C.DynamicLibrary.Key]));
                }
                else if (library is C.CSDKModule)
                {
                    // SDK modules are collections of libraries, not one in particular
                    // thus do nothing as they are undefined at this point, and may yet be pulled in automatically
                }
                else if (library is C.HeaderLibrary)
                {
                    // no library
                }
                else if (library is OSXFramework)
                {
                    // frameworks are dealt with elsewhere
                }
                else
                {
                    throw new Bam.Core.Exception("Don't know how to handle this module type, {0}", library.ToString());
                }
            }

            // convert link settings to the Xcode project
            (sender.Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

            foreach (var library in libraries)
            {
                if (library is C.StaticLibrary)
                {
                    target.DependsOn(library.MetaData as XcodeBuilder.Target);
                }
                else if (library is C.IDynamicLibrary)
                {
                    target.DependsOn(library.MetaData as XcodeBuilder.Target);
                }
                else if (library is C.CSDKModule)
                {
                    // do nothing, just an area for external
                }
                else if (library is C.HeaderLibrary)
                {
                    // no library
                }
                else if (library is OSXFramework)
                {
                    // frameworks are dealt with elsewhere
                }
                else
                {
                    throw new Bam.Core.Exception("Don't know how to handle this module type");
                }
            }

            // order only dependents
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }
                if (required is HeaderLibrary)
                {
                    // the target for a HeaderLibrary has no FileReference output, and thus cannot be an order only dependency
                    continue;
                }

                var requiredTarget = required.MetaData as XcodeBuilder.Target;
                if (null != requiredTarget)
                {
                    target.Requires(requiredTarget);
                }
            }
        }
コード例 #11
0
        SharedSettings(
            System.Collections.Generic.IEnumerable <Bam.Core.Module> objectFiles,
            System.Type convertExtensionClassType,
            System.Type conversionInterfaceType,
            Bam.Core.TypeArray convertParameterTypes)
        {
            var sharedInterfaces      = SharedInterfaces(objectFiles);
            var implementedInterfaces = new Bam.Core.TypeArray(sharedInterfaces);

            implementedInterfaces.Add(conversionInterfaceType);

            // define a new type, that contains just the shared interfaces between all object files
            // (any interface not shared, must be cloned later)
            var typeSignature          = "IDESharedSettings";
            var assemblyName           = new System.Reflection.AssemblyName(typeSignature);
            var assemblyBuilder        = System.AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, System.Reflection.Emit.AssemblyBuilderAccess.Run);
            var moduleBuilder          = assemblyBuilder.DefineDynamicModule("MainModule", true);
            var sharedSettingsTypeDefn = moduleBuilder.DefineType(typeSignature,
                                                                  System.Reflection.TypeAttributes.Public |
                                                                  System.Reflection.TypeAttributes.Class |
                                                                  System.Reflection.TypeAttributes.AutoClass |
                                                                  System.Reflection.TypeAttributes.AnsiClass |
                                                                  System.Reflection.TypeAttributes.BeforeFieldInit |
                                                                  System.Reflection.TypeAttributes.AutoLayout,
                                                                  typeof(C.SettingsBase),
                                                                  implementedInterfaces.ToArray());

            // TODO: is this necessary?
#if false
            sharedSettingsTypeDefn.DefineDefaultConstructor(
                System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName);
#endif

            // implement 'automatic property' setter and getters for each property in each interface
            foreach (var i in sharedInterfaces)
            {
                var properties = i.GetProperties();
                foreach (var prop in properties)
                {
                    var dynamicProperty = sharedSettingsTypeDefn.DefineProperty(prop.Name,
                                                                                System.Reflection.PropertyAttributes.None,
                                                                                prop.PropertyType,
                                                                                System.Type.EmptyTypes);
                    var field = sharedSettingsTypeDefn.DefineField("m" + prop.Name,
                                                                   prop.PropertyType,
                                                                   System.Reflection.FieldAttributes.Private);
                    var methodAttrs = System.Reflection.MethodAttributes.Public |
                                      System.Reflection.MethodAttributes.HideBySig |
                                      System.Reflection.MethodAttributes.Virtual;
                    if (prop.IsSpecialName)
                    {
                        methodAttrs |= System.Reflection.MethodAttributes.SpecialName;
                    }
                    var getter = sharedSettingsTypeDefn.DefineMethod("get_" + prop.Name,
                                                                     methodAttrs,
                                                                     prop.PropertyType,
                                                                     System.Type.EmptyTypes);
                    var setter = sharedSettingsTypeDefn.DefineMethod("set_" + prop.Name,
                                                                     methodAttrs,
                                                                     null,
                                                                     new[] { prop.PropertyType });
                    var getIL = getter.GetILGenerator();
                    getIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                    getIL.Emit(System.Reflection.Emit.OpCodes.Ldfld, field);
                    getIL.Emit(System.Reflection.Emit.OpCodes.Ret);
                    dynamicProperty.SetGetMethod(getter);
                    var setIL = setter.GetILGenerator();
                    setIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                    setIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                    setIL.Emit(System.Reflection.Emit.OpCodes.Stfld, field);
                    setIL.Emit(System.Reflection.Emit.OpCodes.Ret);
                    dynamicProperty.SetSetMethod(setter);
                }
            }

            var projectSettingsConvertMethod = sharedSettingsTypeDefn.DefineMethod("Convert",
                                                                                   System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Final | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.Virtual,
                                                                                   null,
                                                                                   convertParameterTypes.ToArray());
            var convertIL = projectSettingsConvertMethod.GetILGenerator();
            foreach (var i in sharedInterfaces)
            {
                var extConvertParameterTypes = new Bam.Core.TypeArray(i);
                extConvertParameterTypes.AddRange(convertParameterTypes);
                var methInfo = convertExtensionClassType.GetMethod("Convert", extConvertParameterTypes.ToArray());
                if (null == methInfo)
                {
                    throw new Bam.Core.Exception("Unable to locate the function {0}.{1}(this {2})", convertExtensionClassType.FullName, "Convert", i.Name);
                }
                // TODO: can this be simplified, using the ldarg opcode? a simple loop would suffice
                convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                if (extConvertParameterTypes.Count > 1)
                {
                    convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                }
                if (extConvertParameterTypes.Count > 2)
                {
                    convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_2);
                }
                if (extConvertParameterTypes.Count > 3)
                {
                    convertIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_3);
                }
                convertIL.Emit(System.Reflection.Emit.OpCodes.Call, methInfo);
            }
            convertIL.Emit(System.Reflection.Emit.OpCodes.Ret);

            var sharedSettingsType = sharedSettingsTypeDefn.CreateType();
            var attributeType      = typeof(Bam.Core.SettingsExtensionsAttribute);

            // now that we have an instance of the shared settings type, calculate the values of the individual settings across all object files
            // for all shared interfaces
            var commonSettings = System.Activator.CreateInstance(sharedSettingsType) as SettingsBase;
            commonSettings.InitializeAllInterfaces(objectFiles.First(), true, false);
            foreach (var i in sharedInterfaces)
            {
                var attributeArray = i.GetCustomAttributes(attributeType, false);
                if (0 == attributeArray.Length)
                {
                    throw new Bam.Core.Exception("Settings interface {0} is missing attribute {1}", i.ToString(), attributeType.ToString());
                }

                var attribute = attributeArray[0] as Bam.Core.SettingsExtensionsAttribute;

                var cloneSettingsMethod = attribute.GetMethod("Clone", new[] { i, i });
                if (null == cloneSettingsMethod)
                {
                    throw new Bam.Core.Exception("Unable to find extension method {0}.Clone(this {1}, {1}, {1}, {1})",
                                                 attribute.ExtensionsClassName,
                                                 i.ToString());
                }

                var intersectSettingsMethod = attribute.GetMethod("Intersect", new[] { i, i });
                if (null == intersectSettingsMethod)
                {
                    throw new Bam.Core.Exception("Unable to find extension method {0}.Intersect(this {1}, {1})",
                                                 attribute.ExtensionsClassName,
                                                 i.ToString());
                }

                var objectFileCount = objectFiles.Count();
                cloneSettingsMethod.Invoke(null, new[] { commonSettings, objectFiles.First().Settings });
                for (int objIndex = 1; objIndex < objectFileCount; ++objIndex)
                {
                    intersectSettingsMethod.Invoke(null, new[] { commonSettings, objectFiles.ElementAt(objIndex).Settings });
                }
            }
            return(commonSettings);
        }
コード例 #12
0
ファイル: XcodeLinker.cs プロジェクト: knocte/BuildAMation
        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)
        {
            if (0 == objectFiles.Count)
            {
                return;
            }

            var workspace = Bam.Core.Graph.Instance.MetaData as XcodeBuilder.WorkspaceMeta;
            var target = workspace.EnsureTargetExists(sender);
            target.EnsureOutputFileReferenceExists(
                sender.CreateTokenizedString("@filename($(0))", executablePath),
                (sender is IDynamicLibrary) ? XcodeBuilder.FileReference.EFileType.DynamicLibrary : XcodeBuilder.FileReference.EFileType.Executable,
                (sender is IDynamicLibrary) ? XcodeBuilder.Target.EProductType.DynamicLibrary : XcodeBuilder.Target.EProductType.Executable);
            var configuration = target.GetConfiguration(sender);
            if (sender is IDynamicLibrary && !((sender is Plugin) || (sender is C.Cxx.Plugin)))
            {
                if (sender.Macros["OutputName"].Equals(sender.Macros["modulename"]))
                {
                    configuration.SetProductName(sender.CreateTokenizedString("${TARGET_NAME}.$(MajorVersion)"));
                }
                else
                {
                    configuration.SetProductName(sender.CreateTokenizedString("$(OutputName).$(MajorVersion)"));
                }
            }
            else
            {
                if (sender.Macros["OutputName"].Equals(sender.Macros["modulename"]))
                {
                    configuration.SetProductName(Bam.Core.TokenizedString.CreateVerbatim("${TARGET_NAME}"));
                }
                else
                {
                    configuration.SetProductName(sender.Macros["OutputName"]);
                }
            }

            foreach (var header in headers)
            {
                target.EnsureHeaderFileExists((header as HeaderFile).InputPath);
            }

            if (objectFiles.Count > 1)
            {
                var xcodeConvertParameterTypes = new Bam.Core.TypeArray
                {
                    typeof(Bam.Core.Module),
                    typeof(XcodeBuilder.Configuration)
                };

                var sharedSettings = C.SettingsBase.SharedSettings(
                    objectFiles,
                    typeof(ClangCommon.XcodeCompilerImplementation),
                    typeof(XcodeProjectProcessor.IConvertToProject),
                    xcodeConvertParameterTypes);
                (sharedSettings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

                foreach (var objFile in objectFiles)
                {
                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    var deltaSettings = (objFile.Settings as C.SettingsBase).CreateDeltaSettings(sharedSettings, objFile);
                    if (null != deltaSettings)
                    {
                        var commandLine = new Bam.Core.StringArray();
                        (deltaSettings as CommandLineProcessor.IConvertToCommandLine).Convert(commandLine);
                        if (commandLine.Count > 0)
                        {
                            // Cannot set per-file-per-configuration settings, so blend them together
                            if (null == buildFile.Settings)
                            {
                                buildFile.Settings = commandLine;
                            }
                            else
                            {
                                buildFile.Settings.AddRangeUnique(commandLine);
                            }
                        }
                    }
                    configuration.BuildFiles.Add(buildFile);
                }
            }
            else
            {
                (objectFiles[0].Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);
                foreach (var objFile in objectFiles)
                {
                    var buildFile = objFile.MetaData as XcodeBuilder.BuildFile;
                    configuration.BuildFiles.Add(buildFile);
                }
            }

            // add library search paths prior to converting linker settings
            var linker = sender.Settings as C.ICommonLinkerSettings;
            foreach (var library in libraries)
            {
                if (library is C.StaticLibrary)
                {
                    linker.LibraryPaths.Add(library.CreateTokenizedString("@dir($(0))", library.GeneratedPaths[C.StaticLibrary.Key]));
                }
                else if (library is C.IDynamicLibrary)
                {
                    linker.LibraryPaths.Add(library.CreateTokenizedString("@dir($(0))", library.GeneratedPaths[C.DynamicLibrary.Key]));
                }
                else if (library is C.CSDKModule)
                {
                    // SDK modules are collections of libraries, not one in particular
                    // thus do nothing as they are undefined at this point, and may yet be pulled in automatically
                }
                else if (library is C.HeaderLibrary)
                {
                    // no library
                }
                else if (library is OSXFramework)
                {
                    // frameworks are dealt with elsewhere
                }
                else
                {
                    throw new Bam.Core.Exception("Don't know how to handle this module type, {0}", library.ToString());
                }
            }

            // convert link settings to the Xcode project
            (sender.Settings as XcodeProjectProcessor.IConvertToProject).Convert(sender, configuration);

            foreach (var library in libraries)
            {
                if (library is C.StaticLibrary)
                {
                    target.DependsOn(library.MetaData as XcodeBuilder.Target);
                }
                else if (library is C.IDynamicLibrary)
                {
                    target.DependsOn(library.MetaData as XcodeBuilder.Target);
                }
                else if (library is C.CSDKModule)
                {
                    // do nothing, just an area for external
                }
                else if (library is C.HeaderLibrary)
                {
                    // no library
                }
                else if (library is OSXFramework)
                {
                    // frameworks are dealt with elsewhere
                }
                else
                {
                    throw new Bam.Core.Exception("Don't know how to handle this module type");
                }
            }

            // order only dependents
            foreach (var required in sender.Requirements)
            {
                if (null == required.MetaData)
                {
                    continue;
                }
                if (required is HeaderLibrary)
                {
                    // the target for a HeaderLibrary has no FileReference output, and thus cannot be an order only dependency
                    continue;
                }

                var requiredTarget = required.MetaData as XcodeBuilder.Target;
                if (null != requiredTarget)
                {
                    target.Requires(requiredTarget);
                }
            }
        }