def build_environment(self): """ collects the buildtime information from dependencies. This is the typical use case of build_requires defining information for consumers """ build_env = Environment() # First visit the direct build_requires for build_require in self._conanfile.dependencies.build_requires: # Lower priority, the runenv of all transitive "requires" of the build requires for require in build_require.dependencies.requires: build_env.compose(self._collect_transitive_runenv(require)) # Second, the implicit self information in build_require.cpp_info build_env.compose(self._runenv_from_cpp_info(build_require.cpp_info)) # Finally, higher priority, explicit buildenv_info if build_require.buildenv_info: build_env.compose(build_require.buildenv_info) # Requires in host context can also bring some direct buildenv_info def _collect_transitive_buildenv(d): r = Environment() for child in d.dependencies.requires: r.compose(_collect_transitive_buildenv(child)) # Then the explicit self if d.buildenv_info: r.compose(d.buildenv_info) return r for require in self._conanfile.dependencies.requires: build_env.compose(_collect_transitive_buildenv(require)) # The profile environment has precedence, applied last profile_env = self._conanfile.buildenv build_env.compose(profile_env) return build_env
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(profile_env) for require, build_require in self._conanfile.dependencies.build.items(): if require.direct: # higher priority, explicit buildenv_info if build_require.buildenv_info: build_env.compose(build_require.buildenv_info) # Lower priority, the runenv of all transitive "requires" of the build requires if build_require.runenv_info: build_env.compose(build_require.runenv_info) # Then the implicit build_env.compose(runenv_from_cpp_info(build_require.cpp_info)) # Requires in host context can also bring some direct buildenv_info for require in self._conanfile.dependencies.host.values(): if require.buildenv_info: build_env.compose(require.buildenv_info) return build_env
def _collect_transitive_buildenv(d): r = Environment() for child in d.dependencies.requires: r.compose(_collect_transitive_buildenv(child)) # Then the explicit self if d.buildenv_info: r.compose(d.buildenv_info) return r
def test_compose_path_combinations(op1, v1, op2, v2, result): env = Environment() if op1 != "unset": getattr(env, op1+"_path")("MyVar", v1) else: env.unset("MyVar") env2 = Environment() if op2 != "unset": getattr(env2, op2+"_path")("MyVar", v2) else: env2.unset("MyVar") env.compose(env2) assert env.value("MyVar", pathsep=":") == result
def test_compose_combinations(op1, v1, s1, op2, v2, s2, result): env = Environment() if op1 != "unset": getattr(env, op1)("MyVar", v1, s1) else: env.unset("MyVar") env2 = Environment() if op2 != "unset": getattr(env2, op2)("MyVar", v2, s2) else: env2.unset("MyVar") env.compose(env2) assert env.value("MyVar") == result
def test_compose_combinations(op1, v1, s1, op2, v2, s2, result): env = Environment() if op1 != "unset": getattr(env, op1)("MyVar", v1, s1) else: env.unset("MyVar") env2 = Environment() if op2 != "unset": getattr(env2, op2)("MyVar", v2, s2) else: env2.unset("MyVar") env.compose(env2) with environment_append({"MyVar": "MyVar"}): assert env.get("MyVar") == result assert env.var("MyVar").get_str("{name}") == result
def environment(self): """ collects the runtime information from dependencies. For normal libraries should be very occasional """ runenv = Environment() # FIXME: Missing profile info # FIXME: Cache value? host_req = self._conanfile.dependencies.host test_req = self._conanfile.dependencies.test for _, dep in list(host_req.items()) + list(test_req.items()): if dep.runenv_info: runenv.compose(dep.runenv_info) runenv.compose(runenv_from_cpp_info(dep.cpp_info)) return runenv
def run_environment(self): """ collects the runtime information from dependencies. For normal libraries should be very occasional """ runenv = Environment() # At the moment we are adding "test-requires" (build_requires in host context) # to the "runenv", but this will be investigated for build_require in self._conanfile.dependencies.build_requires: if build_require.context == CONTEXT_HOST: runenv.compose(self._collect_transitive_runenv(build_require)) for require in self._conanfile.dependencies.requires: runenv.compose(self._collect_transitive_runenv(require)) # FIXME: Missing profile info result = runenv return result
def test_dict_access(): env = Environment() env.append("MyVar", "MyValue", separator="@") ret = env.items() assert dict(ret) == {"MyVar": "MyValue"} env = Environment() env.prepend("MyVar", "MyValue", separator="@") ret = env.items() assert dict(ret) == {"MyVar": "MyValue"} assert env["MyVar"] == "MyValue" env2 = Environment() env2.define("MyVar", "MyValue2") env.compose(env2) ret = env.items() assert dict(ret) == {"MyVar": "MyValue@MyValue2"} with pytest.raises(KeyError): _ = env["Missing"] # With previous values in the environment env = Environment() env.prepend("MyVar", "MyValue", separator="@") old_env = dict(os.environ) os.environ.update({"MyVar": "PreviousValue"}) try: assert env["MyVar"] == "MyValue@PreviousValue" finally: os.environ.clear() os.environ.update(old_env) env = Environment() env.append_path("MyVar", "MyValue") old_env = dict(os.environ) os.environ.update({"MyVar": "PreviousValue"}) try: assert env["MyVar"] == "PreviousValue{}MyValue".format(os.pathsep) with env.apply(): assert os.getenv("MyVar") == "PreviousValue{}MyValue".format( os.pathsep) finally: os.environ.clear() os.environ.update(old_env) assert list(env.keys()) == ["MyVar"] assert dict(env.items()) == {"MyVar": "MyValue"}
def test_compose(): env = Environment() env.define("MyVar", "MyValue") env.define("MyVar2", "MyValue2") env.define("MyVar3", "MyValue3") env.define("MyVar4", "MyValue4") env.unset("MyVar5") env2 = Environment() env2.define("MyVar", "MyNewValue") env2.append("MyVar2", "MyNewValue2") env2.prepend("MyVar3", "MyNewValue3") env2.unset("MyVar4") env2.define("MyVar5", "MyNewValue5") env.compose(env2) assert env.value("MyVar") == "MyValue" assert env.value("MyVar2") == 'MyValue2' assert env.value("MyVar3") == 'MyValue3' assert env.value("MyVar4") == "MyValue4" assert env.value("MyVar5") == ''
def _collect_transitive_runenv(self, d): r = Environment() for child in d.dependencies.requires: r.compose(self._collect_transitive_runenv(child)) # Apply "d" runenv, first the implicit r.compose(self._runenv_from_cpp_info(d.cpp_info)) # Then the explicit if d.runenv_info: r.compose(d.runenv_info) return r
def build_environment(self): """ collects the buildtime information from dependencies. This is the typical use case of build_requires defining information for consumers """ build_env = Environment() # Top priority: profile profile_env = self._conanfile.buildenv build_env.compose(profile_env) # First visit the direct build_requires transitive_requires = [] for build_require in self._conanfile.dependencies.build_requires: # higher priority, explicit buildenv_info if build_require.buildenv_info: build_env.compose(build_require.buildenv_info) # Second, the implicit self information in build_require.cpp_info build_env.compose( self._runenv_from_cpp_info(build_require.cpp_info)) # Lower priority, the runenv of all transitive "requires" of the build requires for require in build_require.dependencies.requires: if require not in transitive_requires: transitive_requires.append(require) self._apply_transitive_runenv(transitive_requires, build_env) # Requires in host context can also bring some direct buildenv_info def _apply_transitive_buildenv(reqs, env): all_requires = [] while reqs: new_requires = [] for r in reqs: # The explicit has more priority if r.buildenv_info: env.compose(r.buildenv_info) for transitive in r.dependencies.requires: # Avoid duplication/repetitions if transitive not in new_requires and transitive not in all_requires: new_requires.append(transitive) reqs = new_requires _apply_transitive_buildenv(self._conanfile.dependencies.requires, build_env) return build_env