Beispiel #1
0
    def test_replace_in_file(self):
        replace_in_file(self.win_file, "nis", "nus")
        replace_in_file(self.bytes_file, "nis", "nus")

        content = tools.load(self.win_file)
        self.assertNotIn("nis", content)
        self.assertIn("nus", content)

        content = tools.load(self.bytes_file)
        self.assertNotIn("nis", content)
        self.assertIn("nus", content)
Beispiel #2
0
def get_version():
    try:
        content = tools.load("jamroot.jam")
        match = re.search(r"constant\s*VERSION\s*:\s*(\S+)\s*;", content)
        return match.group(1)
    except:
        pass
Beispiel #3
0
    def _get_file_conf(self, section, varname=None):
        """ Gets the section or variable from config file.
        If the queried element is not found an exception is raised.
        """
        try:
            if not os.path.exists(self.config_filename):
                jwt_random_secret = ''.join(random.choice(string.ascii_letters) for _ in range(24))
                updown_random_secret = ''.join(random.choice(string.ascii_letters) for _ in range(24))
                server_conf = default_server_conf.format(jwt_secret=jwt_random_secret,
                                                         updown_secret=updown_random_secret)
                save(self.config_filename, server_conf)

            if not self._loaded:
                self._loaded = True
                # To avoid encoding problems we use our tools.load
                if six.PY3:
                    self.read_string(tools.load(self.config_filename))
                else:
                    self.read(self.config_filename)

            if varname:
                section = dict(self.items(section))
                return section[varname]
            else:
                return self.items(section)
        except NoSectionError:
            raise ConanException("No section '%s' found" % section)
        except Exception as exc:
            logger.debug(exc)
            raise ConanException("Invalid configuration, "
                                 "missing %s: %s" % (section, varname))
    def _configure_cmake(self):
        if self._cmake:
            return self._cmake
        self._cmake = CMake(self, generator="Ninja")

        self._cmake.definitions["INSTALL_MKSPECSDIR"] = os.path.join(self.package_folder, "res", "archdatadir", "mkspecs")
        self._cmake.definitions["INSTALL_ARCHDATADIR"] = os.path.join(self.package_folder, "res", "archdatadir")
        self._cmake.definitions["INSTALL_DATADIR"] = os.path.join(self.package_folder, "res", "datadir")
        self._cmake.definitions["INSTALL_SYSCONFDIR"] = os.path.join(self.package_folder, "res", "sysconfdir")

        self._cmake.definitions["QT_BUILD_TESTS"] = "OFF"
        self._cmake.definitions["QT_BUILD_EXAMPLES"] = "OFF"

        if self.settings.compiler == "Visual Studio":
            if self.settings.compiler.runtime == "MT" or self.settings.compiler.runtime == "MTd":
                self._cmake.definitions["FEATURE_static_runtime"] = "ON"

        if self.options.multiconfiguration:
            self._cmake.generator = "Ninja Multi-Config"
            self._cmake.definitions["CMAKE_CONFIGURATION_TYPES"] = "Release;Debug"
        self._cmake.definitions["FEATURE_optimize_size"] = ("ON" if self.settings.build_type == "MinSizeRel" else "OFF")

        for module in self._submodules:
            if module != 'qtbase':
                self._cmake.definitions["BUILD_%s" % module] = ("ON" if self.options.get_safe(module) else "OFF")

        self._cmake.definitions["FEATURE_system_zlib"] = "ON"

        self._cmake.definitions["INPUT_opengl"] = self.options.get_safe("opengl", "no")

        # openSSL
        if not self.options.openssl:
            self._cmake.definitions["INPUT_openssl"] = "no"
        else:
            if self.options["openssl"].shared:
                self._cmake.definitions["INPUT_openssl"] = "runtime"
            else:
                self._cmake.definitions["INPUT_openssl"] = "linked"


        for opt, conf_arg in [("with_glib", "glib"),
                              ("with_icu", "icu"),
                              ("with_fontconfig", "fontconfig"),
                              ("with_mysql", "sql_mysql"),
                              ("with_pq", "sql_psql"),
                              ("with_odbc", "sql_odbc"),
                              ("gui", "gui"),
                              ("widgets", "widgets"),
                              ("with_zstd", "zstd"),
                              ("with_vulkan", "vulkan"),
                              ("with_brotli", "brotli")]:
            self._cmake.definitions["FEATURE_%s" % conf_arg] = ("ON" if self.options.get_safe(opt, False) else "OFF")


        for opt, conf_arg in [
                              ("with_doubleconversion", "doubleconversion"),
                              ("with_freetype", "freetype"),
                              ("with_harfbuzz", "harfbuzz"),
                              ("with_libjpeg", "jpeg"),
                              ("with_libpng", "png"),
                              ("with_sqlite3", "sqlite"),
                              ("with_pcre2", "pcre2"),]:
            if self.options.get_safe(opt, False):
                if self.options.multiconfiguration:
                    self._cmake.definitions["FEATURE_%s" % conf_arg] = "ON"
                else:
                    self._cmake.definitions["FEATURE_system_%s" % conf_arg] = "ON"
            else:
                self._cmake.definitions["FEATURE_%s" % conf_arg] = "OFF"
                self._cmake.definitions["FEATURE_system_%s" % conf_arg] = "OFF"

        if self.settings.os == "Macos":
            self._cmake.definitions["FEATURE_framework"] = "OFF"
        elif self.settings.os == "Android":
            self._cmake.definitions["CMAKE_ANDROID_NATIVE_API_LEVEL"] = self.settings.os.api_level
            self._cmake.definitions["ANDROID_ABI"] =  {"armv7": "armeabi-v7a",
                                           "armv8": "arm64-v8a",
                                           "x86": "x86",
                                           "x86_64": "x86_64"}.get(str(self.settings.arch))

        if self.options.sysroot:
            self._cmake.definitions["CMAKE_SYSROOT"] = self.options.sysroot

        if self.options.device:
            self._cmake.definitions["QT_QMAKE_TARGET_MKSPEC"] = os.path.join("devices", self.options.device)
        else:
            xplatform_val = self._xplatform()
            if xplatform_val:
                self._cmake.definitions["QT_QMAKE_TARGET_MKSPEC"] = xplatform_val
            else:
                self.output.warn("host not supported: %s %s %s %s" %
                                 (self.settings.os, self.settings.compiler,
                                  self.settings.compiler.version, self.settings.arch))
        if self.options.cross_compile:
            self._cmake.definitions["QT_QMAKE_DEVICE_OPTIONS"] = "CROSS_COMPILE=%s" % self.options.cross_compile

        self._cmake.definitions["FEATURE_pkg_config"] = "ON"
        if self.settings.compiler == "gcc" and self.settings.build_type == "Debug" and not self.options.shared:
            self._cmake.definitions["BUILD_WITH_PCH"]= "OFF" # disabling PCH to save disk space

        try:
            self._cmake.configure(source_folder="qt6")
        except:
            cmake_err_log = os.path.join(self.build_folder, "CMakeFiles", "CMakeError.log")
            cmake_out_log = os.path.join(self.build_folder, "CMakeFiles", "CMakeOutput.log")
            if (os.path.isfile(cmake_err_log)):
                self.output.info(tools.load(cmake_err_log))
            if (os.path.isfile(cmake_out_log)):
                self.output.info(tools.load(cmake_out_log))
            raise
        return self._cmake
