conan/tools/env/virtualbuildenv.py
from conan.tools.env import Environment
from conan.tools.env.virtualrunenv import runenv_from_cpp_info
class VirtualBuildEnv:
""" captures the conanfile environment that is defined from its
dependencies, and also from profiles
"""
def __init__(self, conanfile):
self._conanfile = conanfile
self._conanfile.virtualbuildenv = False
self.basename = "conanbuildenv"
# TODO: Make this use the settings_build
self.configuration = conanfile.settings.get_safe("build_type")
if self.configuration:
self.configuration = self.configuration.lower()
self.arch = conanfile.settings.get_safe("arch")
if self.arch:
self.arch = self.arch.lower()
@property
def _filename(self):
f = self.basename
if self.configuration:
f += "-" + self.configuration.replace(".", "_")
if self.arch:
f += "-" + self.arch.replace(".", "_")
return f
def environment(self):
""" collects the buildtime information from dependencies. This is the typical use case
of build_requires defining information for consumers
"""
# FIXME: Cache value?
build_env = Environment()
# Top priority: profile
profile_env = self._conanfile.buildenv
build_env.compose_env(profile_env)
build_requires = self._conanfile.dependencies.build.topological_sort
for require, build_require in reversed(build_requires.items()):
if require.direct: # Only buildenv_info from direct deps is propagated
# higher priority, explicit buildenv_info
if build_require.buildenv_info:
build_env.compose_env(build_require.buildenv_info)
# Lower priority, the runenv of all transitive "requires" of the build requires
if build_require.runenv_info:
build_env.compose_env(build_require.runenv_info)
# Then the implicit
if hasattr(self._conanfile, "settings_build"):
os_name = self._conanfile.settings_build.get_safe("os")
else:
os_name = self._conanfile.settings.get_safe("os")
build_env.compose_env(runenv_from_cpp_info(self._conanfile, build_require, os_name))
# Requires in host context can also bring some direct buildenv_info
host_requires = self._conanfile.dependencies.host.topological_sort
for require in reversed(host_requires.values()):
if require.buildenv_info:
build_env.compose_env(require.buildenv_info)
return build_env
def vars(self, scope="build"):
return self.environment().vars(self._conanfile, scope=scope)
def generate(self, scope="build"):
build_env = self.environment()
build_env.vars(self._conanfile, scope=scope).save_script(self._filename)