Example #1
0
    def _download_file(self, url, auth, headers, file_path, try_resume=False):
        t1 = time.time()
        if try_resume and file_path and os.path.exists(file_path):
            range_start = os.path.getsize(file_path)
            headers = headers.copy() if headers else {}
            headers["range"] = "bytes={}-".format(range_start)
        else:
            range_start = 0

        try:
            response = self._requester.get(url,
                                           stream=True,
                                           verify=self._verify_ssl,
                                           auth=auth,
                                           headers=headers)
        except Exception as exc:
            raise ConanException("Error downloading file %s: '%s'" %
                                 (url, exc))

        if not response.ok:
            if response.status_code == 404:
                raise NotFoundException("Not found: %s" % url)
            elif response.status_code == 403:
                if auth is None or (hasattr(auth, "token")
                                    and auth.token is None):
                    # TODO: This is a bit weird, why this conversion? Need to investigate
                    raise AuthenticationException(response_to_str(response))
                raise ForbiddenException(response_to_str(response))
            elif response.status_code == 401:
                raise AuthenticationException()
            raise ConanException("Error %d downloading file %s" %
                                 (response.status_code, url))

        def read_response(size):
            for chunk in response.iter_content(size):
                yield chunk

        def write_chunks(chunks, path):
            ret = None
            downloaded_size = range_start
            if path:
                mkdir(os.path.dirname(path))
                mode = "ab" if range_start else "wb"
                with open(path, mode) as file_handler:
                    for chunk in chunks:
                        assert ((six.PY3 and isinstance(chunk, bytes))
                                or (six.PY2 and isinstance(chunk, str)))
                        file_handler.write(chunk)
                        downloaded_size += len(chunk)
            else:
                ret_data = bytearray()
                for chunk in chunks:
                    ret_data.extend(chunk)
                    downloaded_size += len(chunk)
                ret = bytes(ret_data)
            return ret, downloaded_size

        def get_total_length():
            if range_start:
                content_range = response.headers.get("Content-Range", "")
                match = re.match(r"^bytes (\d+)-(\d+)/(\d+)", content_range)
                if not match or range_start != int(match.group(1)):
                    raise ConanException("Error in resumed download from %s\n"
                                         "Incorrect Content-Range header %s" %
                                         (url, content_range))
                return int(match.group(3))
            else:
                total_size = response.headers.get('Content-Length') or len(
                    response.content)
                return int(total_size)

        try:
            logger.debug("DOWNLOAD: %s" % url)
            total_length = get_total_length()
            action = "Downloading" if range_start == 0 else "Continuing download of"
            description = "{} {}".format(
                action, os.path.basename(file_path)) if file_path else None
            progress = progress_bar.Progress(total_length, self._output,
                                             description)
            progress.initial_value(range_start)

            chunk_size = 1024 if not file_path else 1024 * 100
            written_chunks, total_downloaded_size = write_chunks(
                progress.update(read_response(chunk_size)), file_path)
            gzip = (response.headers.get("content-encoding") == "gzip")
            response.close()
            # it seems that if gzip we don't know the size, cannot resume and shouldn't raise
            if total_downloaded_size != total_length and not gzip:
                if (file_path
                        and total_length > total_downloaded_size > range_start
                        and response.headers.get("Accept-Ranges") == "bytes"):
                    written_chunks = self._download_file(url,
                                                         auth,
                                                         headers,
                                                         file_path,
                                                         try_resume=True)
                else:
                    raise ConanException(
                        "Transfer interrupted before complete: %s < %s" %
                        (total_downloaded_size, total_length))

            duration = time.time() - t1
            log_download(url, duration)
            return written_chunks

        except Exception as e:
            logger.debug(e.__class__)
            logger.debug(traceback.format_exc())
            # If this part failed, it means problems with the connection to server
            raise ConanConnectionError(
                "Download failed, check server, possibly try again\n%s" %
                str(e))
Example #2
0
 def _check_field(self, field):
     if field not in self._data:
         raise ConanException(
             undefined_field(self._name, field, self.fields,
                             self._parent_value))
Example #3
0
 def test(self, args=None, build_dir=None, target=None):
     if isinstance(args, ConanFile):
         raise ConanException(deprecated_conanfile_param_message)
     if not target:
         target = "RUN_TESTS" if self._compiler == "Visual Studio" else "test"
     self._build_new(args=args, build_dir=build_dir, target=target)
Example #4
0
 def test(self):
     """ test the generated executable.
     E.g.  self.run("./example")
     """
     raise ConanException(
         "You need to create a method 'test' in your test/conanfile.py")
Example #5
0
 def value(self, v):
     v = str(v)
     if self._definition != "ANY" and v not in self._definition:
         raise ConanException(
             bad_value_msg(self._name, v, self.values_range))
     self._value = v