Beispiel #5
0
class LibvncserverConan(ConanFile):
    name = "libvncserver"
    version = tools.load("version.txt")
    license = "GPL 2.0"
    author = "David Callu - callu.david at gmail.com"
    url = "https://github.com/ledocc/conan-libvncserver"
    description = "A library for easy implementation of a VNC server"
    topics = ("vnc" "vnc-client" "vnc-server" "library" "remote-desktop")
    settings = "os", "compiler", "build_type", "arch"
    options = dict({
        "shared": [True, False],
        "with_24bpp": [True, False],
        "with_ffmpeg": [True, False],
        #        "with_gcrypt": [True, False],
        #        "with_gnutls": [True, False],
        "with_ipv6": [True, False],
        "with_jpeg": [True, False],
        #        "with_lzo": [True, False],
        "with_openssl": [True, False],
        "with_png": [True, False],
        #        "with_sasl": [True, False],
        #        "with_sdl": [True, False],
        #        "with_systemd": [True, False],
        "with_threads": [True, False],
        "with_tightvnc_filetransfer": [True, False],
        "with_websockets": [True, False],
        "with_zlib": [True, False]
    })

    default_options = dict({
        "shared": False,
        "with_24bpp": True,
        "with_ffmpeg": False,
        #        "with_gcrypt": False,
        #        "with_gnutls": False,
        "with_ipv6": True,
        "with_jpeg": True,
        #        "with_lzo": False,
        "with_openssl": True,
        "with_png": True,
        #        "with_sasl": False,
        #        "with_sdl": False,
        #        "with_systemd": False,
        "with_threads": True,
        "with_tightvnc_filetransfer": False,
        "with_websockets": True,
        "with_zlib": True
    })

    generators = "cmake"
    homepage = "https://github.com/LibVNC/libvncserver"
    build_requires = (("cmake_installer/3.15.3@conan/stable"),
                      ("ninja_installer/1.9.0@bincrafters/stable"))

    exports_sources = ['patches/*']
    exports = ['version.txt']

    folder_name = "libvncserver-LibVNCServer-{}".format(version)

    def configure(self):
        del self.settings.compiler.libcxx

    def source(self):
        archive_name = "LibVNCServer-" + self.version + ".tar.gz"
        tools.get(
            self.homepage + "/archive/" + archive_name,
            sha256=
            "33cbbb4e15bb390f723c311b323cef4a43bcf781984f92d92adda3243a116136")

        tools.patch(patch_file="patches/cmake_export.patch",
                    base_path=os.path.join(self.source_folder,
                                           self.folder_name))

    def requirements(self):
        if self.options.with_ffmpeg:
            self.requires("ffmpeg/4.2@bincrafters/stable")
#        if self.options.with_gcrypt:
#            self.requires("")
#        if self.options.with_gnutls:
#            self.requires("")
        if self.options.with_jpeg:
            self.requires("libjpeg/9c@bincrafters/stable")
#        if self.options.with_lzo:
#            self.requires("")
        if self.options.with_openssl:
            self.requires("OpenSSL/1.1.1c@conan/stable")
        if self.options.with_png:
            self.requires("libpng/1.6.37@bincrafters/stable")
#        if self.options.with_sasl:
#            self.requires("")
#        if self.options.with_sdl:
#            self.requires("")
#        if self.options.with_systemd:
#            self.requires("")
        if self.options.with_zlib:
            self.requires("zlib/1.2.11@conan/stable")

    def build(self):
        cmake = self._configure_cmake()
        cmake.build()
        if self._should_build_test() and self._should_run_test():
            self.run("ctest --output_on_failure --timeout=3000",
                     cwd=cmake.build_folder)

    def package(self):
        cmake = self._configure_cmake()
        cmake.install()
        self.copy("COPYING", dst="licenses/LibVNCServer", ignore_case=True)

    def _configure_cmake(self):
        cmake = CMake(self, set_cmake_flags=True)
        cmake.generator = "Ninja"
        cmake.verbose = True
        if not self._should_build_test():
            cmake.definitions["BUILD_TESTING"] = "OFF"

        cmake.definitions[
            "WITH_24BPP"] = "ON" if self.options.with_24bpp else "OFF"
        cmake.definitions[
            "WITH_FFMPEG"] = "ON" if self.options.with_ffmpeg else "OFF"
        cmake.definitions[
            "WITH_GCRYPT"] = "OFF"  #"ON" if self.options.with_gcrypt else "OFF"
        cmake.definitions[
            "WITH_GNUTLS"] = "OFF"  #"ON" if self.options.with_gnutls else "OFF"
        cmake.definitions[
            "WITH_IPV6"] = "ON" if self.options.with_ipv6 else "OFF"
        cmake.definitions[
            "WITH_JPEG"] = "ON" if self.options.with_jpeg else "OFF"
        cmake.definitions[
            "WITH_LZO"] = "OFF"  #"ON" if self.options.with_lzo else "OFF"
        cmake.definitions[
            "WITH_OPENSSL"] = "ON" if self.options.with_openssl else "OFF"
        cmake.definitions[
            "WITH_PNG"] = "ON" if self.options.with_png else "OFF"
        cmake.definitions[
            "WITH_SASL"] = "OFF"  #"ON" if self.options.with_sasl else "OFF"
        cmake.definitions[
            "WITH_SDL"] = "OFF"  #"ON" if self.options.with_sdl else "OFF"
        cmake.definitions[
            "WITH_SYSTEMD"] = "OFF"  #"ON" if self.options.with_systemd else "OFF"
        cmake.definitions[
            "WITH_THREADS"] = "ON" if self.options.with_threads else "OFF"
        cmake.definitions[
            "WITH_TIGHTVNC_FILETRANSFER"] = "ON" if self.options.with_tightvnc_filetransfer else "OFF"
        cmake.definitions[
            "WITH_WEBSOCKETS"] = "ON" if self.options.with_websockets else "OFF"
        cmake.definitions[
            "WITH_ZLIB"] = "ON" if self.options.with_zlib else "OFF"

        cmake.configure(source_dir="../" + self.folder_name, build_dir="build")
        return cmake

    def _should_build_test(self):
        if (self.settings.get_safe("compiler")
                == "Visual Studio") and (self.settings.get_safe("build_type")
                                         == "Debug"):
            self.output.warn(
                "Skipping test : Visual Studio build in Debug mode fail to compile."
            )
            return False
        return True

    def _should_run_test(self):
        if tools.cross_building(self.settings):
            self.output.warn("Skipping test : cross built package.")
            return False
        return True
Beispiel #6
0
 def _extract_license(self):
     with tools.chdir(
             os.path.join(self.source_folder, self._source_subfolder)):
         tmp = tools.load("zlib.h")
         license_contents = tmp[2:tmp.find("*/", 1)]
         tools.save("LICENSE", license_contents)
Beispiel #7
0
 def _project_version(self):
     version_file = os.path.join(self.recipe_folder, "..", "VERSION")
     return tools.load(version_file).strip()
Beispiel #8
0
 def _extract_license(self):
     file_content = tools.load(
         os.path.join(self.source_folder, self._source_subfolder,
                      "test.cpp"))
     return file_content[:file_content.find("*/")]
 def set_version(self):
     self.version = tools.load(path.join(self.recipe_folder,
                                         "version.txt")).strip()
