Esempio n. 1
0
def gen_project(fips_dir, proj_dir, cfg, force) :
    """private: generate build files for one config"""

    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    defines = {}
    defines['FIPS_USE_CCACHE'] = 'ON' if settings.get(proj_dir, 'ccache') else 'OFF'
    defines['FIPS_AUTO_IMPORT'] = 'OFF' if dep.get_policy(proj_dir, 'no_auto_import') else 'ON'
    if cfg['platform'] == 'ios':
        ios_team_id = settings.get(proj_dir, 'iosteam')
        if ios_team_id:
            defines['FIPS_IOS_TEAMID'] = ios_team_id
    do_it = force
    if not os.path.isdir(build_dir) :
        os.makedirs(build_dir)
        do_it = True
    if do_it :
        # if Ninja build tool and on Windows, need to copy 
        # the precompiled ninja.exe to the build dir
        log.colored(log.YELLOW, "=== generating: {}".format(cfg['name']))
        log.info("config file: {}".format(cfg['path']))
        toolchain_path = config.get_toolchain(fips_dir, proj_dir, cfg)
        if toolchain_path :
            log.info("Using Toolchain File: {}".format(toolchain_path))
        if cfg['build_tool'] == 'ninja' :
            ninja.prepare_ninja_tool(fips_dir, build_dir)
        cmake_result = cmake.run_gen(cfg, fips_dir, proj_dir, build_dir, toolchain_path, defines)
        if cfg['build_tool'] == 'vscode_cmake':
            vscode.write_workspace_settings(fips_dir, proj_dir, cfg)
        return cmake_result
    else :
        return True
Esempio n. 2
0
def get_vs_header_paths(fips_dir, proj_dir, cfg):
    '''hacky way to find the header search path in the latest installed
    Windows 10 Kit and Visual Studio instance
    '''
    if util.get_host_platform() != 'win':
        return []

    # Windows system headers are in 2 locations, first find the latest Windows Kit
    result = []
    kits = glob.glob('C:/Program Files (x86)/Windows Kits/10/Include/*/')
    if kits:
        latest = max(kits).replace('\\', '/')
        subdirs = glob.glob(latest + '/*/')
        for d in subdirs:
            result.append(d.replace('\\', '/'))

    # next get the used active Visual Studio instance from the cmake cache
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
    outp = subprocess.check_output(['cmake', '-LA', '.'],
                                   cwd=build_dir).decode("utf-8")
    for line in outp.splitlines():
        if line.startswith('CMAKE_LINKER:FILEPATH='):
            bin_index = line.find('/bin/')
            if bin_index > 0:
                result.append(line[22:bin_index + 1] + 'include')
    return result
Esempio n. 3
0
def gen_project(fips_dir, proj_dir, cfg, force):
    """private: generate build files for one config"""

    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    defines = {}
    defines['FIPS_USE_CCACHE'] = 'ON' if settings.get(proj_dir,
                                                      'ccache') else 'OFF'
    do_it = force
    if not os.path.isdir(build_dir):
        os.makedirs(build_dir)
        do_it = True
    if do_it:
        # if Ninja build tool and on Windows, need to copy
        # the precompiled ninja.exe to the build dir
        if cfg['build_tool'] == 'ninja':
            ninja.prepare_ninja_tool(fips_dir, build_dir)
        log.colored(log.YELLOW, "=== generating: {}".format(cfg['name']))
        toolchain_path = config.get_toolchain(fips_dir, proj_dir, cfg)
        if toolchain_path:
            log.info("Using Toolchain File: {}".format(toolchain_path))
        return cmake.run_gen(cfg, fips_dir, proj_dir, build_dir,
                             toolchain_path, defines)
    else:
        return True
Esempio n. 4
0
def configure(fips_dir, proj_dir, cfg_name):
    """run ccmake or cmake-gui on the provided project and config

    :param fips_dir:    absolute fips path
    :param proj_dir:    absolute project dir
    :cfg_name:          build config name
    """

    dep.fetch_imports(fips_dir, proj_dir)
    proj_name = util.get_project_name_from_dir(proj_dir)
    util.ensure_valid_project_dir(proj_dir)
    dep.gather_and_write_imports(fips_dir, proj_dir, cfg_name)

    # load configs, if more then one, only use first one
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs:
        cfg = configs[0]
        log.colored(log.YELLOW, '=== configuring: {}'.format(cfg['name']))

        # generate build files
        if not gen_project(fips_dir, proj_dir, cfg, True):
            log.error("Failed to generate '{}' of project '{}'".format(
                cfg['name'], proj_name))

        # run ccmake or cmake-gui
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
        if ccmake.check_exists(fips_dir):
            ccmake.run(build_dir)
        elif cmake_gui.check_exists(fips_dir):
            cmake_gui.run(build_dir)
        else:
            log.error(
                "Neither 'ccmake' nor 'cmake-gui' found (run 'fips diag')")
    else:
        log.error("No configs found for '{}'".format(cfg_name))
Esempio n. 5
0
def configure(fips_dir, proj_dir, cfg_name) :
    """run ccmake or cmake-gui on the provided project and config

    :param fips_dir:    absolute fips path
    :param proj_dir:    absolute project dir
    :cfg_name:          build config name
    """

    dep.fetch_imports(fips_dir, proj_dir)
    proj_name = util.get_project_name_from_dir(proj_dir)
    util.ensure_valid_project_dir(proj_dir)
    dep.gather_and_write_imports(fips_dir, proj_dir)

    # load configs, if more then one, only use first one
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs :
        cfg = configs[0]
        log.colored(log.YELLOW, '=== configuring: {}'.format(cfg['name']))

        # generate build files
        if not gen_project(fips_dir, proj_dir, cfg, True) :
            log.error("Failed to generate '{}' of project '{}'".format(cfg['name'], proj_name))

        # run ccmake or cmake-gui
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
        if ccmake.check_exists(fips_dir) :
            ccmake.run(build_dir)
        elif cmake_gui.check_exists(fips_dir) :
            cmake_gui.run(build_dir)
        else :
            log.error("Neither 'ccmake' nor 'cmake-gui' found (run 'fips diag')")
    else :
        log.error("No configs found for '{}'".format(cfg_name))
Esempio n. 6
0
def get_vs_header_paths(fips_dir, proj_dir, cfg):
    '''hacky way to find the header search path in the latest installed
    Windows 10 Kit and Visual Studio instance
    '''
    if util.get_host_platform() != 'win':
        return []

    # Windows system headers are in 2 locations, first find the latest Windows Kit
    result = []
    kits = glob.glob('C:/Program Files (x86)/Windows Kits/10/Include/*/')
    if kits:
        latest = max(kits).replace('\\','/')
        subdirs = glob.glob(latest + '/*/')
        for d in subdirs:
            result.append(d.replace('\\','/'))

    # next get the used active Visual Studio instance from the cmake cache
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
    outp = subprocess.check_output(['cmake', '-LA', '.'], cwd=build_dir).decode("utf-8")
    for line in outp.splitlines():
        if line.startswith('CMAKE_LINKER:FILEPATH='):
            bin_index = line.find('/bin/')
            if bin_index > 0:
                result.append(line[22:bin_index+1]+'include')
    return result
Esempio n. 7
0
def clean(fips_dir, proj_dir, cfg_name):
    """clean build files

    :param fips_dir:    absolute path of fips
    :param proj_dir:    absolute project path
    :param cfg_name:    config name (or pattern)
    """
    proj_name = util.get_project_name_from_dir(proj_dir)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs:
        num_cleaned_configs = 0
        for cfg in configs:
            build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
            build_dir_exists = os.path.isdir(build_dir)
            deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name'])
            deploy_dir_exists = os.path.isdir(deploy_dir)

            if build_dir_exists or deploy_dir_exists:
                log.colored(log.YELLOW, "=== clean: {}".format(cfg['name']))
                num_cleaned_configs += 1

            if build_dir_exists:
                shutil.rmtree(build_dir)
                log.info("  deleted '{}'".format(build_dir))

            if deploy_dir_exists:
                shutil.rmtree(deploy_dir)
                log.info("  deleted '{}'".format(deploy_dir))
        if num_cleaned_configs == 0:
            log.colored(log.YELLOW,
                        "=== clean: nothing to clean for {}".format(cfg_name))
    else:
        log.error("No valid configs found for '{}'".format(cfg_name))