Example #6
0
def patch(base_path=None,
          patch_file=None,
          patch_string=None,
          strip=0,
          output=None):
    """Applies a diff from file (patch_file)  or string (patch_string)
    in base_path directory or current dir if None"""
    class PatchLogHandler(logging.Handler):
        def __init__(self):
            logging.Handler.__init__(self, logging.DEBUG)
            self.output = output or ConanOutput(sys.stdout, True)
            self.patchname = patch_file if patch_file else "patch"

        def emit(self, record):
            logstr = self.format(record)
            if record.levelno == logging.WARN:
                self.output.warn("%s: %s" % (self.patchname, logstr))
            else:
                self.output.info("%s: %s" % (self.patchname, logstr))

    patchlog = logging.getLogger("patch")
    if patchlog:
        patchlog.handlers = []
        patchlog.addHandler(PatchLogHandler())

    if not patch_file and not patch_string:
        return
    if patch_file:
        patchset = fromfile(patch_file)
    else:
        patchset = fromstring(patch_string.encode())

    if not patchset:
        raise ConanException("Failed to parse patch: %s" %
                             (patch_file if patch_file else "string"))

    # account for new and deleted files, upstream dep won't fix them
    items = []
    for p in patchset:
        source = p.source.decode("utf-8")
        if source.startswith("a/"):
            source = source[2:]
        target = p.target.decode("utf-8")
        if target.startswith("b/"):
            target = target[2:]
        if "dev/null" in source:
            if base_path:
                target = os.path.join(base_path, target)
            hunks = [s.decode("utf-8") for s in p.hunks[0].text]
            new_file = "".join(hunk[1:] for hunk in hunks)
            save(target, new_file)
        elif "dev/null" in target:
            if base_path:
                source = os.path.join(base_path, source)
            os.unlink(source)
        else:
            items.append(p)
    patchset.items = items

    if not patchset.apply(root=base_path, strip=strip):
        raise ConanException("Failed to apply patch: %s" % patch_file)
Example #7
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(walk(self._conanfile.build_folder),
                        walk(self._conanfile.package_folder))

        # We don't want warnings printed because there is no replacement of the abs path.
        # there could be MANY cmake files in the package and the normal thing is to not find
        # the abs paths
        _null_out = ConanOutput(StringIO())
        for root, _, files in allwalk:
            for f in files:
                if f.endswith(".cmake") and not f.startswith("conan"):
                    path = os.path.join(root, f)

                    tools.replace_path_in_file(path,
                                               pf,
                                               replstr,
                                               strict=False,
                                               output=_null_out)

                    # patch paths of dependent packages that are found in any cmake files of the
                    # current package
                    for dep in self._conanfile.deps_cpp_info.deps:
                        from_str = self._conanfile.deps_cpp_info[dep].rootpath
                        dep_str = "${CONAN_%s_ROOT}" % dep.upper()
                        ret = tools.replace_path_in_file(path,
                                                         from_str,
                                                         dep_str,
                                                         strict=False,
                                                         output=_null_out)
                        if ret:
                            self._conanfile.output.info(
                                "Patched paths for %s: %s to %s" %
                                (dep, from_str, dep_str))
Example #8
0
def run_in_windows_bash(conanfile,
                        bashcmd,
                        cwd=None,
                        subsystem=None,
                        msys_mingw=True,
                        env=None,
                        with_login=True):
    """ Will run a unix command inside a bash terminal
        It requires to have MSYS2, CYGWIN, or WSL
    """
    env = env or {}
    if platform.system() != "Windows":
        raise ConanException("Command only for Windows operating system")
    subsystem = subsystem or OSInfo.detect_windows_subsystem()

    if not subsystem:
        raise ConanException(
            "Cannot recognize the Windows subsystem, install MSYS2/cygwin "
            "or specify a build_require to apply it.")

    if subsystem == MSYS2 and msys_mingw:
        # This needs to be set so that msys2 bash profile will set up the environment correctly.
        env_vars = {
            "MSYSTEM": ("MINGW32" if conanfile.settings.get_safe("arch")
                        == "x86" else "MINGW64"),
            "MSYS2_PATH_TYPE":
            "inherit"
        }
    else:
        env_vars = {}

    with environment_append(env_vars):

        hack_env = ""
        # In the bash.exe from WSL this trick do not work, always the /usr/bin etc at first place
        if subsystem != WSL:

            def get_path_value(container, subsystem_name):
                """Gets the path from the container dict and returns a
                string with the path for the subsystem_name"""
                _path_key = next(
                    (name
                     for name in container.keys() if "path" == name.lower()),
                    None)
                if _path_key:
                    _path_value = container.get(_path_key)
                    if isinstance(_path_value, list):
                        return ":".join([
                            unix_path(path, path_flavor=subsystem_name)
                            for path in _path_value
                        ])
                    else:
                        return unix_path(_path_value,
                                         path_flavor=subsystem_name)

            # First get the PATH from the conanfile.env
            inherited_path = get_path_value(conanfile.env, subsystem)
            # Then get the PATH from the real env
            env_path = get_path_value(env, subsystem)

            # Both together
            full_env = ":".join(v for v in [env_path, inherited_path] if v)
            # Put the build_requires and requires path at the first place inside the shell
            hack_env = ' && PATH="%s:$PATH"' % full_env if full_env else ""

        for var_name, value in env.items():
            if var_name == "PATH":
                continue
            hack_env += ' && %s=%s' % (var_name, value)

        # Needed to change to that dir inside the bash shell
        if cwd and not os.path.isabs(cwd):
            cwd = os.path.join(get_cwd(), cwd)

        curdir = unix_path(cwd or get_cwd(), path_flavor=subsystem)
        to_run = 'cd "%s"%s && %s ' % (curdir, hack_env, bashcmd)
        bash_path = OSInfo.bash_path()
        bash_path = '"%s"' % bash_path if " " in bash_path else bash_path
        login = "******" if with_login else ""
        wincmd = '%s %s -c %s' % (bash_path, login, escape_windows_cmd(to_run))
        conanfile.output.info('run_in_windows_bash: %s' % wincmd)

        # If is there any other env var that we know it contains paths, convert it to unix_path
        used_special_vars = [
            var for var in ["AR", "AS", "RANLIB", "LD", "STRIP", "CC", "CXX"]
            if var in conanfile.env.keys()
        ]
        normalized_env = {
            p: unix_path(conanfile.env[p], path_flavor=subsystem)
            for p in used_special_vars
        }

        # https://github.com/conan-io/conan/issues/2839 (subprocess=True)
        with environment_append(normalized_env):
            return conanfile._conan_runner(wincmd,
                                           output=conanfile.output,
                                           subprocess=True)
