def __init__(self, shared=None, options=None, options_values=None): options = options or "" self.command = None self.path = None self.settings = None self.options = Options(PackageOptions.loads(options)) if options_values: for var, value in options_values.items(): self.options._data[var] = value self.deps_cpp_info = MockDepsCppInfo( ) # ("deps_cpp_info", "sysroot")("/path/to/sysroot") self.deps_cpp_info.sysroot = "/path/to/sysroot" self.output = TestBufferConanOutput() self.in_local_cache = False if shared is not None: self.options = namedtuple("options", "shared")(shared) self.should_configure = True self.should_build = True self.should_install = True self.should_test = True self.generators = [] self.captured_env = {} self.deps_env_info = DepsEnvInfo() self.env_info = EnvInfo() self.deps_user_info = DepsUserInfo() self._conan_env_values = EnvValues() self.layout = Layout() self.layout.set_base_source_folder(".") self.layout.set_base_build_folder(".") self.layout.set_base_install_folder("myinstallfolder")
def __init__(self, output, runner, display_name="", user=None, channel=None): # an output stream (writeln, info, warn error) self.output = ScopedOutput(display_name, output) self.display_name = display_name # something that can run commands, as os.sytem self._conan_runner = runner self._conan_user = user self._conan_channel = channel self.compatible_packages = [] self._conan_using_build_profile = False self.layout = Layout()
def __init__(self, output, runner, display_name="", user=None, channel=None): # an output stream (writeln, info, warn error) self.output = ScopedOutput(display_name, output) self.display_name = display_name # something that can run commands, as os.sytem self._conan_runner = runner self._conan_user = user self._conan_channel = channel self.compatible_packages = [] self._conan_using_build_profile = False self._conan_requester = None self.layout = Layout() self.buildenv_info = Environment() self.runenv_info = Environment() self._conan_buildenv = None # The profile buildenv, will be assigned initialize() self._conan_node = None # access to container Node object, to access info, context, deps... self.virtualenv = True # Set to false to opt-out automatic usage of VirtualEnv self._conan_new_cpp_info = None # Will be calculated lazy in the getter
def __init__(self, output, runner, display_name="", user=None, channel=None, requester=None): # an output stream (writeln, info, warn error) self.output = ScopedOutput(display_name, output) self.display_name = display_name # something that can run commands, as os.sytem self._conan_runner = runner self._conan_user = user self._conan_channel = channel self.compatible_packages = [] self._conan_using_build_profile = False self._conan_requester = requester self.layout = Layout() self.buildenv_info = Environment() self.runenv_info = Environment() self._conan_buildenv = None # The profile buildenv, will be assigned initialize()
def __init__(self, settings, options=None, runner=None): self.layout = Layout() self.deps_cpp_info = MockDepsCppInfo() self.settings = settings self.runner = runner self.options = options or MockOptions({}) self.generators = [] self.output = TestBufferConanOutput() self.should_configure = True self.should_build = True self.should_install = True self.should_test = True self.package_folder = None
class ConanFile(object): """ The base class for all package recipes """ name = None version = None # Any str, can be "1.1" or whatever url = None # The URL where this File is located, as github, to collaborate in package # The license of the PACKAGE, just a shortcut, does not replace or # change the actual license of the source code license = None author = None # Main maintainer/responsible for the package, any format description = None topics = None homepage = None build_policy = None short_paths = False apply_env = True # Apply environment variables from requires deps_env_info and profiles exports = None exports_sources = None generators = ["txt"] revision_mode = "hash" # Vars to control the build steps (build(), package()) should_configure = True should_build = True should_install = True should_test = True in_local_cache = True develop = False # Defaulting the reference fields default_channel = None default_user = None # Settings and Options settings = None options = None default_options = None provides = None deprecated = None # layout layout = None def __init__(self, output, runner, display_name="", user=None, channel=None): # an output stream (writeln, info, warn error) self.output = ScopedOutput(display_name, output) self.display_name = display_name # something that can run commands, as os.sytem self._conan_runner = runner self._conan_user = user self._conan_channel = channel self.compatible_packages = [] self._conan_using_build_profile = False self._conan_requester = None self.layout = Layout() self.buildenv_info = Environment() self.runenv_info = Environment() self._conan_buildenv = None # The profile buildenv, will be assigned initialize() self._conan_node = None # access to container Node object, to access info, context, deps... self.virtualenv = True # Set to false to opt-out automatic usage of VirtualEnv @property def context(self): return self._conan_node.context @property def dependencies(self): return ConanFileDependencies(self._conan_node) @property def ref(self): return self._conan_node.ref @property def pref(self): return self._conan_node.pref @property def buildenv(self): # Lazy computation of the package buildenv based on the profileone if not isinstance(self._conan_buildenv, Environment): # TODO: missing user/channel ref_str = "{}/{}".format(self.name, self.version) self._conan_buildenv = self._conan_buildenv.get_env(ref_str) return self._conan_buildenv def initialize(self, settings, env, buildenv=None): self._conan_buildenv = buildenv if isinstance(self.generators, str): self.generators = [self.generators] # User defined options self.options = create_options(self) self.requires = create_requirements(self) self.settings = create_settings(self, settings) conan_v2_error( "Setting 'cppstd' is deprecated in favor of 'compiler.cppstd'," " please update your recipe.", 'cppstd' in self.settings.fields) # needed variables to pack the project self.cpp_info = None # Will be initialized at processing time self._conan_dep_cpp_info = None # Will be initialized at processing time self.deps_cpp_info = DepsCppInfo() # environment variables declared in the package_info self.env_info = None # Will be initialized at processing time self.deps_env_info = DepsEnvInfo() # user declared variables self.user_info = None # Keys are the package names (only 'host' if different contexts) self.deps_user_info = DepsUserInfo() # user specified env variables self._conan_env_values = env.copy() # user specified -e if self.description is not None and not isinstance( self.description, six.string_types): raise ConanException("Recipe 'description' must be a string.") @property def source_folder(self): return self.layout.source_folder @source_folder.setter def source_folder(self, folder): self.layout.set_base_source_folder(folder) @property def build_folder(self): return self.layout.build_folder @build_folder.setter def build_folder(self, folder): self.layout.set_base_build_folder(folder) @property def package_folder(self): return self.layout.base_package_folder @package_folder.setter def package_folder(self, folder): self.layout.set_base_package_folder(folder) @property def install_folder(self): return self.layout.base_install_folder @install_folder.setter def install_folder(self, folder): self.layout.set_base_install_folder(folder) @property def env(self): """Apply the self.deps_env_info into a copy of self._conan_env_values (will prioritize the self._conan_env_values, user specified from profiles or -e first, then inherited)""" # Cannot be lazy cached, because it's called in configure node, and we still don't have # the deps_env_info objects available tmp_env_values = self._conan_env_values.copy() tmp_env_values.update(self.deps_env_info) ret, multiple = tmp_env_values.env_dicts(self.name, self.version, self._conan_user, self._conan_channel) ret.update(multiple) return ret @property def channel(self): if not self._conan_channel: _env_channel = os.getenv("CONAN_CHANNEL") conan_v2_error( "Environment variable 'CONAN_CHANNEL' is deprecated", _env_channel) self._conan_channel = _env_channel or self.default_channel if not self._conan_channel: raise ConanException( "channel not defined, but self.channel is used in conanfile" ) return self._conan_channel @property def user(self): if not self._conan_user: _env_username = os.getenv("CONAN_USERNAME") conan_v2_error( "Environment variable 'CONAN_USERNAME' is deprecated", _env_username) self._conan_user = _env_username or self.default_user if not self._conan_user: raise ConanException( "user not defined, but self.user is used in conanfile") return self._conan_user def collect_libs(self, folder=None): conan_v2_error( "'self.collect_libs' is deprecated, use 'tools.collect_libs(self)' instead" ) return tools.collect_libs(self, folder=folder) @property def build_policy_missing(self): return self.build_policy == "missing" @property def build_policy_always(self): return self.build_policy == "always" def source(self): pass def system_requirements(self): """ this method can be overwritten to implement logic for system package managers, as apt-get You can define self.global_system_requirements = True, if you want the installation to be for all packages (not depending on settings/options/requirements) """ def config_options(self): """ modify options, probably conditioned to some settings. This call is executed before config_settings. E.g. if self.settings.os == "Windows": del self.options.shared # shared/static not supported in win """ def configure(self): """ modify settings, probably conditioned to some options. This call is executed after config_options. E.g. if self.options.header_only: self.settings.clear() This is also the place for conditional requirements """ def build(self): """ build your project calling the desired build tools as done in the command line. E.g. self.run("cmake --build .") Or use the provided build helpers. E.g. cmake.build() """ self.output.warn("This conanfile has no build step") def package(self): """ package the needed files from source and build folders. E.g. self.copy("*.h", src="src/includes", dst="includes") """ self.output.warn("This conanfile has no package step") def package_info(self): """ define cpp_build_info, flags, etc """ def run(self, command, output=True, cwd=None, win_bash=False, subsystem=None, msys_mingw=True, ignore_errors=False, run_environment=False, with_login=True, env="conanbuildenv"): command = environment_wrap_command(env, command) def _run(): if not win_bash: return self._conan_runner(command, output, os.path.abspath(RUN_LOG_NAME), cwd) # FIXME: run in windows bash is not using output return tools.run_in_windows_bash(self, bashcmd=command, cwd=cwd, subsystem=subsystem, msys_mingw=msys_mingw, with_login=with_login) if run_environment: # When using_build_profile the required environment is already applied through # 'conanfile.env' in the contextmanager 'get_env_context_manager' with tools.run_environment( self) if not self._conan_using_build_profile else no_op(): if OSInfo().is_macos and isinstance(command, string_types): # Security policy on macOS clears this variable when executing /bin/sh. To # keep its value, set it again inside the shell when running the command. command = 'DYLD_LIBRARY_PATH="%s" DYLD_FRAMEWORK_PATH="%s" %s' % \ (os.environ.get('DYLD_LIBRARY_PATH', ''), os.environ.get("DYLD_FRAMEWORK_PATH", ''), command) retcode = _run() else: retcode = _run() if not ignore_errors and retcode != 0: raise ConanException("Error %d while executing %s" % (retcode, command)) return retcode def package_id(self): """ modify the binary info, typically to narrow values e.g.: self.info.settings.compiler = "Any" => All compilers will generate same ID """ 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") def __repr__(self): return self.display_name