예제 #1
0
        private IAssemblyInfo BuildAndLoadAssembly(IList <string> sharpmakeFiles, IBuilderContext context, IEnumerable <ISourceAttributeParser> parsers = null, IEnumerable <IParsingFlowParser> flowParsers = null)
        {
            Assembler assembler = new Assembler(Defines);

            // Add sharpmake assembly
            assembler.Assemblies.Add(_sharpmakeAssembly.Value);

            // Add generators assembly to be able to reference them from .sharpmake.cs files
            assembler.Assemblies.Add(_sharpmakeGeneratorAssembly.Value);

            // Add attribute parsers
            if (parsers != null)
            {
                assembler.UseDefaultParsers = false;
                assembler.AttributeParsers.AddRange(parsers);
            }
            else
            {
                foreach (var parser in _attributeParsers)
                {
                    assembler.AttributeParsers.Add(parser);
                }
            }

            if (flowParsers != null)
            {
                assembler.ParsingFlowParsers.AddRange(flowParsers);
            }

            var newAssemblyInfo = assembler.BuildAssembly(context, sharpmakeFiles.ToArray());

            if (newAssemblyInfo.Assembly == null && context.CompileErrorBehavior == BuilderCompileErrorBehavior.ThrowException)
            {
                throw new InternalError();
            }

            // Keep track of assemblies explicitly referenced by compiled files
            foreach (var fullpath in assembler.References.Distinct())
            {
                var    assemblyName = AssemblyName.GetAssemblyName(fullpath).FullName;
                string assemblyPath;
                if (_references.TryGetValue(assemblyName, out assemblyPath) && !string.Equals(assemblyPath, fullpath, StringComparison.OrdinalIgnoreCase))
                {
                    throw new Error($"Assembly {assemblyName} present in two different locations: {fullpath} and {assemblyPath}.");
                }
                _references[assemblyName] = fullpath;
            }

            if (newAssemblyInfo.Assembly != null)
            {
                _builtAssemblies[newAssemblyInfo.Assembly.FullName] = newAssemblyInfo.Assembly;
            }
            return(newAssemblyInfo);
        }
예제 #2
0
파일: Builder.cs 프로젝트: vasama/Sharpmake
        // Expect a list of existing files with their full path
        public void LoadSharpmakeFiles(params string[] sharpmakeFiles)
        {
            Assembler assembler = new Assembler();

            // Add sharpmake assembly
            Assembly sharpmake = Assembly.GetAssembly(typeof(Builder));

            assembler.Assemblies.Add(sharpmake);

            // Add generators assembly to be able to reference them from .sharpmake files.
            DirectoryInfo entryDirectoryInfo = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
            string        generatorsAssembly = entryDirectoryInfo.FullName + Path.DirectorySeparatorChar + "Sharpmake.Generators.dll";
            Assembly      generators         = Assembly.LoadFrom(generatorsAssembly);

            assembler.Assemblies.Add(generators);

            _projectAssembly = assembler.BuildAssembly(sharpmakeFiles);

            if (_projectAssembly == null)
            {
                throw new InternalError();
            }

            // Keep track of assemblies explicitly referenced by compiled files
            _referenceList = assembler.References.ToDictionary(fullpath => AssemblyName.GetAssemblyName(fullpath).FullName.ToString(), fullpath => fullpath);

            // load platforms if they were passed as references
            using (var extensionLoader = new ExtensionLoader())
            {
                foreach (var referencePath in assembler.References)
                {
                    try
                    {
                        extensionLoader.LoadExtension(referencePath, false);
                    }
                    catch (Error)
                    {
                        // skip non-sharpmake extension
                    }
                }
            }

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

            LoadAssemblies(_projectAssembly);
        }
