예제 #1
0
        private void ImportProjectFolderRecursively(XmlElement projectOrFolder,
                                                    ImportedExternalProject.ConstructedVirtualDirectory constructedDir,
                                                    ProjectImportParameters parameters,
                                                    IVariableExpander expander,
                                                    IProjectImportService service)
        {
            foreach (var el in projectOrFolder.ChildNodes.OfType <XmlElement>())
            {
                if (el.Name == "file")
                {
                    string relPath = ExpandVariables(el.GetAttribute("file_name"), expander, service);
                    if (!string.IsNullOrEmpty(relPath) && !relPath.EndsWith(".vec"))
                    {
                        string fullPath = Path.Combine(Path.GetDirectoryName(parameters.ProjectFile), relPath);
                        constructedDir.AddFile(fullPath, relPath.EndsWith(".h", StringComparison.InvariantCultureIgnoreCase));
                    }
                }
                else if (el.Name == "folder")
                {
                    string name = el.GetAttribute("Name");
                    if (string.IsNullOrEmpty(name))
                    {
                        name = "Subfolder";
                    }

                    if (name == "Source Files" || name == "Header Files")
                    {
                        //Visual Studio already provides filters for source/header files, so we don't need to specify them explicitly
                        ImportProjectFolderRecursively(el, constructedDir, parameters, expander, service);
                    }
                    else
                    {
                        ImportProjectFolderRecursively(el, constructedDir.ProvideSudirectory(name), parameters, expander, service);
                    }
                }
            }
        }
예제 #2
0
        public ImportedExternalProject ImportProject(ProjectImportParameters parameters, IProjectImportService service)
        {
            XmlDocument xml = new XmlDocument();

            xml.Load(parameters.ProjectFile);

            string deviceName = (xml.SelectSingleNode("package/generators/generator/select/@Dname") as XmlAttribute)?.Value;

            if (deviceName == null)
            {
                throw new Exception("Failed to extract the device name from " + deviceName);
            }

            HashSet <string> allHeaderDirs = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);
            string           baseDir       = Path.GetDirectoryName(parameters.ProjectFile);

            ImportedExternalProject.ConstructedVirtualDirectory rootDir = new ImportedExternalProject.ConstructedVirtualDirectory();

            foreach (var file in xml.SelectNodes("package/generators/generator/project_files/file").OfType <XmlElement>())
            {
                string category = file.GetAttribute("category");
                string name     = file.GetAttribute("name");

                if (category == "header")
                {
                    allHeaderDirs.Add(Path.GetDirectoryName(name));
                }

                rootDir.AddFile(Path.Combine(baseDir, name), category == "header");
            }

            bool hasFreeRTOS = false;

            foreach (var component in xml.SelectNodes("package/components/component").OfType <XmlElement>())
            {
                string group    = component.GetAttribute("Cgroup");
                string subGroup = component.GetAttribute("Csub");
                if (subGroup == "FREERTOS")
                {
                    hasFreeRTOS = true;
                }
                foreach (var file in component.SelectNodes("files/file").OfType <XmlElement>())
                {
                    string category     = file.GetAttribute("category");
                    string relativePath = file.GetAttribute("name");

                    string condition = file.GetAttribute("condition");
                    if (!string.IsNullOrEmpty(condition))
                    {
                        if (condition == "FreeRTOS")
                        {
                            if (!hasFreeRTOS)
                            {
                                continue;
                            }
                        }
                        else if (condition != "GCC Toolchain")
                        {
                            continue;   //This is a IAR-only or Keil-only file
                        }
                    }

                    int    idx = relativePath.LastIndexOfAny(new[] { '\\', '/' });
                    string name, dir;
                    if (idx == -1)
                    {
                        name = relativePath;
                        dir  = "";
                    }
                    else
                    {
                        name = relativePath.Substring(idx + 1);
                        dir  = relativePath.Substring(0, idx);
                    }

                    if (category == "sourceAsm" && name.StartsWith("startup_", StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;   //VisualGDB provides its own startup files for STM32 devices that are compatible with STM32CubeMX-generated files
                    }
                    if (category == "header" && dir != "")
                    {
                        allHeaderDirs.Add(dir);
                    }

                    string path = group;
                    if (!string.IsNullOrEmpty(subGroup))
                    {
                        path += "/" + subGroup;
                    }

                    if (relativePath.Contains("*"))
                    {
                        string physicalDir = Path.Combine(baseDir, dir);
                        if (Directory.Exists(physicalDir))
                        {
                            foreach (var fn in Directory.GetFiles(physicalDir, name))
                            {
                                rootDir.ProvideSudirectory(path).AddFile(fn, category == "header");
                            }
                        }
                    }
                    else
                    {
                        rootDir.ProvideSudirectory(path).AddFile(Path.Combine(baseDir, relativePath), category == "header");
                    }
                }
            }

            List <string> macros = new List <string> {
                "$$com.sysprogs.bspoptions.primary_memory$$_layout", "$$com.sysprogs.stm32.hal_device_family$$"
            };

            string[] includeDirs = allHeaderDirs.Select(d => Path.Combine(baseDir, d)).ToArray();

            PropertyDictionary2 mcuConfiguration = null;

            if (hasFreeRTOS)
            {
                macros.Add("USE_FREERTOS");
                ApplyFreeRTOSFixes(rootDir, ref includeDirs, ref mcuConfiguration);
            }

            Dictionary <string, string> temporaryExistingFileCollection = null;

            FixInvalidPathsRecursively(rootDir, baseDir, ref temporaryExistingFileCollection);

            deviceName = deviceName.TrimEnd('x');
            deviceName = deviceName.Substring(0, deviceName.Length - 1);

            return(new ImportedExternalProject
            {
                DeviceNameMask = new Regex(deviceName.Replace("x", ".*") + ".*"),
                OriginalProjectFile = parameters.ProjectFile,
                RootDirectory = rootDir,
                GNUTargetID = "arm-eabi",
                ReferencedFrameworks = new string[0],   //Unless this is explicitly specified, VisualGDB will try to reference the default frameworks (STM32 HAL) that will conflict with the STM32CubeMX-generated files.

                MCUConfiguration = mcuConfiguration,

                Configurations = new[]
                {
                    new ImportedExternalProject.ImportedConfiguration
                    {
                        Settings = new ImportedExternalProject.InvariantProjectBuildSettings
                        {
                            IncludeDirectories = includeDirs,
                            PreprocessorMacros = macros.ToArray()
                        }
                    }
                }
            });
        }