Esempio n. 8
0
def build(fips_dir, proj_dir, cfg_name, target=None, build_tool_args=None):
    """perform a build of config(s) in project

    :param fips_dir:        absolute path of fips
    :param proj_dir:        absolute path of project dir
    :param cfg_name:        config name or pattern
    :param target:          optional target name (build all if None)
    :param build_tool_args: optional string array of cmdline args forwarded to the build tool
    :returns:               True if build was successful
    """

    # prepare
    dep.fetch_imports(fips_dir, proj_dir)
    proj_name = util.get_project_name_from_dir(proj_dir)
    util.ensure_valid_project_dir(proj_dir)
    dep.gather_and_write_imports(fips_dir, proj_dir, cfg_name)

    # load the config(s)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    num_valid_configs = 0
    if configs:
        for cfg in configs:
            # check if config is valid
            config_valid, _ = config.check_config_valid(fips_dir,
                                                        proj_dir,
                                                        cfg,
                                                        print_errors=True)
            if config_valid:
                log.colored(log.YELLOW, "=== building: {}".format(cfg['name']))

                if not gen_project(fips_dir, proj_dir, cfg, False):
                    log.error("Failed to generate '{}' of project '{}'".format(
                        cfg['name'], proj_name))

                # select and run build tool
                build_dir = util.get_build_dir(fips_dir, proj_name,
                                               cfg['name'])
                num_jobs = settings.get(proj_dir, 'jobs')
                result = cmake.run_build(fips_dir, target, cfg['build_type'],
                                         build_dir, num_jobs, build_tool_args)
                if result:
                    num_valid_configs += 1
                else:
                    log.error(
                        "Failed to build config '{}' of project '{}'".format(
                            cfg['name'], proj_name))
            else:
                log.error("Config '{}' not valid in this environment".format(
                    cfg['name']))
    else:
        log.error("No valid configs found for '{}'".format(cfg_name))

    if num_valid_configs != len(configs):
        log.error('{} out of {} configs failed!'.format(
            len(configs) - num_valid_configs, len(configs)))
        return False
    else:
        log.colored(log.GREEN, '{} configs built'.format(num_valid_configs))
        return True
Esempio n. 9
0
def build(fips_dir, proj_dir, cfg_name, target=None) :
    """perform a build of config(s) in project

    :param fips_dir:    absolute path of fips
    :param proj_dir:    absolute path of project dir
    :param cfg_name:    config name or pattern
    :param target:      optional target name (build all if None)
    :returns:           True if build was successful
    """

    # prepare
    dep.fetch_imports(fips_dir, proj_dir)
    proj_name = util.get_project_name_from_dir(proj_dir)
    util.ensure_valid_project_dir(proj_dir)
    dep.gather_and_write_imports(fips_dir, proj_dir)

    # load the config(s)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    num_valid_configs = 0
    if configs :
        for cfg in configs :
            # check if config is valid
            config_valid, _ = config.check_config_valid(fips_dir, cfg, print_errors=True)
            if config_valid :
                log.colored(log.YELLOW, "=== building: {}".format(cfg['name']))

                if not gen_project(fips_dir, proj_dir, cfg, False) :
                    log.error("Failed to generate '{}' of project '{}'".format(cfg['name'], proj_name))

                # select and run build tool
                build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
                num_jobs = settings.get(proj_dir, 'jobs')
                result = False
                if cfg['build_tool'] == make.name :
                    result = make.run_build(fips_dir, target, build_dir, num_jobs)
                elif cfg['build_tool'] == ninja.name :
                    result = ninja.run_build(fips_dir, target, build_dir, num_jobs)
                elif cfg['build_tool'] == xcodebuild.name :
                    result = xcodebuild.run_build(fips_dir, target, cfg['build_type'], build_dir, num_jobs)
                else :
                    result = cmake.run_build(fips_dir, target, cfg['build_type'], build_dir)
                
                if result :
                    num_valid_configs += 1
                else :
                    log.error("Failed to build config '{}' of project '{}'".format(cfg['name'], proj_name))
            else :
                log.error("Config '{}' not valid in this environment".format(cfg['name']))
    else :
        log.error("No valid configs found for '{}'".format(cfg_name))

    if num_valid_configs != len(configs) :
        log.error('{} out of {} configs failed!'.format(len(configs) - num_valid_configs, len(configs)))
        return False      
    else :
        log.colored(log.GREEN, '{} configs built'.format(num_valid_configs))
        return True
Esempio n. 10
0
File: open.py Progetto: rbxnk/fips
def run(fips_dir, proj_dir, args):
    """run the 'open' verb (opens project in IDE)"""
    if not util.is_valid_project_dir(proj_dir):
        log.error('must be run in a project directory')
    proj_name = util.get_project_name_from_dir(proj_dir)
    cfg_name = None
    if len(args) > 0:
        cfg_name = args[0]
    if not cfg_name:
        cfg_name = settings.get(proj_dir, 'config')

    # check the cmake generator of this config
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs:
        # hmm, only look at first match, 'open' doesn't
        # make sense with config-patterns
        cfg = configs[0]

        # find build dir, if it doesn't exist, generate it
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
        if not os.path.isdir(build_dir):
            log.warn("build dir not found, generating...")
            project.gen(fips_dir, proj_dir, cfg['name'])

        # first check if this is a VSCode project
        if cfg['build_tool'] == 'vscode_cmake':
            vscode.run(proj_dir)
            return
        # check if this is a CLion project
        if cfg['build_tool'] == 'clion':
            clion.run(proj_dir)
            return
        # try to open as Xcode project
        proj = glob.glob(build_dir + '/*.xcodeproj')
        if proj:
            subprocess.call('open "{}"'.format(proj[0]), shell=True)
            return
        # try to open as VS project
        proj = glob.glob(build_dir + '/*.sln')
        if proj:
            subprocess.call('cmd /c start {}'.format(proj[0]), shell=True)
            return
        # try to open as eclipse project
        proj = glob.glob(build_dir + '/.cproject')
        if proj:
            subprocess.call(
                'eclipse -nosplash --launcher.timeout 60 -application org.eclipse.cdt.managedbuilder.core.headlessbuild -import "{}"'
                .format(build_dir),
                shell=True)
            subprocess.call('eclipse', shell=True)
            return

        log.error("don't know how to open a '{}' project in {}".format(
            cfg['generator'], build_dir))
    else:
        log.error("config '{}' not found".format(cfg_name))
Esempio n. 11
0
def write_cmake_tools_settings(fips_dir, proj_dir, vscode_dir, cfg):
    '''write a settings.json for CMakeTools plugin settings'''
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    settings = {
        'cmake.buildDirectory': build_dir,
        'cmake.configureSettings': {
            'FIPS_CONFIG:': cfg['name']
        }
    }
    with open(vscode_dir + '/settings.json', 'w') as f:
        json.dump(settings, f, indent=1, separators=(',',':'))
Esempio n. 12
0
File: open.py Progetto: floooh/fips
def run(fips_dir, proj_dir, args) :
    """run the 'open' verb (opens project in IDE)"""
    if not util.is_valid_project_dir(proj_dir) :
        log.error('must be run in a project directory')
    proj_name = util.get_project_name_from_dir(proj_dir)
    cfg_name = None
    if len(args) > 0 :
        cfg_name = args[0]
    if not cfg_name :
        cfg_name = settings.get(proj_dir, 'config')

    # check the cmake generator of this config
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs :
        # hmm, only look at first match, 'open' doesn't
        # make sense with config-patterns
        cfg = configs[0]

        # find build dir, if it doesn't exist, generate it
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
        if not os.path.isdir(build_dir) :
            log.warn("build dir not found, generating...")
            project.gen(fips_dir, proj_dir, cfg['name'])

        # first check if this is a VSCode project
        if cfg['build_tool'] == 'vscode_cmake':
            vscode.run(proj_dir)
            return
        # check if this is a CLion project
        if cfg['build_tool'] == 'clion':
            clion.run(proj_dir)
            return
        # try to open as Xcode project
        proj = glob.glob(build_dir + '/*.xcodeproj')
        if proj :
            subprocess.call('open "{}"'.format(proj[0]), shell=True)
            return
        # try to open as VS project
        proj = glob.glob(build_dir + '/*.sln')
        if proj :
            subprocess.call('cmd /c start {}'.format(proj[0]), shell=True)
            return
        # try to open as eclipse project
        proj = glob.glob(build_dir + '/.cproject')
        if proj :
            subprocess.call('eclipse -nosplash --launcher.timeout 60 -application org.eclipse.cdt.managedbuilder.core.headlessbuild -import "{}"'.format(build_dir), shell=True)
            subprocess.call('eclipse', shell=True)
            return

        log.error("don't know how to open a '{}' project in {}".format(cfg['generator'], build_dir))
    else :
        log.error("config '{}' not found".format(cfg_name))