예제 #3
0
        private Assembly BuildAndLoadAssembly(IList <string> sharpmakeFiles)
        {
            Assembler assembler = new Assembler();

            // Add sharpmake assembly
            assembler.Assemblies.Add(SharpmakeAssembly.Value);

            // Add generators assembly to be able to reference them from .sharpmake.cs files
            assembler.Assemblies.Add(SharpmakeGeneratorAssembly.Value);

            Assembly newAssembly = assembler.BuildAssembly(sharpmakeFiles.ToArray());

            if (newAssembly == null)
            {
                throw new InternalError();
            }

            // Keep track of assemblies explicitly referenced by compiled files
            foreach (var fullpath in assembler.References.Distinct())
            {
                var    assemblyName = AssemblyName.GetAssemblyName(fullpath).FullName;
                string assemblyPath;
                if (_references.TryGetValue(assemblyName, out assemblyPath) && !string.Equals(assemblyPath, fullpath, StringComparison.OrdinalIgnoreCase))
                {
                    throw new Error($"Assembly {assemblyName} present in two different locations: {fullpath} and {assemblyPath}.");
                }
                _references[assemblyName] = fullpath;
            }

            // Load platforms if they were passed as references
            using (var extensionLoader = new ExtensionLoader())
            {
                foreach (var referencePath in assembler.References)
                {
                    extensionLoader.LoadExtension(referencePath, false);
                }
            }

            _builtAssemblies.Add(newAssembly);
            return(newAssembly);
        }
예제 #4
0
        public static TDelegate BuildDelegate <TDelegate>(string sourceFilePath, string fullFunctionName, Assembly[] assemblies)
            where TDelegate : class
        {
            FileInfo fileInfo = new FileInfo(sourceFilePath);

            if (!fileInfo.Exists)
            {
                throw new Error("source file name not found: {0}", sourceFilePath);
            }

            Type delegateType = typeof(TDelegate);

            Error.Valid(IsDelegate(delegateType), "BuildDelegate<FUNC_TYPE>(), FUNC_TYPE is not a delegate");
            MethodInfo delegateMethodInfo = GetDelegateMethodInfo(delegateType);


            ParameterInfo[] delegateParameterInfos = delegateMethodInfo.GetParameters();
            ParameterInfo   delegateReturnInfos    = delegateMethodInfo.ReturnParameter;

            Assembler assembler = new Assembler();

            assembler.UseDefaultReferences = false;
            assembler.Assemblies.AddRange(assemblies);

            Assembly assembly = assembler.BuildAssembly(fileInfo.FullName);

            List <MethodInfo> matchMethods = new List <MethodInfo>();

            foreach (Type type in assembly.GetTypes())
            {
                MethodInfo[] methodInfos = type.GetMethods();

                foreach (MethodInfo methodInfo in methodInfos)
                {
                    string fullName = methodInfo.DeclaringType.FullName + "." + methodInfo.Name;
                    if (fullFunctionName == fullName &&
                        methodInfo.IsStatic && methodInfo.GetParameters().Length == delegateMethodInfo.GetParameters().Length)
                    {
                        ParameterInfo[] parameterInfos = methodInfo.GetParameters();
                        ParameterInfo   returnInfos    = methodInfo.ReturnParameter;

                        bool equal = (returnInfos.GetType() == delegateReturnInfos.GetType() &&
                                      parameterInfos.Length == delegateParameterInfos.Length);

                        if (equal)
                        {
                            for (int i = 0; i < parameterInfos.Length; ++i)
                            {
                                if (parameterInfos[i].GetType() != delegateParameterInfos[i].GetType())
                                {
                                    equal = false;
                                    break;
                                }
                            }
                        }
                        if (equal)
                        {
                            matchMethods.Add(methodInfo);
                        }
                    }
                }
            }

            if (matchMethods.Count != 1)
            {
                throw new Error("Cannot find method name {0} that match {1} in {2}", fullFunctionName, delegateMethodInfo.ToString(), sourceFilePath);
            }

            MethodInfo method = matchMethods[0];

            // bind the method
            Delegate returnDelegate;

            try
            {
                returnDelegate = method.CreateDelegate(delegateType);
                InternalError.Valid(returnDelegate != null);
            }
            catch (Exception e)
            {
                throw new InternalError(e);
            }

            TDelegate result = returnDelegate as TDelegate;

            InternalError.Valid(result != null, "Cannot cast built delegate into user delegate");

            return(result);
        }