Example #9
0
 def gzopen_patched(name,
                    mode="r",
                    fileobj=None,
                    compresslevel=None,
                    **kwargs):
     raise ConanException("Error gzopen %s" % name)
Example #10
0
def vswhere(all_=False,
            prerelease=False,
            products=None,
            requires=None,
            version="",
            latest=False,
            legacy=False,
            property_="",
            nologo=True):

    # 'version' option only works if Visual Studio 2017 is installed:
    # https://github.com/Microsoft/vswhere/issues/91

    products = list() if products is None else products
    requires = list() if requires is None else requires

    if legacy and (products or requires):
        raise ConanException(
            "The 'legacy' parameter cannot be specified with either the "
            "'products' or 'requires' parameter")

    installer_path = None
    program_files = get_env("ProgramFiles(x86)") or get_env("ProgramFiles")
    if program_files:
        expected_path = os.path.join(program_files, "Microsoft Visual Studio",
                                     "Installer", "vswhere.exe")
        if os.path.isfile(expected_path):
            installer_path = expected_path
    vswhere_path = installer_path or which("vswhere")

    if not vswhere_path:
        raise ConanException(
            "Cannot locate vswhere in 'Program Files'/'Program Files (x86)' "
            "directory nor in PATH")

    arguments = list()
    arguments.append(vswhere_path)

    # Output json format
    arguments.append("-format")
    arguments.append("json")

    if all_:
        arguments.append("-all")

    if prerelease:
        arguments.append("-prerelease")

    if products:
        arguments.append("-products")
        arguments.extend(products)

    if requires:
        arguments.append("-requires")
        arguments.extend(requires)

    if len(version) != 0:
        arguments.append("-version")
        arguments.append(version)

    if latest:
        arguments.append("-latest")

    if legacy:
        arguments.append("-legacy")

    if len(property_) != 0:
        arguments.append("-property")
        arguments.append(property_)

    if nologo:
        arguments.append("-nologo")

    try:
        output = check_output(arguments).strip()
        # Ignore the "description" field, that even decoded contains non valid charsets for json
        # (ignored ones)
        output = "\n".join([
            line for line in output.splitlines()
            if not line.strip().startswith('"description"')
        ])

    except (ValueError, subprocess.CalledProcessError,
            UnicodeDecodeError) as e:
        raise ConanException("vswhere error: %s" % str(e))

    return json.loads(output)