Esempio n. 13
0
def make_clean(fips_dir, proj_dir, cfg_name):
    """perform a 'make clean' on the project

    :param fips_dir:    absolute path of fips
    :param proj_dir:    absolute path of project dir
    :param cfg_name:    config name or pattern
    """

    proj_name = util.get_project_name_from_dir(proj_dir)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    num_valid_configs = 0
    if configs:
        for cfg in configs:
            config_valid, _ = config.check_config_valid(fips_dir,
                                                        proj_dir,
                                                        cfg,
                                                        print_errors=True)
            if config_valid:
                log.colored(log.YELLOW, "=== cleaning: {}".format(cfg['name']))

                build_dir = util.get_build_dir(fips_dir, proj_name,
                                               cfg['name'])
                result = False
                if cfg['build_tool'] == make.name:
                    result = make.run_clean(fips_dir, build_dir)
                elif cfg['build_tool'] == ninja.name:
                    result = ninja.run_clean(fips_dir, build_dir)
                elif cfg['build_tool'] == xcodebuild.name:
                    result = xcodebuild.run_clean(fips_dir, build_dir)
                else:
                    result = cmake.run_clean(fips_dir, build_dir)

                if result:
                    num_valid_configs += 1
                else:
                    log.error(
                        "Failed to clean config '{}' of project '{}'".format(
                            cfg['name'], proj_name))
            else:
                log.error("Config '{}' not valid in this environment".format(
                    cfg['name']))
    else:
        log.error("No valid configs found for '{}'".format(cfg_name))

    if num_valid_configs != len(configs):
        log.error('{} out of {} configs failed!'.format(
            len(configs) - num_valid_configs, len(configs)))
        return False
    else:
        log.colored(log.GREEN, '{} configs cleaned'.format(num_valid_configs))
        return True
Esempio n. 14
0
def write_cmake_tools_settings(fips_dir, proj_dir, vscode_dir, cfg):
    '''write a settings.json for CMakeTools plugin settings'''
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
    settings = {
        'cmake.buildDirectory': build_dir,
        'cmake.configureSettings': {
            'FIPS_CONFIG:': cfg['name']
        }
    }
    settings_path = vscode_dir + '/settings.json' 
    log.info('  writing {}'.format(settings_path))
    with open(settings_path, 'w') as f:
        json.dump(settings, f, indent=1, separators=(',',':'))
Esempio n. 15
0
def write_c_cpp_properties_json(fips_dir, proj_dir, impex, cfg):
    '''write the .vscode/c_cpp_properties.json files for main project
       and all dependent projects
    '''
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    inc_paths = read_cmake_headerdirs(fips_dir, proj_dir, cfg)
    defines = read_cmake_defines(fips_dir, proj_dir, cfg)
    props = {'configurations': [], 'version': 3}
    for config_name in ['Mac', 'Linux', 'Win32']:
        c = {
            'name': config_name,
            'browse': {
                'limitSymbolsToIncludeHeaders': True,
                'databaseFilename': '{}/browse.VS.code'.format(build_dir)
            }
        }
        config_incl_paths = []
        intellisense_mode = 'clang-x64'
        if config_name == 'Mac':
            config_incl_paths = get_cc_header_paths()
            config_defines = ['_DEBUG', '__GNUC__', '__APPLE__', '__clang__']
        elif config_name == 'Linux':
            config_incl_paths = get_cc_header_paths()
            config_defines = ['_DEBUG', '__GNUC__']
        else:
            intellisense_mode = 'msvc-x64'
            config_incl_paths = get_vs_header_paths(fips_dir, proj_dir, cfg)
            config_defines = ['_DEBUG', '_WIN32']
        config_incl_paths.extend(inc_paths)
        config_defines.extend(defines)

        c['includePath'] = config_incl_paths
        c['defines'] = config_defines
        c['browse']['path'] = config_incl_paths
        c['intelliSenseMode'] = intellisense_mode
        props['configurations'].append(c)

    # add dependencies in reverse order, so that main project is first
    for dep_proj_name in reversed(impex):
        dep_proj_dir = util.get_project_dir(fips_dir, dep_proj_name)
        vscode_dir = dep_proj_dir + '/.vscode'
        if not os.path.isdir(vscode_dir):
            os.makedirs(vscode_dir)
        prop_path = vscode_dir + '/c_cpp_properties.json'
        log.info('  writing {}'.format(prop_path))
        with open(prop_path, 'w') as f:
            json.dump(props, f, indent=1, separators=(',', ':'))
Esempio n. 16
0
def gen_project(fips_dir, proj_dir, cfg, force):
    """private: generate build files for one config"""

    proj_name = util.get_project_name_from_dir(proj_dir)
    deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name'])
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
    defines = {}
    defines['FIPS_USE_CCACHE'] = 'ON' if settings.get(proj_dir,
                                                      'ccache') else 'OFF'
    defines['FIPS_AUTO_IMPORT'] = 'OFF' if dep.get_policy(
        proj_dir, 'no_auto_import') else 'ON'
    if cfg['generator'] in ['Ninja', 'Unix Makefiles']:
        defines['CMAKE_EXPORT_COMPILE_COMMANDS'] = 'ON'
    if cfg['platform'] == 'ios':
        defines['CMAKE_OSX_SYSROOT'] = xcrun.get_ios_sdk_sysroot()
        ios_team_id = settings.get(proj_dir, 'iosteam')
        if ios_team_id:
            defines['FIPS_IOS_TEAMID'] = ios_team_id
    if cfg['platform'] == 'osx':
        defines['CMAKE_OSX_SYSROOT'] = xcrun.get_macos_sdk_sysroot()
    if cfg['platform'] == 'emscripten':
        defines['EMSCRIPTEN_ROOT'] = emsdk.get_emscripten_root(fips_dir)
    if cfg['platform'] == 'wasisdk':
        defines['WASISDK_ROOT'] = wasisdk.get_wasisdk_root(fips_dir)
    do_it = force
    if not os.path.isdir(build_dir):
        os.makedirs(build_dir)
    if not os.path.isfile(build_dir + '/CMakeCache.txt'):
        do_it = True
    if do_it:
        # if Ninja build tool and on Windows, need to copy
        # the precompiled ninja.exe to the build dir
        log.colored(log.YELLOW, "=== generating: {}".format(cfg['name']))
        log.info("config file: {}".format(cfg['path']))
        toolchain_path = config.get_toolchain(fips_dir, proj_dir, cfg)
        if toolchain_path:
            log.info("Using Toolchain File: {}".format(toolchain_path))
        is_local_build = settings.get(proj_dir, 'local')
        cmake_result = cmake.run_gen(cfg, fips_dir, proj_dir, build_dir,
                                     is_local_build, toolchain_path, defines)
        if vscode.match(cfg['build_tool']):
            vscode.write_workspace_settings(
                fips_dir, proj_dir, cfg, settings.get_all_settings(proj_dir))
        if clion.match(cfg['build_tool']):
            clion.write_workspace_settings(fips_dir, proj_dir, cfg)
        return cmake_result
    else:
        return True
Esempio n. 17
0
def make_clean(fips_dir, proj_dir, cfg_name) :
    """perform a 'make clean' on the project

    :param fips_dir:    absolute path of fips
    :param proj_dir:    absolute path of project dir
    :param cfg_name:    config name or pattern
    """

    proj_name = util.get_project_name_from_dir(proj_dir)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    num_valid_configs = 0
    if configs :
        for cfg in configs :
            config_valid, _ = config.check_config_valid(fips_dir, cfg, print_errors=True)
            if config_valid :
                log.colored(log.YELLOW, "=== cleaning: {}".format(cfg['name']))

                build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
                result = False
                if cfg['build_tool'] == make.name :
                    result = make.run_clean(fips_dir, build_dir)
                elif cfg['build_tool'] == ninja.name :
                    result = ninja.run_clean(fips_dir, build_dir)
                elif cfg['build_tool'] == xcodebuild.name :
                    result = xcodebuild.run_clean(fips_dir, build_dir)
                else :
                    result = cmake.run_clean(fips_dir, build_dir)
                    
                if result :
                    num_valid_configs += 1
                else :
                    log.error("Failed to clean config '{}' of project '{}'".format(cfg['name'], proj_name))
            else :
                log.error("Config '{}' not valid in this environment".format(cfg['name']))
    else :
        log.error("No valid configs found for '{}'".format(cfg_name))

    if num_valid_configs != len(configs) :
        log.error('{} out of {} configs failed!'.format(len(configs) - num_valid_configs, len(configs)))
        return False      
    else :
        log.colored(log.GREEN, '{} configs cleaned'.format(num_valid_configs))
        return True
