def _handle_node_workspace(self, node, workspace_package, inverse_levels, deps_graph): conan_ref, conan_file = node.conan_ref, node.conanfile output = ScopedOutput("Workspace %s" % conan_ref.name, self._out) include_dirs = workspace_package.includedirs lib_dirs = workspace_package.libdirs self._call_package_info(conan_file, workspace_package.package_folder) if include_dirs: conan_file.cpp_info.includedirs = include_dirs if lib_dirs: conan_file.cpp_info.libdirs = lib_dirs # Make sure the folders exists, otherwise they will be filtered out lib_paths = [ os.path.join(conan_file.cpp_info.rootpath, p) if not os.path.isabs(p) else p for p in lib_dirs ] for p in lib_paths: mkdir(p) self._propagate_info(node, inverse_levels, deps_graph, output) build_folder = workspace_package.build_folder write_generators(conan_file, build_folder, output) save(os.path.join(build_folder, CONANINFO), conan_file.info.dumps()) output.info("Generated %s" % CONANINFO) save(os.path.join(build_folder, BUILD_INFO), TXTGenerator(conan_file).content) output.info("Generated %s" % BUILD_INFO) # Build step might need DLLs, binaries as protoc to generate source files # So execute imports() before build, storing the list of copied_files from conans.client.importer import run_imports copied_files = run_imports(conan_file, build_folder, output) report_copied_files(copied_files, output)
def _handle_node_editable(self, node, graph_info): # Get source of information package_layout = self._cache.package_layout(node.ref) base_path = package_layout.base_folder() self._call_package_info(node.conanfile, package_folder=base_path, ref=node.ref) node.conanfile.cpp_info.filter_empty = False # Try with package-provided file editable_cpp_info = package_layout.editable_cpp_info() if editable_cpp_info: editable_cpp_info.apply_to(node.ref, node.conanfile.cpp_info, settings=node.conanfile.settings, options=node.conanfile.options) build_folder = editable_cpp_info.folder(node.ref, EditableLayout.BUILD_FOLDER, settings=node.conanfile.settings, options=node.conanfile.options) if build_folder is not None: build_folder = os.path.join(base_path, build_folder) output = node.conanfile.output write_generators(node.conanfile, build_folder, output) save(os.path.join(build_folder, CONANINFO), node.conanfile.info.dumps()) output.info("Generated %s" % CONANINFO) graph_info_node = GraphInfo(graph_info.profile_host, root_ref=node.ref) graph_info_node.options = node.conanfile.options.values graph_info_node.graph_lock = graph_info.graph_lock graph_info_node.save(build_folder) output.info("Generated graphinfo") save(os.path.join(build_folder, BUILD_INFO), TXTGenerator(node.conanfile).content) output.info("Generated %s" % BUILD_INFO) # Build step might need DLLs, binaries as protoc to generate source files # So execute imports() before build, storing the list of copied_files copied_files = run_imports(node.conanfile, build_folder) report_copied_files(copied_files, output)
def run_imports(conanfile, current_path, output): file_importer = FileImporter(conanfile, current_path) conanfile.copy = file_importer conanfile.imports() copied_files = file_importer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output) return copied_files
def _report_files_from_manifest(output, manifest): copied_files = list(manifest.files()) copied_files.remove(CONANINFO) if not copied_files: output.warn("No files in this package!") return report_copied_files(copied_files, output, message_suffix="Packaged")
def _report_files_from_manifest(output, package_folder): digest = FileTreeManifest.load(package_folder) copied_files = list(digest.files()) copied_files.remove(CONANINFO) if not copied_files: output.warn("No files in this package!") return report_copied_files(copied_files, output, message_suffix="Packaged")
def _report_save_manifest(copied_files, output, dest_folder, manifest_name): report_copied_files(copied_files, output) if copied_files: date = calendar.timegm(time.gmtime()) file_dict = {} for f in copied_files: abs_path = os.path.join(dest_folder, f) file_dict[f] = md5sum(abs_path) manifest = FileTreeManifest(date, file_dict) manifest.save(dest_folder, manifest_name)
def install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, filename=None, update=False, check_updates=False, integrity=False, scopes=None, generators=None): """ Fetch and build all dependencies for the given reference @param reference: ConanFileReference or path to user space conanfile @param current_path: where the output files will be saved @param remote: install only from that remote @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...] @param settings: list of tuples: [(settingname, settingvalue), (settingname, value)...] """ generators = generators or [] objects = self._get_graph(reference, current_path, remote, options, settings, filename, update, check_updates, integrity, scopes) (_, deps_graph, _, registry, conanfile, remote_proxy, loader) = objects Printer(self._user_io.out).print_graph(deps_graph, registry) # Warn if os doesn't match try: if detected_os() != loader._settings.os: message = '''You are building this package with settings.os='%s' on a '%s' system. If this is your intention, you can ignore this message. If not: - Check the passed settings (-s) - Check your global settings in ~/.conan/conan.conf - Remove conaninfo.txt to avoid bad cached settings ''' % (loader._settings.os, detected_os()) self._user_io.out.warn(message) except ConanException: # Setting os doesn't exist pass installer = ConanInstaller(self._paths, self._user_io, remote_proxy) installer.install(deps_graph, build_mode) scope_prefix = "PROJECT" if not isinstance(reference, ConanFileReference) else str(reference) output = ScopedOutput(scope_prefix, self._user_io.out) # Write generators tmp = list(conanfile.generators) # Add the command line specified generators tmp.extend(generators) conanfile.generators = tmp write_generators(conanfile, current_path, output) if not isinstance(reference, ConanFileReference): content = normalize(conanfile.info.dumps()) save(os.path.join(current_path, CONANINFO), content) output.info("Generated %s" % CONANINFO) local_installer = FileImporter(deps_graph, self._paths, current_path) conanfile.copy = local_installer conanfile.imports() copied_files = local_installer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output)
def run_imports(conanfile, current_path, output): file_importer = FileImporter(conanfile, current_path) conanfile.copy = file_importer conanfile.imports() copied_files = file_importer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output) if copied_files: date = calendar.timegm(time.gmtime()) file_dict = {} for f in copied_files: abs_path = os.path.join(current_path, f) file_dict[f] = md5sum(abs_path) manifest = FileTreeManifest(date, file_dict) save(os.path.join(current_path, IMPORTS_MANIFESTS), str(manifest)) return copied_files
def test_output_string(self): output = TestBufferConanOutput() files = [ '/abs/path/to/file.pdf', '../rel/path/to/file2.pdf', '../rel/path/to/file3.pdf', '../rel/path/to/file4.pdf', '../rel/path/to/file5.pdf', '../rel/path/to/file6.pdf', '../rel/path/to/file7.pdf', '/without/ext/no_ext1', 'no_ext2', 'a/other.txt' ] report_copied_files(files, output) lines = sorted(str(output).splitlines()) self.assertEqual("Copied 7 '.pdf' files", lines[2]) self.assertEqual("Copied 2 files: no_ext1, no_ext2", lines[1]) self.assertEqual("Copied 1 '.txt' file: other.txt", lines[0])
def run_imports(conanfile, current_path, output): file_importer = FileImporter(conanfile, current_path) conanfile.copy = file_importer # FIXME: The environment has to be properly defined even for "conan imports" with environment_append(conanfile.env or []): conanfile.imports() copied_files = file_importer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output) if copied_files: date = calendar.timegm(time.gmtime()) file_dict = {} for f in copied_files: abs_path = os.path.join(current_path, f) file_dict[f] = md5sum(abs_path) manifest = FileTreeManifest(date, file_dict) save(os.path.join(current_path, IMPORTS_MANIFESTS), str(manifest)) return copied_files
def run_imports(conanfile, dest_folder, output): file_importer = _FileImporter(conanfile, dest_folder) conanfile.copy = file_importer conanfile.imports_folder = dest_folder with environment_append(conanfile.env): conanfile.imports() copied_files = file_importer.copied_files import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output) if copied_files: date = calendar.timegm(time.gmtime()) file_dict = {} for f in copied_files: abs_path = os.path.join(dest_folder, f) file_dict[f] = md5sum(abs_path) manifest = FileTreeManifest(date, file_dict) save(os.path.join(dest_folder, IMPORTS_MANIFESTS), str(manifest)) return copied_files
def install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, info=None, filename=None, update=False): """ Fetch and build all dependencies for the given reference @param reference: ConanFileReference or path to user space conanfile @param current_path: where the output files will be saved @param remote: install only from that remote @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...] @param settings: list of tuples: [(settingname, settingvalue), (settingname, settingvalue)...] """ reference_given = True if not isinstance(reference, ConanFileReference): conanfile_path = reference reference_given = False reference = None loader = self._loader(current_path, settings, options) # Not check for updates for info command, it'll be checked when dep graph is built check_updates = not info remote_proxy = ConanProxy(self._paths, self._user_io, self._remote_manager, remote, update, check_updates) if reference_given: project_reference = None conanfile_path = remote_proxy.get_conanfile(reference) output = ScopedOutput(str(reference), self._user_io.out) conanfile = loader.load_conan(conanfile_path, output, consumer=True) else: project_reference = "PROJECT" output = ScopedOutput(project_reference, self._user_io.out) try: if filename and filename.endswith(".txt"): raise NotFoundException() conan_file_path = os.path.join(conanfile_path, filename or CONANFILE) conanfile = loader.load_conan(conan_file_path, output, consumer=True) is_txt = False if conanfile.name is not None and conanfile.version is not None: project_reference = "%s/%s@" % (conanfile.name, conanfile.version) project_reference += "PROJECT" except NotFoundException: # Load requirements.txt conan_path = os.path.join(conanfile_path, filename or CONANFILE_TXT) conanfile = loader.load_conan_txt(conan_path, output) is_txt = True # build deps graph and install it builder = DepsBuilder(remote_proxy, self._user_io.out, loader) deps_graph = builder.load(reference, conanfile) registry = RemoteRegistry(self._paths.registry, self._user_io.out) if info: graph_updates_info = builder.get_graph_updates_info(deps_graph) Printer(self._user_io.out).print_info(deps_graph, project_reference, info, registry, graph_updates_info, remote) return Printer(self._user_io.out).print_graph(deps_graph, registry) installer = ConanInstaller(self._paths, self._user_io, remote_proxy) installer.install(deps_graph, build_mode) if not reference_given: if is_txt: conanfile.info.settings = loader._settings.values # Just in case the current package is header only, we still store the full settings # for reference and compiler checks conanfile.info.full_settings = loader._settings.values content = normalize(conanfile.info.dumps()) save(os.path.join(current_path, CONANINFO), content) output.info("Generated %s" % CONANINFO) write_generators(conanfile, current_path, output) local_installer = FileImporter(deps_graph, self._paths, current_path) conanfile.copy = local_installer conanfile.imports() copied_files = local_installer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output)
def _handle_node_editable(self, node, profile_host, profile_build, graph_lock): # Get source of information conanfile = node.conanfile ref = node.ref package_layout = self._cache.package_layout(ref) base_path = package_layout.base_folder() if hasattr(conanfile, "layout"): conanfile.folders.set_base_folders(base_path, package_layout.output_folder) else: conanfile.folders.set_base_package(base_path) conanfile.folders.set_base_source(None) conanfile.folders.set_base_build(None) conanfile.folders.set_base_install(None) self._call_package_info(conanfile, package_folder=base_path, ref=ref, is_editable=True) # New editables mechanism based on Folders if hasattr(conanfile, "layout"): output = conanfile.output output.info("Rewriting files of editable package " "'{}' at '{}'".format(conanfile.name, conanfile.generators_folder)) self._generator_manager.write_generators( conanfile, conanfile.install_folder, conanfile.generators_folder, output) write_toolchain(conanfile, conanfile.generators_folder, output) output.info("Generated toolchain") graph_info_node = GraphInfo(profile_host, root_ref=node.ref) graph_info_node.options = node.conanfile.options.values graph_info_node.graph_lock = graph_lock graph_info_node.save(base_path) output.info("Generated conan.lock") copied_files = run_imports(conanfile) report_copied_files(copied_files, output) return node.conanfile.cpp_info.filter_empty = False # OLD EDITABLE LAYOUTS: # Try with package-provided file editable_cpp_info = package_layout.editable_cpp_info() if editable_cpp_info: editable_cpp_info.apply_to(ref, conanfile.cpp_info, settings=conanfile.settings, options=conanfile.options) build_folder = editable_cpp_info.folder( ref, EditableLayout.BUILD_FOLDER, settings=conanfile.settings, options=conanfile.options) if build_folder is not None: build_folder = os.path.join(base_path, build_folder) output = conanfile.output self._generator_manager.write_generators( conanfile, build_folder, build_folder, output) write_toolchain(conanfile, build_folder, output) save(os.path.join(build_folder, CONANINFO), conanfile.info.dumps()) output.info("Generated %s" % CONANINFO) graph_info_node = GraphInfo(profile_host, root_ref=node.ref) graph_info_node.options = node.conanfile.options.values graph_info_node.graph_lock = graph_lock graph_info_node.save(build_folder) output.info("Generated graphinfo") graph_lock_file = GraphLockFile(profile_host, profile_build, graph_lock) graph_lock_file.save(os.path.join(build_folder, "conan.lock")) save(os.path.join(build_folder, BUILD_INFO), TXTGenerator(conanfile).content) output.info("Generated %s" % BUILD_INFO) # Build step might need DLLs, binaries as protoc to generate source files # So execute imports() before build, storing the list of copied_files conanfile.folders.set_base_imports(build_folder) copied_files = run_imports(conanfile) report_copied_files(copied_files, output)
def _build_package(self, export_folder, src_folder, build_folder, package_folder, conan_file, output): """ builds the package, creating the corresponding build folder if necessary and copying there the contents from the src folder. The code is duplicated in every build, as some configure processes actually change the source code """ output.info('Building your package in %s' % build_folder) if not build_exists(build_folder): config_source(export_folder, src_folder, conan_file, output) output.info('Copying sources to build folder') def check_max_path_len(src, files): if platform.system() != "Windows": return [] filtered_files = [] for the_file in files: source_path = os.path.join(src, the_file) # Without storage path, just relative rel_path = os.path.relpath(source_path, src_folder) dest_path = os.path.normpath(os.path.join(build_folder, rel_path)) # it is NOT that "/" is counted as "\\" so it counts double # seems a bug in python, overflows paths near the limit of 260, if len(dest_path) >= 249: filtered_files.append(the_file) output.warn("Filename too long, file excluded: %s" % dest_path) return filtered_files shutil.copytree(src_folder, build_folder, symlinks=True, ignore=check_max_path_len) os.chdir(build_folder) conan_file._conanfile_directory = build_folder # Read generators from conanfile and generate the needed files write_generators(conan_file, build_folder, output) # Build step might need DLLs, binaries as protoc to generate source files # So execute imports() before build, storing the list of copied_files from conans.client.importer import FileImporter local_installer = FileImporter(self._deps_graph, self._paths, build_folder) conan_file.copy = local_installer conan_file.imports() copied_files = local_installer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output) try: # This is necessary because it is different for user projects # than for packages conan_file._conanfile_directory = build_folder conan_file.build() self._out.writeln("") output.success("Package '%s' built" % conan_file.info.package_id()) output.info("Build folder %s" % build_folder) except Exception as e: os.chdir(src_folder) self._out.writeln("") output.error("Package '%s' build failed" % conan_file.info.package_id()) output.warn("Build folder %s" % build_folder) raise ConanException("%s: %s" % (conan_file.name, str(e))) finally: conan_file._conanfile_directory = export_folder # Now remove all files that were imported with imports() for f in copied_files: try: if(f.startswith(build_folder)): os.remove(f) except Exception: self._out.warn("Unable to remove imported file from build: %s" % f)
def install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, info=None, filename=None, update=False): """ Fetch and build all dependencies for the given reference @param reference: ConanFileReference or path to user space conanfile @param current_path: where the output files will be saved @param remote: install only from that remote @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...] @param settings: list of tuples: [(settingname, settingvalue), (settingname, value)...] """ reference_given = True if not isinstance(reference, ConanFileReference): conanfile_path = reference reference_given = False reference = None loader = self._loader(current_path, settings, options) # Not check for updates for info command, it'll be checked when dep graph is built check_updates = not info remote_proxy = ConanProxy(self._paths, self._user_io, self._remote_manager, remote, update, check_updates) if reference_given: project_reference = None conanfile_path = remote_proxy.get_conanfile(reference) output = ScopedOutput(str(reference), self._user_io.out) conanfile = loader.load_conan(conanfile_path, output, consumer=True) else: project_reference = "PROJECT" output = ScopedOutput(project_reference, self._user_io.out) try: if filename and filename.endswith(".txt"): raise NotFoundException("") conan_file_path = os.path.join(conanfile_path, filename or CONANFILE) conanfile = loader.load_conan(conan_file_path, output, consumer=True) is_txt = False if conanfile.name is not None and conanfile.version is not None: project_reference = "%s/%s@" % (conanfile.name, conanfile.version) project_reference += "PROJECT" except NotFoundException: # Load requirements.txt conan_path = os.path.join(conanfile_path, filename or CONANFILE_TXT) conanfile = loader.load_conan_txt(conan_path, output) is_txt = True # build deps graph and install it builder = DepsBuilder(remote_proxy, self._user_io.out, loader) deps_graph = builder.load(reference, conanfile) registry = RemoteRegistry(self._paths.registry, self._user_io.out) if info: graph_updates_info = builder.get_graph_updates_info(deps_graph) Printer(self._user_io.out).print_info(deps_graph, project_reference, info, registry, graph_updates_info, remote) return Printer(self._user_io.out).print_graph(deps_graph, registry) installer = ConanInstaller(self._paths, self._user_io, remote_proxy) installer.install(deps_graph, build_mode) if not reference_given: if is_txt: conanfile.info.settings = loader._settings.values # Just in case the current package is header only, we still store the full settings # for reference and compiler checks conanfile.info.full_settings = loader._settings.values content = normalize(conanfile.info.dumps()) save(os.path.join(current_path, CONANINFO), content) output.info("Generated %s" % CONANINFO) write_generators(conanfile, current_path, output) local_installer = FileImporter(deps_graph, self._paths, current_path) conanfile.copy = local_installer conanfile.imports() copied_files = local_installer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output)
def install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, info=None, filename=None, update=False, check_updates=False, integrity=False, scopes=None): """ Fetch and build all dependencies for the given reference @param reference: ConanFileReference or path to user space conanfile @param current_path: where the output files will be saved @param remote: install only from that remote @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...] @param settings: list of tuples: [(settingname, settingvalue), (settingname, value)...] """ reference_given = True if not isinstance(reference, ConanFileReference): conanfile_path = reference reference_given = False reference = None loader = self._loader(current_path, settings, options, scopes) # Not check for updates for info command, it'll be checked when dep graph is built remote_proxy = ConanProxy(self._paths, self._user_io, self._remote_manager, remote, update=update, check_updates=check_updates, check_integrity=integrity) if reference_given: project_reference = None conanfile_path = remote_proxy.get_conanfile(reference) output = ScopedOutput(str(reference), self._user_io.out) conanfile = loader.load_conan(conanfile_path, output, consumer=True) else: project_reference = "PROJECT" output = ScopedOutput(project_reference, self._user_io.out) try: if filename and filename.endswith(".txt"): raise NotFoundException("") conan_file_path = os.path.join(conanfile_path, filename or CONANFILE) conanfile = loader.load_conan(conan_file_path, output, consumer=True) is_txt = False if conanfile.name is not None and conanfile.version is not None: project_reference = "%s/%s@" % (conanfile.name, conanfile.version) project_reference += "PROJECT" except NotFoundException: # Load requirements.txt conan_path = os.path.join(conanfile_path, filename or CONANFILE_TXT) conanfile = loader.load_conan_txt(conan_path, output) is_txt = True # build deps graph and install it builder = DepsBuilder(remote_proxy, self._user_io.out, loader) deps_graph = builder.load(reference, conanfile) registry = RemoteRegistry(self._paths.registry, self._user_io.out) if info: if check_updates: graph_updates_info = builder.get_graph_updates_info(deps_graph) else: graph_updates_info = {} Printer(self._user_io.out).print_info(deps_graph, project_reference, info, registry, graph_updates_info, remote) return Printer(self._user_io.out).print_graph(deps_graph, registry) # Warn if os doesn't match try: if detected_os() != conanfile.settings.os: message = '''You are building this package with settings.os='%s' on a '%s' system. If this is your intention, you can ignore this message. If not: - Check the passed settings (-s) - Check your global settings in ~/.conan/conan.conf - Remove conaninfo.txt to avoid bad cached settings ''' % (conanfile.settings.os, detected_os()) self._user_io.out.warn(message) except ConanException: # Setting os doesn't exist pass installer = ConanInstaller(self._paths, self._user_io, remote_proxy) installer.install(deps_graph, build_mode) if not reference_given: if is_txt: conanfile.info.settings = loader._settings.values # Just in case the current package is header only, we still store the full settings # for reference and compiler checks conanfile.info.full_settings = loader._settings.values conanfile.info.scope = self._current_scopes content = normalize(conanfile.info.dumps()) save(os.path.join(current_path, CONANINFO), content) output.info("Generated %s" % CONANINFO) write_generators(conanfile, current_path, output) local_installer = FileImporter(deps_graph, self._paths, current_path) conanfile.copy = local_installer conanfile.imports() copied_files = local_installer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output)
def _build_package(self, export_folder, src_folder, build_folder, conan_file, output): """ builds the package, creating the corresponding build folder if necessary and copying there the contents from the src folder. The code is duplicated in every build, as some configure processes actually change the source code """ output.info('Building your package in %s' % build_folder) config_source(export_folder, src_folder, conan_file, output) output.info('Copying sources to build folder') def check_max_path_len(src, files): if platform.system() != "Windows": return [] filtered_files = [] for the_file in files: source_path = os.path.join(src, the_file) # Without storage path, just relative rel_path = os.path.relpath(source_path, src_folder) dest_path = os.path.normpath( os.path.join(build_folder, rel_path)) # it is NOT that "/" is counted as "\\" so it counts double # seems a bug in python, overflows paths near the limit of 260, if len(dest_path) >= 249: filtered_files.append(the_file) output.warn("Filename too long, file excluded: %s" % dest_path) return filtered_files shutil.copytree(src_folder, build_folder, symlinks=True, ignore=check_max_path_len) logger.debug("Copied to %s" % build_folder) logger.debug("Files copied %s" % os.listdir(build_folder)) os.chdir(build_folder) conan_file._conanfile_directory = build_folder # Read generators from conanfile and generate the needed files logger.debug("Writing generators") write_generators(conan_file, build_folder, output) logger.debug("Files copied after generators %s" % os.listdir(build_folder)) # Build step might need DLLs, binaries as protoc to generate source files # So execute imports() before build, storing the list of copied_files from conans.client.importer import FileImporter local_installer = FileImporter(self._deps_graph, self._client_cache, build_folder) conan_file.copy = local_installer conan_file.imports() copied_files = local_installer.execute() import_output = ScopedOutput("%s imports()" % output.scope, output) report_copied_files(copied_files, import_output) try: # This is necessary because it is different for user projects # than for packages conan_file._conanfile_directory = build_folder logger.debug( "Call conanfile.build() with files in build folder: %s" % os.listdir(build_folder)) conan_file.build() self._out.writeln("") output.success("Package '%s' built" % conan_file.info.package_id()) output.info("Build folder %s" % build_folder) except Exception as e: os.chdir(src_folder) self._out.writeln("") output.error("Package '%s' build failed" % conan_file.info.package_id()) output.warn("Build folder %s" % build_folder) raise ConanException("%s: %s" % (conan_file.name, str(e))) finally: conan_file._conanfile_directory = export_folder # Now remove all files that were imported with imports() for f in copied_files: try: if (f.startswith(build_folder)): os.remove(f) except Exception: self._out.warn( "Unable to remove imported file from build: %s" % f)