Example #11
0
def vcvars_command(settings,
                   arch=None,
                   compiler_version=None,
                   force=False,
                   vcvars_ver=None,
                   winsdk_version=None,
                   output=None):
    output = default_output(output, 'conans.client.tools.win.vcvars_command')

    arch_setting = arch or settings.get_safe("arch")

    compiler = settings.get_safe("compiler")
    if compiler == 'Visual Studio':
        compiler_version = compiler_version or settings.get_safe(
            "compiler.version")
    else:
        # vcvars might be still needed for other compilers, e.g. clang-cl or Intel C++,
        # as they might be using Microsoft STL and other tools
        # (e.g. resource compiler, manifest tool, etc)
        # in this case, use the latest Visual Studio available on the machine
        last_version = latest_vs_version_installed(output=output)

        compiler_version = compiler_version or last_version
    os_setting = settings.get_safe("os")
    if not compiler_version:
        raise ConanException(
            "compiler.version setting required for vcvars not defined")

    # https://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx
    arch_setting = arch_setting or 'x86_64'
    arch_build = settings.get_safe("arch_build") or detected_architecture()
    if os_setting == 'WindowsCE':
        vcvars_arch = "x86"
    elif arch_build == 'x86_64':
        # Only uses x64 tooling if arch_build explicitly defines it, otherwise
        # Keep the VS default, which is x86 toolset
        # This will probably be changed in conan 2.0
        if ((settings.get_safe("arch_build")
             or os.getenv("PreferredToolArchitecture") == "x64")
                and int(compiler_version) >= 12):
            x86_cross = "amd64_x86"
        else:
            x86_cross = "x86"
        vcvars_arch = {
            'x86': x86_cross,
            'x86_64': 'amd64',
            'armv7': 'amd64_arm',
            'armv8': 'amd64_arm64'
        }.get(arch_setting)
    elif arch_build == 'x86':
        vcvars_arch = {
            'x86': 'x86',
            'x86_64': 'x86_amd64',
            'armv7': 'x86_arm',
            'armv8': 'x86_arm64'
        }.get(arch_setting)

    if not vcvars_arch:
        raise ConanException('unsupported architecture %s' % arch_setting)

    existing_version = os.environ.get("VisualStudioVersion")

    if existing_version:
        command = ["echo Conan:vcvars already set"]
        existing_version = existing_version.split(".")[0]
        if existing_version != compiler_version:
            message = "Visual environment already set to %s\n " \
                      "Current settings visual version: %s" % (existing_version, compiler_version)
            if not force:
                raise ConanException("Error, %s" % message)
            else:
                output.warn(message)
    else:
        vs_path = vs_installation_path(str(compiler_version))

        if not vs_path or not os.path.isdir(vs_path):
            raise ConanException(
                "VS non-existing installation: Visual Studio %s" %
                str(compiler_version))
        else:
            if int(compiler_version) > 14:
                vcvars_path = os.path.join(vs_path,
                                           "VC/Auxiliary/Build/vcvarsall.bat")
                command = [
                    'set "VSCMD_START_DIR=%%CD%%" && '
                    'call "%s" %s' % (vcvars_path, vcvars_arch)
                ]
            else:
                vcvars_path = os.path.join(vs_path, "VC/vcvarsall.bat")
                command = ['call "%s" %s' % (vcvars_path, vcvars_arch)]
        if int(compiler_version) >= 14:
            if winsdk_version:
                command.append(winsdk_version)
            if vcvars_ver:
                command.append("-vcvars_ver=%s" % vcvars_ver)

    if os_setting == 'WindowsStore':
        os_version_setting = settings.get_safe("os.version")
        if os_version_setting == '8.1':
            command.append('store 8.1')
        elif os_version_setting == '10.0':
            windows_10_sdk = find_windows_10_sdk()
            if not windows_10_sdk:
                raise ConanException(
                    "cross-compiling for WindowsStore 10 (UWP), "
                    "but Windows 10 SDK wasn't found")
            command.append('store %s' % windows_10_sdk)
        else:
            raise ConanException('unsupported Windows Store version %s' %
                                 os_version_setting)
    return " ".join(command)
Example #12
0
 def configure(self):
     del self.settings.compiler.libcxx
     if self.settings.compiler == "Visual Studio" and int(
             str(self.settings.compiler.version)) < 14:
         raise ConanException("Visual Studio >= 14 (2015) is required")
Example #13
0
 def configure(self):
     if self.settings.compiler == 'Visual Studio' and int(
             self.settings.compiler.version.value) < 14:
         raise ConanException(
             "{} requires Visual Studio version 14 or greater".format(
                 self.name))
Example #14
0
def create_package(conanfile,
                   package_id,
                   source_folder,
                   build_folder,
                   package_folder,
                   install_folder,
                   hook_manager,
                   conanfile_path,
                   ref,
                   local=False,
                   copy_info=False):
    """ copies built artifacts, libs, headers, data, etc. from build_folder to
    package folder
    """
    mkdir(package_folder)
    output = conanfile.output
    # Make the copy of all the patterns
    output.info("Generating the package")
    output.info("Package folder %s" % package_folder)

    try:
        conanfile.package_folder = package_folder
        conanfile.source_folder = source_folder
        conanfile.install_folder = install_folder
        conanfile.build_folder = build_folder

        hook_manager.execute("pre_package",
                             conanfile=conanfile,
                             conanfile_path=conanfile_path,
                             reference=ref,
                             package_id=package_id)

        package_output = ScopedOutput("%s package()" % output.scope, output)
        output.highlight("Calling package()")

        folders = [source_folder, build_folder
                   ] if source_folder != build_folder else [build_folder]
        conanfile.copy = FileCopier(folders, package_folder)
        with conanfile_exception_formatter(str(conanfile), "package"):
            with chdir(build_folder):
                conanfile.package()
    except Exception as e:
        if not local:
            os.chdir(build_folder)
            try:
                rmdir(package_folder)
            except Exception as e_rm:
                output.error("Unable to remove package folder %s\n%s" %
                             (package_folder, str(e_rm)))
                output.warn("**** Please delete it manually ****")

        if isinstance(e, ConanExceptionInUserConanfileMethod):
            raise
        raise ConanException(e)

    hook_manager.execute("post_package",
                         conanfile=conanfile,
                         conanfile_path=conanfile_path,
                         reference=ref,
                         package_id=package_id)

    manifest = _create_aux_files(install_folder, package_folder, conanfile,
                                 copy_info)
    _report_files_from_manifest(package_output, manifest)
    package_id = package_id or os.path.basename(package_folder)

    output.success("Package '%s' created" % package_id)

    prev = manifest.summary_hash
    output.info("Created package revision %s" % prev)
    return prev