Esempio n. 18
0
def gen_project(fips_dir, proj_dir, cfg, force) :
    """private: generate build files for one config"""

    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    defines = {}
    defines['FIPS_USE_CCACHE'] = 'ON' if settings.get(proj_dir, 'ccache') else 'OFF'
    do_it = force
    if not os.path.isdir(build_dir) :
        os.makedirs(build_dir)
        do_it = True
    if do_it :
        # if Ninja build tool and on Windows, need to copy 
        # the precompiled ninja.exe to the build dir
        if cfg['build_tool'] == 'ninja' :
            ninja.prepare_ninja_tool(fips_dir, build_dir)
        log.colored(log.YELLOW, "=== generating: {}".format(cfg['name']))
        toolchain_path = config.get_toolchain_for_platform(fips_dir, cfg['platform'])
        return cmake.run_gen(cfg, proj_dir, build_dir, toolchain_path, defines)
    else :
        return True
Esempio n. 19
0
 def run(fips_dir, proj_dir, args):
     """run the 'nebula' verb"""
     if len(args) > 0:
         noun = args[0]
         if noun == 'set':
             if len(args) > 2:
                 setKey(args[1], args[2])
             else:
                 log.error("Expected setting and value")
         elif noun == 'get':
             if len(args) > 1:
                 key = argToKey(args[1])
                 if key != "":
                     reg_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
                                               base_reg, 0,
                                               _winreg.KEY_READ)
                     keyval, regtype = _winreg.QueryValueEx(reg_key, key)
                     _winreg.CloseKey(reg_key)
                     log.info(keyval)
                 else:
                     log.error("Invalid setting")
             else:
                 log.error("Expected setting name")
         elif noun == 'cleannidl':
             proj = util.get_project_name_from_dir(proj_dir)
             cfg = settings.get(proj_dir, 'config')
             path = util.get_build_dir(fips_dir, proj, cfg) + "/nidl"
             shutil.rmtree(path, True)
     else:
         try:
             reg_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, base_reg,
                                       0, _winreg.KEY_READ)
             workval, regtype = _winreg.QueryValueEx(reg_key, "workdir")
             rootval, regtype = _winreg.QueryValueEx(reg_key, "path")
             _winreg.CloseKey(reg_key)
             log.colored(log.YELLOW, "Current settings")
             log.optional("Project directory", workval)
             log.optional("Nebula root director", rootval)
         except WindowsError:
             log.colored(log.YELLOW, "No Nebula settings in registry\n")
Esempio n. 20
0
def write_c_cpp_properties_json(fips_dir, proj_dir, vscode_dir, cfg):
    '''write the .vscode/c_cpp_properties.json file'''
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    inc_paths = read_cmake_headerdirs(fips_dir, proj_dir, cfg)
    defines = read_cmake_defines(fips_dir, proj_dir, cfg)
    props = {
        'configurations': [],
        'version': 3
    }
    for config_name in ['Mac','Linux','Win32']:
        c = {
            'name': config_name,
            'browse': {
                'limitSymbolsToIncludeHeaders': True,
                'databaseFilename': '{}/browse.VS.code'.format(build_dir)
            }
        }
        config_incl_paths = []
        intellisense_mode = 'clang-x64'
        if config_name == 'Mac':
            config_incl_paths = get_cc_header_paths()
            config_defines = ['_DEBUG','__GNUC__','__APPLE__','__clang__']
        elif config_name == 'Linux':
            config_incl_paths = get_cc_header_paths()
            config_defines = ['_DEBUG','__GNUC__']
        else:
            intellisense_mode = 'msvc-x64'
            config_incl_paths = get_vs_header_paths(fips_dir, proj_dir, cfg)
            config_defines = ['_DEBUG','_WIN32']
        config_incl_paths.extend(inc_paths)
        config_defines.extend(defines)
        
        c['includePath'] = config_incl_paths
        c['defines'] = config_defines
        c['browse']['path'] = config_incl_paths
        c['intelliSenseMode'] = intellisense_mode
        props['configurations'].append(c)
    with open(vscode_dir + '/c_cpp_properties.json', 'w') as f:
        json.dump(props, f, indent=1, separators=(',',':'))
Esempio n. 21
0
def run(fips_dir, proj_dir, args):
    """run the 'open' verb (opens project in IDE)"""
    if not util.is_valid_project_dir(proj_dir):
        log.error('must be run in a project directory')
    proj_name = util.get_project_name_from_dir(proj_dir)
    cfg_name = None
    if len(args) > 0:
        cfg_name = args[0]
    if not cfg_name:
        cfg_name = settings.get(proj_dir, 'config')

    # check the cmake generator of this config
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs:
        # hmm, only look at first match, 'open' doesn't
        # make sense with config-patterns
        cfg = configs[0]

        # find build dir, if it doesn't exist, generate it
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
        if not os.path.isdir(build_dir):
            log.warn("build dir not found, generating...")
            project.gen(fips_dir, proj_dir, cfg['name'])

        if 'Xcode' in cfg['generator']:
            # find the Xcode project
            proj = glob.glob(build_dir + '/*.xcodeproj')
            subprocess.call(['open', proj[0]])
        elif 'Visual Studio' in cfg['generator']:
            # find the VisualStudio project file
            proj = glob.glob(build_dir + '/*.sln')
            subprocess.call(['cmd', '/c', 'start', proj[0]])
        else:
            log.error("don't know how to open a '{}' project".format(
                cfg['generator']))
    else:
        log.error("config '{}' not found".format(cfg_name))
Esempio n. 22
0
def run(fips_dir, proj_dir, args) :
    """run the 'open' verb (opens project in IDE)"""
    if not util.is_valid_project_dir(proj_dir) :
        log.error('must be run in a project directory')
    proj_name = util.get_project_name_from_dir(proj_dir)
    cfg_name = None
    if len(args) > 0 :
        cfg_name = args[0]
    if not cfg_name :
        cfg_name = settings.get(proj_dir, 'config')
        
    # check the cmake generator of this config
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs :
        # hmm, only look at first match, 'open' doesn't
        # make sense with config-patterns
        cfg = configs[0]

        # find build dir, if it doesn't exist, generate it
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
        if not os.path.isdir(build_dir) :
            log.warn("build dir not found, generating...")
            project.gen(fips_dir, proj_dir, cfg['name'])
        
        # try to open as Xcode project
        proj = glob.glob(build_dir + '/*.xcodeproj')
        if proj :
            subprocess.call('open {}'.format(proj[0]), shell=True)
        else :
            # try to open as VS project
            proj = glob.glob(build_dir + '/*.sln')
            if proj :
                subprocess.call('cmd /c start {}'.format(proj[0]), shell=True)
            else :
                log.error("don't know how to open a '{}' project".format(cfg['generator']))
    else :
        log.error("config '{}' not found".format(cfg_name))
Esempio n. 23
0
def get_target_list(fips_dir, proj_dir, cfg_name):
    """get project targets config name, only works
    if a cmake run was performed before

    :param fips_dir:        absolute path to fips
    :param proj_dir:        absolute project path
    :param cfg_name:        the config name
    :returns:   (success, targets)
    """
    proj_name = util.get_project_name_from_dir(proj_dir)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs:
        cfg = configs[0]
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
        targets_path = build_dir + '/fips_targets.yml'
        if os.path.isfile(targets_path):
            targets = []
            with open(targets_path) as f:
                targets = yaml.load(f)
            return True, targets
        else:
            return False, []
    else:
        log.error("No valid configs found for '{}'".format(cfg_name))
Esempio n. 24
0
def get_target_list(fips_dir, proj_dir, cfg_name) :
    """get project targets config name, only works
    if a cmake run was performed before

    :param fips_dir:        absolute path to fips
    :param proj_dir:        absolute project path
    :param cfg_name:        the config name
    :returns:   (success, targets)
    """
    proj_name = util.get_project_name_from_dir(proj_dir)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs :
        cfg = configs[0]
        build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
        targets_path = build_dir + '/fips_targets.yml'
        if os.path.isfile(targets_path) :
            targets = []
            with open(targets_path) as f :
                targets = yaml.load(f)
            return True, targets
        else :
            return False, []
    else :
        log.error("No valid configs found for '{}'".format(cfg_name))
