diff --git a/tools/export/atmelstudio/__init__.py b/tools/export/atmelstudio/__init__.py index f123810b8a..531f7fdfbe 100644 --- a/tools/export/atmelstudio/__init__.py +++ b/tools/export/atmelstudio/__init__.py @@ -16,6 +16,7 @@ limitations under the License. """ import uuid from os.path import splitext, basename, dirname +from os import remove from tools.export.exporters import Exporter, deprecated_exporter @@ -83,3 +84,8 @@ class AtmelStudio(Exporter): target = self.target.lower() self.gen_file('atmelstudio/atsln.tmpl', ctx, '%s.atsln' % self.project_name) self.gen_file('atmelstudio/cppproj.tmpl', ctx, '%s.cppproj' % self.project_name) + + @staticmethod + def clean(project_name): + remove('%s.atsln' % project_name) + remove('%s.cppproj' % project_name) diff --git a/tools/export/cces/__init__.py b/tools/export/cces/__init__.py index 2d90fa93e8..359042fcb8 100644 --- a/tools/export/cces/__init__.py +++ b/tools/export/cces/__init__.py @@ -408,6 +408,12 @@ class CCES(Exporter): print("CCES files generated.") + + @staticmethod + def clean(_): + os.remove('cces.json') + os.remove('README.md') + @staticmethod def build(project_name, log_name='build_log.txt', cleanup=True): """ @@ -436,6 +442,7 @@ class CCES(Exporter): # cleanup workspace if os.path.exists(workspace): shutil.rmtree(workspace, True) + CCES.clean(project_name) # check return code for failure if ret_code != 0: diff --git a/tools/export/cdt/__init__.py b/tools/export/cdt/__init__.py index 29b9fdd2de..226526ba2d 100644 --- a/tools/export/cdt/__init__.py +++ b/tools/export/cdt/__init__.py @@ -1,7 +1,8 @@ import re from os.path import join, exists -from os import makedirs +from os import makedirs, remove +import shutil from tools.export.makefile import Makefile, GccArm, Armc5, IAR @@ -39,6 +40,12 @@ class Eclipse(Makefile): self.gen_file('cdt/.cproject.tmpl', ctx, '.cproject') self.gen_file('cdt/.project.tmpl', ctx, '.project') + @staticmethod + def clean(project_name): + shutil.rmtree("eclipse-extras") + remove(".cproject") + remove(".project") + class EclipseGcc(Eclipse, GccArm): LOAD_EXE = True diff --git a/tools/export/cmake/__init__.py b/tools/export/cmake/__init__.py index 9c1638e9d1..a83f773abf 100644 --- a/tools/export/cmake/__init__.py +++ b/tools/export/cmake/__init__.py @@ -112,6 +112,15 @@ class CMake(Exporter): except TemplateNotFound: pass + @staticmethod + def clean(_): + remove("CMakeLists.txt") + # legacy .build directory cleaned if exists + if exists('.build'): + shutil.rmtree('.build') + if exists('BUILD'): + shutil.rmtree('BUILD') + @staticmethod def build(project_name, log_name="build_log.txt", cleanup=True): """ Build Make project """ @@ -162,13 +171,8 @@ class CMake(Exporter): # Cleanup the exported and built files if cleanup: - remove("CMakeLists.txt") remove(log_name) - # legacy .build directory cleaned if exists - if exists('.build'): - shutil.rmtree('.build') - if exists('BUILD'): - shutil.rmtree('BUILD') + CMake.clean(project_name) if ret_code != 0: # Seems like something went wrong. diff --git a/tools/export/cmsis/__init__.py b/tools/export/cmsis/__init__.py index b036d674aa..f6eceddc73 100644 --- a/tools/export/cmsis/__init__.py +++ b/tools/export/cmsis/__init__.py @@ -153,3 +153,8 @@ class CMSIS(Exporter): 'date': '' } self.gen_file('cmsis/cpdsc.tmpl', ctx, 'project.cpdsc') + + + @staticmethod + def clean(_): + os.remove('project.cpdsc') diff --git a/tools/export/coide/__init__.py b/tools/export/coide/__init__.py index 873950ac71..9e47247015 100644 --- a/tools/export/coide/__init__.py +++ b/tools/export/coide/__init__.py @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. """ from os.path import splitext, basename +from os import remove from tools.export.exporters import Exporter, deprecated_exporter @@ -109,3 +110,7 @@ class CoIDE(Exporter): # Project file self.gen_file('coide/%s.coproj.tmpl' % target, ctx, '%s.coproj' % self.project_name) + + @staticmethod + def clean(project_name): + remove('%s.coproj' % project_name) diff --git a/tools/export/e2studio/__init__.py b/tools/export/e2studio/__init__.py index f37565b5b1..3a3776335f 100644 --- a/tools/export/e2studio/__init__.py +++ b/tools/export/e2studio/__init__.py @@ -14,6 +14,7 @@ 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 import remove from tools.export.gnuarmeclipse import GNUARMEclipse class E2Studio(GNUARMEclipse): @@ -39,3 +40,8 @@ class E2Studio(GNUARMEclipse): self.gen_file('gnuarmeclipse/.project.tmpl', jinja_ctx, '.project', trim_blocks=True, lstrip_blocks=True) self.gen_file_nonoverwrite('gnuarmeclipse/mbedignore.tmpl', jinja_ctx, '.mbedignore') self.gen_file('gnuarmeclipse/makefile.targets.tmpl', jinja_ctx, 'makefile.targets', trim_blocks=True, lstrip_blocks=True) + + @staticmethod + def clean(project_name): + remove('%s OpenOCD 5x.launch' % project_name) + remove('%s OpenOCD.launch' % project_name) diff --git a/tools/export/embitz/__init__.py b/tools/export/embitz/__init__.py index 180a1b7073..9cdd1f03a4 100644 --- a/tools/export/embitz/__init__.py +++ b/tools/export/embitz/__init__.py @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. """ from os.path import splitext, basename +from os import remove from tools.targets import TARGET_MAP from tools.export.exporters import Exporter, apply_supported_whitelist @@ -87,3 +88,7 @@ class EmBitz(Exporter): } self.gen_file('embitz/eix.tmpl', ctx, '%s.eix' % self.project_name) + + @staticmethod + def clean(project_name): + remove("%s.eix" % project_name) diff --git a/tools/export/exporters.py b/tools/export/exporters.py index c4d9e198ee..b9dc8c7591 100644 --- a/tools/export/exporters.py +++ b/tools/export/exporters.py @@ -50,6 +50,7 @@ class Exporter(object): NAME = None TARGETS = set() TOOLCHAIN = None + CLEAN_FILES = ("GettingStarted.html",) def __init__(self, target, export_dir, project_name, toolchain, @@ -217,12 +218,28 @@ class Exporter(object): Returns -1 on failure and 0 on success """ - raise NotImplemented("Implement in derived Exporter class.") + raise NotImplementedError("Implement in derived Exporter class.") + + @staticmethod + def clean(project_name): + """Clean a previously exported project + This method is assumed to be executed at the same level as exporter + project files and project source code. + See uvision/__init__.py, iar/__init__.py, and makefile/__init__.py for + example implemenation. + + Positional Arguments: + project_name - the name of the project to build; often required by + exporter's build command. + + Returns nothing. May raise exceptions + """ + raise NotImplementedError("Implement in derived Exporter class.") @abstractmethod def generate(self): """Generate an IDE/tool specific project file""" - raise NotImplemented("Implement a generate function in Exporter child class") + raise NotImplementedError("Implement a generate function in Exporter child class") @classmethod def is_target_supported(cls, target_name): diff --git a/tools/export/gnuarmeclipse/__init__.py b/tools/export/gnuarmeclipse/__init__.py index c0f05f03d7..99860dcd36 100644 --- a/tools/export/gnuarmeclipse/__init__.py +++ b/tools/export/gnuarmeclipse/__init__.py @@ -299,6 +299,17 @@ class GNUARMEclipse(Exporter): print print 'Done. Import the \'{0}\' project in Eclipse.'.format(self.project_name) + @staticmethod + def clean(_): + os.remove('.project') + os.remove('.cproject') + if exists('Debug'): + shutil.rmtree('Debug') + if exists('Release'): + shutil.rmtree('Release') + if exists('makefile.targets'): + os.remove('makefile.targets') + # override @staticmethod def build(project_name, log_name="build_log.txt", cleanup=True): @@ -366,14 +377,6 @@ class GNUARMEclipse(Exporter): if cleanup: if exists(log_name): os.remove(log_name) - os.remove('.project') - os.remove('.cproject') - if exists('Debug'): - shutil.rmtree('Debug') - if exists('Release'): - shutil.rmtree('Release') - if exists('makefile.targets'): - os.remove('makefile.targets') # Always remove the temporary folder. if exists(tmp_folder): diff --git a/tools/export/iar/__init__.py b/tools/export/iar/__init__.py index 641c142d02..69b53dbb96 100644 --- a/tools/export/iar/__init__.py +++ b/tools/export/iar/__init__.py @@ -138,6 +138,17 @@ class IAR(Exporter): self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd") self.gen_file('iar/ewp.tmpl', ctx, self.project_name + ".ewp") + @staticmethod + def clean(project_name): + os.remove(project_name + ".ewp") + os.remove(project_name + ".ewd") + os.remove(project_name + ".eww") + # legacy output file location + if exists('.build'): + shutil.rmtree('.build') + if exists('BUILD'): + shutil.rmtree('BUILD') + @staticmethod def build(project_name, log_name="build_log.txt", cleanup=True): """ Build IAR project """ @@ -179,14 +190,7 @@ class IAR(Exporter): # Cleanup the exported and built files if cleanup: - os.remove(project_name + ".ewp") - os.remove(project_name + ".ewd") - os.remove(project_name + ".eww") - # legacy output file location - if exists('.build'): - shutil.rmtree('.build') - if exists('BUILD'): - shutil.rmtree('BUILD') + IAR.clean(project_name) if ret_code !=0: # Seems like something went wrong. diff --git a/tools/export/kds/__init__.py b/tools/export/kds/__init__.py index 6df777a19a..ae50c2b236 100644 --- a/tools/export/kds/__init__.py +++ b/tools/export/kds/__init__.py @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. """ from os.path import splitext, basename +from os import remove from tools.export.exporters import Exporter, deprecated_exporter @@ -47,3 +48,7 @@ class KDS(Exporter): self.gen_file('kds/%s_project.tmpl' % self.target.lower(), ctx, '.project') self.gen_file('kds/%s_cproject.tmpl' % self.target.lower(), ctx, '.cproject') self.gen_file('kds/launch.tmpl', ctx, '%s.launch' % self.project_name) + + @staticmethod + def clean(project_name): + remove('%s.launch' % project_name) diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index a717dfe168..3c0fc2a857 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -148,6 +148,15 @@ class Makefile(Exporter): return flags + @staticmethod + def clean(_): + remove("Makefile") + # legacy .build directory cleaned if exists + if exists('.build'): + shutil.rmtree('.build') + if exists('BUILD'): + shutil.rmtree('BUILD') + @staticmethod def build(project_name, log_name="build_log.txt", cleanup=True): """ Build Make project """ @@ -178,13 +187,8 @@ class Makefile(Exporter): # Cleanup the exported and built files if cleanup: - remove("Makefile") remove(log_name) - # legacy .build directory cleaned if exists - if exists('.build'): - shutil.rmtree('.build') - if exists('BUILD'): - shutil.rmtree('BUILD') + Makefile.clean(project_name) if ret_code != 0: # Seems like something went wrong. diff --git a/tools/export/mcuxpresso/__init__.py b/tools/export/mcuxpresso/__init__.py index f145c61cbd..8768d8537d 100644 --- a/tools/export/mcuxpresso/__init__.py +++ b/tools/export/mcuxpresso/__init__.py @@ -230,6 +230,17 @@ class MCUXpresso(GNUARMEclipse): print print 'Done. Import the \'{0}\' project in Eclipse.'.format(self.project_name) + @staticmethod + def clean(_): + remove('.project') + remove('.cproject') + if exists('Debug'): + shutil.rmtree('Debug') + if exists('Release'): + shutil.rmtree('Release') + if exists('makefile.targets'): + remove('makefile.targets') + # override @staticmethod def build(project_name, log_name="build_log.txt", cleanup=True): @@ -299,14 +310,7 @@ class MCUXpresso(GNUARMEclipse): if cleanup: if exists(log_name): remove(log_name) - remove('.project') - remove('.cproject') - if exists('Debug'): - shutil.rmtree('Debug') - if exists('Release'): - shutil.rmtree('Release') - if exists('makefile.targets'): - remove('makefile.targets') + MCUXpresso.clean(project_name) # Always remove the temporary folder. if exists(tmp_folder): diff --git a/tools/export/nb/__init__.py b/tools/export/nb/__init__.py index 8b9174bfa5..47a815f1d7 100644 --- a/tools/export/nb/__init__.py +++ b/tools/export/nb/__init__.py @@ -1,5 +1,6 @@ import os import copy +import shutil from os.path import relpath, join, exists, dirname, basename from os import makedirs @@ -275,6 +276,11 @@ class GNUARMNetbeans(Exporter): print print 'Done. Import the \'{0}\' project in Netbeans.'.format(self.project_name) + @staticmethod + def clean(_): + shutil.rmtree("nbproject") + remove("Makefile") + # ------------------------------------------------------------------------- @staticmethod diff --git a/tools/export/qtcreator/__init__.py b/tools/export/qtcreator/__init__.py index b10fbcf87c..7ec9107de8 100644 --- a/tools/export/qtcreator/__init__.py +++ b/tools/export/qtcreator/__init__.py @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. """ from os.path import splitext, basename +from os import remove from tools.targets import TARGET_MAP from tools.export.exporters import Exporter from tools.export.makefile import GccArm @@ -63,3 +64,8 @@ class QtCreator(GccArm): # finally, generate the Makefile super(QtCreator, self).generate() + + @staticmethod + def clean(project_name): + for ext in ['creator', 'files', 'includes', 'config']: + remove("%s.%s" % (project_name, ext)) diff --git a/tools/export/simplicity/__init__.py b/tools/export/simplicity/__init__.py index 8319e58637..d0b5f7e220 100644 --- a/tools/export/simplicity/__init__.py +++ b/tools/export/simplicity/__init__.py @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. """ from os.path import split,splitext, basename +from os import remove from tools.export.exporters import Exporter, deprecated_exporter @@ -194,3 +195,7 @@ class SimplicityV3(Exporter): ''' self.gen_file('simplicity/slsproj.tmpl', ctx, '%s.slsproj' % self.project_name) + + @staticmethod + def clean(project_name): + remove('%s.slsproj' % project_name) diff --git a/tools/export/sw4stm32/__init__.py b/tools/export/sw4stm32/__init__.py index 4045fc1b7a..607840fa48 100644 --- a/tools/export/sw4stm32/__init__.py +++ b/tools/export/sw4stm32/__init__.py @@ -16,6 +16,7 @@ limitations under the License. """ from os.path import splitext, basename, join +import shutil from tools.utils import mkdir from tools.export.gnuarmeclipse import GNUARMEclipse from tools.export.gnuarmeclipse import UID @@ -557,3 +558,7 @@ class Sw4STM32(GNUARMEclipse): 'makefile.targets', trim_blocks=True, lstrip_blocks=True) self.gen_file('sw4stm32/launch.tmpl', ctx, self.project_name + ' ' + options['debug']['name'] + '.launch') + + @staticmethod + def clean(_): + shutil.rmtree(".settings") diff --git a/tools/export/uvision/__init__.py b/tools/export/uvision/__init__.py index 77f2b8d948..749dffa6cd 100644 --- a/tools/export/uvision/__init__.py +++ b/tools/export/uvision/__init__.py @@ -238,6 +238,16 @@ class Uvision(Exporter): self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") + @staticmethod + def clean(project_name): + os.remove(project_name + ".uvprojx") + os.remove(project_name + ".uvoptx") + # legacy .build directory cleaned if exists + if exists('.build'): + shutil.rmtree('.build') + if exists('BUILD'): + shutil.rmtree('BUILD') + @staticmethod def build(project_name, log_name='build_log.txt', cleanup=True): """ Build Uvision project """ @@ -257,13 +267,7 @@ class Uvision(Exporter): # Cleanup the exported and built files if cleanup: os.remove(log_name) - os.remove(project_name+".uvprojx") - os.remove(project_name+".uvoptx") - # legacy .build directory cleaned if exists - if exists('.build'): - shutil.rmtree('.build') - if exists('BUILD'): - shutil.rmtree('BUILD') + Uvision.clean(project_name) # Returns 0 upon success, 1 upon a warning, and neither upon an error if ret_code != 0 and ret_code != 1: diff --git a/tools/export/vscode/__init__.py b/tools/export/vscode/__init__.py index 0a855827d2..450e04537f 100644 --- a/tools/export/vscode/__init__.py +++ b/tools/export/vscode/__init__.py @@ -14,7 +14,7 @@ # limitations under the License. from os.path import join, exists, realpath, relpath, basename, isfile, splitext -from os import makedirs, listdir +from os import makedirs, listdir, remove, rmdir import json from tools.export.makefile import Makefile, GccArm, Armc5, IAR @@ -83,6 +83,11 @@ class VSCode(Makefile): with open(join(self.export_dir, '.vscode', 'c_cpp_properties.json'), 'w') as outfile: json.dump(cpp_props, outfile, indent=4, separators=(',', ': ')) + @staticmethod + def clean(_): + for f in ['launch', 'settings', 'tasts', 'c_cpp_properties']: + remove(".vscode/%s.json" % f) + rmdir(".vscode") class VSCodeGcc(VSCode, GccArm): LOAD_EXE = True diff --git a/tools/project.py b/tools/project.py index 3aef27a606..141dfe8783 100644 --- a/tools/project.py +++ b/tools/project.py @@ -1,14 +1,16 @@ """ The CLI entry point for exporting projects from the mbed tools to any of the supported IDEs or project structures. """ +from __future__ import absolute_import, print_function import sys -from os.path import join, abspath, dirname, exists, basename +from os.path import (join, abspath, dirname, exists, basename, normpath, + realpath, basename) +from os import remove ROOT = abspath(join(dirname(__file__), "..")) sys.path.insert(0, ROOT) from shutil import move, rmtree from argparse import ArgumentParser -from os.path import normpath, realpath from tools.paths import EXPORT_DIR, MBED_HAL, MBED_LIBRARIES, MBED_TARGETS_PATH from tools.settings import BUILD_DIR @@ -191,7 +193,7 @@ def main(): # Print available tests in order and exit if options.list_tests is True: - print '\n'.join([str(test) for test in sorted(TEST_MAP.values())]) + print('\n'.join([str(test) for test in sorted(TEST_MAP.values())])) sys.exit() # Only prints matrix of supported IDEs @@ -199,7 +201,7 @@ def main(): if options.supported_ides == "matrix": print_large_string(mcu_ide_matrix()) elif options.supported_ides == "ides": - print mcu_ide_list() + print(mcu_ide_list()) exit(0) # Only prints matrix of supported IDEs @@ -212,9 +214,9 @@ def main(): readme.write("\n") readme.write(html) except IOError as exc: - print "I/O error({0}): {1}".format(exc.errno, exc.strerror) + print("I/O error({0}): {1}".format(exc.errno, exc.strerror)) except: - print "Unexpected error:", sys.exc_info()[0] + print("Unexpected error:", sys.exc_info()[0]) raise exit(0) @@ -246,14 +248,20 @@ def main(): args_error(parser, "%s not supported by %s"%(mcu,options.ide)) profile = extract_profile(parser, options, toolchain_name, fallback="debug") if options.clean: - rmtree(BUILD_DIR) + for cls in EXPORTERS.values(): + try: + cls.clean(basename(abspath(options.source_dir[0]))) + except (NotImplementedError, IOError, OSError): + pass + for f in EXPORTERS.values()[0].CLEAN_FILES: + remove(f) try: export(mcu, options.ide, build=options.build, src=options.source_dir, macros=options.macros, project_id=options.program, zip_proj=zip_proj, build_profile=profile, app_config=options.app_config) except NotSupportedException as exc: - print "[ERROR] %s" % str(exc) + print("[ERROR] %s" % str(exc)) if __name__ == "__main__": main()