Example #15
0
 def _ensure_exists(self, field):
     if field not in self._data:
         raise ConanException(
             option_not_exist_msg(field, list(self._data.keys())))
Example #16
0
 def _check_git_repo(self):
     try:
         self.run("status")
     except Exception:
         raise ConanException("Not a valid git repository")
Example #17
0
 def __getitem__(self, item):
     raise ConanException(
         "self.%s not defined. If you need it for a "
         "local command run 'conan install'" % field_name)
Example #18
0
def get_gnu_triplet(os_, arch, compiler=None):
    """
    Returns string with <machine>-<vendor>-<op_system> triplet (<vendor> can be omitted in practice)

    :param os_: os to be used to create the triplet
    :param arch: arch to be used to create the triplet
    :param compiler: compiler used to create the triplet (only needed fo windows)
    """

    if os_ == "Windows" and compiler is None:
        raise ConanException(
            "'compiler' parameter for 'get_gnu_triplet()' is not specified and "
            "needed for os=Windows")

    # Calculate the arch
    machine = {
        "x86": "i686" if os_ != "Linux" else "x86",
        "x86_64": "x86_64",
        "armv8": "aarch64",
        "armv8_32": "aarch64",  # https://wiki.linaro.org/Platform/arm64-ilp32
        "armv8.3": "aarch64",
        "asm.js": "asmjs",
        "wasm": "wasm32",
    }.get(arch, None)

    if not machine:
        # https://wiki.debian.org/Multiarch/Tuples
        if os_ == "AIX":
            if "ppc32" in arch:
                machine = "rs6000"
            elif "ppc64" in arch:
                machine = "powerpc"
        elif "arm" in arch:
            machine = "arm"
        elif "ppc32be" in arch:
            machine = "powerpcbe"
        elif "ppc64le" in arch:
            machine = "powerpc64le"
        elif "ppc64" in arch:
            machine = "powerpc64"
        elif "ppc32" in arch:
            machine = "powerpc"
        elif "mips64" in arch:
            machine = "mips64"
        elif "mips" in arch:
            machine = "mips"
        elif "sparcv9" in arch:
            machine = "sparc64"
        elif "sparc" in arch:
            machine = "sparc"
        elif "s390x" in arch:
            machine = "s390x-ibm"
        elif "s390" in arch:
            machine = "s390-ibm"
        elif "sh4" in arch:
            machine = "sh4"

    if machine is None:
        raise ConanException(
            "Unknown '%s' machine, Conan doesn't know how to "
            "translate it to the GNU triplet, please report at "
            " https://github.com/conan-io/conan/issues" % arch)

    # Calculate the OS
    if compiler == "gcc":
        windows_op = "w64-mingw32"
    elif compiler == "Visual Studio":
        windows_op = "windows-msvc"
    else:
        windows_op = "windows"

    op_system = {
        "Windows": windows_op,
        "Linux": "linux-gnu",
        "Darwin": "apple-darwin",
        "Android": "linux-android",
        "Macos": "apple-darwin",
        "iOS": "apple-darwin",
        "watchOS": "apple-darwin",
        "tvOS": "apple-darwin",
        # NOTE: it technically must be "asmjs-unknown-emscripten" or
        # "wasm32-unknown-emscripten", but it's not recognized by old config.sub versions
        "Emscripten": "local-emscripten",
        "AIX": "ibm-aix",
        "Neutrino": "nto-qnx"
    }.get(os_, os_.lower())

    if os_ in ("Linux", "Android"):
        if "arm" in arch and "armv8" not in arch:
            op_system += "eabi"

        if (arch == "armv5hf" or arch == "armv7hf") and os_ == "Linux":
            op_system += "hf"

        if arch == "armv8_32" and os_ == "Linux":
            op_system += "_ilp32"  # https://wiki.linaro.org/Platform/arm64-ilp32

    return "%s-%s" % (machine, op_system)
