diff --git a/.gitignore b/.gitignore index 077f454b..a6ac31d4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,12 @@ embedded/dist .vscode/ .history/ *.pyc +.vs/ +Debug/ +Release/ +*.vsarduino.h +__vm/ +*.user +*.vcxproj +*.vcxproj.filters +*.suo diff --git a/Grbl_Esp32.sln b/Grbl_Esp32.sln new file mode 100644 index 00000000..0ae0bade --- /dev/null +++ b/Grbl_Esp32.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29306.81 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Grbl_Esp32", "Grbl_Esp32.vcxproj", "{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x64.ActiveCfg = Debug|x64 + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x64.Build.0 = Debug|x64 + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x86.ActiveCfg = Debug|Win32 + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x86.Build.0 = Debug|Win32 + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x64.ActiveCfg = Release|x64 + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x64.Build.0 = Release|x64 + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x86.ActiveCfg = Release|Win32 + {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EEC94F4B-059C-4596-94B8-1C4C9CE5E0DD} + EndGlobalSection +EndGlobal diff --git a/VisualStudio.md b/VisualStudio.md new file mode 100644 index 00000000..f79aef28 --- /dev/null +++ b/VisualStudio.md @@ -0,0 +1,26 @@ +# Getting started with GRBL_ESP32 in Visual Studio + +**!! Important !! There's a huge difference between Visual Studio and +Visual Studio Code. This document is about Visual Studio, not Visual +Studio Code!** + +First, get PlatformIO to work with Visual studio. The steps that +need to be taken for this are the following: + +1. Install python. This is needed for both PlatformIO and for generating + the vcxproj file. +2. From https://docs.platformio.org/en/latest/core/index.html#piocore + you should install the PlatformIO Core (CLI). Make sure you update + the command line search path. +3. Use python to generate a vcxproj file: `python generate_vcxproj.py`. +4. Start Grbl_Esp32.sln + +## Building + +Building is as easy as building your solution. + +## Uploading + +Uploading can be done from the command line using platformio. For +example, run `platformio run --target upload --upload-port COM7`. +For more details, see [the documentation of pio](https://dokk.org/documentation/platformio/v3.6.1/platforms/espressif32/). diff --git a/generate_vcxproj.py b/generate_vcxproj.py new file mode 100644 index 00000000..36b77907 --- /dev/null +++ b/generate_vcxproj.py @@ -0,0 +1,275 @@ +''' + Visual studio project file generator + Grbl_ESP32 is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Grbl_ESP32. If not, see . + @authors: atlaste [github.com/atlaste] +''' + +PATHS_TO_SEARCH = ['Grbl_Esp32'] +HEADER_EXT = ['.h', '.inl'] +SOURCE_EXT = ['.c', '.cpp'] +OTHER_EXT = ['.ino', '.md'] + +import os, uuid + +def UUID(name): + return str(uuid.uuid3(uuid.NAMESPACE_OID, name)).upper() + +def FilterFromPath(path): + (head, tail) = os.path.split(path) + head = head.replace('/', '\\').replace('..\\', '').replace('.\\', '') + if head == '.': + return '' + + h = head[0:10]; + if h == 'Grbl_Esp32': + h = head[11:] + return h + +class Vcxproj: + # configuration, platform + ConfigurationFmt = '\n'.join([ + ' ', + ' {0}', + ' {1}', + ' ']) + # item name, item file + ItemFmt = '\n'.join([ + ' <{0} Include="{1}" />']) + + # configuration, platform + ConfigTypePropertyGroupFmt = '\n'.join([ + ' ', + ' Makefile', + ' true', + ' v142', + ' ']) + + # configuration, platform + ImportGroupFmt = '\n'.join([ + ' ', + ' ', + ' ' + ]) + + # configuration, platform + PIOPropertyGroupFmt = '\n'.join([ + ' ', + ' platformio --force run', + ' platformio --force run -t clean', + ' WIN32;_DEBUG;$(NMakePreprocessorDefinitions)', + ' $(HOMEDRIVE)$(HOMEPATH)\\.platformio\\packages\\toolchain-xtensa32\\xtensa-esp32-elf\\include;$(HOMEDRIVE)$(HOMEPATH)\\.platformio\\packages\\framework-arduinoespressif32\\cores\\esp32;$(NMakeIncludeSearchPath)', + ' ' + ]) + + @staticmethod + def Configuration(configuration, platform): + return Vcxproj.ConfigurationFmt.format(configuration, platform) + + @staticmethod + def Item(name, file): + return Vcxproj.ItemFmt.format(name, file) + + @staticmethod + def ConfigTypePropertyGroup(configuration, platform): + return Vcxproj.ConfigTypePropertyGroupFmt.format(configuration, platform) + + @staticmethod + def ImportGroup(configuration, platform): + return Vcxproj.ImportGroupFmt.format(configuration, platform) + + @staticmethod + def PIOPropertyGroup(configuration, platform): + return Vcxproj.PIOPropertyGroupFmt.format(configuration, platform) + +class Filters: + # itemtype, path, folder + ItemFmt = '\n'.join([ + ' <{0} Include="{1}">', + ' {2}', + ' ']) + + # folder, uuid + FilterFmt = '\n'.join([ + ' ', + ' {{{1}}}', + ' ']) + + @staticmethod + def Item(itemtype, path): + folder = FilterFromPath(path) + return Filters.ItemFmt.format(itemtype, path, folder) + + @staticmethod + def Filter(folder): + uid = UUID(folder) + return Filters.FilterFmt.format(folder, uid) + +class Generator: + Folders = set() + + # Files + Headers = set() + Sources = set() + Others = set() + + # Stuffs + Platforms = set(['Win32','x64']) + Configurations = set(['Debug','Release']) + Name = 'Grbl_Esp32' + + def AddFolder(self, path): + filt = FilterFromPath(path) + if filt == '': + return + if filt not in self.Folders: + self.Folders.add(filt) + filters = '' + for f in os.path.split(filt): + filters = os.path.join(filters, f) + if filters != '': + self.Folders.add(filters) + + def AddFile(self, path): + (root, ext) = os.path.splitext(path) + if ext in HEADER_EXT: + self.Headers.add(path) + elif ext in SOURCE_EXT: + self.Sources.add(path) + elif ext in OTHER_EXT: + self.Others.add(path) + else: + return + + self.AddFolder(path) + + def Walk(self, path): + if path == 'Grbl_Esp32\\Custom' or path == 'Grbl_Esp32/Custom': + return + if os.path.isfile(path): + self.AddFile(path) + else: + for subPath in os.listdir(path): + self.Walk(os.path.join(path, subPath)) + + def CreateProject(self): + project = [] + project.append('') + project.append('') + + project.append('') + for p in self.Platforms: + for c in self.Configurations: + project.append(Vcxproj.Configuration(c, p)) + project.append('') + + # cpp header files + project.append('') + for f in self.Headers: + project.append(Vcxproj.Item('ClInclude', f)) + project.append('') + + # cpp source files + project.append('') + for f in self.Sources: + project.append(Vcxproj.Item('ClCompile', f)) + project.append('') + + # md files and ino file + project.append('') + for f in self.Others: + project.append(Vcxproj.Item('None', f)) + project.append('') + + # Bookkeeping, compilation, etc. + project.append('') + project.append(' 16.0') + project.append(' {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}') + project.append(' Win32Proj') + project.append('') + + project.append('') + for p in self.Platforms: + for c in self.Configurations: + project.append(Vcxproj.ConfigTypePropertyGroup(c, p)) + + project.append('') + project.append('') + project.append('') + project.append(' ') + project.append('') + + for p in self.Platforms: + for c in self.Configurations: + project.append(Vcxproj.ImportGroup(c, p)) + project.append('') + + for p in self.Platforms: + for c in self.Configurations: + project.append(Vcxproj.PIOPropertyGroup(c, p)) + + project.append('') + project.append('') + project.append('') + project.append(' ') + project.append('') + project.append('') + project.append(' ') + project.append(' ') + project.append(' ') + project.append(' ') + project.append('') + return '\n'.join(project) + + def CreateFilters(self): + project = [] + project.append('') + project.append('') + + project.append('') + for f in self.Folders: + project.append(Filters.Filter(f)) + project.append('') + + project.append('') + for f in self.Headers: + project.append(Filters.Item('ClInclude', f)) + project.append('') + + project.append('') + for f in self.Sources: + project.append(Filters.Item('ClCompile', f)) + project.append('') + + project.append('') + for f in self.Others: + project.append(Filters.Item('None', f)) + project.append('') + + project.append('') + return '\n'.join(project) + + def Generate(self): + f = open(self.Name + '.vcxproj', 'w') + f.write(self.CreateProject()) + f.close() + + f = open(self.Name + '.vcxproj.filters', 'w') + f.write(self.CreateFilters()) + f.close() + +def main(paths): + generator = Generator() + for path in paths: + generator.Walk(path) + generator.Generate() + +main(PATHS_TO_SEARCH)