public BuildInformation(Entity rootEntity, string buildType, bool configure, bool noConfigure, string buildProperties, string output) { RootEntity = rootEntity; BuildType = buildType; Configure = configure; NoConfigure = noConfigure; BuildProperties = buildProperties; Output = output; }
private void CopyExternalLibrariesToOutputDirectory(Entity target, Dictionary <Entity, VirtualFile> projectLibraries, out IEnumerable <string> externalLibraries, out IEnumerable <VirtualFile> copiedLibraries) { VirtualDirectory deployDirectory = DeployEntity.Decorate(target).DeployDirectory; VirtualDirectory externalDirectory = deployDirectory.Directory("auto-deployed-external-libraries"); externalDirectory.Clear(); executionContext.Observable.OnNext(new Change(() => externalDirectory.UnClear(), "Cleared automatic copied external libraries.")); externalLibraries = Enumerable.Empty <string>(); copiedLibraries = Enumerable.Empty <VirtualFile>(); List <VirtualFile> newLibraryFiles = new List <VirtualFile>(); if (deployDirectory.Files("*.so", true).Except(projectLibraries.Values).Any()) { externalLibraries = deployDirectory.Files("*.so", true).Except(projectLibraries.Values) .Select(f => f.FullName).ToArray(); //external libraries where copied by user; no further action is required return; } BuildEntity buildEntity = BuildEntity.Decorate(target); if (!buildEntity.HasBuildSystem) { TargetEntity targetEntity = TargetEntity.Decorate(target); executionContext.WriteWarning(new CMakeBuildSystemNotFoundException(targetEntity.FullName, buildEntity.BuildType).Message); return; } externalLibraries = buildEntity.BuildSystem.ExternalLibraries; TargetEntity entity = TargetEntity.Decorate(target); if (entity.Version >= new Version(20, 6)) { foreach (string externalLibrary in buildEntity.BuildSystem.ExternalLibraries) { VirtualFile newFile = fileSystem.GetFile(externalLibrary).CopyTo(deployDirectory); newLibraryFiles.Add(newFile); executionContext.Observable.OnNext(new Change(() => newFile.Delete(), $"Copied {externalLibrary} to {newFile.FullName}.")); } } else { foreach (string externalLibrary in buildEntity.BuildSystem.ExternalLibraries) { executionContext.WriteWarning($"The library {externalLibrary} must be transferred to the device {entity.FullName} into the directory \"usr/local/lib\" manually."); } } copiedLibraries = newLibraryFiles; }
public int BuildLibraryForProject(Entity project, ChangeObservable observable, string metaFilesDirectory, string libraryLocation, string outputDirectory, Guid libraryGuid, IEnumerable <string> targets, IEnumerable <string> externalLibraries, string buildType) { userInterface.WriteInformation("Starting library generation..."); ProjectEntity projectEntity = ProjectEntity.Decorate(project); IEnumerable <(Target, string)> targetsSet; if (!targets.Any()) { TargetsResult ts = targetParser.Targets(projectEntity, false); if (!ts.ValidTargets.Any()) { throw new FormattableException ("Please use --target to specify for which targets the library shall be generated."); } else { HashSet <(Target, string)> targetsHashSet = new HashSet <(Target, string)>(); foreach (Target target in ts.ValidTargets) { targetsHashSet.Add((target, null)); } targetsSet = targetsHashSet; } } else { targetsSet = targetParser.GetSpecificTargets(targets, false); } Dictionary <Target, IEnumerable <VirtualFile> > externalLibs = ExternalLibrariesParser.ParseExternalLibraries(externalLibraries, targetParser, fileSystem, targetsSet.Select(t => t.Item1)); int result = libraryBuilderExecuter.Execute(projectEntity, metaFilesDirectory, libraryLocation, outputDirectory, observable, userInterface, libraryGuid, targetsSet, externalLibs, buildType); if (result == 0) { userInterface.WriteInformation("Successfully generated library!"); } return(result); }
//TODO Patch libmeta here public int Execute(Entity dataModel) { ProjectEntity project = ProjectEntity.Decorate(dataModel.Root); CodeEntity projectCodeEntity = CodeEntity.Decorate(project); string projectName = projectCodeEntity.Namespace; IEnumerable <Entity> targets = project.Targets.ToArray(); if (!targets.Any()) { throw new FormattableException("Please use --target to specify for which targets the library shall be generated."); } Dictionary <Entity, VirtualFile> projectLibraries = targets.ToDictionary(t => t, FindLibrary); List <string> externalLibraries = new List <string>(); List <VirtualFile> deletableFiles = new List <VirtualFile>(); foreach (Entity target in targets) { CopyExternalLibrariesToOutputDirectory(target, projectLibraries, out IEnumerable <string> libraries, out IEnumerable <VirtualFile> toBeDeleted); externalLibraries.AddRange(libraries); deletableFiles.AddRange(toBeDeleted); } CheckMetaFiles(targets.First()); string commandOptionsFile = GenerateCommandOptions(project, projectLibraries, projectName); int result = ExecuteLibraryBuilderWithCommandOptions(commandOptionsFile, project); foreach (VirtualFile deletable in deletableFiles) { deletable.Delete(); } return(result); VirtualFile FindLibrary(Entity target) { VirtualDirectory deployDirectory = DeployEntity.Decorate(target).DeployDirectory; string libFile = deployDirectory.Files("*.so", true) .OrderByDescending(f => f.Name.Equals($"lib{projectName}.so", StringComparison.OrdinalIgnoreCase)) .ThenByDescending(f => f.LastWriteTime) .FirstOrDefault() ?.FullName; if (string.IsNullOrEmpty(libFile)) { throw new LibraryNotFoundException(deployDirectory.FullName); } VirtualFile file = fileSystem.GetFile(libFile); return(file); } void CheckMetaFiles(Entity target) { TemplateEntity projectTemplateEntity = TemplateEntity.Decorate(project); VirtualDirectory deployDirectory = DeployEntity.Decorate(target).DeployDirectory; if (!fileSystem.FileExists(Path.Combine(deployDirectory.FullName, $"{projectName}.libmeta"))) { throw new MetaLibraryNotFoundException(deployDirectory.FullName); } PatchLibmeta(fileSystem.GetFile(Path.Combine(deployDirectory.FullName, $"{projectName}.libmeta"))); IEnumerable <VirtualFile> metaFiles = deployDirectory.Files(searchRecursive: true); IEnumerable <Entity> componentsWithoutMetaFile = projectTemplateEntity.EntityHierarchy .Where(e => e.Type.Equals("component", StringComparison.OrdinalIgnoreCase)) .Where(c => !metaFiles.Any(f => f.Name.Equals($"{c.Name}.{Constants.CompmetaExtension}", StringComparison.Ordinal))) .ToArray(); if (componentsWithoutMetaFile.Any()) { throw new MetaFileNotFoundException(deployDirectory.FullName, $"{componentsWithoutMetaFile.First().Name}.{Constants.CompmetaExtension}"); } IEnumerable <Entity> programsWithoutMetaFile = projectTemplateEntity.EntityHierarchy .Where(e => e.Type.Equals("program", StringComparison.OrdinalIgnoreCase)) .Where(p => !metaFiles.Any(f => f.Name.Equals($"{p.Name}.{Constants.ProgmetaExtension}", StringComparison.Ordinal))) .ToArray(); if (programsWithoutMetaFile.Any()) { throw new MetaFileNotFoundException(deployDirectory.FullName, $"{programsWithoutMetaFile.First().Name}.{Constants.ProgmetaExtension}"); } } void PatchLibmeta(VirtualFile libmetaFile) { if (!externalLibraries.Any()) { return; } XmlSerializer serializer = new XmlSerializer(typeof(MetaConfigurationDocument)); MetaConfigurationDocument document; try { using (Stream fileStream = libmetaFile.OpenRead()) using (XmlReader reader = XmlReader.Create(fileStream)) { document = (MetaConfigurationDocument)serializer.Deserialize(reader); } } catch (XmlException e) { executionContext.WriteWarning($"Cannot parse libmeta file. Cannot patch dependencies. {e.Message}"); return; } document.schemaVersion = "4.0"; LibraryDefinition definition = (LibraryDefinition)document.Item; IEnumerable <string> dependencies = externalLibraries.Select(Path.GetFileName) .Concat(definition.Dependencies?.Select(d => d.path) ?? Enumerable.Empty <string>()); definition.Dependencies = dependencies.Select(d => new DependencyDefinition { path = d }).ToArray(); using (Stream fileStream = libmetaFile.OpenWrite()) using (XmlWriter writer = XmlWriter.Create(fileStream, new XmlWriterSettings { Indent = true })) { serializer.Serialize(writer, document); } } }