Пример #1
0
        public override bool Execute()
        {
            compiler = new GCC(string.IsNullOrEmpty(CompilerPath) ? DefaultCompiler : CompilerPath);

            Logger.Instance = new XBuildLogProvider(Log);             // TODO: maybe initialise statically
            var flags = (Flags != null && Flags.Any()) ? Flags.Aggregate(string.Empty, (curr, next) => string.Format("{0} {1}", curr, next.ItemSpec)) : string.Empty;

            using (var cache = new FileCacheManager(ObjectFilesDirectory))
            {
                var objectFiles       = new List <string>();
                var compilationResult = System.Threading.Tasks.Parallel.ForEach(Sources.Select(x => x.ItemSpec), new System.Threading.Tasks.ParallelOptions {
                    MaxDegreeOfParallelism = Parallel ? -1 : 1
                }, (source, loopState) => {
                    var objectFile = ObjectFilesDirectory == null ? regex.Replace(source, ".o") : string.Format("{0}/{1}", ObjectFilesDirectory, regex.Replace(source, ".o"));
                    if (!compiler.Compile(source, objectFile, flags, cache.SourceHasChanged))
                    {
                        loopState.Break();
                    }

                    lock (objectFiles)
                    {
                        objectFiles.Add(objectFile);
                    }
                });
                if (compilationResult.LowestBreakIteration != null)
                {
                    return(false);
                }

                ObjectFiles = objectFiles.Any() ? objectFiles.Select(x => new TaskItem(x)).ToArray() : new TaskItem[0];

                return(true);
            }
        }