Beispiel #10
0
def pre_export(output, conanfile, conanfile_path, reference, **kwargs):
    conanfile_content = tools.load(conanfile_path)
    export_folder_path = os.path.dirname(conanfile_path)
    settings = _get_settings(conanfile)
    header_only = _is_recipe_header_only(conanfile)
    installer = settings is not None and "os_build" in settings and "arch_build" in settings

    @run_test("KB-H001", output)
    def test(out):
        if settings and "cppstd" in settings:
            out.error(
                "The 'cppstd' setting is deprecated. Use the 'compiler.cppstd' "
                "subsetting instead")

    @run_test("KB-H002", output)
    def test(out):
        if reference.name != reference.name.lower():
            out.error("The library name has to be lowercase")
        if reference.version != reference.version.lower():
            out.error("The library version has to be lowercase")

    @run_test("KB-H003", output)
    def test(out):
        def _message_attr(attributes, out_method):
            for field in attributes:
                field_value = getattr(conanfile, field, None)
                if not field_value:
                    out_method("Conanfile doesn't have '%s' attribute. " %
                               field)

        if not re.search(r"(\s{4}|\t)name\s*=", conanfile_content):
            out.error("Conanfile doesn't have 'name' attribute.")
        _message_attr(["url", "license", "description", "homepage", "topics"],
                      out.error)

    @run_test("KB-H005", output)
    def test(out):
        no_copy_source = getattr(conanfile, "no_copy_source", None)
        if not settings and header_only and not no_copy_source:
            out.warn(
                "This recipe is a header only library as it does not declare "
                "'settings'. Please include 'no_copy_source' to avoid unnecessary copy steps"
            )

    @run_test("KB-H006", output)
    def test(out):
        options = getattr(conanfile, "options", None)
        if settings and options and not header_only and "fPIC" not in options and not installer:
            out.warn(
                "This recipe does not include an 'fPIC' option. Make sure you are using the "
                "right casing")

    @run_test("KB-H008", output)
    def test(out):
        # This regex takes advantage that a conan reference is always a string
        vrange_match = re.compile(
            r'.*[\'"][a-zA-Z0-9_+.-]+/\[.+\]@[a-zA-Z0-9_+./-]+[\'"].*')
        for num, line in enumerate(conanfile_content.splitlines(), 1):
            if vrange_match.match(line):
                out.error("Possible use of version ranges, line %s:\n %s" %
                          (num, line))

    @run_test("KB-H009", output)
    def test(out):
        max_folder_size = int(os.getenv("CONAN_MAX_RECIPE_FOLDER_SIZE_KB",
                                        256))
        dir_path = os.path.dirname(conanfile_path)
        total_size = 0
        for path, dirs, files in os.walk(dir_path):
            dirs[:] = [d for d in dirs if d not in [".conan"]
                       ]  # Discard the generated .conan directory
            if os.path.relpath(path, dir_path).replace(
                    "\\", "/").startswith("test_package/build"):
                # Discard any file in temp builds
                continue
            for files_it in files:
                file_path = os.path.join(path, files_it)
                total_size += os.path.getsize(file_path)

        total_size_kb = total_size / 1024
        out.success("Total recipe size: %s KB" % total_size_kb)
        if total_size_kb > max_folder_size:
            out.error(
                "The size of your recipe folder ({} KB) is larger than the maximum allowed"
                " size ({}KB).".format(total_size_kb, max_folder_size))

    @run_test("KB-H023", output)
    def test(out):
        for attr_it in ["exports", "exports_sources"]:
            exports = getattr(conanfile, attr_it, None)
            out.info("exports: {}".format(exports))
            if exports is None:
                continue
            exports = [exports] if isinstance(exports, str) else exports
            for exports_it in exports:
                for license_it in ["copying", "license", "copyright"]:
                    if license_it in exports_it.lower():
                        out.error("This recipe is exporting a license file. "
                                  "Remove %s from `%s`" %
                                  (exports_it, attr_it))

    @run_test("KB-H024", output)
    def test(out):
        dir_path = os.path.dirname(conanfile_path)
        test_package_path = os.path.join(dir_path, "test_package")
        if not os.path.exists(test_package_path):
            out.error("There is no 'test_package' for this recipe")
        elif not os.path.exists(os.path.join(test_package_path,
                                             "conanfile.py")):
            out.error("There is no 'conanfile.py' in 'test_package' folder")

    @run_test("KB-H025", output)
    def test(out):
        def _search_for_metaline(from_line, to_line, lines):
            for index in range(from_line, to_line):
                line_number = index + 1
                if "# -*- coding:" in lines[index] or \
                   "# coding=" in lines[index]:
                    out.error(
                        "PEP 263 (encoding) is not allowed in the conanfile. "
                        "Remove the line {}".format(line_number))
                if "#!" in lines[index]:
                    out.error("Shebang (#!) detected in your recipe. "
                              "Remove the line {}".format(line_number))
                if "# vim:" in lines[index]:
                    out.error(
                        "vim editor configuration detected in your recipe. "
                        "Remove the line {}".format(line_number))

        conanfile_lines = conanfile_content.splitlines()
        first_lines_range = 5 if len(conanfile_lines) > 5 else len(
            conanfile_lines)
        _search_for_metaline(0, first_lines_range, conanfile_lines)

        last_lines_range = len(conanfile_lines) - 3 if len(
            conanfile_lines) > 8 else len(conanfile_lines)
        _search_for_metaline(last_lines_range, len(conanfile_lines),
                             conanfile_lines)

    @run_test("KB-H027", output)
    def test(out):
        url = getattr(conanfile, "url", None)
        if url and not url.startswith(
                "https://github.com/conan-io/conan-center-index"):
            out.error("The attribute 'url' should point to: "
                      "https://github.com/conan-io/conan-center-index")

    @run_test("KB-H028", output)
    def test(out):
        def _find_cmake_minimum(folder):
            for (root, _, filenames) in os.walk(folder):
                for filename in filenames:
                    if filename.lower().startswith("cmake") and \
                       (filename.endswith(".txt") or filename.endswith(".cmake")) and \
                       os.path.join("test_package", "build") not in root:
                        cmake_path = os.path.join(root, filename)
                        cmake_content = tools.load(cmake_path).lower()
                        for line in cmake_content.splitlines():
                            if line.startswith("#") or re.search(
                                    r"^\s+#", line) or len(line.strip()) == 0:
                                continue
                            elif "cmake_minimum_required(version" in line or \
                                 "cmake_minimum_required (version" in line:
                                break
                            else:
                                file_path = os.path.join(
                                    os.path.relpath(root), filename)
                                out.error(
                                    "The CMake file '%s' must contain a minimum version "
                                    "declared at the beginning (e.g. cmake_minimum_required(VERSION 3.1.2))"
                                    % file_path)

        dir_path = os.path.dirname(conanfile_path)
        _find_cmake_minimum(dir_path)

    @run_test("KB-H029", output)
    def test(out):
        test_package_path = os.path.join(export_folder_path, "test_package")
        if not os.path.exists(os.path.join(test_package_path, "conanfile.py")):
            return

        test_package_conanfile = tools.load(
            os.path.join(test_package_path, "conanfile.py"))
        if "RunEnvironment" in test_package_conanfile and \
           not re.search(r"self\.run\(.*, run_environment=True\)", test_package_conanfile):
            out.error(
                "The 'RunEnvironment()' build helper is no longer needed. "
                "It has been integrated into the self.run(..., run_environment=True)"
            )

    @run_test("KB-H032", output)
    def test(out):
        if conanfile.name in ["libusb", "backward-cpp"
                              ] or conanfile.version == "system":
            out.info("'{}' is part of the allowlist.".format(conanfile.name))
            return
        if "def system_requirements" in conanfile_content and \
           "SystemPackageTool" in conanfile_content:
            import re
            match = re.search(r'(\S+)\s?=\s?(tools.)?SystemPackageTool',
                              conanfile_content)
            if ("SystemPackageTool().install" in conanfile_content) or \
               (match and "{}.install".format(match.group(1)) in conanfile_content):
                out.error(
                    "The method 'SystemPackageTool.install' is not allowed in the recipe."
                )

    @run_test("KB-H030", output)
    def test(out):
        conandata_path = os.path.join(export_folder_path, "conandata.yml")
        version = conanfile.version
        allowed_first_level = ["sources", "patches"]
        allowed_sources = ["url", "sha256", "sha1", "md5"]
        allowed_patches = [
            "patch_file", "base_path", "url", "sha256", "sha1", "md5"
        ]

        def _not_allowed_entries(info, allowed_entries):
            not_allowed = []
            fields = info if isinstance(info, list) else [info]
            for field in fields:
                if isinstance(field, dict):
                    return _not_allowed_entries(list(field.keys()),
                                                allowed_entries)
                else:
                    if field not in allowed_entries:
                        not_allowed.append(field)
            return not_allowed

        conandata_yml = load_yml(conandata_path)
        if not conandata_yml:
            return
        entries = _not_allowed_entries(list(conandata_yml.keys()),
                                       allowed_first_level)
        if entries:
            out.error(
                "First level entries %s not allowed. Use only first level entries %s in "
                "conandata.yml" % (entries, allowed_first_level))

        for entry in conandata_yml:
            if entry in ['sources', 'patches']:
                if not isinstance(conandata_yml[entry], dict):
                    out.error(
                        "Expecting a dictionary with versions as keys under '{}' element"
                        .format(entry))
                else:
                    versions = conandata_yml[entry].keys()
                    if any([not isinstance(it, str) for it in versions]):
                        out.error(
                            "Versions in conandata.yml should be strings. Add quotes around the numbers"
                        )

            def validate_one(e, name, allowed):
                not_allowed = _not_allowed_entries(e, allowed)
                if not_allowed:
                    out.error(
                        "Additional entries %s not allowed in '%s':'%s' of "
                        "conandata.yml" % (not_allowed, name, version))
                    return False
                return True

            def validate_recursive(e, data, name, allowed):
                if isinstance(
                        e,
                        str) and e not in allowed_sources and not isinstance(
                            data[e], str):
                    for child in data[e]:
                        if not validate_recursive(child, data[e], name,
                                                  allowed):
                            return False
                    return True
                else:
                    return validate_one(e, name, allowed)

            if version not in conandata_yml[entry]:
                continue
            for element in conandata_yml[entry][version]:
                if entry == "patches":
                    if not validate_recursive(
                            element, conandata_yml[entry][version], "patches",
                            allowed_patches):
                        return
                if entry == "sources":
                    if not validate_recursive(
                            element, conandata_yml[entry][version], "sources",
                            allowed_sources):
                        return

    @run_test("KB-H034", output)
    def test(out):
        test_package_path = os.path.join(export_folder_path, "test_package")
        if not os.path.exists(os.path.join(test_package_path, "conanfile.py")):
            return

        test_package_conanfile = tools.load(
            os.path.join(test_package_path, "conanfile.py"))
        if "def imports" in test_package_conanfile:
            out.error(
                "The method `imports` is not allowed in test_package/conanfile.py"
            )

    @run_test("KB-H037", output)
    def test(out):
        author = getattr(conanfile, "author", None)
        if author:
            if isinstance(author, str):
                author = '"%s"' % author
            out.error(
                "Conanfile should not contain author. Remove 'author = {}'".
                format(author))

    @run_test("KB-H040", output)
    def test(out):
        if "self.cpp_info.name =" in conanfile_content:
            out.error("CCI uses the name of the package for cmake generator."
                      " Use 'cpp_info.names' instead.")

        for generator in ["cmake", "cmake_multi"]:
            if "self.cpp_info.names['{}']".format(generator) in conanfile_content or \
               'self.cpp_info.names["{}"]'.format(generator) in conanfile_content:
                out.error(
                    "CCI uses the name of the package for {0} generator. "
                    "Conanfile should not contain 'self.cpp_info.names['{0}']'. "
                    " Use 'cmake_find_package' and 'cmake_find_package_multi' instead."
                    .format(generator))

    @run_test("KB-H041", output)
    def test(out):
        checked_fileexts = ".c", ".cc", ".cpp", ".cxx", ".h", ".hxx", ".hpp", \
                           ".py", ".txt", ".yml", ".cmake", ".xml", ".patch", ".md"

        files_noext = "Makefile", "GNUMakefile"

        def _check_final_newline(path):
            try:
                last_char = tools.load(path)[-1]
            except (OSError, IndexError):
                return  # File is empty ==> ignore
            if last_char not in ("\n", "\r"):
                out.error(
                    "File '{}' does not end with an endline".format(path))

        for root, _, filenames in os.walk(export_folder_path):
            if os.path.relpath(root, export_folder_path).replace(
                    "\\", "/").startswith("test_package/build"):
                # Discard any file in temp builds
                continue
            for filename in filenames:
                _, fileext = os.path.splitext(filename)
                if filename in files_noext or fileext.lower(
                ) in checked_fileexts:
                    _check_final_newline(os.path.join(root, filename))

        config_yml = os.path.join(export_folder_path, os.path.pardir,
                                  "config.yml")
        if os.path.isfile(config_yml):
            _check_final_newline(config_yml)

    @run_test("KB-H044", output)
    def test(out):
        for forbidden in ["self.requires.add", "self.build_requires.add"]:
            if forbidden in conanfile_content:
                out.error(
                    "The method '{}()' is not allowed. Use '{}()' instead.".
                    format(forbidden, forbidden.replace(".add", "")))

    @run_test("KB-H045", output)
    def test(out):
        if "self.options.remove" in conanfile_content:
            out.error(
                "Found 'self.options.remove'. Replace it by 'del self.options.<opt>'."
            )

    @run_test("KB-H047", output)
    def test(out):
        def _check_non_ascii(filename, content):
            import unicodedata
            for num, line in enumerate(content.splitlines(), 1):
                bad_chars = {
                    num: char
                    for num, char in enumerate(line, 1) if ord(char) >= 128
                }
                if bad_chars:
                    out.error(
                        "The file '{}' contains a non-ascii character at line ({})."
                        " Only ASCII characters are allowed, please remove it."
                        .format(filename, num))
                    indexes = bad_chars.keys()
                    draw = [
                        '^' if i in indexes else ' '
                        for i in range(1, len(line))
                    ]
                    draw = ''.join(draw)
                    bad_chars = bad_chars.values()
                    bad_chars = [
                        "\\x%s (%s)" %
                        (format(ord(c), 'x'), unicodedata.name(c))
                        for c in bad_chars
                    ]
                    message = "bad characters: " + ' '.join(bad_chars)
                    output.info(message)
                    output.info(line)
                    output.info(draw)

        _check_non_ascii("conanfile.py", conanfile_content)
        test_package_dir = os.path.join(os.path.dirname(conanfile_path),
                                        "test_package")
        test_package_path = os.path.join(test_package_dir, "conanfile.py")
        if os.path.exists(test_package_path):
            test_package_content = tools.load(test_package_path)
            _check_non_ascii("test_package/conanfile.py", test_package_content)

    @run_test("KB-H046", output)
    def test(out):
        def check_for_verbose_flag(cmakelists_path):
            cmake_content = tools.load(cmakelists_path)
            if "cmake_verbose_makefile" in cmake_content.lower():
                out.error(
                    "The CMake definition 'set(CMAKE_VERBOSE_MAKEFILE ON)' is not allowed. "
                    "Remove it from {}.".format(
                        os.path.relpath(cmakelists_path)))

        dir_path = os.path.dirname(conanfile_path)
        test_package_path = os.path.join(dir_path, "test_package")
        for cmake_path in [
                os.path.join(dir_path, "CMakeLists.txt"),
                os.path.join(test_package_path, "CMakeLists.txt")
        ]:
            if os.path.exists(cmake_path):
                check_for_verbose_flag(cmake_path)

    @run_test("KB-H048", output)
    def test(out):
        dir_path = os.path.dirname(conanfile_path)
        cmake_test_pkg = os.path.join(dir_path, "test_package",
                                      "CMakeLists.txt")
        if os.path.isfile(cmake_test_pkg):
            cmake_content = tools.load(cmake_test_pkg)
            if re.search(r"cmake_minimum_required\(version [\"']?2",
                         cmake_content.lower()):
                out.error(
                    "The test_package/CMakeLists.txt requires CMake 3.1 at least."
                    " Update to 'cmake_minimum_required(VERSION 3.1)'.")

        cmake_path = os.path.join(dir_path, "CMakeLists.txt")
        if os.path.isfile(cmake_path):
            cmake_content = tools.load(cmake_path)
            if re.search(r"cmake_minimum_required\(version [\"']?2", cmake_content.lower()) and \
               "cxx_standard" in cmake_content.lower():
                out.error(
                    "The CMake definition CXX_STANDARD requires CMake 3.1 at least."
                    " Update to 'cmake_minimum_required(VERSION 3.1)'.")

    @run_test("KB-H049", output)
    def test(out):
        dir_path = os.path.dirname(conanfile_path)
        cmake_path = os.path.join(dir_path, "CMakeLists.txt")
        if os.path.isfile(cmake_path):
            cmake_content = tools.load(cmake_path)
            match = re.search(
                r"cmake_minimum_required\s?\(VERSION (\d?\.?\d?\.?\d+)\)",
                cmake_content, re.I)
            if match and tools.Version(match.group(1)) < "3.4":
                for cmake_def in [
                        "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS",
                        "WINDOWS_EXPORT_ALL_SYMBOLS"
                ]:
                    if cmake_def in cmake_content:
                        out.error(
                            "The CMake definition {} requires CMake 3.4 at least. Update "
                            "CMakeLists.txt to 'cmake_minimum_required(VERSION 3.4)'."
                            .format(cmake_def))
                        break

    @run_test("KB-H051", output)
    def test(out):
        default_options = getattr(conanfile, "default_options")
        if default_options and not isinstance(default_options, dict):
            out.error("Use a dictionary to declare 'default_options'")

    @run_test("KB-H052", output)
    def test(out):
        config_path = os.path.abspath(
            os.path.join(export_folder_path, os.path.pardir, "config.yml"))
        config_yml = load_yml(config_path)

        conandata_path = os.path.join(export_folder_path, "conandata.yml")
        conandata_yml = load_yml(conandata_path)

        if not config_yml or not conandata_yml:
            return

        if 'versions' not in config_yml:
            return

        if 'sources' not in conandata_yml:
            return

        versions_conandata = conandata_yml['sources'].keys()
        versions_config = config_yml['versions'].keys()
        conandata_path = os.path.relpath(conandata_path, export_folder_path)
        config_path = os.path.relpath(config_path, export_folder_path)

        for version in versions_conandata:
            if version not in versions_config:
                out.error(
                    'The version "{}" exists in "{}" but not in "{}", so it will not be built.'
                    ' Please update "{}" to include newly added '
                    'version "{}".'.format(version, conandata_path,
                                           config_path, config_path, version))

    @run_test("KB-H053", output)
    def test(out):
        def _is_private_import(line):
            if line in ["from conans.model import Generator"]:
                return False
            allowed_list = ["tools", "errors"]
            for pattern in ["from conans.", "import conans."]:
                if line.startswith(pattern):
                    for allowed in allowed_list:
                        if line.startswith(pattern + allowed):
                            return False
                    return True
            return False

        def _check_private_imports(filename, content):
            for num, line in enumerate(content.splitlines(), 1):
                if _is_private_import(line):
                    out.error(
                        "The file {} imports private conan API on line {}, "
                        "this is strongly discouraged.".format(filename, num))
                    out.error(line)

        _check_private_imports("conanfile.py", conanfile_content)
        test_package_dir = os.path.join(os.path.dirname(conanfile_path),
                                        "test_package")
        test_package_path = os.path.join(test_package_dir, "conanfile.py")
        if os.path.exists(test_package_path):
            test_package_content = tools.load(test_package_path)
            _check_private_imports("test_package/conanfile.py",
                                   test_package_content)

    @run_test("KB-H055", output)
    def test(out):
        for prefix in ["", "build_"]:
            if hasattr(conanfile, "{}requires".format(prefix)) and \
               callable(getattr(conanfile, "{}requirements".format(prefix), None)):
                out.error(
                    "Both '{0}requires' attribute and '{0}requirements()' method should not "
                    "be declared at same recipe.".format(prefix))