예제 #3
0
        public ImportedExternalProject ImportProject(ProjectImportParameters parameters, IProjectImportService service)
        {
            var parser = new ParserImpl();
            List <VendorSample> result = new List <VendorSample>();

            parser.ParseSingleProject(null, parameters.ProjectFile, null, null, null, SW4STM32ProjectParserBase.ProjectSubtype.Auto, result);
            if (result.Count == 0)
            {
                throw new Exception("Failed to parse the project file");
            }

            ImportedExternalProject.ConstructedVirtualDirectory rootDir = new ImportedExternalProject.ConstructedVirtualDirectory();

            Dictionary <string, string> physicalDirToVirtualPaths = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);

            var sample = result[0];

            if (parser.OptionDictionary.TryGetValue(sample, out var opts) && opts.SourceFiles != null)
            {
                foreach (var sf in opts.SourceFiles)
                {
                    string virtualDir = Path.GetDirectoryName(sf.VirtualPath);
                    physicalDirToVirtualPaths[Path.GetDirectoryName(sf.FullPath)] = virtualDir;
                    rootDir.ProvideSudirectory(virtualDir).AddFile(sf.FullPath, false);
                }
            }
            else
            {
                foreach (var src in sample.SourceFiles ?? new string[0])
                {
                    rootDir.AddFile(src, false);
                }
            }

            foreach (var src in sample.HeaderFiles ?? new string[0])
            {
                if (physicalDirToVirtualPaths.TryGetValue(Path.GetDirectoryName(src), out string virtualDir))
                {
                    rootDir.ProvideSudirectory(virtualDir).AddFile(src, true);
                }
                else if (physicalDirToVirtualPaths.TryGetValue(Path.GetDirectoryName(src).Replace(@"\Inc", @"\Src"), out virtualDir))
                {
                    rootDir.ProvideSudirectory(virtualDir).AddFile(src, true);
                }
                else
                {
                    rootDir.AddFile(src, true);
                }
            }

            return(new ImportedExternalProject
            {
                DeviceNameMask = new Regex(sample.DeviceID),
                OriginalProjectFile = parameters.ProjectFile,
                RootDirectory = rootDir,
                GNUTargetID = "arm-eabi",
                ReferencedFrameworks = new string[0],

                MCUConfiguration = sample.Configuration.MCUConfiguration,

                Configurations = new[]
                {
                    new ImportedExternalProject.ImportedConfiguration
                    {
                        Settings = new ImportedExternalProject.InvariantProjectBuildSettings
                        {
                            IncludeDirectories = sample.IncludeDirectories,
                            PreprocessorMacros = sample.PreprocessorMacros,
                            LinkerScript = sample.LinkerScript,
                        }
                    }
                }
            });
        }
