// Makes a Vcxproj rule from a BFFOnly rule.
            protected MocSourceAndTargetFile(MocSourceAndTargetFile reference)
            {
                Filter     = ProjectFilter.ExcludeBFF;
                Executable = reference.Executable;
                // Input is the intermediate file.
                KeyInput = reference.IntermediateFile;
                // We also depend on the actual input file.
                AdditionalInputs.Add(reference.KeyInput);
                Output      = reference.Output;
                Description = reference.Description;

                SourceFile       = reference.SourceFile;
                IntermediateFile = reference.IntermediateFile;
                IsCPPFile        = reference.IsCPPFile;

                IncludePaths.AddRange(reference.IncludePaths);
                ForceIncludes.AddRange(reference.ForceIncludes);
                CombinedDefines = reference.CombinedDefines;
            }
Exemplo n.º 2
0
        // Call this from Project::ExcludeOutputFiles() to find the list of files we need to moc.
        // This is after resolving files, but before filtering them, and before they get mapped to
        // configurations, so this is a good spot to add additional files.
        public void GenerateListOfFilesToMoc(Project project, string QTExecFolder)
        {
            string mocExe = QTExecFolder + "moc.exe";
            string rccExe = QTExecFolder + "rcc.exe";
            string uicExe = QTExecFolder + "uic.exe";

            // Filter all the files by the filters we've already specified, so we don't moc a file that's excluded from the solution.
            RegexOptions filterOptions = RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase;
            List <Regex> filters       = project.SourceFilesExcludeRegex.Select(filter => new Regex(filter, filterOptions)).ToList();

            filters.AddRange(ExcludeMocRegex.Select(filter => new Regex(filter, filterOptions)));

            var preFilteredFiles = project.ResolvedSourceFiles.Where(file => !filters.Any(filter => filter.IsMatch(file)) && !project.Configurations.Any(conf => FileIsPrecompiledHeader(file, conf))).ToList();

            // Async load all the source files and look for Q_OBJECT that we want to keep.
            var answerSetTask = Task.WhenAll(preFilteredFiles.Select(async file => new { file = file, runMoc = await FileContainsQObject(file) }));
            // Compile a list of qrc and ui files.
            Strings qrcFiles = new Strings(preFilteredFiles.Where(file => file.EndsWith(".qrc", StringComparison.InvariantCultureIgnoreCase)));
            Strings uiFiles  = new Strings(preFilteredFiles.Where(file => file.EndsWith(".ui", StringComparison.InvariantCultureIgnoreCase)));

            // Wait for the moc files.
            answerSetTask.Wait();
            var filterPass = answerSetTask.Result;
            // These are the files we want to moc.
            Strings FilteredResolvedSourceFiles = new Strings(filterPass.Where(result => result.runMoc).Select(result => result.file));

            // Compile a list of files where we don't want to compile the moc output.
            List <Regex> filesToExclude = ExcludeMocFromCompileRegex.Select(filter => new Regex(filter, filterOptions)).ToList();


            foreach (ProjConfiguration conf in project.Configurations)
            {
                // Setup exclusions.
                string QTMocOutputBase = Path.GetDirectoryName(conf.IntermediatePath);
                string targetName      = conf.Target.Name;
                string outputFolder    = QTMocOutputBase + @"\qt\" + targetName.ToLowerInvariant() + @"\";

                // We make the current output folder included directly so you can use the same #include directive to get the correct cpp file.
                conf.IncludePrivatePaths.Add(outputFolder);
                // Also include the project file folder, since the moc tool generates includes from this location.
                conf.IncludePrivatePaths.Add(conf.ProjectPath);

                // We need to exclude the generation files folder from the build on all targets except our own.
                string rootFolderForRegex = Util.GetCapitalizedPath(conf.ProjectPath);
                string outputRegex        = Util.PathGetRelative(rootFolderForRegex, outputFolder);
                outputRegex = outputRegex.Replace("..\\", "").Replace("\\", "\\\\") + @"\\";
                foreach (ProjConfiguration confToExclude in project.Configurations)
                {
                    if (confToExclude == conf || confToExclude.ProjectFullFileNameWithExtension != conf.ProjectFullFileNameWithExtension)
                    {
                        continue;
                    }
                    confToExclude.SourceFilesBuildExcludeRegex.Add(outputRegex);
                }

                // Build a list of all files to moc in this configuration.
                var mocTargets = new List <MocSourceAndTargetFile>();
                foreach (string file in FilteredResolvedSourceFiles)
                {
                    var target = new MocSourceAndTargetFile(targetName, mocExe, outputFolder, outputFolder, file);
                    if (filesToExclude.Any(filter => filter.IsMatch(file)))
                    {
                        target.TargetFileNotCompiled = true;
                    }
                    mocTargets.Add(target);
                    if (target.IsCPPFile)
                    {
                        mocTargets.Add(new MocVcxprojBuildStep(target));
                    }
                }
                if (mocTargets.Count > 0)
                {
                    MocTargetsPerConfiguration.Add(conf, mocTargets);
                }

                if (qrcFiles.Count > 0)
                {
                    RccTargetsPerConfiguration.Add(conf, qrcFiles.Select(file => new RccSourceAndTargetFile(targetName, rccExe, outputFolder, file)).ToList());
                }
                if (uiFiles.Count > 0)
                {
                    UicTargetsPerConfiguration.Add(conf, uiFiles.Select(file => new UicSourceAndTargetFile(targetName, uicExe, outputFolder, file)).ToList());
                }
            }

            // Add all the new source files to the project file.
            foreach (var values in MocTargetsPerConfiguration)
            {
                foreach (var target in values.Value)
                {
                    // We only need to include outputs that have build steps.  For source files, that's the intermediate file, for
                    // header files, that's the target file, if it wasn't excluded.
                    values.Key.CustomFileBuildSteps.Add(target);
                    if (target.IsCPPFile)
                    {
                        project.ResolvedSourceFiles.Add(target.IntermediateFile);
                    }
                    else if (!target.TargetFileNotCompiled)
                    {
                        project.ResolvedSourceFiles.Add(target.Output);
                    }
                }
            }

            foreach (var values in RccTargetsPerConfiguration)
            {
                foreach (var target in values.Value)
                {
                    values.Key.CustomFileBuildSteps.Add(target);
                    project.ResolvedSourceFiles.Add(target.Output);
                }
            }

            foreach (var values in UicTargetsPerConfiguration)
            {
                foreach (var target in values.Value)
                {
                    values.Key.CustomFileBuildSteps.Add(target);
                    // uic files generate header files - we don't need to run a build step on them, so don't include them in the vcxproj listing.
                    //project.ResolvedSourceFiles.Add(target.Output);
                }
            }
        }
Exemplo n.º 3
0
 public MocVcxprojBuildStep(MocSourceAndTargetFile reference)
     : base(reference)
 {
 }