def _get_version_from_dependency_file():
    file_content = tools.load(DEPENDENCY_FILE_PATH)
    content = json.loads(file_content)
    return str(content['version'])
Beispiel #12
0
    def patch_config_paths(self):
        """
        changes references to the absolute path of the installed package and its dependencies in
        exported cmake config files to the appropriate conan variable. This makes
        most (sensible) cmake config files portable.

        For example, if a package foo installs a file called "fooConfig.cmake" to
        be used by cmake's find_package method, normally this file will contain
        absolute paths to the installed package folder, for example it will contain
        a line such as:

            SET(Foo_INSTALL_DIR /home/developer/.conan/data/Foo/1.0.0/...)

        This will cause cmake find_package() method to fail when someone else
        installs the package via conan.

        This function will replace such mentions to

            SET(Foo_INSTALL_DIR ${CONAN_FOO_ROOT})

        which is a variable that is set by conanbuildinfo.cmake, so that find_package()
        now correctly works on this conan package.

        For dependent packages, if a package foo installs a file called "fooConfig.cmake" to
        be used by cmake's find_package method and if it depends to a package bar,
        normally this file will contain absolute paths to the bar package folder,
        for example it will contain a line such as:

            SET_TARGET_PROPERTIES(foo PROPERTIES
                  INTERFACE_INCLUDE_DIRECTORIES
                  "/home/developer/.conan/data/Bar/1.0.0/user/channel/id/include")

        This function will replace such mentions to

            SET_TARGET_PROPERTIES(foo PROPERTIES
                  INTERFACE_INCLUDE_DIRECTORIES
                  "${CONAN_BAR_ROOT}/include")

        If the install() method of the CMake object in the conan file is used, this
        function should be called _after_ that invocation. For example:

            def build(self):
                cmake = CMake(self)
                cmake.configure()
                cmake.build()
                cmake.install()
                cmake.patch_config_paths()
        """
        if not self._conanfile.should_install:
            return
        if not self._conanfile.name:
            raise ConanException(
                "cmake.patch_config_paths() can't work without package name. "
                "Define name in your recipe")
        pf = self.definitions.get(cmake_install_prefix_var_name)
        replstr = "${CONAN_%s_ROOT}" % self._conanfile.name.upper()
        allwalk = chain(os.walk(self._conanfile.build_folder),
                        os.walk(self._conanfile.package_folder))
        for root, _, files in allwalk:
            for f in files:
                if f.endswith(".cmake"):
                    path = os.path.join(root, f)
                    tools.replace_in_file(path, pf, replstr, strict=False)

                    # patch paths of dependent packages that are found in any cmake files of the
                    # current package
                    path_content = tools.load(path)
                    for dep in self._conanfile.deps_cpp_info.deps:
                        from_str = self._conanfile.deps_cpp_info[dep].rootpath
                        # try to replace only if from str is found
                        if path_content.find(from_str) != -1:
                            dep_str = "${CONAN_%s_ROOT}" % dep.upper()
                            self._conanfile.output.info(
                                "Patching paths for %s: %s to %s" %
                                (dep, from_str, dep_str))
                            tools.replace_in_file(path,
                                                  from_str,
                                                  dep_str,
                                                  strict=False)
