示例#1
0
 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;
        }
示例#3
0
        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);
                    }
            }
        }