diff --git a/tools/export/__init__.py b/tools/export/__init__.py index 139ee2b08e..e586c22b86 100644 --- a/tools/export/__init__.py +++ b/tools/export/__init__.py @@ -30,7 +30,7 @@ from tools.build_api import scan_resources from tools.toolchains import Resources from tools.export import lpcxpresso, ds5_5, iar, makefile from tools.export import embitz, coide, kds, simplicity, atmelstudio -from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt +from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt, vscode from tools.export import gnuarmeclipse from tools.export import qtcreator from tools.targets import TARGET_NAMES @@ -58,7 +58,10 @@ EXPORTERS = { 'gnuarmeclipse': gnuarmeclipse.GNUARMEclipse, 'qtcreator': qtcreator.QtCreator, 'zip' : zip.ZIP, - 'cmsis' : cmsis.CMSIS + 'cmsis' : cmsis.CMSIS, + 'vscode_gcc_arm' : vscode.VSCodeGcc, + 'vscode_iar' : vscode.VSCodeIAR, + 'vscode_armc5' : vscode.VSCodeArmc5 } ERROR_MESSAGE_UNSUPPORTED_TOOLCHAIN = """ diff --git a/tools/export/vscode/__init__.py b/tools/export/vscode/__init__.py new file mode 100644 index 0000000000..8a2e4ac6f7 --- /dev/null +++ b/tools/export/vscode/__init__.py @@ -0,0 +1,95 @@ +# mbed SDK +# Copyright (c) 2011-2016 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from os.path import join, exists, realpath, relpath, basename, isfile, splitext +from os import makedirs, listdir +import json + +from tools.export.makefile import Makefile, GccArm, Armc5, IAR + +class VSCode(Makefile): + """Generic VSCode project. Intended to be subclassed by classes that + specify a type of Makefile. + """ + def generate(self): + """Generate Makefile and VSCode launch and task files + """ + super(VSCode, self).generate() + ctx = { + 'name': self.project_name, + 'elf_location': join('BUILD', self.project_name)+'.elf', + 'c_symbols': self.toolchain.get_symbols(), + 'asm_symbols': self.toolchain.get_symbols(True), + 'target': self.target, + 'include_paths': self.resources.inc_dirs, + 'load_exe': str(self.LOAD_EXE).lower() + } + + if not exists(join(self.export_dir, '.vscode')): + makedirs(join(self.export_dir, '.vscode')) + + self.gen_file('vscode/tasks.tmpl', ctx, + join('.vscode', 'tasks.json')) + self.gen_file('vscode/launch.tmpl', ctx, + join('.vscode', 'launch.json')) + self.gen_file('vscode/settings.tmpl', ctx, + join('.vscode', 'settings.json')) + + # So.... I want all .h and .hpp files in self.resources.inc_dirs + all_directories = [] + + for directory in self.resources.inc_dirs: + if not directory: + continue + + if directory == ".": + all_directories.append("${workspaceRoot}/*") + else: + all_directories.append(directory.replace("./", "${workspaceRoot}/") + "/*") + + cpp_props = { + "configurations": [ + { + "name": "Windows", + "includePath": [x.replace("/", "\\") for x in all_directories] + }, + { + "name": "Mac", + "includePath": all_directories + }, + { + "name": "Linux", + "includePath": all_directories + } + ] + } + + with open(join(self.export_dir, '.vscode', 'c_cpp_properties.json'), 'w') as outfile: + json.dump(cpp_props, outfile, indent=4, separators=(',', ': ')) + + +class VSCodeGcc(VSCode, GccArm): + LOAD_EXE = True + NAME = "VSCode-GCC-ARM" + +class VSCodeArmc5(VSCode, Armc5): + LOAD_EXE = True + NAME = "VSCode-Armc5" + +class VSCodeIAR(VSCode, IAR): + LOAD_EXE = True + NAME = "VSCode-IAR" + + diff --git a/tools/export/vscode/launch.tmpl b/tools/export/vscode/launch.tmpl new file mode 100644 index 0000000000..8808142cf2 --- /dev/null +++ b/tools/export/vscode/launch.tmpl @@ -0,0 +1,64 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C++ Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceRoot}/BUILD/${workspaceRootFolderName}.elf", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceRoot}", + "environment": [], + "externalConsole": false, + "debugServerArgs": "", + "serverLaunchTimeout": 20000, + "filterStderr": true, + "filterStdout": false, + "serverStarted": "GDB\\ server\\ started", + "preLaunchTask": "make", + "setupCommands": [ + { "text": "-target-select remote localhost:3333", "description": "connect to target", "ignoreFailures": false }, + { "text": "-file-exec-and-symbols ${workspaceRoot}/BUILD/${workspaceRootFolderName}.elf", "description": "load file", "ignoreFailures": false}, + { "text": "-interpreter-exec console \"monitor endian little\"", "ignoreFailures": false }, + { "text": "-interpreter-exec console \"monitor reset\"", "ignoreFailures": false }, + { "text": "-interpreter-exec console \"monitor halt\"", "ignoreFailures": false }, + { "text": "-interpreter-exec console \"monitor arm semihosting enable\"", "ignoreFailures": false }, + { "text": "-target-download", "description": "flash target", "ignoreFailures": false } + ], + "logging": { + "moduleLoad": true, + "trace": true, + "engineLogging": true, + "programOutput": true, + "exceptions": true + }, + "linux": { + "MIMode": "gdb", + "MIDebuggerPath": "/usr/bin/arm-none-eabi-gdb", + "debugServerPath": "pyocd-gdbserver" + }, + "osx": { + "MIMode": "gdb", + "MIDebuggerPath": "/usr/local/bin/arm-none-eabi-gdb", + "debugServerPath": "pyocd-gdbserver" + }, + "windows": { + "preLaunchTask": "make.exe", + "MIMode": "gdb", + "MIDebuggerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\4.9 2015q3\\bin\\arm-none-eabi-gdb.exe", + "debugServerPath": "pyocd-gdbserver.exe", + "setupCommands": [ + { "text": "-environment-cd ${workspaceRoot}\\BUILD" }, + { "text": "-target-select remote localhost:3333", "description": "connect to target", "ignoreFailures": false }, + { "text": "-file-exec-and-symbols ${workspaceRootFolderName}.elf", "description": "load file", "ignoreFailures": false}, + { "text": "-interpreter-exec console \"monitor endian little\"", "ignoreFailures": false }, + { "text": "-interpreter-exec console \"monitor reset\"", "ignoreFailures": false }, + { "text": "-interpreter-exec console \"monitor halt\"", "ignoreFailures": false }, + { "text": "-interpreter-exec console \"monitor arm semihosting enable\"", "ignoreFailures": false }, + { "text": "-target-download", "description": "flash target", "ignoreFailures": false } + ] + } + } + ] +} diff --git a/tools/export/vscode/settings.tmpl b/tools/export/vscode/settings.tmpl new file mode 100644 index 0000000000..2ea509ad94 --- /dev/null +++ b/tools/export/vscode/settings.tmpl @@ -0,0 +1,4 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "C_Cpp.addWorkspaceRootToIncludePath": false +} diff --git a/tools/export/vscode/tasks.tmpl b/tools/export/vscode/tasks.tmpl new file mode 100644 index 0000000000..dbfa7aa037 --- /dev/null +++ b/tools/export/vscode/tasks.tmpl @@ -0,0 +1,30 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "0.1.0", + "name": "make", + "isShellCommand": true, + "showOutput": "always", + "problemMatcher": { + "owner": "cpp", + "fileLocation": ["relative", "${workspaceRoot}/mbed-os"], + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + } + }, + "args": ["-j"], + "linux": { + "command": "make" + }, + "osx": { + "command": "make" + }, + "windows": { + "command": "make.exe" + } +}