Beispiel #13
0
 def package(self):
     header = tools.load(os.path.join(self._source_subfolder, "sqlite3.h"))
     license_content = header[3:header.find("***", 1)]
     tools.save(os.path.join(self.package_folder, "licenses", "LICENSE"), license_content)
     cmake = self._configure_cmake()
     cmake.install()
 def _extract_license(self):
     header = tools.load(os.path.join(
         self._source_subfolder, "portable_endian.h"))
     license_contents = header[0:(header.find("#ifndef", 1))]
     tools.save("LICENSE", license_contents)
Beispiel #15
0
 def set_version(self):
     content = load(os.path.join(self.recipe_folder, "CMakeLists.txt"))
     version = re.search(r"project\(cdsp VERSION (.*)\)", content).group(1)
     self.version = version.strip()
Beispiel #16
0
 def configure(self):
     self.repo_revision = tools.load("revision")
Beispiel #17
0
    def _create_components_file_from_cmake_target_file(self, target_file_path):
        components = {}

        target_content = tools.load(target_file_path)

        cmake_functions = re.findall(
            r"(?P<func>add_library|set_target_properties)[\n|\s]*\([\n|\s]*(?P<args>[^)]*)\)",
            target_content)
        for (cmake_function_name, cmake_function_args) in cmake_functions:
            cmake_function_args = re.split(r"[\s|\n]+",
                                           cmake_function_args,
                                           maxsplit=2)

            cmake_imported_target_name = cmake_function_args[0]
            cmake_target_nonamespace = cmake_imported_target_name.replace(
                "nmos-cpp::", "")
            component_name = cmake_target_nonamespace.lower()
            # Conan component name cannot be the same as the package name
            if component_name == "nmos-cpp":
                component_name = "nmos-cpp-lib"

            components.setdefault(component_name,
                                  {"cmake_target": cmake_target_nonamespace})

            if cmake_function_name == "add_library":
                cmake_imported_target_type = cmake_function_args[1]
                if cmake_imported_target_type in ["STATIC", "SHARED"]:
                    # library filenames are based on the target name by default
                    lib_name = cmake_target_nonamespace
                    # the filename may be changed by a straightforward command:
                    # set_property(TARGET Bonjour PROPERTY OUTPUT_NAME dnssd)
                    # but we'd have to read the nmos-cpp-targets-<config>.cmake files
                    # and parse the IMPORTED_LOCATION_<CONFIG> values
                    if lib_name == "Bonjour":
                        lib_name = "dnssd"
                    components[component_name]["libs"] = [lib_name]
            elif cmake_function_name == "set_target_properties":
                target_properties = re.findall(
                    r"(?P<property>INTERFACE_[A-Z_]+)[\n|\s]+\"(?P<values>.+)\"",
                    cmake_function_args[2])
                for target_property in target_properties:
                    property_type = target_property[0]
                    # '\', '$' and '"' are escaped; '$' especially is important here
                    # see https://github.com/conan-io/conan/blob/release/1.39/conans/client/generators/cmake_common.py#L43-L48
                    property_values = re.sub(r"\\(.)", r"\1",
                                             target_property[1]).split(";")
                    if property_type == "INTERFACE_LINK_LIBRARIES":
                        for dependency in property_values:
                            match_private = re.fullmatch(
                                r"\$<LINK_ONLY:(.+)>", dependency)
                            if match_private:
                                dependency = match_private.group(1)
                            if "::" in dependency:
                                dependency = dependency.replace(
                                    "nmos-cpp::", "")
                                # Conan component name cannot be the same as the package name
                                if dependency == "nmos-cpp":
                                    dependency = "nmos-cpp-lib"
                                # Conan packages for Boost, cpprestsdk, websocketpp, OpenSSL and Avahi have component names that (except for being lowercase) match the CMake targets
                                # json-schema-validator overrides cmake_find_package[_multi] names
                                elif dependency == "nlohmann_json_schema_validator::nlohmann_json_schema_validator":
                                    dependency = "json-schema-validator::json-schema-validator"
                                # mdnsresponder overrides cmake_find_package[_multi] names
                                elif dependency == "DNSSD::DNSSD":
                                    dependency = "mdnsresponder::mdnsresponder"
                                components[component_name].setdefault(
                                    "requires" if not match_private else
                                    "requires_private",
                                    []).append(dependency.lower())
                            elif "${_IMPORT_PREFIX}/lib/" in dependency:
                                self.output.warn(
                                    "{} recipe does not handle {} {} (yet)".
                                    format(self.name, property_type,
                                           dependency))
                            else:
                                components[component_name].setdefault(
                                    "system_libs", []).append(dependency)
                    elif property_type == "INTERFACE_COMPILE_DEFINITIONS":
                        for property_value in property_values:
                            components[component_name].setdefault(
                                "defines", []).append(property_value)
                    elif property_type == "INTERFACE_COMPILE_FEATURES":
                        for property_value in property_values:
                            if property_value not in ["cxx_std_11"]:
                                self.output.warn(
                                    "{} recipe does not handle {} {} (yet)".
                                    format(self.name, property_type,
                                           property_value))
                    elif property_type == "INTERFACE_COMPILE_OPTIONS":
                        for property_value in property_values:
                            # handle forced include (Visual Studio /FI, gcc -include) by relying on includedirs containing "include"
                            property_value = property_value.replace(
                                "${_IMPORT_PREFIX}/include/", "")
                            components[component_name].setdefault(
                                "cxxflags", []).append(property_value)
                    elif property_type == "INTERFACE_INCLUDE_DIRECTORIES":
                        for property_value in property_values:
                            if property_value not in [
                                    "${_IMPORT_PREFIX}/include"
                            ]:
                                self.output.warn(
                                    "{} recipe does not handle {} {} (yet)".
                                    format(self.name, property_type,
                                           property_value))
                    elif property_type == "INTERFACE_LINK_OPTIONS":
                        for property_value in property_values:
                            # workaround required because otherwise "/ignore:4099" gets converted to "\ignore:4099.obj"
                            # thankfully the MSVC linker accepts both '/' and '-' for the option specifier and Visual Studio
                            # handles link options appearing in Link/AdditionalDependencies rather than Link/AdditionalOptions
                            # because the CMake generators put them in INTERFACE_LINK_LIBRARIES rather than INTERFACE_LINK_OPTIONS
                            # see https://github.com/conan-io/conan/pull/8812
                            # and https://docs.microsoft.com/en-us/cpp/build/reference/linking?view=msvc-160#command-line
                            property_value = re.sub(r"^/", r"-",
                                                    property_value)
                            components[component_name].setdefault(
                                "linkflags", []).append(property_value)
                    else:
                        self.output.warn(
                            "{} recipe does not handle {} (yet)".format(
                                self.name, property_type))

        # Save components informations in json file
        with open(self._components_helper_filepath, "w") as json_file:
            json.dump(components, json_file, indent=4)
