RED = '\033[1;31m'
GREEN = '\033[1;32m'
YELLOW = '\033[1;33m'
BLUE = '\033[1;36m'
DEF = '\033[0;0m'
def error(msg, fatal=True) :
def warn(msg) :
def ok(item, status) :
def failed(item, status) :
def optional(item, status) :
def info(msg) :
def colored(color, msg) : def fix_path(path) :
def get_workspace_dir(fips_dir) :
def get_project_dir(fips_dir, proj_name) :
def get_build_root_dir(fips_dir, proj_name):
def get_deploy_root_dir(fips_dir, proj_name):
def get_build_dir(fips_dir, proj_name, cfg) :
def get_deploy_dir(fips_dir, proj_name, cfg) :
def get_fips_dir(proj_dir, name):
def get_configs_dir(proj_dir):
def get_verbs_dir(proj_dir):
def get_generators_dir(proj_dir):
def get_toolchains_dir(proj_dir):
def get_giturl_from_url(url) :
def get_gitbranch_from_url(url) :
def get_project_name_from_url(url) :
def get_project_name_from_dir(proj_dir) :
def load_fips_yml(proj_dir) :
def lookup_target_cwd(proj_dir, target) :
def is_valid_project_dir(proj_dir) :
def ensure_valid_project_dir(proj_dir) :
def is_git_url(url) :
def confirm(question) :
def url_download_hook(count, block_size, total_size) :
def get_host_platform() :
def get_cfg_target_list(fips_dir, proj_dir, cfg):
def get_cfg_headersdirs_by_target(fips_dir, proj_dir, cfg):
def get_cfg_defines_by_target(fips_dir, proj_dir, cfg):
def get_num_cpucores(): def get_imports(fips_dir, proj_dir) :
def get_exports(proj_dir) :
def get_policy(proj_dir, policy) :
def _rec_get_all_imports_exports(fips_dir, proj_dir, result) :
def get_all_imports_exports(fips_dir, proj_dir) :
def _rec_fetch_imports(fips_dir, proj_dir, handled) :
def fetch_imports(fips_dir, proj_dir) :
def gather_imports(fips_dir, proj_dir) :
def write_imports(fips_dir, proj_dir, cfg_name, imported) :
def gather_and_write_imports(fips_dir, proj_dir, cfg_name) :
def check_imports(fips_dir, proj_dir) :
def check_local_changes(fips_dir, proj_dir) :
def _rec_update_imports(fips_dir, proj_dir, handled) :
def update_imports(fips_dir, proj_dir): def check_exists(fips_dir, major=2, minor=8) :
def run_gen(cfg, fips_dir, project_dir, build_dir, local_build, toolchain_path, defines) :
def run_build(fips_dir, target, build_type, build_dir, num_jobs=1, args=None) :
def run_clean(fips_dir, build_dir) : def check_exists(fips_dir) :
def match(build_tool):
def run_build(fips_dir, target, build_dir, num_jobs=1, args=None) :
def run_clean(fips_dir, build_dir) : def get_ninja_name() :
def get_ninja_tool(fips_dir) :
def check_exists(fips_dir) :
def match(build_tool):
def run_build(fips_dir, target, build_dir, num_jobs=1, args=None) :
def run_clean(fips_dir, build_dir) : def check_exists(fips_dir) :
def match(build_tool):
def run_build(fips_dir, target, build_type, build_dir, num_jobs=1, args=None) :
def run_clean(fips_dir, build_dir) : def try_exists(exe_name):
def exe_name():
def check_exists(fips_dir) :
def match(build_tool):
def run(proj_dir):
def read_cmake_targets(fips_dir, proj_dir, cfg, types):
def read_cmake_headerdirs(fips_dir, proj_dir, cfg):
def read_cmake_defines(fips_dir, proj_dir, cfg):
def problem_matcher():
def get_cc_header_paths():
def get_vs_header_paths(fips_dir, proj_dir, cfg):
def list_extensions() :
def write_tasks_json(fips_dir, proj_dir, vscode_dir, cfg):
def write_launch_json(fips_dir, proj_dir, vscode_dir, cfg, proj_settings):
def write_c_cpp_properties_json(fips_dir, proj_dir, impex, cfg):
def write_cmake_tools_settings(fips_dir, proj_dir, vscode_dir, cfg):
def write_code_workspace_file(fips_dir, proj_dir, impex, cfg):
def remove_vscode_tasks_launch_files(fips_dir, proj_dir, impex, cfg):
def write_workspace_settings(fips_dir, proj_dir, cfg, proj_settings):
def cleanup(fips_dir, proj_dir): def check_exists(fips_dir) :
def match(build_tool):
def run(proj_dir):
def write_clion_module_files(fips_dir, proj_dir, cfg):
def write_clion_workspace_file(fips_dir, proj_dir, cfg):
def write_workspace_settings(fips_dir, proj_dir, cfg):
def cleanup(fips_dir, proj_dir): EMSDK_URL = "https://github.com/emscripten-core/emsdk.git"
EMSDK_DEFAULT_VERSION = 'latest'
def remove_readonly(func, path, _):
def get_sdkroot_dir(fips_dir):
def sdkroot_exists(fips_dir):
def make_dirs(fips_dir):
def get_emsdk_dir(fips_dir):
def emsdk_dir_exists(fips_dir):
def get_emsdk_path(fips_dir):
def check_exists(fips_dir):
def get_em_config(fips_dir):
def run(fips_dir, cmdline):
def clone_or_update_emsdk(fips_dir):
def list(fips_dir):
def activate(fips_dir, emsdk_version):
def install(fips_dir, emsdk_version):
def remove_old_sdks(fips_dir):
def uninstall(fips_dir):
def parse_config(fips_dir):
def show_config(fips_dir):
def get_emscripten_root(fips_dir): def get_sdk_dir(fips_dir) :
def check_exists(fips_dir) :
def get_adb_path(fips_dir):
def get_tools_url() :
def get_tools_archive_path(fips_dir):
def target_to_package_name(target):
def install_package(fips_dir, pkg):
def ensure_sdk_dirs(fips_dir) :
def uncompress(fips_dir, path) :
def compute_sha256(path, converter=lambda x: x, chunk_size=65536) :
def strip_whitespace(bin_str) :
def setup(fips_dir) :
import os.path
import glob
import yaml
from collections import OrderedDict
from mod import log, util, dep
from mod.tools import cmake, make, ninja, xcodebuild, vscode, clion
from mod import emsdk, android
            # try the fips directory
            toolchain_path = '{}/cmake-toolchains/{}'.format(fips_dir, toolchain)
            if os.path.isfile(toolchain_path) :
                return toolchain_path
    # fallthrough: no toolchain file found
    return None