Example #19
0
    def __init__(self,
                 conanfile,
                 generator=None,
                 cmake_system_name=True,
                 parallel=True,
                 build_type=None,
                 toolset=None,
                 make_program=None,
                 set_cmake_flags=False,
                 msbuild_verbosity="minimal",
                 cmake_program=None,
                 generator_platform=None,
                 append_vcvars=False):
        """
        :param conanfile: Conanfile instance
        :param generator: Generator name to use or none to autodetect
        :param cmake_system_name: False to not use CMAKE_SYSTEM_NAME variable,
               True for auto-detect or directly a string with the system name
        :param parallel: Try to build with multiple cores if available
        :param build_type: Overrides default build type coming from settings
        :param toolset: Toolset name to use (such as llvm-vs2014) or none for default one,
                applies only to certain generators (e.g. Visual Studio)
        :param set_cmake_flags: whether or not to set CMake flags like CMAKE_CXX_FLAGS,
                CMAKE_C_FLAGS, etc. it's vital to set for certain projects
                (e.g. using CMAKE_SIZEOF_VOID_P or CMAKE_LIBRARY_ARCHITECTURE)
        :param msbuild_verbosity: verbosity level for MSBuild (in case of Visual Studio generator)
        :param cmake_program: Path to the custom cmake executable
        :param generator_platform: Generator platform name or none to autodetect (-A cmake option)
        """
        if not isinstance(conanfile, ConanFile):
            raise ConanException(
                "First argument of CMake() has to be ConanFile. Use CMake(self)"
            )

        self._append_vcvars = append_vcvars
        self._conanfile = conanfile
        self._settings = conanfile.settings
        self._build_type = build_type or conanfile.settings.get_safe(
            "build_type")
        self._cmake_program = os.getenv(
            "CONAN_CMAKE_PROGRAM") or cmake_program or "cmake"

        self.generator_platform = generator_platform
        self.generator = generator or get_generator(conanfile)

        if not self.generator:
            self._conanfile.output.warn(
                "CMake generator could not be deduced from settings")
        self.parallel = parallel
        # Initialize definitions (won't be updated if conanfile or any of these variables change)
        builder = CMakeDefinitionsBuilder(self._conanfile,
                                          cmake_system_name=cmake_system_name,
                                          make_program=make_program,
                                          parallel=parallel,
                                          generator=self.generator,
                                          set_cmake_flags=set_cmake_flags,
                                          forced_build_type=build_type,
                                          output=self._conanfile.output)
        # FIXME CONAN 2.0: CMake() interface should be always the constructor and self.definitions.
        # FIXME CONAN 2.0: Avoid properties and attributes to make the user interface more clear

        self.definitions = builder.get_definitions()
        self.definitions["CONAN_EXPORTED"] = "1"

        self.toolset = toolset or get_toolset(self._settings)
        self.build_dir = None
        self.msbuild_verbosity = os.getenv(
            "CONAN_MSBUILD_VERBOSITY") or msbuild_verbosity
Example #20
0
def load_conanfile_class(conanfile_path):
    loaded, filename = _parse_file(conanfile_path)
    try:
        return _parse_module(loaded, filename)
    except Exception as e:  # re-raise with file name
        raise ConanException("%s: %s" % (conanfile_path, str(e)))
Example #21
0
 def _get_conf(self, varname):
     """Gets the section from config file or raises an exception"""
     try:
         return self.items(varname)
     except NoSectionError:
         raise ConanException("Invalid configuration, missing %s" % varname)
Example #22
0
    def _raise_incorrect_components_definition(self, package_name, package_requires):
        if not self.components and not self.requires:
            return

        # Raise if mixing components
        if self.components and \
            (self.includedirs != [self._default_values.includedir] or
             self.libdirs != [self._default_values.libdir] or
             self.bindirs != [self._default_values.bindir] or
             self.resdirs != [self._default_values.resdir] or
             self.builddirs != [self._default_values.builddir] or
             self.frameworkdirs != [self._default_values.frameworkdir] or
             self.libs or
             self.system_libs or
             self.frameworks or
             self.defines or
             self.cflags or
             self.cxxflags or
             self.sharedlinkflags or
             self.exelinkflags or
             self.get_build_modules() or
             self.requires):
            raise ConanException("self.cpp_info.components cannot be used with self.cpp_info "
                                 "global values at the same time")
        if self._configs:
            raise ConanException("self.cpp_info.components cannot be used with self.cpp_info configs"
                                 " (release/debug/...) at the same time")

        pkg_requires = [require.ref.name for require in package_requires.values()]

        def _check_components_requires_instersection(comp_requires):
            reqs = [it.split(COMPONENT_SCOPE)[0] for it in comp_requires if COMPONENT_SCOPE in it]
            # Raise on components requires without package requires
            for pkg_require in pkg_requires:
                if package_requires[pkg_require].private or package_requires[pkg_require].override:
                    # Not standard requires, skip
                    continue
                if pkg_require not in reqs:
                    raise ConanException("Package require '%s' not used in components requires"
                                         % pkg_require)
            # Raise on components requires requiring inexistent package requires
            for comp_require in reqs:
                reason = None
                if comp_require not in pkg_requires:
                    reason = "not defined as a recipe requirement"
                elif package_requires[comp_require].private and package_requires[
                    comp_require].override:
                    reason = "it was defined as an overridden private recipe requirement"
                elif package_requires[comp_require].private:
                    reason = "it was defined as a private recipe requirement"
                elif package_requires[comp_require].override:
                    reason = "it was defined as an overridden recipe requirement"

                if reason is not None:
                    raise ConanException("Package require '%s' declared in components requires "
                                         "but %s" % (comp_require, reason))

        if self.components:
            # Raise on component name
            for comp_name, comp in self.components.items():
                if comp_name == package_name:
                    raise ConanException(
                        "Component name cannot be the same as the package name: '%s'"
                        % comp_name)

            # check that requires are used in components and check that components exists in requires
            requires_from_components = set()
            for comp_name, comp in self.components.items():
                requires_from_components.update(comp.requires)

            _check_components_requires_instersection(requires_from_components)
        else:
            _check_components_requires_instersection(self.requires)