Пример #2
0
        public override bool Execute()
        {
            Logger.Instance = new XBuildLogProvider(Log);             // TODO: maybe initialise statically; this put in constructor causes NRE

            if (!ObjectFiles.Any())
            {
                return(true);
            }

            var lfiles = new List <string>();
            var ofiles = ObjectFiles.Select(x => x.ItemSpec);
            var flags  = (Flags != null && Flags.Any()) ? Flags.Select(x => x.ItemSpec).ToList() : new List <string>();

            if (Libraries != null)
            {
                foreach (var library in Libraries.Select(x => x.ItemSpec))
                {
                    if (File.Exists(library))
                    {
                        var directory = Path.GetDirectoryName(library);
                        var fileName  = Path.GetFileName(library);

                        lfiles.Add(library);
                        flags.Add(string.Format(" -L{0} -l:{1}", directory, fileName));
                    }
                    else
                    {
                        flags.Add(string.Format("-l{0}", library));
                    }
                }
            }

            var joinedFlags = string.Join(" ", flags);

            using (var cache = new FileCacheManager(Path.GetDirectoryName(Output)))
            {
                if (!cache.SourceHasChanged(ofiles.Union(lfiles), joinedFlags) && File.Exists(Output))
                {
                    return(true);
                }
            }

            // linking
            var linker = new GLD(string.IsNullOrEmpty(LinkerPath) ? DefaultLinker : LinkerPath);

            return(linker.Link(ofiles, Output, joinedFlags));
        }
        public override bool Execute()
        {
            Logger.Instance = new XBuildLogProvider(Log);             // TODO: maybe initialise statically; this put in constructor causes NRE

            if (!ObjectFiles.Any())
            {
                return(true);
            }

            var lfiles = new List <string>();
            var ofiles = ObjectFiles.Select(x => x.ItemSpec);
            var flags  = (Flags != null && Flags.Any()) ? Flags.Select(x => x.ItemSpec).ToList() : new List <string>();

            if (Libraries != null)
            {
                foreach (var library in Libraries.Select(x => x.ItemSpec))
                {
                    if (File.Exists(library))
                    {
                        var directory = Path.GetDirectoryName(library);
                        var fileName  = Path.GetFileName(library);

                        lfiles.Add(library);
                        flags.Add(string.Format(" -L{0} -l:{1}", directory, fileName));
                    }
                    else
                    {
                        flags.Add(string.Format("-l{0}", library));
                    }
                }
            }

            var joinedFlags = string.Join(" ", flags);

            using (var cache = new FileCacheManager(Path.GetDirectoryName(Output)))
            {
                if (!cache.SourceHasChanged(ofiles.Union(lfiles), joinedFlags) && File.Exists(Output))
                {
                    return(true);
                }
            }

            // linking
            var linkerPath = string.IsNullOrEmpty(LinkerPath) ? DefaultLinker : LinkerPath;
            var linker     = new GLD(linkerPath);

            try
            {
                return(linker.Link(ofiles, Output, joinedFlags));
            }
            catch (Exception e)
            {
                if (e is Win32Exception error)
                {
                    if (error.NativeErrorCode == Utilities.ErrorFileNotFound)
                    {
                        Logger.Instance.LogError($"Could not find \"{LinkerPath}\" linker.");
                    }
                    else
                    {
                        Logger.Instance.LogError($"An error was encountered while trying to run \"{LinkerPath}\" linker: {e.Message}.");
                    }
                }
                else
                {
                    Logger.Instance.LogError($"An unknown exception has been thrown in CLinkerTask. Message: { e.Message }.");
                }
                return(false);
            }
        }
        public override bool Execute()
        {
            compiler = new GCC(string.IsNullOrEmpty(CompilerPath) ? DefaultCompiler : CompilerPath);

            Logger.Instance = new XBuildLogProvider(Log);             // TODO: maybe initialise statically
            var flags = (Flags != null && Flags.Any()) ? Flags.Aggregate(string.Empty, (curr, next) => string.Format("{0} {1}", curr, next.ItemSpec)) : string.Empty;

            using (var cache = new FileCacheManager(ObjectFilesDirectory))
            {
                var objectFiles = new List <string>();
                System.Threading.Tasks.ParallelLoopResult compilationResult;
                try
                {
                    // We normalize the directory separator in paths to make handling of gcc -MM easier.
                    var sourceFiles = System.IO.Path.DirectorySeparatorChar == '\\'
                                                ? Sources.Select(x => x.ItemSpec.Replace("\\", "/"))
                                                : Sources.Select(x => x.ItemSpec);

                    compilationResult = System.Threading.Tasks.Parallel.ForEach(sourceFiles, new System.Threading.Tasks.ParallelOptions {
                        MaxDegreeOfParallelism = Parallel ? -1 : 1
                    }, (source, loopState) =>
                    {
                        var objectFile = ObjectFilesDirectory == null ? regex.Replace(source, ".o") : string.Format("{0}/{1}", ObjectFilesDirectory, regex.Replace(source, ".o"));

                        if (!compiler.Compile(source, objectFile, flags, cache.SourceHasChanged))
                        {
                            loopState.Break();
                        }

                        lock (objectFiles)
                        {
                            objectFiles.Add(objectFile);
                        }
                    });
                }
                catch (Exception e)
                {
                    if (e.InnerException is Win32Exception error)
                    {
                        if (error.NativeErrorCode == Utilities.ErrorFileNotFound)
                        {
                            Logger.Instance.LogError($"Could not find \"{CompilerPath}\" compiler.");
                        }
                        else
                        {
                            Logger.Instance.LogError($"An error was encountered while trying to run \"{CompilerPath}\" compiler: {e.InnerException.Message}.");
                        }
                    }
                    else
                    {
                        Logger.Instance.LogError($"An unknown exception has been thrown in CCompilerTask. Message: { e.InnerException?.Message ?? e.Message }.");
                    }
                    return(false);
                }
                if (compilationResult.LowestBreakIteration != null)
                {
                    return(false);
                }

                ObjectFiles = objectFiles.Any() ? objectFiles.Select(x => new TaskItem(x)).ToArray() : new TaskItem[0];

                return(true);
            }
        }