diff --git a/.project b/.project new file mode 100644 index 0000000..73e7ab7 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + ccstudiodss + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/.pydevproject b/.pydevproject new file mode 100644 index 0000000..98114ac --- /dev/null +++ b/.pydevproject @@ -0,0 +1,5 @@ + + +python +python interpreter + diff --git a/src/ccstudiodss/api.py b/src/ccstudiodss/api.py index 6eacd0e..f73fb0f 100644 --- a/src/ccstudiodss/api.py +++ b/src/ccstudiodss/api.py @@ -1,12 +1,16 @@ + import contextlib import os import pathlib +import subprocess +import tempfile import attr import javabridge import ccstudiodss.utils +build_type_choices = ('incremental', 'full', 'clean') def add_jars(base_path=None): if base_path is None: @@ -103,3 +107,42 @@ def run(self): def restart(self): self.debug_session.target.reset() self.debug_session.target.runAsynch() + +def build(target, build_type, project_root, project_name): + if project_name is None: + project_name = pathlib.Path(project_root).parts[-1] + + with tempfile.TemporaryDirectory() as d: + base_command = ( + os.fspath(ccstudiodss.utils.find_executable()), + '-noSplash', + '-data', d, + ) + + try: + subprocess.run( + [ + *base_command, + '-application', 'com.ti.ccstudio.apps.projectImport', + '-ccs.location', str(project_root), + '-ccs.renameTo', project_name, + ], + check=True, + ) + except subprocess.CalledProcessError: + pass + + for this_build_type in (build_type, 'incremental'): + completed_process = subprocess.run( + [ + *base_command, + '-application', 'com.ti.ccstudio.apps.projectBuild', + '-ccs.projects', project_name, + '-ccs.configuration', target, + '-ccs.buildType', this_build_type, + ], + ) + + completed_process.check_returncode() + + return pathlib.Path(project_root)/target/(project_name + '.out') diff --git a/src/ccstudiodss/cli.py b/src/ccstudiodss/cli.py index ba87762..ab63fb5 100644 --- a/src/ccstudiodss/cli.py +++ b/src/ccstudiodss/cli.py @@ -8,6 +8,46 @@ import ccstudiodss.utils +DSS_PROJECT_ROOT = 'DSS_PROJECT_ROOT' +project_root_option = click.option( + '--project-root', + type=click.Path(exists=True, file_okay=False, resolve_path=True), + envvar=DSS_PROJECT_ROOT, + help=( + 'Directory containing the .project file' + ' (${})'.format(DSS_PROJECT_ROOT) + ), +) + + +DSS_PROJECT_NAME = 'DSS_PROJECT_NAME' +project_name_option = click.option( + '--project-name', + type=str, + envvar=DSS_PROJECT_NAME, + help=( + 'Project name used for build artifacts' + ' (${})'.format(DSS_PROJECT_NAME) + ), +) + + +def default_base_path(): + base_path = ccstudiodss.utils.find_base_path() + if base_path is None: + return {'required': True} + + return {'default': base_path} + +ccs_base_path_option = click.option( + '--ccs-base-path', + type=click.Path(exists=True, file_okay=False), + show_default=True, + **default_base_path(), + help='CCS base directory, e.g. /ti/ccsv8/ccs_base' +) + + @click.group() def cli(): pass @@ -33,11 +73,6 @@ def default_ccxml(): **default_ccxml(), ) -ccs_base_path_option = click.option( - '--ccs-base-path', - type=click.Path(exists=True, file_okay=False), -) - @cli.command() @click.option( @@ -80,3 +115,47 @@ def docs(ccs_base_path, open_): webbrowser.open(path) else: click.echo(path) + +build_type_option = click.option( + '--build-type', + type=click.Choice(ccstudiodss.api.build_type_choices), + default=ccstudiodss.api.build_type_choices[0], + show_default=True, +) + +target_option = click.option('--target', required=True) +@cli.command() +@target_option +@build_type_option +@project_root_option +@project_name_option +def build(target, build_type, project_root, project_name): + """Build the project using Code Composer Studio + """ + ccstudiodss.api.build( + target=target, + build_type=build_type, + project_root=project_root, + project_name=project_name, + ) + + +GRIDTIED_CCXML = 'GRIDTIED_CCXML' + +def create_ccxml_option(project_root): + paths = list(project_root.glob('*.ccxml')) + if len(paths) != 1: + default_or_required = {'required': True} + else: + default_or_required = {'default': paths[0]} + + ccxml_option = click.option( + '--ccxml', + type=click.Path(exists=True, dir_okay=False), + envvar=GRIDTIED_CCXML, + **default_or_required, + help='.ccxml device configuration file (${})'.format(GRIDTIED_CCXML), + show_default=True, + ) + + return ccxml_option diff --git a/src/ccstudiodss/utils.py b/src/ccstudiodss/utils.py index 5eba817..b3dde49 100644 --- a/src/ccstudiodss/utils.py +++ b/src/ccstudiodss/utils.py @@ -16,7 +16,7 @@ class BasePathError(Exception): pathlib.Path(os.sep)/'opt'/'ti'/'ccsv{}'.format(version)/'ccs_base' for version in versions ), - *( # in case the ccsv8 or such gets doubled up + *( pathlib.Path(os.sep)/'opt'/'ti'/'ccsv{}'.format(version)/'ccsv{}'.format(version)/'ccs_base' for version in versions ), @@ -24,7 +24,7 @@ class BasePathError(Exception): pathlib.Path.home()/'ti'/'ccsv{}'.format(version)/'ccs_base' for version in versions ), - *( # in case the ccsv8 or such gets doubled up + *( pathlib.Path.home()/'ti'/'ccsv{}'.format(version)/'ccsv{}'.format(version)/'ccs_base' for version in versions ), @@ -59,3 +59,7 @@ def find_base_path(): raise BasePathError('Unable to find base path in: {}'.format( ', '.join(repr(str(path)) for path in base_paths), )) + + +def find_executable(): + return find_base_path().parents[0]/'eclipse'/'ccstudio'