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); }
// 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); }
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); }
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); }