Esempio n. 25
0
def clean(fips_dir, proj_dir, cfg_name) :
    """clean build files

    :param fips_dir:    absolute path of fips
    :param proj_dir:    absolute project path
    :param cfg_name:    config name (or pattern)
    """
    proj_name = util.get_project_name_from_dir(proj_dir)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs :
        for cfg in configs :
            log.colored(log.YELLOW, "=== clean: {}".format(cfg['name']))

            build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
            if os.path.isdir(build_dir) :
                shutil.rmtree(build_dir)
                log.info("  deleted '{}'".format(build_dir))

            deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg)
            if os.path.isdir(deploy_dir) :
                shutil.rmtree(deploy_dir)
                log.info("  deleted '{}'".format(deploy_dir))
    else :
        log.error("No valid configs found for '{}'".format(cfg_name))
Esempio n. 26
0
def run(fips_dir, proj_dir, args) :
    
    if not util.is_valid_project_dir(proj_dir) :
        log.error('must be run in a project directory')
    
    proj_name = util.get_project_name_from_dir(proj_dir)

    cfg_name = None
    if len(args) > 0 :
        cfg_name = args[0]
    if not cfg_name :
        cfg_name = settings.get(proj_dir, 'config')

    build_dir = util.get_build_dir(fips_dir, proj_name, cfg_name)

    cache_file = build_dir + '/CMakeCache.txt'
    if not os.path.isfile(cache_file) :
        log.error('generate project first!')

    if sys.platform == "win32" :
        os.startfile(cache_file)
    else :
        opener ="open" if sys.platform == "darwin" else "xdg-open"
        subprocess.call([opener, cache_file])
Esempio n. 27
0
def clean(fips_dir, proj_dir, cfg_name):
    """clean build files

    :param fips_dir:    absolute path of fips
    :param proj_dir:    absolute project path
    :param cfg_name:    config name (or pattern)
    """
    proj_name = util.get_project_name_from_dir(proj_dir)
    configs = config.load(fips_dir, proj_dir, cfg_name)
    if configs:
        for cfg in configs:
            log.colored(log.YELLOW, "=== clean: {}".format(cfg['name']))

            build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
            if os.path.isdir(build_dir):
                shutil.rmtree(build_dir)
                log.info("  deleted '{}'".format(build_dir))

            deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg)
            if os.path.isdir(deploy_dir):
                shutil.rmtree(deploy_dir)
                log.info("  deleted '{}'".format(deploy_dir))
    else:
        log.error("No valid configs found for '{}'".format(cfg_name))
Esempio n. 28
0
def write_c_cpp_properties_json(fips_dir, proj_dir, impex, cfg):
    '''write the .vscode/c_cpp_properties.json files for main project
       and all dependent projects
    '''
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])
    defines = read_cmake_defines(fips_dir, proj_dir, cfg)
    compile_commands_path = build_dir + '/compile_commands.json'
    has_compile_command_json = os.path.isfile(compile_commands_path)
    inc_paths = None
    if not has_compile_command_json:
        inc_paths = read_cmake_headerdirs(fips_dir, proj_dir, cfg)
    props = {
        'configurations': [],
        'version': 3
    }
    for config_name in ['Mac','Linux','Win32']:
        c = {
            'name': config_name,
            'browse': {
                'limitSymbolsToIncludedHeaders': True,
                'databaseFilename': '{}/browse.VS.code'.format(build_dir)
            }
        }
        config_incl_paths = None
        compiler_path = None
        intellisense_mode = 'clang-x64'
        if config_name == 'Mac':
            if not has_compile_command_json:
                config_incl_paths = get_cc_header_paths()
            config_defines = ['_DEBUG','__GNUC__','__APPLE__','__clang__']
            compiler_path = '/usr/bin/c++'
        elif config_name == 'Linux':
            if not has_compile_command_json:
                config_incl_paths = get_cc_header_paths()
            config_defines = ['_DEBUG','__GNUC__']
            compiler_path = '/usr/bin/c++'
        else:
            if not has_compile_command_json:
                config_incl_paths = get_vs_header_paths(fips_dir, proj_dir, cfg)
            intellisense_mode = 'msvc-x64'
            config_defines = ['_DEBUG','_WIN32']
        if inc_paths:
            config_incl_paths.extend(inc_paths)
        config_defines.extend(defines)
        
        if compiler_path:
            c['compilerPath'] = compiler_path
        if has_compile_command_json:
            c['compileCommands'] = compile_commands_path
        if config_incl_paths:
            c['includePath'] = config_incl_paths
        c['defines'] = config_defines
        if config_incl_paths:
            c['browse']['path'] = config_incl_paths
        c['intelliSenseMode'] = intellisense_mode
        props['configurations'].append(c)
    
    # add dependencies in reverse order, so that main project is first
    for dep_proj_name in reversed(impex):
        dep_proj_dir = util.get_project_dir(fips_dir, dep_proj_name)
        vscode_dir = dep_proj_dir + '/.vscode'
        if not os.path.isdir(vscode_dir):
            os.makedirs(vscode_dir)
        prop_path = vscode_dir + '/c_cpp_properties.json'
        log.info('  writing {}'.format(prop_path))
        with open(prop_path, 'w') as f:
            json.dump(props, f, indent=1, separators=(',',':'))
Esempio n. 29
0
def write_workspace_settings(fips_dir, proj_dir, cfg):
    '''write the VSCode launch.json, tasks.json and
    c_cpp_properties.json files from cmake output files
    '''
    proj_name = util.get_project_name_from_dir(proj_dir)
    deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    vscode_dir = proj_dir + '/.vscode'
    if not os.path.isdir(vscode_dir):
        os.makedirs(vscode_dir)
    exe_targets = read_cmake_targets(fips_dir, proj_dir, cfg, ['app'])
    all_targets = read_cmake_targets(fips_dir, proj_dir, cfg, None)
    inc_paths = read_cmake_headerdirs(fips_dir, proj_dir, cfg)

    if util.get_host_platform() == 'win':
        fips_cmd = 'fips'
    else:
        fips_cmd = './fips'

    # write a tasks.json file
    tasks = {
        'version': '0.1.0',
        'command': fips_cmd,
        'isShellCommand': True,
        'showOutput': 'silent',
        'suppressTaskName': True,
        'echoCommand': True,
        'tasks': []
    }
    for tgt in all_targets:
        tasks['tasks'].append({
            'taskName': tgt,
            'args': ['make', tgt],
            'problemMatcher': problem_matcher(),
        })
    tasks['tasks'].append({
        'isBuildCommand': True,
        'taskName': 'ALL',
        'args': ['build'],
        'problemMatcher': problem_matcher()
    })
    with open(vscode_dir + '/tasks.json', 'w') as f:
        json.dump(tasks, f, indent=1, separators=(',', ':'))

    # write a launch.json with 1 config per build target
    launch = {'version': '0.2.0', 'configurations': []}
    for tgt in exe_targets:
        path = deploy_dir + '/' + tgt
        if util.get_host_platform() == 'win':
            path += '.exe'
        cwd = os.path.dirname(path)
        osx_path = path + '.app/Contents/MacOS/' + tgt
        osx_cwd = os.path.dirname(osx_path)
        if os.path.isdir(osx_cwd):
            path = osx_path
            cwd = osx_cwd
        if util.get_host_platform() == 'win':
            c = {
                'name': tgt,
                'type': 'cppvsdbg',
                'request': 'launch',
                'program': path,
                'args': [],
                'stopAtEntry': True,
                'cwd': cwd,
                'environment': [],
                'externalConsole': False
            }
        elif util.get_host_platform() == 'linux':
            c = {
                'name': tgt,
                'type': 'cppdbg',
                'request': 'launch',
                'program': path,
                'args': [],
                'stopAtEntry': True,
                'cwd': cwd,
                'externalConsole': False,
                'MIMode': 'gdb'
            }
        else:
            c = {
                'name': tgt,
                'type': 'cppdbg',
                'request': 'launch',
                'program': path,
                'args': [],
                'stopAtEntry': True,
                'cwd': cwd,
                'externalConsole': False,
                'MIMode': 'lldb'
            }
        launch['configurations'].append(c)

    # add a python code-generator debug config
    c = {
        'name':
        'fips codegen',
        'type':
        'python',
        'request':
        'launch',
        'stopOnEntry':
        True,
        'pythonPath':
        '${config:python.pythonPath}',
        'program':
        proj_dir + '/.fips-gen.py',
        'args': [build_dir + '/fips_codegen.yml'],
        "cwd":
        proj_dir,
        "debugOptions":
        ["WaitOnAbnormalExit", "WaitOnNormalExit", "RedirectOutput"]
    }
    launch['configurations'].append(c)

    # add a python debug config for each fips verb
    for verb_name, verb_mod in verb.verbs.items():
        # ignore standard verbs
        if fips_dir not in inspect.getfile(verb_mod):
            c = {
                'name':
                'fips {}'.format(verb_name),
                'type':
                'python',
                'request':
                'launch',
                'stopOnEntry':
                True,
                'pythonPath':
                '${config:python.pythonPath}',
                'program':
                proj_dir + '/fips',
                'args': [verb_name],
                'cwd':
                proj_dir,
                "debugOptions":
                ["WaitOnAbnormalExit", "WaitOnNormalExit", "RedirectOutput"]
            }
            launch['configurations'].append(c)

    with open(vscode_dir + '/launch.json', 'w') as f:
        json.dump(launch, f, indent=1, separators=(',', ':'))

    # write a c_cpp_properties.json file with header-search paths
    props = {'configurations': []}
    for config_name in ['Mac', 'Linux', 'Win32']:
        c = {
            'name': config_name,
            'browse': {
                'limitSymbolsToIncludeHeaders': True,
                'databaseFilename': '{}/browse.VS.code'.format(build_dir)
            }
        }
        config_incl_paths = []
        if config_name == 'Mac':
            config_incl_paths = [
                '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1',
                '/usr/local/include',
                '/applications/xcode.app/contents/developer/toolchains/xcodedefault.xctoolchain/usr/lib/clang/8.1.0/include',
                '/applications/xcode.app/contents/developer/toolchains/xcodedefault.xctoolchain/usr/include',
                '/usr/include'
            ]
        elif config_name == 'Linux':
            config_incl_paths = ['/usr/include', '/usr/local/include']
        else:
            config_incl_paths = [
                # FIXME
                'C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*'
            ]
        for inc_path in inc_paths:
            config_incl_paths.append(inc_path)
        c['includePath'] = config_incl_paths
        c['browse']['path'] = config_incl_paths
        props['configurations'].append(c)
    with open(vscode_dir + '/c_cpp_properties.json', 'w') as f:
        json.dump(props, f, indent=1, separators=(',', ':'))
