예제 #1
0
    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)
예제 #2
0
파일: installer.py 프로젝트: vermosen/conan
    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)
예제 #3
0
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
예제 #4
0
파일: packager.py 프로젝트: ytljc2003/conan
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")
예제 #5
0
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")
예제 #6
0
파일: importer.py 프로젝트: 19317362/conan
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)
예제 #7
0
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)
예제 #8
0
    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)
예제 #9
0
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
예제 #10
0
    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])
예제 #11
0
파일: importer.py 프로젝트: conan-io/conan
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
예제 #12
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
예제 #13
0
파일: importer.py 프로젝트: zesem/conan
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
예제 #14
0
파일: importer.py 프로젝트: nesono/conan
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
예제 #15
0
    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)
예제 #16
0
    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)
예제 #17
0
    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)
예제 #18
0
파일: manager.py 프로젝트: esteve/conan
    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)
예제 #19
0
    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)
예제 #20
0
파일: installer.py 프로젝트: xlong88/conan
    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)