Beispiel #18
0
 def _extract_license(self):
     aaplus_header = tools.load(
         os.path.join(self._source_subfolder, "AA+.h"))
     begin = aaplus_header.find("Copyright")
     end = aaplus_header.find("*/", begin)
     return aaplus_header[begin:end]
Beispiel #19
0
def load_yml(path):
    if os.path.isfile(path):
        return yaml.safe_load(tools.load(path))
    return None
 def _extract_license(self):
     header = tools.load(
         os.path.join(self._source_subfolder, "angelscript", "include",
                      "angelscript.h"))
     tools.save("LICENSE",
                header[header.find("/*", 1) + 3:header.find("*/", 1)])
Beispiel #21
0
 def copy_file_to_source(self, name):
     file_content = tools.load(name)
     path_to_source = os.path.join(self.source_folder, self.folder_name,
                                   name)
     tools.save(path_to_source, file_content)
     print("Copied", name, "=>", path_to_source)
Beispiel #22
0
 def _get_license(self):
     readme = tools.load(os.path.join(self.source_folder, self._source_subfolder, "README.md"))
     begin = readme.find("Copyright")
     end = readme.find("\n## Introduction", begin)
     return readme[begin:end]
Beispiel #23
0
    def get_command(self, project_file, props_file_path=None, targets=None, upgrade_project=True,
                    build_type=None, arch=None, parallel=True, toolset=None, platforms=None,
                    use_env=False):

        targets = targets or []
        command = []

        if upgrade_project and not get_env("CONAN_SKIP_VS_PROJECTS_UPGRADE", False):
            command.append("devenv %s /upgrade &&" % project_file)
        else:
            self._output.info("Skipped sln project upgrade")

        build_type = build_type or self._settings.get_safe("build_type")
        arch = arch or self._settings.get_safe("arch")
        if not build_type:
            raise ConanException("Cannot build_sln_command, build_type not defined")
        if not arch:
            raise ConanException("Cannot build_sln_command, arch not defined")

        command.append("msbuild %s /p:Configuration=%s" % (project_file, build_type))
        msvc_arch = {'x86': 'x86',
                     'x86_64': 'x64',
                     'armv7': 'ARM',
                     'armv8': 'ARM64'}
        if platforms:
            msvc_arch.update(platforms)
        msvc_arch = msvc_arch.get(str(arch))
        try:
            sln = tools.load(project_file)
            pattern = re.compile(r"GlobalSection\(SolutionConfigurationPlatforms\)"
                                 r"(.*?)EndGlobalSection", re.DOTALL)
            solution_global = pattern.search(sln).group(1)
            lines = solution_global.splitlines()
            lines = [s.split("=")[0].strip() for s in lines]
        except Exception:
            pass
        else:
            config = "%s|%s" % (build_type, msvc_arch)
            if config not in "".join(lines):
                self._output.warn("***** The configuration %s does not exist in this solution *****" % config)
                self._output.warn("Use 'platforms' argument to define your architectures")

        if use_env:
            command.append('/p:UseEnv=true')

        if msvc_arch:
            command.append('/p:Platform="%s"' % msvc_arch)

        if parallel:
            command.append('/m:%s' % cpu_count())

        if targets:
            command.append("/target:%s" % ";".join(targets))

        if toolset:
            command.append("/p:PlatformToolset=%s" % toolset)

        if props_file_path:
            command.append('/p:ForceImportBeforeCppTargets="%s"' % props_file_path)

        return " ".join(command)