Esempio n. 30
0
def write_launch_json(fips_dir, proj_dir, vscode_dir, cfg):
    '''write the .vscode/launch.json file'''
    proj_name = util.get_project_name_from_dir(proj_dir)
    exe_targets = read_cmake_targets(fips_dir, proj_dir, cfg, ['app'])
    deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name'])
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])

    pre_launch_build_options = [('', True), (' [Skip Build]', False)]
    stop_at_entry_options = [('', False), (' [Stop At Entry]', True)]

    launch = {
        'version': '0.2.0',
        'configurations': []
    }
    for tgt in exe_targets:
        for pre_launch_build in pre_launch_build_options:
            for stop_at_entry in stop_at_entry_options:
                path = deploy_dir + '/' + tgt
                if util.get_host_platform() == 'win':
                    path += '.exe'
                cwd = os.path.dirname(path)
                osx_path = path + '.app/Contents/MacOS/' + tgt
                osx_cwd = os.path.dirname(osx_path)
                if os.path.isdir(osx_cwd):
                    path = osx_path
                    cwd = osx_cwd
                if util.get_host_platform() == 'win':
                    c = {
                        'name': tgt + pre_launch_build[0] + stop_at_entry[0],
                        'type': 'cppvsdbg',
                        'request': 'launch',
                        'program': path,
                        'args': [],
                        'stopAtEntry': stop_at_entry[1],
                        'cwd': cwd,
                        'environment': [],
                        'externalConsole': False,
                        'preLaunchTask': tgt if pre_launch_build[1] else ''
                    }
                elif util.get_host_platform() == 'linux':
                    c = {
                        'name': tgt + pre_launch_build[0] + stop_at_entry[0],
                        'type': 'cppdbg',
                        'request': 'launch',
                        'program': path,
                        'args': [],
                        'stopAtEntry': stop_at_entry[1],
                        'cwd': cwd,
                        'externalConsole': False,
                        'MIMode': 'gdb',
                        'preLaunchTask': tgt if pre_launch_build[1] else ''
                    }
                else:
                    c = {
                        'name': tgt + pre_launch_build[0] + stop_at_entry[0],
                        'type': 'cppdbg',
                        'request': 'launch',
                        'program': path,
                        'args': [],
                        'stopAtEntry': stop_at_entry[1],
                        'cwd': cwd,
                        'externalConsole': False,
                        'MIMode': 'lldb',
                        'preLaunchTask': tgt if pre_launch_build[1] else ''
                    }
                launch['configurations'].append(c)

    # add a python code-generator debug config
    c = {
        'name': 'fips codegen',
        'type': 'python',
        'request': 'launch',
        'stopOnEntry': True,
        'pythonPath': '${config:python.pythonPath}',
        'program': build_dir + '/fips-gen.py',
        'args': [ build_dir + '/fips_codegen.yml' ],
        "cwd": proj_dir,
        "debugOptions": [
            "WaitOnAbnormalExit",
            "WaitOnNormalExit",
            "RedirectOutput"
        ]
    }
    launch['configurations'].append(c)

    # add a python debug config for each fips verb
    for verb_name, verb_mod in verb.verbs.items() :
        # ignore standard verbs
        if fips_dir not in inspect.getfile(verb_mod):
            c = {
                'name': 'fips {}'.format(verb_name),
                'type': 'python',
                'request': 'launch',
                'stopOnEntry': True,
                'pythonPath': '${config:python.pythonPath}',
                'program': proj_dir + '/fips',
                'args': [ verb_name ],
                'cwd': proj_dir,
                "debugOptions": [
                    "WaitOnAbnormalExit",
                    "WaitOnNormalExit",
                    "RedirectOutput"
                ]
            }
            launch['configurations'].append(c)
    launch_path = vscode_dir + '/launch.json'
    log.info('  writing {}'.format(launch_path))
    with open(launch_path, 'w') as f:
        json.dump(launch, f, indent=1, separators=(',',':'))
Esempio n. 31
0
def write_workspace_settings(fips_dir, proj_dir, cfg):
    '''write the VSCode launch.json, tasks.json and
    c_cpp_properties.json files from cmake output files
    '''
    proj_name = util.get_project_name_from_dir(proj_dir)
    deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg)
    vscode_dir = proj_dir + '/.vscode'
    if not os.path.isdir(vscode_dir):
        os.makedirs(vscode_dir)
    exe_targets = read_cmake_targets(fips_dir, proj_dir, cfg, ['app'])
    all_targets = read_cmake_targets(fips_dir, proj_dir, cfg, None)
    inc_paths = read_cmake_headerdirs(fips_dir, proj_dir, cfg)

    if util.get_host_platform() == 'win':
        fips_cmd = 'fips'
    else:
        fips_cmd = './fips'

    # write a tasks.json file
    tasks = {
        'version': '0.1.0',
        'command': fips_cmd,
        'isShellCommand': True,
        'showOutput': 'silent',
        'suppressTaskName': True,
        'echoCommand': True,
        'tasks': []
    }
    for tgt in all_targets:
        tasks['tasks'].append({
            'taskName': tgt,
            'args': ['make', tgt],
            'problemMatcher': problem_matcher(),
        })
    tasks['tasks'].append({
        'isBuildCommand': True,
        'taskName': 'ALL',
        'args': ['build'],
        'problemMatcher': problem_matcher()
    })
    with open(vscode_dir + '/tasks.json', 'w') as f:
        json.dump(tasks, f, indent=1, separators=(',', ':'))

    # write a launch.json with 1 config per build target
    launch = {'version': '0.2.0', 'configurations': []}
    for tgt in exe_targets:
        path = deploy_dir + '/' + tgt
        if util.get_host_platform() == 'win':
            path += '.exe'
        cwd = os.path.dirname(path)
        osx_path = path + '.app/Contents/MacOS/' + tgt
        osx_cwd = os.path.dirname(osx_path)
        if os.path.isdir(osx_cwd):
            path = osx_path
            cwd = osx_cwd
        if util.get_host_platform() == 'win':
            c = {
                'name': tgt,
                'type': 'cppvsdbg',
                'request': 'launch',
                'program': path,
                'stopAtEntry': True,
                'cwd': cwd,
                'environment': [],
                'externalConsole': False
            }
        else:
            c = {
                'name': tgt,
                'type': 'cppdbg',
                'request': 'launch',
                'program': path,
                'stopAtEntry': True,
                'cwd': cwd,
                'externalConsole': False,
                'linux': {
                    'MIMode':
                    'gdb',
                    'setupCommands': [{
                        'description': 'Enable pretty-printing for gdb',
                        'text': '--enable-pretty-printing',
                        'ignoreFailures': True
                    }]
                },
                'osx': {
                    'MIMode': 'lldb'
                }
            }
        launch['configurations'].append(c)

    # add a python code-generator debug config
    c = {
        'name':
        'fips codegen',
        'type':
        'python',
        'request':
        'launch',
        'stopOnEntry':
        True,
        'pythonPath':
        '${config.python.pythonPath}',
        'program':
        proj_dir + '/.fips-gen.py',
        'args': [build_dir + '/fips_codegen.yml'],
        "cwd":
        proj_dir,
        "debugOptions":
        ["WaitOnAbnormalExit", "WaitOnNormalExit", "RedirectOutput"]
    }
    launch['configurations'].append(c)

    # TODO: add entries for local fips verbs?

    with open(vscode_dir + '/launch.json', 'w') as f:
        json.dump(launch, f, indent=1, separators=(',', ':'))

    # write a c_cpp_properties.json file with header-search paths
    props = {'configurations': []}
    for config_name in ['Mac', 'Linux', 'Win32']:
        c = {
            'name': config_name,
            'browse': {
                'limitSymbolsToIncludeHeaders': True,
                'databaseFilename': ''
            }
        }
        if config_name in ['Mac', 'Linux']:
            c['includePath'] = ['/usr/include', '/usr/local/include']
        else:
            c['includePath'] = [
                # FIXME
                'C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*'
            ]
        for inc_path in inc_paths:
            c['includePath'].append(inc_path)
        props['configurations'].append(c)
    with open(vscode_dir + '/c_cpp_properties.json', 'w') as f:
        json.dump(props, f, indent=1, separators=(',', ':'))