#-------------------------------------------------------------------------------
def exists(pattern, proj_dirs) : 
    """test if at least one matching config exists

    :param pattern:     config name pattern (e.g. 'linux-make-*')
    :param proj_dir:    array of toplevel dirs to search (must have /configs subdir)
    :returns:           True if at least one matching config exists
    """
    for curDir in proj_dirs :
        if len(glob.glob('{}/configs/{}.yml'.format(curDir, pattern))) > 0 :
            return True
    return False

#-------------------------------------------------------------------------------
def get_config_dirs(fips_dir, proj_dir) :
    """return list of config directories, including all imports

    :param fips_dir: absolute fips directory
    :param proj_dir: absolute project directory
    :returns:        list of all directories with config files
    """
    dirs = []
    if fips_dir != proj_dir :
        success, result = dep.get_all_imports_exports(fips_dir, proj_dir)
        if success :
            for dep_proj_name in result :
                dep_proj_dir = result[dep_proj_name]['proj_dir']
                dep_configs_dir = util.get_configs_dir(dep_proj_dir)
                if dep_configs_dir:
                    dirs.append(dep_configs_dir)
        else :
            log.warn("missing import directories, please run 'fips fetch'")
    dirs.append(fips_dir + '/configs')
    return dirs

#-------------------------------------------------------------------------------
def list(fips_dir, proj_dir, pattern) :
    """return { dir : [cfgname, ...] } in fips_dir/configs and
    proj_dir/fips-files/configs

    :param fips_dir:    absolute fips directory
    :param proj_dir:    absolute project directory
    :param pattern:     global pattern for config-name(s)
    :returns:           a map of matching configs per dir
    """
    dirs = get_config_dirs(fips_dir, proj_dir)
    res = OrderedDict()
    for curDir in dirs :
        res[curDir] = []
        paths = glob.glob('{}/*.yml'.format(curDir))
        for path in paths :
            fname = os.path.split(path)[1]
            fname = os.path.splitext(fname)[0]
            res[curDir].append(fname)
        res[curDir].sort()
    return res

#-------------------------------------------------------------------------------
def load(fips_dir, proj_dir, pattern) :
    """load one or more matching configs from fips and current project dir

    :param fips_dir:    absolute fips directory
    :param proj_dir:    absolute project directory
    :param pattern:     config name pattern (e.g. 'linux-make-*')
    :returns:   an array of loaded config objects
    """
    dirs = get_config_dirs(fips_dir, proj_dir)
    configs = []
    for curDir in dirs :
        paths = glob.glob('{}/{}.yml'.format(curDir, pattern))
        for path in paths :
            try :
                with open(path, 'r') as f :
                    cfg = yaml.load(f)
                folder, fname = os.path.split(path)

                # patch path, folder, and name
                cfg['path'] = path
                cfg['folder'] = folder
                cfg['name'] = os.path.splitext(fname)[0]
                if 'generator' not in cfg :
                    cfg['generator'] = 'Default'
                if 'generator-platform' not in cfg :
                    cfg['generator-platform'] = None
                if 'generator-toolset' not in cfg :
                    cfg['generator-toolset'] = None
                if 'defines' not in cfg :
                    cfg['defines'] = None

                # don't append multiple configs with the same name
                for c in configs:
                    if c['name'] == cfg['name']:
                        break
                else:
                    configs.append(cfg)
            except yaml.error.YAMLError as e:
                log.error('YML parse error: {}', e.message)
    return configs

#-------------------------------------------------------------------------------
def missing_build_tools(fips_dir, tool_name) :
    """check if a build tool is installed"""
    missing = []
    if tool_name == 'cmake' :
        if not cmake.check_exists(fips_dir):
            missing.append(cmake.name)
    elif tool_name == 'make' :
        if not make.check_exists(fips_dir):
            missing.append(make.name)
    elif tool_name == 'ninja' :
        if not ninja.check_exists(fips_dir):
            missing.append(ninja.name)
    elif tool_name == 'xcodebuild' :

        if not xcodebuild.check_exists(fips_dir):