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 _build(self, conanfile, pref, build_folder): # Read generators from conanfile and generate the needed files logger.info("GENERATORS: Writing generators") write_generators(conanfile, build_folder, self._output) # 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(conanfile, build_folder) try: self._hook_manager.execute("pre_build", conanfile=conanfile, reference=pref.ref, package_id=pref.id) logger.debug("Call conanfile.build() with files in build folder: %s", os.listdir(build_folder)) self._output.highlight("Calling build()") with conanfile_exception_formatter(str(conanfile), "build"): conanfile.build() self._output.success("Package '%s' built" % pref.id) self._output.info("Build folder %s" % build_folder) self._hook_manager.execute("post_build", conanfile=conanfile, reference=pref.ref, package_id=pref.id) except Exception as exc: self._output.writeln("") self._output.error("Package '%s' build failed" % pref.id) self._output.warn("Build folder %s" % build_folder) if isinstance(exc, ConanExceptionInUserConanfileMethod): raise exc raise ConanException(exc) finally: # Now remove all files that were imported with imports() remove_imports(conanfile, copied_files, self._output)
def _build(self, conanfile, pref): # Read generators from conanfile and generate the needed files logger.info("GENERATORS: Writing generators") write_generators(conanfile, conanfile.build_folder, self._output) logger.info("TOOLCHAIN: Writing toolchain") write_toolchain(conanfile, conanfile.build_folder, self._output) # 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(conanfile, conanfile.build_folder) try: run_build_method(conanfile, self._hook_manager, reference=pref.ref, package_id=pref.id) self._output.success("Package '%s' built" % pref.id) self._output.info("Build folder %s" % conanfile.build_folder) except Exception as exc: self._output.writeln("") self._output.error("Package '%s' build failed" % pref.id) self._output.warn("Build folder %s" % conanfile.build_folder) if isinstance(exc, ConanExceptionInUserConanfileMethod): raise exc raise ConanException(exc) finally: # Now remove all files that were imported with imports() remove_imports(conanfile, copied_files, self._output)
def _build_package(self): """ 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. Receives the build_folder because it can change if the method build_id() exists """ package_folder = self._client_cache.package( self._package_reference, self._conan_file.short_paths) os.chdir(self.build_folder) self._conan_file.build_folder = self.build_folder self._conan_file.conanfile_directory = self.build_folder self._conan_file.package_folder = package_folder # In local cache, install folder always is build_folder self._conan_file.install_folder = self.build_folder # Read generators from conanfile and generate the needed files logger.debug("Writing generators") write_generators(self._conan_file, self.build_folder, self._out) logger.debug("Files copied after generators %s", os.listdir(self.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 run_imports copied_files = run_imports(self._conan_file, self.build_folder, self._out) try: # This is necessary because it is different for user projects # than for packages logger.debug( "Call conanfile.build() with files in build folder: %s", os.listdir(self.build_folder)) self._out.highlight("Calling build()") with conanfile_exception_formatter(str(self._conan_file), "build"): self._conan_file.build() self._out.success("Package '%s' built" % self._conan_file.info.package_id()) self._out.info("Build folder %s" % self.build_folder) except Exception as exc: self._out.writeln("") self._out.error("Package '%s' build failed" % self._conan_file.info.package_id()) self._out.warn("Build folder %s" % self.build_folder) if isinstance(exc, ConanExceptionInUserConanfileMethod): raise exc raise ConanException(exc) finally: export_folder = self._client_cache.export(self._conan_ref) self._conan_file.conanfile_directory = export_folder # Now remove all files that were imported with imports() for f in copied_files: try: if f.startswith(self.build_folder): os.remove(f) except OSError: self._out.warn( "Unable to remove imported file from build: %s" % f)
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 _build_package(self): """ calls the imports + conanfile.build() method """ os.chdir(self.build_folder) self._conan_file.build_folder = self.build_folder self._conan_file.package_folder = self.package_folder # In local cache, install folder always is build_folder self._conan_file.install_folder = self.build_folder # Read generators from conanfile and generate the needed files logger.debug("Writing generators") write_generators(self._conan_file, self.build_folder, self._out) logger.debug("Files copied after generators %s", os.listdir(self.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 run_imports copied_files = run_imports(self._conan_file, self.build_folder, self._out) try: # This is necessary because it is different for user projects # than for packages self._plugin_manager.execute( "pre_build", conanfile=self._conan_file, reference=self._conan_ref, package_id=self._package_reference.package_id) logger.debug( "Call conanfile.build() with files in build folder: %s", os.listdir(self.build_folder)) self._out.highlight("Calling build()") with conanfile_exception_formatter(str(self._conan_file), "build"): self._conan_file.build() self._out.success("Package '%s' built" % self._conan_file.info.package_id()) self._out.info("Build folder %s" % self.build_folder) self._plugin_manager.execute( "post_build", conanfile=self._conan_file, reference=self._conan_ref, package_id=self._package_reference.package_id) except Exception as exc: self._out.writeln("") self._out.error("Package '%s' build failed" % self._conan_file.info.package_id()) self._out.warn("Build folder %s" % self.build_folder) if isinstance(exc, ConanExceptionInUserConanfileMethod): raise exc raise ConanException(exc) finally: # Now remove all files that were imported with imports() remove_imports(self._conan_file, copied_files, self._out)
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 os.path.exists(build_folder): self._config_source(export_folder, src_folder, conan_file, output) output.info('Copying sources to build folder') shutil.copytree(src_folder, build_folder, symlinks=True) 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() try: # This is necessary because it is different for user projects # than for packages conan_file._conanfile_directory = build_folder conan_file.package_folder = package_folder conan_file.build() self._out.writeln("") output.success("Package '%s' built" % os.path.basename(build_folder)) output.info("Build folder %s" % build_folder) except Exception as e: os.chdir(src_folder) self._out.writeln("") output.error("Package '%s' build failed" % os.path.basename(build_folder)) 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: 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, 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 install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, info=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: written in JSON, e.g. {"compiler": "Visual Studio 12", ...} """ if not isinstance(reference, ConanFileReference): conanfile_path = reference reference = None loader = self._loader(current_path, settings, options) installer = ConanInstaller(self._paths, self._user_io, loader, self.remote_manager, remote) if reference: conanfile = installer.retrieve_conanfile(reference, consumer=True) else: try: conan_file_path = os.path.join(conanfile_path, CONANFILE) conanfile = loader.load_conan(conan_file_path, consumer=True) is_txt = False except NotFoundException: # Load requirements.txt conan_path = os.path.join(conanfile_path, CONANFILE_TXT) conanfile = loader.load_conan_txt(conan_path) is_txt = True # build deps graph and install it builder = DepsBuilder(installer, self._user_io.out) deps_graph = builder.load(reference, conanfile) if info: Printer(self._user_io.out).print_info(deps_graph, info) return Printer(self._user_io.out).print_graph(deps_graph) installer.install(deps_graph, build_mode) if not reference: if is_txt: conanfile.info.settings = loader._settings.values conanfile.info.full_settings = loader._settings.values save(os.path.join(current_path, CONANINFO), conanfile.info.dumps()) self._user_io.out.info("Generated %s" % CONANINFO) write_generators(conanfile, current_path, self._user_io.out) local_installer = FileImporter(deps_graph, self._paths, current_path) conanfile.copy = local_installer conanfile.imports() local_installer.execute()
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) if not os.path.exists(build_folder): self._config_source(export_folder, src_folder, conan_file, output) output.info("Copying sources to build folder") shutil.copytree(src_folder, build_folder, symlinks=True) 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() 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" % os.path.basename(build_folder)) output.info("Build folder %s" % build_folder) except Exception as e: os.chdir(src_folder) self._out.writeln("") output.error("Package '%s' build failed" % os.path.basename(build_folder)) 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: os.remove(f) except Exception: self._out.warn("Unable to remove imported file from build: %s" % f)
def _build_package(self, export_folder, src_folder, build_folder, conan_file): """ 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 """ if not os.path.exists(build_folder): self._config_source(export_folder, src_folder, conan_file) self._user_io.out.info('Preparing your build in %s' % build_folder) shutil.copytree(src_folder, build_folder) self._user_io.out.info('Building your packages in %s' % build_folder) os.chdir(build_folder) # Read generators from conanfile and generate the needed files write_generators(conan_file, build_folder, self._user_io.out) try: conan_file.build() except Exception as e: os.chdir(src_folder) raise ConanException("%s: %s" % (conan_file.name, str(e)))
def _build_package(self): """ calls the imports + conanfile.build() method """ os.chdir(self.build_folder) self._conan_file.build_folder = self.build_folder self._conan_file.package_folder = self.package_folder # In local cache, install folder always is build_folder self._conan_file.install_folder = self.build_folder # Read generators from conanfile and generate the needed files logger.debug("Writing generators") write_generators(self._conan_file, self.build_folder, self._out) logger.debug("Files copied after generators %s", os.listdir(self.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 run_imports copied_files = run_imports(self._conan_file, self.build_folder, self._out) try: # This is necessary because it is different for user projects # than for packages logger.debug("Call conanfile.build() with files in build folder: %s", os.listdir(self.build_folder)) self._out.highlight("Calling build()") with conanfile_exception_formatter(str(self._conan_file), "build"): self._conan_file.build() self._out.success("Package '%s' built" % self._conan_file.info.package_id()) self._out.info("Build folder %s" % self.build_folder) except Exception as exc: self._out.writeln("") self._out.error("Package '%s' build failed" % self._conan_file.info.package_id()) self._out.warn("Build folder %s" % self.build_folder) if isinstance(exc, ConanExceptionInUserConanfileMethod): raise exc raise ConanException(exc) finally: # Now remove all files that were imported with imports() remove_imports(self._conan_file, copied_files, self._out)
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 """ try: rmdir(build_folder) rmdir(package_folder) except Exception as e: raise ConanException( "%s\n\nCouldn't remove folder, might be busy or open\n" "Close any app using it, and retry" % str(e)) 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 if getattr(conan_file, 'no_copy_source', False): mkdir(build_folder) conan_file.source_folder = src_folder else: 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)) conan_file.source_folder = build_folder os.chdir(build_folder) conan_file.build_folder = 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 run_imports copied_files = run_imports(conan_file, build_folder, output) try: # This is necessary because it is different for user projects # than for packages logger.debug( "Call conanfile.build() with files in build folder: %s" % os.listdir(build_folder)) with conanfile_exception_formatter(str(conan_file), "build"): 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 exc: 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) if isinstance(exc, ConanExceptionInUserConanfileMethod): raise exc raise ConanException(exc) 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, install_folder, profile, remote_name=None, build_modes=None, update=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, generators=None, no_imports=False, inject_require=None, install_reference=False, keep_build=False): """ Fetch and build all dependencies for the given reference @param reference: ConanFileReference or path to user space conanfile @param install_folder: where the output files will be saved @param remote: install only from that remote @param profile: Profile object with both the -s introduced options and profile read values @param build_modes: List of build_modes specified @param update: Check for updated in the upstream remotes (and update) @param manifest_folder: Folder to install the manifests @param manifest_verify: Verify dependencies manifests against stored ones @param manifest_interactive: Install deps manifests in folder for later verify, asking user for confirmation @param generators: List of generators from command line. If False, no generator will be written @param no_imports: Install specified packages but avoid running imports @param inject_require: Reference to add as a requirement to the conanfile """ if generators is not False: generators = set(generators) if generators else set() generators.add("txt") # Add txt generator by default manifest_manager = ManifestManager(manifest_folder, user_io=self._user_io, client_cache=self._client_cache, verify=manifest_verify, interactive=manifest_interactive) if manifest_folder else None remote_proxy = self.get_proxy(remote_name=remote_name, manifest_manager=manifest_manager) loader = self.get_loader(profile) if not install_reference: if isinstance(reference, ConanFileReference): # is a create loader.dev_reference = reference elif inject_require: loader.dev_reference = inject_require conanfile = self._load_install_conanfile(loader, reference) if inject_require: self._inject_require(conanfile, inject_require) graph_builder = self._get_graph_builder(loader, remote_proxy) deps_graph = graph_builder.load_graph(conanfile, False, update) if not isinstance(reference, ConanFileReference): output = ScopedOutput(("%s (test package)" % str(inject_require)) if inject_require else "PROJECT", self._user_io.out) output.highlight("Installing %s" % reference) else: output = ScopedOutput(str(reference), self._user_io.out) output.highlight("Installing package") Printer(self._user_io.out).print_graph(deps_graph, self._registry) try: if cross_building(loader._settings): b_os, b_arch, h_os, h_arch = get_cross_building_settings(loader._settings) message = "Cross-build from '%s:%s' to '%s:%s'" % (b_os, b_arch, h_os, h_arch) self._user_io.out.writeln(message, Color.BRIGHT_MAGENTA) except ConanException: # Setting os doesn't exist pass build_mode = BuildMode(build_modes, self._user_io.out) build_requires = BuildRequires(loader, graph_builder, self._registry) installer = ConanInstaller(self._client_cache, output, remote_proxy, build_mode, build_requires, recorder=self._recorder) # Apply build_requires to consumer conanfile if not isinstance(reference, ConanFileReference): build_requires.install("", conanfile, installer, profile.build_requires, output, update) installer.install(deps_graph, profile.build_requires, keep_build, update=update) build_mode.report_matches() if install_folder: # Write generators if generators is not False: tmp = list(conanfile.generators) # Add the command line specified generators tmp.extend([g for g in generators if g not in tmp]) conanfile.generators = tmp write_generators(conanfile, install_folder, output) if not isinstance(reference, ConanFileReference): # Write conaninfo content = normalize(conanfile.info.dumps()) save(os.path.join(install_folder, CONANINFO), content) output.info("Generated %s" % CONANINFO) if not no_imports: run_imports(conanfile, install_folder, output) call_system_requirements(conanfile, output) if install_reference: # The conanfile loaded is really a virtual one. The one with the deploy is the first level one deploy_conanfile = deps_graph.inverse_levels()[1][0].conanfile if hasattr(deploy_conanfile, "deploy") and callable(deploy_conanfile.deploy): run_deploy(deploy_conanfile, install_folder, output) if manifest_manager: manifest_manager.print_log()
def deps_install(app, ref_or_path, install_folder, graph_info, remotes=None, build_modes=None, update=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, generators=None, no_imports=False, create_reference=None, keep_build=False, recorder=None): """ Fetch and build all dependencies for the given reference @param app: The ConanApp instance with all collaborators @param ref_or_path: ConanFileReference or path to user space conanfile @param install_folder: where the output files will be saved @param build_modes: List of build_modes specified @param update: Check for updated in the upstream remotes (and update) @param manifest_folder: Folder to install the manifests @param manifest_verify: Verify dependencies manifests against stored ones @param manifest_interactive: Install deps manifests in folder for later verify, asking user for confirmation @param generators: List of generators from command line. If False, no generator will be written @param no_imports: Install specified packages but avoid running imports """ out, user_io, graph_manager, cache = app.out, app.user_io, app.graph_manager, app.cache remote_manager, hook_manager = app.remote_manager, app.hook_manager if generators is not False: generators = set(generators) if generators else set() generators.add("txt") # Add txt generator by default if graph_info.profile_build: out.info("Configuration (profile_host):") out.writeln(graph_info.profile_host.dumps()) out.info("Configuration (profile_build):") out.writeln(graph_info.profile_build.dumps()) else: out.info("Configuration:") out.writeln(graph_info.profile_host.dumps()) deps_graph = graph_manager.load_graph(ref_or_path, create_reference, graph_info, build_modes, False, update, remotes, recorder) root_node = deps_graph.root conanfile = root_node.conanfile if root_node.recipe == RECIPE_VIRTUAL: out.highlight("Installing package: %s" % str(ref_or_path)) else: conanfile.output.highlight("Installing package") print_graph(deps_graph, out) try: if cross_building(conanfile): settings = get_cross_building_settings(conanfile) message = "Cross-build from '%s:%s' to '%s:%s'" % settings out.writeln(message, Color.BRIGHT_MAGENTA) except ConanException: # Setting os doesn't exist pass installer = BinaryInstaller(app, recorder=recorder) # TODO: Extract this from the GraphManager, reuse same object, check args earlier build_modes = BuildMode(build_modes, out) installer.install(deps_graph, remotes, build_modes, update, keep_build=keep_build, graph_info=graph_info) graph_info.graph_lock.complete_matching_prevs() if manifest_folder: manifest_manager = ManifestManager(manifest_folder, user_io=user_io, cache=cache) for node in deps_graph.nodes: if node.recipe in (RECIPE_CONSUMER, RECIPE_VIRTUAL): continue complete_recipe_sources(remote_manager, cache, node.conanfile, node.ref, remotes) manifest_manager.check_graph(deps_graph, verify=manifest_verify, interactive=manifest_interactive) manifest_manager.print_log() if install_folder: conanfile.install_folder = install_folder # Write generators output = conanfile.output if root_node.recipe != RECIPE_VIRTUAL else out if generators is not False: tmp = list(conanfile.generators ) # Add the command line specified generators tmp.extend([g for g in generators if g not in tmp]) conanfile.generators = tmp write_generators(conanfile, install_folder, output) write_toolchain(conanfile, install_folder, output) if not isinstance(ref_or_path, ConanFileReference): # Write conaninfo content = normalize(conanfile.info.dumps()) save(os.path.join(install_folder, CONANINFO), content) output.info("Generated %s" % CONANINFO) graph_info.save(install_folder) output.info("Generated graphinfo") graph_lock_file = GraphLockFile(graph_info.profile_host, graph_info.profile_build, graph_info.graph_lock) graph_lock_file.save(os.path.join(install_folder, "conan.lock")) if not no_imports: run_imports(conanfile, install_folder) if type(conanfile ).system_requirements != ConanFile.system_requirements: call_system_requirements(conanfile, conanfile.output) if not create_reference and isinstance(ref_or_path, ConanFileReference): # The conanfile loaded is a virtual one. The one w deploy is the first level one neighbours = deps_graph.root.neighbors() deploy_conanfile = neighbours[0].conanfile if hasattr(deploy_conanfile, "deploy") and callable( deploy_conanfile.deploy): run_deploy(deploy_conanfile, install_folder)
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, profile, remote=None, build_modes=None, filename=None, update=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, generators=None, no_imports=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 profile: Profile object with both the -s introduced options and profile readed values @param build_modes: List of build_modes specified @param filename: Optional filename of the conanfile @param update: Check for updated in the upstream remotes (and update) @param manifest_folder: Folder to install the manifests @param manifest_verify: Verify dependencies manifests against stored ones @param manifest_interactive: Install deps manifests in folder for later verify, asking user for confirmation @param generators: List of generators from command line @param no_imports: Install specified packages but avoid running imports """ generators = generators or [] manifest_manager = ManifestManager(manifest_folder, user_io=self._user_io, client_cache=self._client_cache, verify=manifest_verify, interactive=manifest_interactive) if manifest_folder else None remote_proxy = ConanProxy(self._client_cache, self._user_io, self._remote_manager, remote, update=update, check_updates=False, manifest_manager=manifest_manager) loader = ConanFileLoader(self._runner, self._client_cache.settings, profile) conanfile = self._get_conanfile_object(loader, reference, filename, current_path) graph_builder = self._get_graph_builder(loader, update, remote_proxy) deps_graph = graph_builder.load(conanfile) # This line is so the conaninfo stores the correct complete info conanfile.info.scope = profile.scopes registry = RemoteRegistry(self._client_cache.registry, self._user_io.out) Printer(self._user_io.out).print_graph(deps_graph, registry) try: if detected_os() != loader._settings.os: message = "Cross-platform from '%s' to '%s'" % (detected_os(), loader._settings.os) self._user_io.out.writeln(message, Color.BRIGHT_MAGENTA) except ConanException: # Setting os doesn't exist pass build_mode = BuildMode(build_modes, self._user_io.out) build_requires = BuildRequires(loader, remote_proxy, self._user_io.out, self._client_cache, self._search_manager, profile.build_requires, current_path, build_mode) # Apply build_requires to consumer conanfile build_requires.install("", conanfile) installer = ConanInstaller(self._client_cache, self._user_io.out, remote_proxy, build_requires) installer.install(deps_graph, build_mode, current_path) build_mode.report_matches() prefix = "PROJECT" if not isinstance(reference, ConanFileReference) else str(reference) output = ScopedOutput(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) if not no_imports: run_imports(conanfile, current_path, output) installer.call_system_requirements(conanfile, output) if manifest_manager: manifest_manager.print_log()
def install(self, reference, install_folder, graph_info, remote_name=None, build_modes=None, update=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, generators=None, no_imports=False, create_reference=None, keep_build=False): """ Fetch and build all dependencies for the given reference @param reference: ConanFileReference or path to user space conanfile @param install_folder: where the output files will be saved @param remote: install only from that remote @param profile: Profile object with both the -s introduced options and profile read values @param build_modes: List of build_modes specified @param update: Check for updated in the upstream remotes (and update) @param manifest_folder: Folder to install the manifests @param manifest_verify: Verify dependencies manifests against stored ones @param manifest_interactive: Install deps manifests in folder for later verify, asking user for confirmation @param generators: List of generators from command line. If False, no generator will be written @param no_imports: Install specified packages but avoid running imports @param inject_require: Reference to add as a requirement to the conanfile """ if generators is not False: generators = set(generators) if generators else set() generators.add("txt") # Add txt generator by default self._user_io.out.info("Configuration:") self._user_io.out.writeln(graph_info.profile.dumps()) result = self._graph_manager.load_graph(reference, create_reference, graph_info, build_modes, False, update, remote_name, self._recorder, None) deps_graph, conanfile, cache_settings = result if not isinstance(reference, ConanFileReference): output = ScopedOutput( ("%s (test package)" % str(create_reference)) if create_reference else "PROJECT", self._user_io.out) output.highlight("Installing %s" % reference) else: output = ScopedOutput(str(reference), self._user_io.out) output.highlight("Installing package") print_graph(deps_graph, self._user_io.out) try: if cross_building(cache_settings): b_os, b_arch, h_os, h_arch = get_cross_building_settings( cache_settings) message = "Cross-build from '%s:%s' to '%s:%s'" % ( b_os, b_arch, h_os, h_arch) self._user_io.out.writeln(message, Color.BRIGHT_MAGENTA) except ConanException: # Setting os doesn't exist pass installer = ConanInstaller(self._client_cache, output, self._remote_manager, recorder=self._recorder, workspace=None, hook_manager=self._hook_manager) installer.install(deps_graph, keep_build) if manifest_folder: manifest_manager = ManifestManager(manifest_folder, user_io=self._user_io, client_cache=self._client_cache) for node in deps_graph.nodes: if not node.conan_ref: continue complete_recipe_sources(self._remote_manager, self._client_cache, node.conanfile, node.conan_ref) manifest_manager.check_graph(deps_graph, verify=manifest_verify, interactive=manifest_interactive) manifest_manager.print_log() if install_folder: # Write generators if generators is not False: tmp = list(conanfile.generators ) # Add the command line specified generators tmp.extend([g for g in generators if g not in tmp]) conanfile.generators = tmp write_generators(conanfile, install_folder, output) if not isinstance(reference, ConanFileReference): # Write conaninfo content = normalize(conanfile.info.dumps()) save(os.path.join(install_folder, CONANINFO), content) output.info("Generated %s" % CONANINFO) graph_info.save(install_folder) output.info("Generated graphinfo") if not no_imports: run_imports(conanfile, install_folder, output) call_system_requirements(conanfile, output) if not create_reference and isinstance(reference, ConanFileReference): # The conanfile loaded is a virtual one. The one w deploy is the first level one neighbours = deps_graph.root.neighbors() deploy_conanfile = neighbours[0].conanfile if hasattr(deploy_conanfile, "deploy") and callable( deploy_conanfile.deploy): run_deploy(deploy_conanfile, install_folder, output)
def install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, filename=None, update=False, check_updates=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, scopes=None, generators=None, profile_name=None, package_settings=None, env=None, package_env=None, no_imports=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)...] @param package_settings: dict name=> settings: {"zlib": [(settingname, settingvalue), ...]} @param profile: name of the profile to use @param env: list of tuples for environment vars: [(var, value), (var2, value2)...] @param package_env: package dict of list of tuples: {"package_name": [(var, value), (var2, value2)...]} """ generators = generators or [] if manifest_folder: manifest_manager = ManifestManager(manifest_folder, user_io=self._user_io, client_cache=self._client_cache, verify=manifest_verify, interactive=manifest_interactive) else: manifest_manager = None profile = self.read_profile(profile_name, current_path) # Mix Settings, Env vars and scopes between profile and command line if profile: profile.update_settings(settings) profile.update_package_settings(package_settings) settings = profile.settings package_settings = profile.package_settings profile.update_env(env) profile.update_packages_env(package_env) env = profile.env package_env = profile.package_env profile.update_scopes(scopes) scopes = profile.scopes objects = self._get_graph(reference, current_path, remote, options, settings, filename, update, check_updates, manifest_manager, scopes, package_settings, env, package_env) (_, 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._client_cache, self._user_io, remote_proxy) installer.install(deps_graph, build_mode) prefix = "PROJECT" if not isinstance(reference, ConanFileReference) else str(reference) output = ScopedOutput(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) if not no_imports: run_imports(conanfile, current_path, output) if manifest_manager: manifest_manager.print_log()
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 install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, info=None, filename=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: written in JSON, e.g. {"compiler": "Visual Studio 12", ...} """ reference_given = True if not isinstance(reference, ConanFileReference): conanfile_path = reference reference_given = False reference = None loader = self._loader(current_path, settings, options) installer = ConanInstaller(self._paths, self._user_io, loader, self.remote_manager, remote) if reference_given: project_reference = None conanfile = installer.retrieve_conanfile(reference, 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) # Calculate a placeholder conan file reference for the project current_user = self._localdb.get_username() if current_user: project_reference += "%s/" % current_user 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(installer, self._user_io.out) deps_graph = builder.load(reference, conanfile) if info: Printer(self._user_io.out).print_info(deps_graph, project_reference, info) return Printer(self._user_io.out).print_graph(deps_graph) 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) self._user_io.out.writeln("") 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() local_installer.execute()
def install(self, reference, current_path, profile, remote=None, build_modes=None, filename=None, update=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, generators=None, no_imports=False, inject_require=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 profile: Profile object with both the -s introduced options and profile readed values @param build_modes: List of build_modes specified @param filename: Optional filename of the conanfile @param update: Check for updated in the upstream remotes (and update) @param manifest_folder: Folder to install the manifests @param manifest_verify: Verify dependencies manifests against stored ones @param manifest_interactive: Install deps manifests in folder for later verify, asking user for confirmation @param generators: List of generators from command line @param no_imports: Install specified packages but avoid running imports """ generators = generators or [] manifest_manager = ManifestManager( manifest_folder, user_io=self._user_io, client_cache=self._client_cache, verify=manifest_verify, interactive=manifest_interactive) if manifest_folder else None remote_proxy = ConanProxy(self._client_cache, self._user_io, self._remote_manager, remote, update=update, check_updates=False, manifest_manager=manifest_manager) loader = ConanFileLoader(self._runner, self._client_cache.settings, self._profile_with_defaults(profile)) conanfile = self._get_conanfile_object(loader, reference, filename, current_path) if inject_require: self._inject_require(conanfile, inject_require) graph_builder = self._get_graph_builder(loader, update, remote_proxy) deps_graph = graph_builder.load(conanfile) # This line is so the conaninfo stores the correct complete info conanfile.info.scope = profile.scopes registry = RemoteRegistry(self._client_cache.registry, self._user_io.out) if inject_require: output = ScopedOutput("%s test package" % str(inject_require), self._user_io.out) output.info("Installing dependencies") elif not isinstance(reference, ConanFileReference): output = ScopedOutput("PROJECT", self._user_io.out) Printer(self._user_io.out).print_graph(deps_graph, registry) else: output = ScopedOutput(str(reference), self._user_io.out) output.highlight("Installing package") try: if loader._settings.os and detected_os() != loader._settings.os: message = "Cross-platform from '%s' to '%s'" % ( detected_os(), loader._settings.os) self._user_io.out.writeln(message, Color.BRIGHT_MAGENTA) except ConanException: # Setting os doesn't exist pass build_mode = BuildMode(build_modes, self._user_io.out) build_requires = BuildRequires(loader, graph_builder, registry, output, profile.build_requires) installer = ConanInstaller(self._client_cache, output, remote_proxy, build_mode, build_requires) # Apply build_requires to consumer conanfile if not isinstance(reference, ConanFileReference): build_requires.install("", conanfile, installer) installer.install(deps_graph, current_path) build_mode.report_matches() # Write generators tmp = list( conanfile.generators) # Add the command line specified generators tmp.extend([g for g in generators if g not in tmp]) 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) if not no_imports: run_imports(conanfile, current_path, output) installer.call_system_requirements(conanfile, output) if manifest_manager: manifest_manager.print_log()
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 run_imports copied_files = run_imports(conan_file, build_folder, 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)
def install(self, reference, current_path, remote=None, options=None, settings=None, build_mode=False, filename=None, update=False, check_updates=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, scopes=None, generators=None, profile_name=None, package_settings=None, env_values=None, no_imports=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)...] @param package_settings: dict name=> settings: {"zlib": [(settingname, settingvalue), ...]} @param profile: name of the profile to use @param env: list of tuples for environment vars: [(var, value), (var2, value2)...] @param package_env: package dict of list of tuples: {"package_name": [(var, value), (var2, value2)...]} """ generators = generators or [] if manifest_folder: manifest_manager = ManifestManager(manifest_folder, user_io=self._user_io, client_cache=self._client_cache, verify=manifest_verify, interactive=manifest_interactive) else: manifest_manager = None profile = self.read_profile(profile_name, current_path) # Mix Settings, Env vars and scopes between profile and command line settings, package_settings, scopes, env_values = _mix_with_profile(profile, settings, package_settings, scopes, env_values) objects = self._get_graph(reference, current_path, remote, options, settings, filename, update, check_updates, manifest_manager, scopes, package_settings, env_values) (_, 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._client_cache, self._user_io, remote_proxy) installer.install(deps_graph, build_mode) prefix = "PROJECT" if not isinstance(reference, ConanFileReference) else str(reference) output = ScopedOutput(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) if not no_imports: run_imports(conanfile, current_path, output) installer.call_system_requirements(conanfile, output) if manifest_manager: manifest_manager.print_log()
def install(self, reference, current_path, profile, remote=None, build_mode=None, filename=None, update=False, check_updates=False, manifest_folder=None, manifest_verify=False, manifest_interactive=False, generators=None, no_imports=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)...] @param package_settings: dict name=> settings: {"zlib": [(settingname, settingvalue), ...]} @param profile: name of the profile to use @param env: list of tuples for environment vars: [(var, value), (var2, value2)...] @param package_env: package dict of list of tuples: {"package_name": [(var, value), (var2, value2)...]} """ generators = generators or [] if manifest_folder: manifest_manager = ManifestManager( manifest_folder, user_io=self._user_io, client_cache=self._client_cache, verify=manifest_verify, interactive=manifest_interactive) else: manifest_manager = None objects = self._get_graph(reference, current_path, profile, remote, filename, update, check_updates, manifest_manager) (_, deps_graph, _, registry, conanfile, remote_proxy, loader) = objects Printer(self._user_io.out).print_graph(deps_graph, registry) try: if detected_os() != loader._settings.os: message = "Cross-platform from '%s' to '%s'" % ( detected_os(), loader._settings.os) self._user_io.out.writeln(message, Color.BRIGHT_MAGENTA) except ConanException: # Setting os doesn't exist pass installer = ConanInstaller(self._client_cache, self._user_io, remote_proxy) installer.install(deps_graph, build_mode) prefix = "PROJECT" if not isinstance( reference, ConanFileReference) else str(reference) output = ScopedOutput(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) if not no_imports: run_imports(conanfile, current_path, output) installer.call_system_requirements(conanfile, output) if manifest_manager: manifest_manager.print_log()
def _build_package(self): """ 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. Receives the build_folder because it can change if the method build_id() exists """ package_folder = self._client_cache.package( self._package_reference, self._conan_file.short_paths) src_folder = self._client_cache.source(self._conan_ref, self._conan_file.short_paths) export_folder = self._client_cache.export(self._conan_ref) export_source_folder = self._client_cache.export_sources( self._conan_ref, self._conan_file.short_paths) try: rmdir(self.build_folder) rmdir(package_folder) except Exception as e: raise ConanException( "%s\n\nCouldn't remove folder, might be busy or open\n" "Close any app using it, and retry" % str(e)) self._out.info('Building your package in %s' % self.build_folder) config_source(export_folder, export_source_folder, src_folder, self._conan_file, self._out) self._out.info('Copying sources to build folder') if getattr(self._conan_file, 'no_copy_source', False): mkdir(self.build_folder) self._conan_file.source_folder = src_folder else: if platform.system( ) == "Windows" and os.getenv("CONAN_USER_HOME_SHORT") != "None": from conans.util.windows import ignore_long_path_files ignore = ignore_long_path_files(src_folder, self.build_folder, self._out) else: ignore = None shutil.copytree(src_folder, self.build_folder, symlinks=True, ignore=ignore) logger.debug("Copied to %s" % self.build_folder) logger.debug("Files copied %s" % os.listdir(self.build_folder)) self._conan_file.source_folder = self.build_folder os.chdir(self.build_folder) self._conan_file.build_folder = self.build_folder self._conan_file._conanfile_directory = self.build_folder # Read generators from conanfile and generate the needed files logger.debug("Writing generators") write_generators(self._conan_file, self.build_folder, self._out) logger.debug("Files copied after generators %s" % os.listdir(self.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 run_imports copied_files = run_imports(self._conan_file, self.build_folder, self._out) try: # This is necessary because it is different for user projects # than for packages logger.debug( "Call conanfile.build() with files in build folder: %s" % os.listdir(self.build_folder)) self._out.highlight("Calling build()") with conanfile_exception_formatter(str(self._conan_file), "build"): self._conan_file.build() self._out.success("Package '%s' built" % self._conan_file.info.package_id()) self._out.info("Build folder %s" % self.build_folder) except Exception as exc: os.chdir(src_folder) self._out.writeln("") self._out.error("Package '%s' build failed" % self._conan_file.info.package_id()) self._out.warn("Build folder %s" % self.build_folder) if isinstance(exc, ConanExceptionInUserConanfileMethod): raise exc raise ConanException(exc) finally: self._conan_file._conanfile_directory = export_folder # Now remove all files that were imported with imports() for f in copied_files: try: if f.startswith(self.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, 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() local_installer.execute()
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 os.path.exists(build_folder): self._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() try: # This is necessary because it is different for user projects # than for packages conan_file._conanfile_directory = build_folder conan_file.package_folder = package_folder conan_file.build() self._out.writeln("") output.success("Package '%s' built" % os.path.basename(build_folder)) output.info("Build folder %s" % build_folder) except Exception as e: os.chdir(src_folder) self._out.writeln("") output.error("Package '%s' build failed" % os.path.basename(build_folder)) 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: os.remove(f) except Exception: self._out.warn( "Unable to remove imported file from build: %s" % f)
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 os.path.exists(build_folder): self._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 seems that "/" is counted as "\\" so it counts double if len(dest_path) + (Counter(dest_path)[os.path.sep]) >= 260: 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() try: # This is necessary because it is different for user projects # than for packages conan_file._conanfile_directory = build_folder conan_file.package_folder = package_folder conan_file.build() self._out.writeln("") output.success("Package '%s' built" % os.path.basename(build_folder)) output.info("Build folder %s" % build_folder) except Exception as e: os.chdir(src_folder) self._out.writeln("") output.error("Package '%s' build failed" % os.path.basename(build_folder)) 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: os.remove(f) except Exception: self._out.warn("Unable to remove imported file from build: %s" % f)