Beispiel #24
0
    def package(self):
        self.output.warn("local cache: %s" % self.in_local_cache)
        self.output.warn("develop: %s" % self.develop)
        # Extract the License/s from the header to a file
        with tools.chdir(os.path.join(self.source_folder,
                                      self.ZIP_FOLDER_NAME)):
            tmp = tools.load("zlib.h")
            license_contents = tmp[2:tmp.find("*/", 1)]
            tools.save("LICENSE", license_contents)

        # Copy the license files
        self.copy("LICENSE", src=self.ZIP_FOLDER_NAME, dst=".")

        # Copy pc file
        self.copy("*.pc", dst="", keep_path=False)
        # Copying zlib.h, zutil.h, zconf.h
        self.copy("*.h",
                  "include",
                  "%s" % self.ZIP_FOLDER_NAME,
                  keep_path=False)
        self.copy("*.h", "include", "%s" % "_build", keep_path=False)

        # Copying static and dynamic libs
        build_dir = os.path.join(self.ZIP_FOLDER_NAME, "_build")
        if self.settings.os == "Windows":
            if self.options.shared:
                build_dir = os.path.join(self.ZIP_FOLDER_NAME, "_build")
                self.copy(pattern="*.dll",
                          dst="bin",
                          src=build_dir,
                          keep_path=False)
                build_dir = os.path.join(self.ZIP_FOLDER_NAME, "_build/lib")
                self.copy(pattern="*zlibd.lib",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
                self.copy(pattern="*zlib.lib",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
                self.copy(pattern="*zlib.dll.a",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
            else:
                build_dir = os.path.join(self.ZIP_FOLDER_NAME, "_build/lib")
                if self.settings.os == "Windows":
                    # MinGW
                    self.copy(pattern="libzlibstaticd.a",
                              dst="lib",
                              src=build_dir,
                              keep_path=False)
                    self.copy(pattern="libzlibstatic.a",
                              dst="lib",
                              src=build_dir,
                              keep_path=False)
                    # Visual Studio
                    self.copy(pattern="zlibstaticd.lib",
                              dst="lib",
                              src=build_dir,
                              keep_path=False)
                    self.copy(pattern="zlibstatic.lib",
                              dst="lib",
                              src=build_dir,
                              keep_path=False)

                lib_path = os.path.join(self.package_folder, "lib")
                suffix = "d" if self.settings.build_type == "Debug" else ""
                if self.settings.compiler == "Visual Studio":
                    current_lib = os.path.join(lib_path,
                                               "zlibstatic%s.lib" % suffix)
                    os.rename(current_lib,
                              os.path.join(lib_path, "zlib%s.lib" % suffix))
                elif self.settings.compiler == "gcc":
                    current_lib = os.path.join(lib_path, "libzlibstatic.a")
                    os.rename(current_lib, os.path.join(lib_path, "libzlib.a"))
        else:
            if self.options.shared:
                if self.settings.os == "Macos":
                    self.copy(pattern="*.dylib",
                              dst="lib",
                              src=build_dir,
                              keep_path=False)
                else:
                    self.copy(pattern="*.so*",
                              dst="lib",
                              src=build_dir,
                              keep_path=False)
            else:
                self.copy(pattern="*.a",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
Beispiel #25
0
def run(output, reply_dir, build_type, conanfile_name):
    message = ''
    for filename in os.listdir(reply_dir):
        if fnmatch.fnmatch(filename, "codemodel-v2-*.json"):
            codemodel = json.loads(
                tools.load(os.path.join(reply_dir, filename)))
            if 'configurations' not in codemodel:
                output.warn("codemodel doesn't have configurations")
                return
            for configuration in codemodel['configurations']:
                if 'name' not in configuration:
                    output.warn("configuration doesn't have a name")
                    continue
                if configuration['name'] == build_type:
                    if 'projects' not in configuration:
                        output.warn("configuration %s doesn't have projects" %
                                    configuration['name'])
                        continue
                    if 'targets' not in configuration:
                        output.warn("configuration %s doesn't have targets" %
                                    configuration['name'])
                        continue
                    for project in configuration['projects']:
                        if 'name' not in project:
                            output.warn("project doesn't have a name")
                            continue
                        if project['name'] != 'cmake_wrapper':
                            output.info('found CMake project: "%s"' %
                                        project['name'])
                            if project['name'] != conanfile_name:
                                name = project['name']
                                output.warn(
                                    'project name "%s" is different from conanfile name "%s"'
                                    % (name, conanfile_name))

                                message += cmake_template.format(name=name)
                    for target in configuration['targets']:
                        if 'name' not in target:
                            output.warn("target doesn't have a name")
                            continue
                        if target['name'] not in SKIP_TARGETS:
                            target_js = json.loads(
                                tools.load(
                                    os.path.join(reply_dir,
                                                 target['jsonFile'])))
                            if 'install' in target_js:
                                if 'name' not in target_js:
                                    output.warn(
                                        "target.js doesn't have a name")
                                    continue
                                if 'nameOnDisk' not in target_js:
                                    output.warn(
                                        "target.js doesn't have a nameOnDisk")
                                    continue
                                if 'type' not in target_js:
                                    output.warn(
                                        "target.js doesn't have a type")
                                    continue
                                name = target_js['name']
                                nameOnDisk = target_js['nameOnDisk']
                                type = target_js['type']
                                dependencies = target_js.get(
                                    'dependencies', [])
                                requires = []
                                for dependency in dependencies:
                                    if 'id' not in dependency:
                                        output.warn(
                                            "dependency doesn't have an id")
                                        continue
                                    id = dependency["id"]
                                    dependency_name, _ = id.split("::@")
                                    if dependency_name not in SKIP_TARGETS:
                                        requires.append(dependency_name)
                                if len(requires):
                                    requires = ', '.join(
                                        ['"%s"' % r for r in requires])
                                    requires = requires_template.format(
                                        component=name, requires=requires)
                                else:
                                    requires = ''
                                if type != 'EXECUTABLE':
                                    output.info(
                                        'found CMake %s target: "%s" ("%s")' %
                                        (type, name, nameOnDisk))
                                    link = nameOnDisk
                                    if fnmatch.fnmatch(nameOnDisk, '*.lib'):
                                        link = nameOnDisk[:-4]
                                    if fnmatch.fnmatch(nameOnDisk, '*.dll'):
                                        link = nameOnDisk[:-4]
                                    if fnmatch.fnmatch(nameOnDisk, 'lib*.a'):
                                        link = nameOnDisk[3:-2]
                                    if name != conanfile_name:
                                        output.warn(
                                            'target name "%s" is different from conanfile name "%s"'
                                            % (name, conanfile_name))
                                        message += component_template.format(
                                            name=name,
                                            component=name,
                                            link=link,
                                            requires=requires)
                    if message:
                        output.warn(
                            'consider adding the following code to the "package_info" method:'
                        )
                        output.warn(message)
                    break
Beispiel #26
0
    def run(self):

        if self._config_url:
            ConfigManager(self._conan_api, self.printer).install(url=self._config_url)

        context = tools.no_op()
        compiler = self.settings.get("compiler", None)
        if not self._exclude_vcvars_precommand:
            if compiler == "Visual Studio" and "compiler.version" in self.settings:
                compiler_set = namedtuple("compiler", "version")(self.settings["compiler.version"])
                mock_sets = namedtuple("mock_settings",
                                       "arch compiler get_safe")(self.settings["arch"], compiler_set,
                                                                 lambda x: self.settings.get(x, None))
                context = tools.vcvars(mock_sets)
        with context:
            self.printer.print_rule()
            self.printer.print_profile(tools.load(self._profile_abs_path))

            with self.printer.foldable_output("conan_create"):
                if client_version < Version("1.10.0"):
                    name, version, user, channel = self._reference
                else:
                    name, version, user, channel, _ = self._reference

                if self._build_policy:
                    self._build_policy = [self._build_policy]
                # https://github.com/conan-io/conan-package-tools/issues/184
                with tools.environment_append({"_CONAN_CREATE_COMMAND_": "1"}):
                    params = {"name": name, "version": version, "user": user,
                              "channel": channel, "build_modes": self._build_policy,
                              "profile_name": self._profile_abs_path}
                    self.printer.print_message("Calling 'conan create'")
                    self.printer.print_dict(params)
                    with tools.chdir(self._cwd):
                        if Version(client_version) >= "1.8.0":
                            from conans.errors import ConanInvalidConfiguration
                            exc_class = ConanInvalidConfiguration
                        else:
                            exc_class = None

                        try:
                            if client_version < Version("1.12.0"):
                                r = self._conan_api.create(".", name=name, version=version,
                                                        user=user, channel=channel,
                                                        build_modes=self._build_policy,
                                                        profile_name=self._profile_abs_path,
                                                        test_folder=self._test_folder)
                            else:
                                r = self._conan_api.create(".", name=name, version=version,
                                                        user=user, channel=channel,
                                                        build_modes=self._build_policy,
                                                        profile_names=[self._profile_abs_path],
                                                        test_folder=self._test_folder)
                        except exc_class as e:
                            self.printer.print_rule()
                            self.printer.print_message("Skipped configuration by the recipe: "
                                                       "%s" % str(e))
                            self.printer.print_rule()
                            return
                        for installed in r['installed']:
                            if installed["recipe"]["id"] == str(self._reference):
                                package_id = installed['packages'][0]['id']
                                if installed['packages'][0]["built"]:
                                    self._uploader.upload_packages(self._reference,
                                                                   self._upload, package_id)
                                else:
                                    self.printer.print_message("Skipping upload for %s, "
                                                               "it hasn't been built" % package_id)
Beispiel #27
0
 def _extract_license(self):
     readme = tools.load(os.path.join(self._source_subfolder, "README"))
     match = next(
         re.finditer("\n[^\n]*license[^\n]*\n", readme, flags=re.I | re.A))
     return readme[match.span()[1]:].strip("*").strip()
Beispiel #28
0
    def package(self):
        self.output.warn("local cache: %s" % self.in_local_cache)
        self.output.warn("develop: %s" % self.develop)
        # Extract the License/s from the header to a file
        with tools.chdir(
                os.path.join(self.source_folder, self._source_subfolder)):
            tmp = tools.load("zlib.h")
            license_contents = tmp[2:tmp.find("*/", 1)]
            tools.save("LICENSE", license_contents)

        # Copy the license files
        self.copy("LICENSE", src=self._source_subfolder, dst="licenses")

        # Copy pc file
        self.copy("*.pc", dst="", keep_path=False)

        # Copy headers
        for header in ["*zlib.h", "*zconf.h"]:
            self.copy(pattern=header,
                      dst="include",
                      src=self._source_subfolder,
                      keep_path=False)
            self.copy(pattern=header,
                      dst="include",
                      src="_build",
                      keep_path=False)

        # Copying static and dynamic libs
        build_dir = os.path.join(self._source_subfolder, "_build")
        lib_path = os.path.join(self.package_folder, "lib")
        suffix = "d" if self.settings.build_type == "Debug" else ""
        if self.settings.os == "Windows":
            if self.options.shared:
                build_dir = os.path.join(self._source_subfolder, "_build")
                self.copy(pattern="*.dll",
                          dst="bin",
                          src=build_dir,
                          keep_path=False)
                build_dir = os.path.join(self._source_subfolder, "_build/lib")
                self.copy(pattern="*zlibd.lib",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
                self.copy(pattern="*zlib.lib",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
                self.copy(pattern="*zlib.dll.a",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
                if tools.os_info.is_linux:
                    self.copy(pattern="*libz.dll.a",
                              dst="lib",
                              src=self._source_subfolder)
                if self.settings.compiler == "Visual Studio":
                    current_lib = os.path.join(lib_path, "zlib%s.lib" % suffix)
                    os.rename(current_lib, os.path.join(lib_path, "zlib.lib"))
            else:
                build_dir = os.path.join(self._source_subfolder, "_build/lib")
                if self.settings.os == "Windows":
                    if tools.os_info.is_windows:
                        # MinGW
                        self.copy(pattern="libzlibstaticd.a",
                                  dst="lib",
                                  src=build_dir,
                                  keep_path=False)
                        self.copy(pattern="libzlibstatic.a",
                                  dst="lib",
                                  src=build_dir,
                                  keep_path=False)
                        # Visual Studio
                        self.copy(pattern="zlibstaticd.lib",
                                  dst="lib",
                                  src=build_dir,
                                  keep_path=False)
                        self.copy(pattern="zlibstatic.lib",
                                  dst="lib",
                                  src=build_dir,
                                  keep_path=False)
                    elif not tools.os_info.is_linux:
                        # MSYS/Cygwin build
                        self.copy(pattern="*libz.a",
                                  dst="lib",
                                  src=self._source_subfolder,
                                  keep_path=False)
                    if tools.os_info.is_linux:
                        self.copy(pattern="libz.a",
                                  dst="lib",
                                  src=self._source_subfolder,
                                  keep_path=False)
                if self.settings.compiler == "Visual Studio":
                    current_lib = os.path.join(lib_path,
                                               "zlibstatic%s.lib" % suffix)
                    os.rename(current_lib, os.path.join(lib_path, "zlib.lib"))
                elif self.settings.compiler == "gcc":
                    if tools.os_info.is_windows:
                        current_lib = os.path.join(lib_path, "libzlibstatic.a")
                        os.rename(current_lib,
                                  os.path.join(lib_path, "libzlib.a"))
        else:
            if self.options.shared:
                if self.settings.os == "Macos":
                    self.copy(pattern="*.dylib",
                              dst="lib",
                              src=build_dir,
                              keep_path=False,
                              symlinks=True)
                else:
                    self.copy(pattern="*.so*",
                              dst="lib",
                              src=build_dir,
                              keep_path=False,
                              symlinks=True)
            else:
                self.copy(pattern="*.a",
                          dst="lib",
                          src=build_dir,
                          keep_path=False)
 def _extract_license(self):
     file = os.path.join(self.package_folder, "include/cute_math2d.h")
     file_content = tools.load(file)
     return file_content[file_content.rfind('/*'):]
Beispiel #30
0
    def read(filename, decode=True):
        '''
		Reads the contents of a file
		'''
        data = tools.load(filename, binary=True)
        return data.decode('utf-8') if decode == True else data
Beispiel #31
0
    def package(self):
        self.copy('LICENSE.TXT', dst='licenses', src=self._source_subfolder)
        lib_path = os.path.join(self.package_folder, 'lib')

        cmake = self._configure_cmake()
        cmake.install()

        if not self.options.shared:
            for ext in ['.a', '.lib']:
                lib = '**/lib/*LLVMTableGenGlobalISel{}'.format(ext)
                self.copy(lib, dst='lib', keep_path=False)
                lib = '*LLVMTableGenGlobalISel{}'.format(ext)
                self.copy(lib, dst='lib', src='lib')

            CMake(self).configure(args=['--graphviz=graph/llvm.dot'], source_dir='.', build_dir='.')
            with tools.chdir('graph'):
                dot_text = tools.load('llvm.dot').replace('\r\n', '\n')

            dep_regex = re.compile(r'//\s(.+)\s->\s(.+)$', re.MULTILINE)
            deps = re.findall(dep_regex, dot_text)

            dummy_targets = defaultdict(list)
            for target, dep in deps:
                if not target.startswith('LLVM'):
                    dummy_targets[target].append(dep)

            cmake_targets = {
                'libffi::libffi': 'ffi',
                'ZLIB::ZLIB': 'z',
                'Iconv::Iconv': 'iconv',
                'LibXml2::LibXml2': 'xml2'
            }

            components = defaultdict(list)
            for lib, dep in deps:
                if not lib.startswith('LLVM'):
                    continue
                elif dep.startswith('-delayload:'):
                    continue
                elif dep.startswith('LLVM'):
                    components[dep]
                elif dep in cmake_targets:
                    dep = cmake_targets[dep]
                elif os.path.exists(dep):
                    dep = os.path.splitext(os.path.basename(dep))[0]
                    dep = dep.replace('lib', '')
                dep = dep.replace('-l', '')

                if dep in dummy_targets.keys():
                    components[lib].extend(dummy_targets[dep])
                    components[lib] = list(set(components[lib]))
                else:
                    components[lib].append(dep)

        tools.rmdir(os.path.join(self.package_folder, 'bin'))
        tools.rmdir(os.path.join(self.package_folder, 'lib', 'cmake'))
        tools.rmdir(os.path.join(self.package_folder, 'share'))

        for name in os.listdir(lib_path):
            if 'LLVM' not in name:
                os.remove(os.path.join(lib_path, name))

        if not self.options.shared:
            if self.options.get_safe('with_zlib', False):
                if not 'z' in components['LLVMSupport']:
                    components['LLVMSupport'].append('z')
            components_path = \
                os.path.join(self.package_folder, 'lib', 'components.json')
            with open(components_path, 'w') as components_file:
                json.dump(components, components_file, indent=4)
        else:
            suffixes = ['.dylib', '.so']
            for name in os.listdir(lib_path):
                if not any(suffix in name for suffix in suffixes):
                    os.remove(os.path.join(lib_path, name))
Beispiel #32
0
 def _extract_pffft_license(self):
     pffft_c = tools.load(os.path.join(self._source_subfolder, "src", "pffft.c"))
     license_contents = pffft_c[pffft_c.find("/* Copyright")+3:pffft_c.find("modern CPUs.")+13]
     tools.save(os.path.join(self.package_folder, "licenses", "LICENSE"), license_contents)
Beispiel #33
0
    def get_command(self, project_file, props_file_path=None, targets=None, upgrade_project=True,
                    build_type=None, arch=None, parallel=True, toolset=None, platforms=None,
                    use_env=False):

        targets = targets or []
        command = []

        if upgrade_project and not get_env("CONAN_SKIP_VS_PROJECTS_UPGRADE", False):
            command.append("devenv %s /upgrade &&" % project_file)
        else:
            self._output.info("Skipped sln project upgrade")

        build_type = build_type or self._settings.get_safe("build_type")
        arch = arch or self._settings.get_safe("arch")
        if not build_type:
            raise ConanException("Cannot build_sln_command, build_type not defined")
        if not arch:
            raise ConanException("Cannot build_sln_command, arch not defined")

        command.append("msbuild %s /p:Configuration=%s" % (project_file, build_type))
        msvc_arch = {'x86': 'x86',
                     'x86_64': 'x64',
                     'armv7': 'ARM',
                     'armv8': 'ARM64'}
        if platforms:
            msvc_arch.update(platforms)
        msvc_arch = msvc_arch.get(str(arch))
        try:
            sln = tools.load(project_file)
            pattern = re.compile(r"GlobalSection\(SolutionConfigurationPlatforms\)"
                                 r"(.*?)EndGlobalSection", re.DOTALL)
            solution_global = pattern.search(sln).group(1)
            lines = solution_global.splitlines()
            lines = [s.split("=")[0].strip() for s in lines]
        except Exception:
            pass
        else:
            config = "%s|%s" % (build_type, msvc_arch)
            if config not in "".join(lines):
                self._output.warn("***** The configuration %s does not exist in this solution *****" % config)
                self._output.warn("Use 'platforms' argument to define your architectures")

        if use_env:
            command.append('/p:UseEnv=true')

        if msvc_arch:
            command.append('/p:Platform="%s"' % msvc_arch)

        if parallel:
            command.append('/m:%s' % cpu_count())

        if targets:
            command.append("/target:%s" % ";".join(targets))

        if toolset:
            command.append("/p:PlatformToolset=%s" % toolset)

        if props_file_path:
            command.append('/p:ForceImportBeforeCppTargets="%s"' % props_file_path)

        return " ".join(command)
Beispiel #34
0
from cpt.packager import ConanMultiPackager
from conans import tools

if __name__ == "__main__":
    builder = ConanMultiPackager(username="******",
                                 reference="libvncserver/" +
                                 tools.load("version.txt"),
                                 channel="testing",
                                 stable_branch_pattern="release/*")
    builder.add_common_builds()
    builder.run()