Esempio n. 32
0
def write_launch_json(fips_dir, proj_dir, vscode_dir, cfg):
    '''write the .vscode/launch.json file'''
    proj_name = util.get_project_name_from_dir(proj_dir)
    exe_targets = read_cmake_targets(fips_dir, proj_dir, cfg, ['app'])
    deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name'])
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg['name'])

    pre_launch_build_options = [('', True), (' [Skip Build]', False)]
    stop_at_entry_options = [('', False), (' [Stop At Entry]', True)]

    launch = {'version': '0.2.0', 'configurations': []}
    for tgt in exe_targets:
        for pre_launch_build in pre_launch_build_options:
            for stop_at_entry in stop_at_entry_options:
                path = deploy_dir + '/' + tgt
                if util.get_host_platform() == 'win':
                    path += '.exe'
                cwd = os.path.dirname(path)
                osx_path = path + '.app/Contents/MacOS/' + tgt
                osx_cwd = os.path.dirname(osx_path)
                if os.path.isdir(osx_cwd):
                    path = osx_path
                    cwd = osx_cwd
                if util.get_host_platform() == 'win':
                    c = {
                        'name': tgt + pre_launch_build[0] + stop_at_entry[0],
                        'type': 'cppvsdbg',
                        'request': 'launch',
                        'program': path,
                        'args': [],
                        'stopAtEntry': stop_at_entry[1],
                        'cwd': cwd,
                        'environment': [],
                        'externalConsole': False,
                        'preLaunchTask': tgt if pre_launch_build[1] else ''
                    }
                elif util.get_host_platform() == 'linux':
                    c = {
                        'name': tgt + pre_launch_build[0] + stop_at_entry[0],
                        'type': 'cppdbg',
                        'request': 'launch',
                        'program': path,
                        'args': [],
                        'stopAtEntry': stop_at_entry[1],
                        'cwd': cwd,
                        'externalConsole': False,
                        'MIMode': 'gdb',
                        'preLaunchTask': tgt if pre_launch_build[1] else ''
                    }
                else:
                    c = {
                        'name': tgt + pre_launch_build[0] + stop_at_entry[0],
                        'type': 'cppdbg',
                        'request': 'launch',
                        'program': path,
                        'args': [],
                        'stopAtEntry': stop_at_entry[1],
                        'cwd': cwd,
                        'externalConsole': False,
                        'MIMode': 'lldb',
                        'preLaunchTask': tgt if pre_launch_build[1] else ''
                    }
                launch['configurations'].append(c)

    # add a python code-generator debug config
    c = {
        'name':
        'fips codegen',
        'type':
        'python',
        'request':
        'launch',
        'stopOnEntry':
        True,
        'pythonPath':
        '${config:python.pythonPath}',
        'program':
        build_dir + '/fips-gen.py',
        'args': [build_dir + '/fips_codegen.yml'],
        "cwd":
        proj_dir,
        "debugOptions":
        ["WaitOnAbnormalExit", "WaitOnNormalExit", "RedirectOutput"]
    }
    launch['configurations'].append(c)

    # add a python debug config for each fips verb
    for verb_name, verb_mod in verb.verbs.items():
        # ignore standard verbs
        if fips_dir not in inspect.getfile(verb_mod):
            c = {
                'name':
                'fips {}'.format(verb_name),
                'type':
                'python',
                'request':
                'launch',
                'stopOnEntry':
                True,
                'pythonPath':
                '${config:python.pythonPath}',
                'program':
                proj_dir + '/fips',
                'args': [verb_name],
                'cwd':
                proj_dir,
                "debugOptions":
                ["WaitOnAbnormalExit", "WaitOnNormalExit", "RedirectOutput"]
            }
            launch['configurations'].append(c)
    launch_path = vscode_dir + '/launch.json'
    log.info('  writing {}'.format(launch_path))
    with open(launch_path, 'w') as f:
        json.dump(launch, f, indent=1, separators=(',', ':'))
Esempio n. 33
0
File: dep.py Progetto: floooh/fips
def write_imports(fips_dir, proj_dir, cfg_name, imported) :
    """write the big imports map created with 'gather_imports'
    to a .fips-imports.cmake file in the current project

    :params fips_dir:   absolute path to fips
    :params proj_dir:   absolute path to current project
    :params imported:   the imports dictionary created with 'gather_imports'
    """

    if imported :
        unique_hdrdirs = []
        unique_libdirs = []
        unique_defines = {}
        unique_modules = {}

        # write a temporary .fips-imports.cmake.tmp file,
        # this will replace the old file, but only if the
        # content is different, this will prevent an unnecessary
        # cmake run if the imports haven't changed
        import_filename = proj_dir + '/.fips-imports.cmake'
        import_tmp_filename = import_filename + '.tmp'
        with open(import_tmp_filename, 'w') as f :
            f.write("#\n# generated by 'fips gen', don't edit, don't add to version control!\n#\n")
            
            for imp_proj_name in imported :
                imp_proj_dir = util.get_project_dir(fips_dir, imp_proj_name)
                
                if imported[imp_proj_name]['cond']:
                    f.write('if ({})\n'.format(imported[imp_proj_name]['cond']))

                # add include and lib search paths
                if imp_proj_dir != proj_dir :
                    f.write('if (EXISTS "{}/fips-include.cmake")\n'.format(imp_proj_dir))
                    f.write('    include("{}/fips-include.cmake")\n'.format(imp_proj_dir))
                    f.write('elseif (EXISTS "{}/fips-files/include.cmake")\n'.format(imp_proj_dir))
                    f.write('    include ("{}/fips-files/include.cmake")\n'.format(imp_proj_dir))
                    f.write('endif()\n')
                    f.write('if (EXISTS "{}/lib/${{FIPS_PLATFORM_NAME}}")\n'.format(imp_proj_dir))
                    f.write('    link_directories("{}/lib/${{FIPS_PLATFORM_NAME}}")\n'.format(imp_proj_dir))
                    f.write('endif()\n')

                # add header search paths
                for hdrdir in imported[imp_proj_name]['hdrdirs'] :
                    if hdrdir not in unique_hdrdirs :
                        f.write('include_directories("{}")\n'.format(hdrdir))
                        unique_hdrdirs.append(hdrdir)

                # add lib search paths
                for libdir in imported[imp_proj_name]['libdirs'] :
                    if libdir not in unique_libdirs :
                        f.write('link_directories("{}")\n'.format(libdir))
                        unique_libdirs.append(libdir)

                # add defines
                for define in imported[imp_proj_name]['defines'] :
                    value = imported[imp_proj_name]['defines'][define]
                    if define not in unique_defines :
                        unique_defines[define] = value
                        if type(value) is str :
                            f.write('add_definitions(-D{}="{}")\n'.format(define, value))
                        else :
                            f.write('add_definitions(-D{}={})\n'.format(define, value))

                # add import modules
                if len(imported[imp_proj_name]['modules']) > 0 :
                    import_functions = []

                    # first add all module import functions
                    for module in imported[imp_proj_name]['modules'] :
                        module_path = imported[imp_proj_name]['modules'][module]
                        if module not in unique_modules :
                            unique_modules[module] = module_path
                            import_func = 'fips_import_{}'.format(module_path).replace('-','_')
                            import_functions.append(import_func)
                            f.write('macro({})\n'.format(import_func))
                            f.write('    set(FIPS_IMPORT 1)\n')
                            f.write('    add_subdirectory("{}" "{}")\n'.format(module, module_path))
                            f.write('    set(FIPS_IMPORT)\n')
                            f.write('endmacro()\n')

                    # if auto-import is enabled, also actually import all modules
                    f.write('if (FIPS_AUTO_IMPORT)\n')
                    group = "Imports"
                    if imported[imp_proj_name]['group'] :
                        group += "/" + imported[imp_proj_name]['group']                        
                    if len(imported[imp_proj_name]['modules']) > 3 :
                        group += "/" + imp_proj_name
                    f.write('    fips_ide_group("{}")\n'.format(group))
                    for import_func in import_functions :
                        f.write('    {}()\n'.format(import_func))
                    f.write('    fips_ide_group("")\n')
                    f.write('endif()\n')
                
                if imported[imp_proj_name]['cond']:
                    f.write('endif()\n')

        # check content of old and new file, only replace if changed
        imports_dirty = True
        if os.path.isfile(import_filename) :
            if filecmp.cmp(import_filename, import_tmp_filename, shallow=False) :
                imports_dirty = False
        if imports_dirty :
            if os.path.isfile(import_filename) :
                os.remove(import_filename)
            os.rename(import_tmp_filename, import_filename)
        else :
            os.remove(import_tmp_filename)

    # write the .fips-imports.py file (copy from template)
    gen_search_paths  = '"{}","{}/generators",\n'.format(fips_dir, fips_dir)
    proj_gen_dir = util.get_generators_dir(proj_dir)
    if proj_gen_dir:
        gen_search_paths += '"{}","{}",\n'.format(proj_dir, proj_gen_dir)
    for imp_proj_name in imported :
        gen_dir = util.get_generators_dir(util.get_project_dir(fips_dir, imp_proj_name))
        if gen_dir:
            gen_search_paths += '"' + gen_dir + '",\n' 
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg_name); 
    if not os.path.isdir(build_dir):
        os.makedirs(build_dir)
    template.copy_template_file(fips_dir, build_dir, 'fips-gen.py', { 'genpaths': gen_search_paths}, True)