Example #23
0
File: new.py Project: niosHD/conan
def cmd_new(ref,
            header=False,
            pure_c=False,
            test=False,
            exports_sources=False,
            bare=False,
            visual_versions=None,
            linux_gcc_versions=None,
            linux_clang_versions=None,
            osx_clang_versions=None,
            shared=None,
            upload_url=None,
            gitignore=None,
            gitlab_gcc_versions=None,
            gitlab_clang_versions=None):
    try:
        tokens = ref.split("@")
        name, version = tokens[0].split("/")
        if len(tokens) == 2:
            user, channel = tokens[1].split("/")
        else:
            user, channel = "user", "channel"

        pattern = re.compile('[\W_]+')
        package_name = pattern.sub('', name).capitalize()
    except ValueError:
        raise ConanException("Bad parameter, please use full package name,"
                             "e.g: MyLib/1.2.3@user/testing")

    # Validate it is a valid reference
    ConanFileReference(name, version, user, channel)

    if header and exports_sources:
        raise ConanException("'header' and 'sources' are incompatible options")
    if pure_c and (header or exports_sources):
        raise ConanException(
            "'pure_c' is incompatible with 'header' and 'sources'")
    if bare and (header or exports_sources):
        raise ConanException(
            "'bare' is incompatible with 'header' and 'sources'")

    if header:
        files = {
            "conanfile.py":
            conanfile_header.format(name=name,
                                    version=version,
                                    package_name=package_name)
        }
    elif exports_sources:
        files = {
            "conanfile.py":
            conanfile_sources.format(name=name,
                                     version=version,
                                     package_name=package_name),
            "src/hello.cpp":
            hello_cpp,
            "src/hello.h":
            hello_h,
            "src/CMakeLists.txt":
            cmake
        }
    elif bare:
        files = {
            "conanfile.py":
            conanfile_bare.format(name=name,
                                  version=version,
                                  package_name=package_name)
        }
    else:
        files = {
            "conanfile.py":
            conanfile.format(name=name,
                             version=version,
                             package_name=package_name)
        }
        if pure_c:
            config = "\n    def configure(self):\n        del self.settings.compiler.libcxx"
            files["conanfile.py"] = files["conanfile.py"] + config

    if test:
        files["test_package/conanfile.py"] = test_conanfile.format(
            name=name,
            version=version,
            user=user,
            channel=channel,
            package_name=package_name)
        files["test_package/CMakeLists.txt"] = test_cmake
        files["test_package/example.cpp"] = test_main

    if gitignore:
        files[".gitignore"] = gitignore_template

    files.update(
        ci_get_files(name, version, user, channel, visual_versions,
                     linux_gcc_versions, linux_clang_versions,
                     osx_clang_versions, shared, upload_url,
                     gitlab_gcc_versions, gitlab_clang_versions))
    return files
Example #24
0
 def update(self, remote_name, url, verify_ssl=True, insert=None):
     if remote_name not in self._remotes:
         raise ConanException("Remote '%s' not found in remotes" %
                              remote_name)
     self._add_update(remote_name, url, verify_ssl, insert)
Example #25
0
    def validate(self):
        if self._value is None and "None" not in self._definition:
            raise ConanException(undefined_value(self._name))

        if isinstance(self._definition, dict):
            self._definition[self._value].validate()