예제 #4
0
        public ImportedExternalProject ImportProject(ProjectImportParameters parameters, IProjectImportService service)
        {
            XmlDocument xml = new XmlDocument();

            xml.Load(parameters.ProjectFile);

            var target = xml.SelectSingleNode("Project/Targets/Target") as XmlElement;

            if (target == null)
            {
                throw new Exception("Failed to locate the target node in " + parameters.ProjectFile);
            }

            string deviceName = (target.SelectSingleNode("TargetOption/TargetCommonOption/Device") as XmlElement)?.InnerText;

            if (deviceName == null)
            {
                throw new Exception("Failed to extract the device name from " + parameters.ProjectFile);
            }

            if (deviceName.EndsWith("x"))
            {
                deviceName = deviceName.TrimEnd('x');
                deviceName = deviceName.Substring(0, deviceName.Length - 1);
            }

            string baseDir = Path.GetDirectoryName(parameters.ProjectFile);

            ImportedExternalProject.ConstructedVirtualDirectory rootDir = new ImportedExternalProject.ConstructedVirtualDirectory();

            foreach (var group in target.SelectNodes("Groups/Group").OfType <XmlElement>())
            {
                string virtualPath = group.SelectSingleNode("GroupName")?.InnerText;
                if (string.IsNullOrEmpty(virtualPath))
                {
                    continue;
                }

                var subdir = rootDir.ProvideSudirectory(virtualPath);
                foreach (var file in group.SelectNodes("Files/File").OfType <XmlElement>())
                {
                    string path = file.SelectSingleNode("FilePath")?.InnerText;
                    string type = file.SelectSingleNode("FileType")?.InnerText;
                    if (type == "2")
                    {
                        //This is an assembly file. Keil uses a different assembly syntax than GCC, so we cannot include this file into the project.
                        //The end user will need to include a GCC-specific replacement manually (unless this is the startup file, in which case VisualGDB
                        //automatically includes a GCC-compatible replacement).
                        continue;
                    }
                    if (string.IsNullOrEmpty(path))
                    {
                        continue;
                    }

                    var adjustedPath = TryAdjustPath(baseDir, path, service);
                    subdir.AddFile(adjustedPath, type == "5");
                }
            }

            List <string> macros = new List <string> {
                "$$com.sysprogs.bspoptions.primary_memory$$_layout"
            };
            List <string> includeDirs = new List <string>();

            var optionsNode = target.SelectSingleNode("TargetOption/TargetArmAds/Cads/VariousControls");

            if (optionsNode != null)
            {
                macros.AddRange((optionsNode.SelectSingleNode("Define")?.InnerText ?? "").Split(',').Select(m => m.Trim()));
                includeDirs.AddRange((optionsNode.SelectSingleNode("IncludePath")?.InnerText ?? "")
                                     .Split(';')
                                     .Select(p => TryAdjustPath(baseDir, p.Trim(), service))
                                     .Where(p => p != null));
            }

            return(new ImportedExternalProject
            {
                DeviceNameMask = new Regex(deviceName.Replace("x", ".*") + ".*"),
                OriginalProjectFile = parameters.ProjectFile,
                RootDirectory = rootDir,
                GNUTargetID = "arm-eabi",
                ReferencedFrameworks = new string[0],   //Unless this is explicitly specified, VisualGDB will try to reference the default frameworks (STM32 HAL) that will conflict with the STM32CubeMX-generated files.

                Configurations = new[]
                {
                    new ImportedExternalProject.ImportedConfiguration
                    {
                        Settings = new ImportedExternalProject.InvariantProjectBuildSettings
                        {
                            IncludeDirectories = includeDirs.ToArray(),
                            PreprocessorMacros = macros.ToArray()
                        }
                    }
                }
            });
        }