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))
def gdb(fips_dir, proj_dir, cfg_name, target=None, target_args=None): """debug a single target with gdb""" # prepare proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) # load the config(s) configs = config.load(fips_dir, proj_dir, cfg_name) 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: deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name']) log.colored(log.YELLOW, "=== gdb: {}".format(cfg['name'])) cmdLine = ['gdb', "-ex", "run", "--args", target] if target_args: cmdLine.extend(target_args) try: subprocess.call(args=cmdLine, cwd=deploy_dir) except OSError: log.error("Failed to execute gdb (not installed?)") else: log.error("Config '{}' not valid in this environment".format( cfg['name'])) else: log.error("No valid configs found for '{}'".format(cfg_name)) return True
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))
def gdb(fips_dir, proj_dir, cfg_name, target=None, target_args=None) : """debug a single target with gdb""" # prepare proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) # load the config(s) configs = config.load(fips_dir, proj_dir, cfg_name) 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 : deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name']) log.colored(log.YELLOW, "=== gdb: {}".format(cfg['name'])) cmdLine = ['gdb', "-ex", "run", "--args", target] if target_args : cmdLine.extend(target_args) try: subprocess.call(args = cmdLine, cwd = deploy_dir) except OSError : log.error("Failed to execute gdb (not installed?)") else : log.error("Config '{}' not valid in this environment".format(cfg['name'])) else : log.error("No valid configs found for '{}'".format(cfg_name)) return True
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
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
def get_all_settings(proj_dir): """return a dictionary with all setting key/value pairs :returns: dictionary with all settings key/value pairs """ util.ensure_valid_project_dir(proj_dir) settings = load(proj_dir) for key in default_settings: if key not in settings: settings[key] = default_settings[key] return settings
def unset(proj_dir, key) : """delete a settings value from the project-local settings file :param proj_dir: absolute project directory :param key: settings key """ util.ensure_valid_project_dir(proj_dir) settings = load(proj_dir) if key in settings : del settings[key] save(proj_dir, settings) proj_name = util.get_project_name_from_dir(proj_dir) log.info("'{}' unset in project '{}'".format(key, proj_name))
def gen(fips_dir, proj_dir, cfg_name) : """generate build files with cmake :param fips_dir: absolute path to fips :param proj_dir: absolute path to project :param cfg_name: config name or pattern (e.g. osx-make-debug) :returns: True if 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) fips_yml_defines = dep.get_fips_yml_defines(proj_dir) num_valid_configs = 0 if configs : for cfg in configs : # Merge fips.yml defines into config defines if fips_yml_defines: if 'defines' in cfg and cfg['defines']: cfg['defines'].update(fips_yml_defines) else: cfg['defines'] = fips_yml_defines # check if config is valid config_valid, _ = config.check_config_valid(fips_dir, proj_dir, cfg, print_errors = True) if config_valid : if gen_project(fips_dir, proj_dir, cfg, True) : num_valid_configs += 1 else : log.error("failed to generate build files for config '{}'".format(cfg['name']), False) else : log.error("'{}' is not a valid config".format(cfg['name']), False) else : log.error("No 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 generated'.format(num_valid_configs)) return True
def valgrind(fips_dir, proj_dir, cfg_name, target, target_args): """debug a single target with valgrind""" # prepare proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) # load the config(s) configs = config.load(fips_dir, proj_dir, cfg_name) 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: deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name']) valgrind_bin = settings.get(proj_dir, 'valgrind') if not valgrind_bin: valgrind_bin = 'valgrind' log.colored( log.YELLOW, "=== valgrind: {} ({})".format(cfg['name'], valgrind_bin)) cmd_line = valgrind_bin if target_args: cmd_line += ' ' + ' '.join(target_args) else: cmd_line += ' ' + '--leak-check=no' cmd_line += ' ' + '--show-reachable=yes' cmd_line += ' ' + '--track-fds=yes' cmd_line += ' ' + '--run-libc-freeres=no' cmd_line += ' ' + "--log-file={}/valgrind-{}.log".format( proj_dir, target) cmd_line += ' ' + "./{}".format(target) #log.colored(log.GREEN, "cmdline: {}".format(cmd_line)) subprocess.call(args=cmd_line, cwd=deploy_dir, shell=True) else: log.error("Config '{}' not valid in this environment".format( cfg['name'])) else: log.error("No valid configs found for '{}'".format(cfg_name)) return True
def get(proj_dir, key) : """return settings value by key, default value if the value doesn't exist in the project-local settings file :param proj_dir: absolute project directory :param key: settings key :returns: settings value, default value for key, or None """ util.ensure_valid_project_dir(proj_dir) value = None settings = load(proj_dir) if key in settings : value = settings[key] if value is None : value = get_default(key) return value
def build_deploy_webpage(fips_dir, proj_dir, chip): ws_dir = util.get_workspace_dir(fips_dir) webpage_dir = '{}/fips-deploy/{}-webpage'.format(ws_dir, chip) if not os.path.isdir(webpage_dir): os.makedirs(webpage_dir) project.gen(fips_dir, proj_dir, BuildConfig) project.build(fips_dir, proj_dir, BuildConfig) proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) src_dir = '{}/fips-deploy/NextSim/{}'.format(ws_dir, BuildConfig) dst_dir = webpage_dir #This area can be cleaned up sometime ns = "NextSim" shutil.copy(src_dir + '/' + ns + '.html', dst_dir + '/index.html') shutil.copy(src_dir + '/' + ns + '.wasm', dst_dir + '/' + ns + '.wasm') shutil.copy(src_dir + '/' + ns + '.js', dst_dir + '/' + ns + '.js') shutil.copy(proj_dir + '/src/res/favicon.png', dst_dir + '/favicon.png') log.colored(log.GREEN, 'Generated Samples web page under {}.'.format(webpage_dir))
def set(proj_dir, key, value) : """update a settings value by key and save project-local .fips-settings file :param proj_dir: absolute project directory :param key: settings key :param value: new value associated with key """ util.ensure_valid_project_dir(proj_dir) settings = load(proj_dir) settings[key] = value save(proj_dir, settings) proj_name = util.get_project_name_from_dir(proj_dir) if type(value) is bool : value_str = 'on' if value else 'off'; else : value_str = str(value) log.info("'{}' set to '{}' in project '{}'".format(key, value_str, proj_name))
def set(proj_dir, key, value) : """update a settings value by key and save project-local .fips-settings file :param proj_dir: absolute project directory :param key: settings key :param value: new value associated with key """ util.ensure_valid_project_dir(proj_dir) settings = load(proj_dir) settings[key] = value save(proj_dir, settings) proj_name = util.get_project_name_from_dir(proj_dir) if type(value) is bool : value_str = 'on' if value else 'off' else : value_str = str(value) log.info("'{}' set to '{}' in project '{}'".format(key, value_str, proj_name))
def gen(fips_dir, proj_dir, cfg_name) : """generate build files with cmake :param fips_dir: absolute path to fips :param proj_dir: absolute path to project :param cfg_name: config name or pattern (e.g. osx-make-debug) :returns: True if 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 : if gen_project(fips_dir, proj_dir, cfg, True) : num_valid_configs += 1 else : log.error("failed to generate build files for config '{}'".format(cfg['name']), False) else : log.error("'{}' is not a valid config".format(cfg['name']), False) else : log.error("No 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 generated'.format(num_valid_configs)) return True
def valgrind(fips_dir, proj_dir, cfg_name, target, target_args) : """debug a single target with valgrind""" # prepare proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) # load the config(s) configs = config.load(fips_dir, proj_dir, cfg_name) 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 : deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name']) valgrind_bin = settings.get(proj_dir, 'valgrind') if not valgrind_bin : valgrind_bin = 'valgrind' log.colored(log.YELLOW, "=== valgrind: {} ({})".format(cfg['name'], valgrind_bin)) cmd_line = valgrind_bin if target_args : cmd_line += ' ' + ' '.join(target_args) else : cmd_line += ' ' + '--leak-check=no' cmd_line += ' ' + '--show-reachable=yes' cmd_line += ' ' + '--track-fds=yes' cmd_line += ' ' + '--run-libc-freeres=no' cmd_line += ' ' + "--log-file={}/valgrind-{}.log".format(proj_dir, target) cmd_line += ' ' + "./{}".format(target) #log.colored(log.GREEN, "cmdline: {}".format(cmd_line)) subprocess.call(args = cmd_line, cwd = deploy_dir, shell = True) else : log.error("Config '{}' not valid in this environment".format(cfg['name'])) else : log.error("No valid configs found for '{}'".format(cfg_name)) return True
def run(fips_dir, proj_dir, cfg_name, target_name, target_args, target_cwd): """run a build target executable :param fips_dir: absolute path of fips :param proj_dir: absolute path of project dir :param cfg_name: config name or pattern :param target_name: the target name :param target_args: command line arguments for build target :param target_cwd: working directory or None """ retcode = 10 proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) # load the config(s) configs = config.load(fips_dir, proj_dir, cfg_name) if configs: for cfg in configs: log.colored( log.YELLOW, "=== run '{}' (config: {}, project: {}):".format( target_name, cfg['name'], proj_name)) # find deploy dir where executables live deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg['name']) if not target_cwd: target_cwd = deploy_dir if cfg['platform'] == 'emscripten': # special case: emscripten app html_name = target_name + '.html' if util.get_host_platform() == 'osx': try: subprocess.call( 'open http://localhost:8080/{} ; http-server -c-1 -g' .format(html_name), cwd=target_cwd, shell=True) except KeyboardInterrupt: return 0 elif util.get_host_platform() == 'win': try: cmd = 'cmd /c start http://localhost:8080/{} && http-server -c-1 -g'.format( html_name) subprocess.call(cmd, cwd=target_cwd, shell=True) except KeyboardInterrupt: return 0 elif util.get_host_platform() == 'linux': try: subprocess.call( 'xdg-open http://localhost:8080/{}; http-server -c-1 -g' .format(html_name), cwd=target_cwd, shell=True) except KeyboardInterrupt: return 0 else: log.error( "don't know how to start HTML app on this platform") elif cfg['platform'] == 'android': try: adb_path = android.get_adb_path(fips_dir) pkg_name = android.target_to_package_name(target_name) # Android: first re-install the apk... cmd = '{} install -r {}.apk'.format(adb_path, target_name) subprocess.call(cmd, shell=True, cwd=deploy_dir) # ...then start the apk cmd = '{} shell am start -n {}/android.app.NativeActivity'.format( adb_path, pkg_name) subprocess.call(cmd, shell=True) # ...then run adb logcat cmd = '{} logcat'.format(adb_path) subprocess.call(cmd, shell=True) return 0 except KeyboardInterrupt: return 0 elif os.path.isdir('{}/{}.app'.format(deploy_dir, target_name)): # special case: Mac app cmd_line = '{}/{}.app/Contents/MacOS/{}'.format( deploy_dir, target_name, target_name) else: cmd_line = '{}/{}'.format(deploy_dir, target_name) if cmd_line: if target_args: cmd_line += ' ' + ' '.join(target_args) try: retcode = subprocess.call(args=cmd_line, cwd=target_cwd, shell=True) except OSError as e: log.error("Failed to execute '{}' with '{}'".format( target_name, e.strerror)) else: log.error("No valid configs found for '{}'".format(cfg_name)) return retcode
def run(fips_dir, proj_dir, cfg_name, target_name, target_args, target_cwd) : """run a build target executable :param fips_dir: absolute path of fips :param proj_dir: absolute path of project dir :param cfg_name: config name or pattern :param target_name: the target name :param target_args: command line arguments for build target :param target_cwd: working directory or None """ retcode = 10 proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) # load the config(s) configs = config.load(fips_dir, proj_dir, cfg_name) if configs : for cfg in configs : log.colored(log.YELLOW, "=== run '{}' (config: {}, project: {}):".format(target_name, cfg['name'], proj_name)) # find deploy dir where executables live deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg) if not target_cwd : target_cwd = deploy_dir if cfg['platform'] in ['emscripten', 'pnacl'] : # special case: emscripten app if cfg['platform'] == 'emscripten' : html_name = target_name + '.html' else : html_name = target_name + '_pnacl.html' if util.get_host_platform() == 'osx' : try : subprocess.call( 'open http://localhost:8000/{} ; python {}/mod/httpserver.py'.format(html_name, fips_dir), cwd = target_cwd, shell=True) except KeyboardInterrupt : return 0 elif util.get_host_platform() == 'win' : try : cmd = 'cmd /c start http://localhost:8000/{} && python {}/mod/httpserver.py'.format(html_name, fips_dir) subprocess.call(cmd, cwd = target_cwd, shell=True) except KeyboardInterrupt : return 0 elif util.get_host_platform() == 'linux' : try : subprocess.call( 'xdg-open http://localhost:8000/{}; python {}/mod/httpserver.py'.format(html_name, fips_dir), cwd = target_cwd, shell=True) except KeyboardInterrupt : return 0 else : log.error("don't know how to start HTML app on this platform") elif os.path.isdir('{}/{}.app'.format(deploy_dir, target_name)) : # special case: Mac app cmd_line = '{}/{}.app/Contents/MacOS/{}'.format(deploy_dir, target_name, target_name) else : cmd_line = '{}/{}'.format(deploy_dir, target_name) if cmd_line : if target_args : cmd_line += ' ' + ' '.join(target_args) try: retcode = subprocess.call(args=cmd_line, cwd=target_cwd, shell=True) except OSError, e: log.error("Failed to execute '{}' with '{}'".format(target_name, e.strerror))
def run(fips_dir, proj_dir, cfg_name, target_name, target_args): """run a build target executable :param fips_dir: absolute path of fips :param proj_dir: absolute path of project dir :param cfg_name: config name or pattern :param target_name: the target name :param target_args: command line arguments for build target """ proj_name = util.get_project_name_from_dir(proj_dir) util.ensure_valid_project_dir(proj_dir) # load the config(s) configs = config.load(fips_dir, proj_dir, cfg_name) if configs: for cfg in configs: log.colored( log.YELLOW, "=== run '{}' (config: {}, project: {}):".format( target_name, cfg['name'], proj_name)) # find deploy dir where executables live deploy_dir = util.get_deploy_dir(fips_dir, proj_name, cfg) cmd_line = [] if cfg['platform'] in ['emscripten', 'pnacl']: # special case: emscripten app if cfg['platform'] == 'emscripten': html_name = target_name + '.html' else: html_name = target_name + '_pnacl.html' if util.get_host_platform() == 'osx': try: subprocess.call([ 'open http://localhost:8000/{} ; python {}/mod/httpserver.py' .format(html_name, fips_dir) ], cwd=deploy_dir, shell=True) except KeyboardInterrupt: pass elif util.get_host_platform() == 'win': try: cmd = [ 'cmd /c start http://localhost:8000/{} && python {}/mod/httpserver.py' .format(html_name, fips_dir) ] subprocess.call(cmd, cwd=deploy_dir, shell=True) except KeyboardInterrupt: pass elif util.get_host_platform() == 'linux': try: subprocess.call([ 'xdg-open http://localhost:8000/{}; python {}/mod/httpserver.py' .format(html_name, fips_dir) ], cwd=deploy_dir, shell=True) except KeyboardInterrupt: pass else: log.error( "don't know how to start HTML app on this platform") elif os.path.isdir('{}/{}.app'.format(deploy_dir, target_name)): # special case: Mac app cmd_line = [ 'open', '{}/{}.app'.format(deploy_dir, target_name) ] if target_args: cmd_line.append('--args') else: cmd_line = ['{}/{}'.format(deploy_dir, target_name)] if cmd_line: if target_args: cmd_line.extend(target_args) try: subprocess.call(args=cmd_line, cwd=deploy_dir) except OSError, e: log.error("Failed to execute '{}' with '{}'".format( target_name, e.strerror))