Example #26
0
    def __init__(self,
                 conanfile,
                 generator=None,
                 cmake_system_name=True,
                 parallel=True,
                 build_type=None,
                 toolset=None,
                 make_program=None,
                 set_cmake_flags=False):
        """
        :param settings_or_conanfile: Conanfile instance (or settings for retro compatibility)
        :param generator: Generator name to use or none to autodetect
        :param cmake_system_name: False to not use CMAKE_SYSTEM_NAME variable,
               True for auto-detect or directly a string with the system name
        :param parallel: Try to build with multiple cores if available
        :param build_type: Overrides default build type comming from settings
        :param toolset: Toolset name to use (such as llvm-vs2014) or none for default one,
                applies only to certain generators (e.g. Visual Studio)
        :param set_cmake_flags: whether or not to set CMake flags like CMAKE_CXX_FLAGS, CMAKE_C_FLAGS, etc.
               it's vital to set for certain projects (e.g. using CMAKE_SIZEOF_VOID_P or CMAKE_LIBRARY_ARCHITECTURE)
        """
        if not isinstance(conanfile, ConanFile):
            raise ConanException(
                "First argument of CMake() has to be ConanFile. Use CMake(self)"
            )

        self._settings = conanfile.settings
        self._conanfile = conanfile

        self._os = self._settings.get_safe("os")
        self._os_build, _, self._os_host, _ = get_cross_building_settings(
            self._settings)

        self._compiler = self._settings.get_safe("compiler")
        self._compiler_version = self._settings.get_safe("compiler.version")
        self._arch = self._settings.get_safe("arch")
        self._op_system_version = self._settings.get_safe("os.version")
        self._libcxx = self._settings.get_safe("compiler.libcxx")
        self._runtime = self._settings.get_safe("compiler.runtime")
        self._build_type = self._settings.get_safe("build_type")
        self._cppstd = self._settings.get_safe("cppstd")

        self.generator = generator or self._generator()
        self.toolset = self._toolset(toolset)
        self.build_dir = None
        self._cmake_system_name = _get_env_cmake_system_name()
        if self._cmake_system_name is None:  # Not overwritten using environment
            self._cmake_system_name = cmake_system_name
        self.parallel = parallel
        self._set_cmake_flags = set_cmake_flags
        self.definitions = self._get_cmake_definitions()
        if build_type and build_type != self._build_type:
            # Call the setter to warn and update the definitions if needed
            self.build_type = build_type

        make_program = os.getenv("CONAN_MAKE_PROGRAM") or make_program
        if make_program:
            if not tools.which(make_program):
                self._conanfile.output.warn(
                    "The specified make program '%s' cannot be found"
                    "and will be ignored" % make_program)
            else:
                self._conanfile.output.info(
                    "Using '%s' as CMAKE_MAKE_PROGRAM" % make_program)
                self.definitions["CMAKE_MAKE_PROGRAM"] = make_program
Example #27
0
File: info.py Project: niosHD/conan
 def _get_key(self, item):
     for reference in self._data:
         if reference.conan.name == item:
             return reference
     raise ConanException("No requirement matching for %s" % (item))
Example #28
0
 def validate(self):
     if self._value is None and "None" not in self._possible_values:
         raise ConanException(option_undefined_msg(self._name))
Example #29
0
def call_system_requirements(conanfile, output):
    try:
        return conanfile.system_requirements()
    except Exception as e:
        output.error("while executing system_requirements(): %s" % str(e))
        raise ConanException("Error in system requirements")
Example #30
0
def config_source(export_folder, src_folder, conan_file, output, force=False):
    """ creates src folder and retrieve, calling source() from conanfile
    the necessary source code
    """
    dirty = os.path.join(src_folder, DIRTY_FILE)

    def remove_source(raise_error=True):
        output.warn("This can take a while for big packages")
        try:
            rmdir(src_folder)
        except BaseException as e_rm:
            save(dirty, "")  # Creation of DIRTY flag
            msg = str(e_rm)
            if six.PY2:
                msg = str(e_rm).decode("latin1")  # Windows prints some chars in latin1
            output.error("Unable to remove source folder %s\n%s" % (src_folder, msg))
            output.warn("**** Please delete it manually ****")
            if raise_error or isinstance(e_rm, KeyboardInterrupt):
                raise ConanException("Unable to remove source folder")

    if force:
        output.warn("Forced removal of source folder")
        remove_source()
    elif os.path.exists(dirty):
        output.warn("Trying to remove dirty source folder")
        remove_source()
    elif conan_file.build_policy_always:
        output.warn("Detected build_policy 'always', trying to remove source folder")
        remove_source()

    if not os.path.exists(src_folder):
        output.info('Configuring sources in %s' % src_folder)
        shutil.copytree(export_folder, src_folder)
        # Now move the export-sources to the right location
        source_sources_folder = os.path.join(src_folder, EXPORT_SOURCES_DIR)
        if os.path.exists(source_sources_folder):
            for filename in os.listdir(source_sources_folder):
                shutil.move(os.path.join(source_sources_folder, filename),
                            os.path.join(src_folder, filename))
            # finally remove copied folder
            os.rmdir(source_sources_folder)
        for f in (EXPORT_TGZ_NAME, EXPORT_SOURCES_TGZ_NAME, CONANFILE+"c", CONANFILE+"o"):
            try:
                os.remove(os.path.join(src_folder, f))
            except OSError:
                pass
        try:
            shutil.rmtree(os.path.join(src_folder, "__pycache__"))
        except OSError:
            pass

        save(dirty, "")  # Creation of DIRTY flag
        os.chdir(src_folder)
        try:
            conan_file.source()
            os.remove(dirty)  # Everything went well, remove DIRTY flag
        except Exception as e:
            os.chdir(export_folder)
            # in case source() fails (user error, typically), remove the src_folder
            # and raise to interrupt any other processes (build, package)
            output.warn("Trying to remove dirty source folder")
            remove_source(raise_error=False)
            msg = format_conanfile_exception(output.scope, "source", e)
            raise ConanException(msg)