Esempio n. 34
0
def write_imports(fips_dir, proj_dir, cfg_name, imported) :
    """write the big imports map created with 'gather_imports'
    to a .fips-imports.cmake file in the current project

    :params fips_dir:   absolute path to fips
    :params proj_dir:   absolute path to current project
    :params imported:   the imports dictionary created with 'gather_imports'
    """

    if imported is not None:
        unique_hdrdirs = []
        unique_condhdrdirs = {}
        unique_libdirs = []
        unique_defines = {}
        unique_modules = {}

        # write a temporary .fips-imports.cmake.tmp file,
        # this will replace the old file, but only if the
        # content is different, this will prevent an unnecessary
        # cmake run if the imports haven't changed
        import_filename = proj_dir + '/.fips-imports.cmake'
        import_tmp_filename = import_filename + '.tmp'
        with open(import_tmp_filename, 'w') as f :
            f.write("#\n# generated by 'fips gen', don't edit, don't add to version control!\n#\n")
            
            for imp_proj_name in imported :
                imp_proj_dir = util.get_project_dir(fips_dir, imp_proj_name)
                
                if imported[imp_proj_name]['cond']:
                    f.write('if ({})\n'.format(imported[imp_proj_name]['cond']))

                # add include and lib search paths
                if imp_proj_dir != proj_dir :
                    f.write('if (EXISTS "{}/fips-include.cmake")\n'.format(imp_proj_dir))
                    f.write('    include("{}/fips-include.cmake")\n'.format(imp_proj_dir))
                    f.write('elseif (EXISTS "{}/fips-files/include.cmake")\n'.format(imp_proj_dir))
                    f.write('    include ("{}/fips-files/include.cmake")\n'.format(imp_proj_dir))
                    f.write('endif()\n')
                    f.write('if (EXISTS "{}/lib/${{FIPS_PLATFORM_NAME}}")\n'.format(imp_proj_dir))
                    f.write('    link_directories("{}/lib/${{FIPS_PLATFORM_NAME}}")\n'.format(imp_proj_dir))
                    f.write('endif()\n')

                # add header search paths
                for hdrdir in imported[imp_proj_name]['hdrdirs'] :
                    if hdrdir not in unique_hdrdirs :
                        f.write('include_directories("{}")\n'.format(hdrdir))
                        unique_hdrdirs.append(hdrdir)

                # add conditional header search paths
                for hdrdir in imported[imp_proj_name]['condhdrdirs'] :
                    value = imported[imp_proj_name]['condhdrdirs'][hdrdir]
                    if hdrdir not in unique_condhdrdirs :
                        unique_condhdrdirs[hdrdir] = value
                        f.write('if ({})\n'.format(value))
                        f.write('    include_directories("{}")\n'.format(hdrdir))
                        f.write('endif()\n')

                # add lib search paths
                for libdir in imported[imp_proj_name]['libdirs'] :
                    if libdir not in unique_libdirs :
                        f.write('link_directories("{}")\n'.format(libdir))
                        unique_libdirs.append(libdir)

                # add defines
                for define in imported[imp_proj_name]['defines'] :
                    value = imported[imp_proj_name]['defines'][define]
                    if define not in unique_defines :
                        unique_defines[define] = value
                        if type(value) is str :
                            f.write('add_definitions(-D{}="{}")\n'.format(define, value))
                        else :
                            f.write('add_definitions(-D{}={})\n'.format(define, value))

                # add import modules
                if len(imported[imp_proj_name]['modules']) > 0 :
                    import_functions = []

                    # first add all module import functions
                    for module in imported[imp_proj_name]['modules'] :
                        module_path = imported[imp_proj_name]['modules'][module]
                        if module not in unique_modules :
                            unique_modules[module] = module_path
                            import_func = 'fips_import_{}'.format(module_path).replace('-','_')
                            import_functions.append(import_func)
                            f.write('macro({})\n'.format(import_func))
                            f.write('    set(FIPS_IMPORT 1)\n')
                            f.write('    add_subdirectory("{}" "{}")\n'.format(module, module_path))
                            f.write('    set(FIPS_IMPORT)\n')
                            f.write('endmacro()\n')

                    # if auto-import is enabled, also actually import all modules
                    f.write('if (FIPS_AUTO_IMPORT)\n')
                    group = "Imports"
                    if imported[imp_proj_name]['group'] :
                        group += "/" + imported[imp_proj_name]['group']                        
                    if len(imported[imp_proj_name]['modules']) > 3 :
                        group += "/" + imp_proj_name
                    f.write('    fips_ide_group("{}")\n'.format(group))
                    for import_func in import_functions :
                        f.write('    {}()\n'.format(import_func))
                    f.write('    fips_ide_group("")\n')
                    f.write('endif()\n')
                
                if imported[imp_proj_name]['cond']:
                    f.write('endif()\n')

        # check content of old and new file, only replace if changed
        imports_dirty = True
        if os.path.isfile(import_filename) :
            if filecmp.cmp(import_filename, import_tmp_filename, shallow=False) :
                imports_dirty = False
        if imports_dirty :
            if os.path.isfile(import_filename) :
                os.remove(import_filename)
            os.rename(import_tmp_filename, import_filename)
        else :
            os.remove(import_tmp_filename)

    # write the .fips-imports.py file (copy from template)
    gen_search_paths  = '"{}","{}/generators",\n'.format(fips_dir, fips_dir)
    proj_gen_dir = util.get_generators_dir(proj_dir)
    if proj_gen_dir:
        gen_search_paths += '"{}","{}",\n'.format(proj_dir, proj_gen_dir)
    for imp_proj_name in imported :
        gen_dir = util.get_generators_dir(util.get_project_dir(fips_dir, imp_proj_name))
        if gen_dir:
            gen_search_paths += '"' + gen_dir + '",\n' 
    proj_name = util.get_project_name_from_dir(proj_dir)
    build_dir = util.get_build_dir(fips_dir, proj_name, cfg_name); 
    if not os.path.isdir(build_dir):
        os.makedirs(build_dir)
    template.copy_template_file(fips_dir, build_dir, 'fips-gen.py', { 'genpaths': gen_search_paths}, True)