def _build(self, build_type=None, target=None): bf = self._conanfile.build_folder if self._build_folder: bf = os.path.join(self._conanfile.build_folder, self._build_folder) if build_type and not self._is_multiconfiguration: self._conanfile.output.error("Don't specify 'build_type' at build time for " "single-config build systems") bt = build_type or self._conanfile.settings.get_safe("build_type") if not bt: conan_v2_behavior("build_type setting should be defined.", v1_behavior=self._conanfile.output.warn) if bt and self._is_multiconfiguration: build_config = "--config %s" % bt else: build_config = "" args = [] if target is not None: args = ["--target", target] build_flags = _compute_build_flags(self._conanfile, self._generator, self._parallel, self._msbuild_verbosity) if build_flags: args += ['--'] + build_flags arg_list = [args_to_string([bf]), build_config, args_to_string(args)] command = "%s --build %s" % (self._cmake_program, join_arguments(arg_list)) self._conanfile.output.info("CMake command: %s" % command) self._conanfile.run(command)
def print_inspect(self, inspect, raw=False): for k, v in inspect.items(): if k == "default_options": if not isinstance(v, dict): conan_v2_behavior( "Declare 'default_options' as a dictionary") if isinstance(v, str): v = OptionsValues.loads(v) elif isinstance(v, tuple): v = OptionsValues(v) elif isinstance(v, list): v = OptionsValues(tuple(v)) elif isinstance(v, dict): v = OptionsValues(v) if raw: self._out.write(str(v)) else: if isinstance(v, (dict, OptionsValues)): self._out.writeln("%s:" % k) for ok, ov in sorted(v.items()): self._out.writeln(" %s: %s" % (ok, ov)) else: self._out.writeln("%s: %s" % (k, str(v)))
def initialize(self, settings, env): 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) if 'cppstd' in self.settings.fields: conan_v2_behavior( "Setting 'cppstd' is deprecated in favor of 'compiler.cppstd'," " please update your recipe.", v1_behavior=self.output.warn) # needed variables to pack the project self.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, and the values a dict with the vars self.deps_user_info = DepsUserInfo() # user specified env variables self._conan_env_values = env.copy() # user specified -e
def initialize(self, settings, env): 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) if 'cppstd' in self.settings.fields: conan_v2_behavior("Setting 'cppstd' is deprecated in favor of 'compiler.cppstd'," " please update your recipe.", v1_behavior=self.output.warn) # 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.")
def run_configure_method(conanfile, down_options, down_ref, ref): """ Run all the config-related functions for the given conanfile object """ # Avoid extra time manipulating the sys.path for python with get_env_context_manager(conanfile, without_python=True): if hasattr(conanfile, "config"): conan_v2_behavior("config() has been deprecated. " "Use config_options() and configure()", v1_behavior=conanfile.output.warn) with conanfile_exception_formatter(str(conanfile), "config"): conanfile.config() with conanfile_exception_formatter(str(conanfile), "config_options"): conanfile.config_options() conanfile.options.propagate_upstream(down_options, down_ref, ref) if hasattr(conanfile, "config"): with conanfile_exception_formatter(str(conanfile), "config"): conanfile.config() with conanfile_exception_formatter(str(conanfile), "configure"): conanfile.configure() conanfile.settings.validate() # All has to be ok! conanfile.options.validate() _validate_fpic(conanfile)
def _run(self, command): compiler = self._settings.get_safe("compiler") if not compiler: conan_v2_behavior("compiler setting should be defined.", v1_behavior=self._conanfile.output.warn) the_os = self._settings.get_safe("os") is_clangcl = the_os == "Windows" and compiler == "clang" is_msvc = compiler == "Visual Studio" is_intel = compiler == "intel" context = tools.no_op() if (is_msvc or is_clangcl) and platform.system() == "Windows": if self.generator in [ "Ninja", "NMake Makefiles", "NMake Makefiles JOM" ]: vcvars_dict = tools.vcvars_dict(self._settings, force=True, filter_known_paths=False, output=self._conanfile.output) context = _environment_add(vcvars_dict, post=self._append_vcvars) elif is_intel: if self.generator in [ "Ninja", "NMake Makefiles", "NMake Makefiles JOM", "Unix Makefiles" ]: intel_compilervars_dict = tools.intel_compilervars_dict( self._conanfile, force=True) context = _environment_add(intel_compilervars_dict, post=self._append_vcvars) with context: self._conanfile.run(command)
def build(self, args=None, build_dir=None, target=None): if not self._conanfile.should_build: return if not self._build_type: conan_v2_behavior("build_type setting should be defined.", v1_behavior=self._conanfile.output.warn) self._build(args, build_dir, target)
def msvc_build_command(settings, sln_path, targets=None, upgrade_project=True, build_type=None, arch=None, parallel=True, force_vcvars=False, toolset=None, platforms=None, output=None): """ Do both: set the environment variables and call the .sln build """ conan_v2_behavior( "'tools.msvc_build_command' is deprecated, use 'MSBuild()' helper instead" ) vcvars_cmd = vcvars_command(settings, force=force_vcvars, output=output) build = build_sln_command(settings, sln_path, targets, upgrade_project, build_type, arch, parallel, toolset=toolset, platforms=platforms, output=output) command = "%s && %s" % (vcvars_cmd, build) return command
def build_sln_command(settings, sln_path, targets=None, upgrade_project=True, build_type=None, arch=None, parallel=True, toolset=None, platforms=None, output=None, verbosity=None, definitions=None): """ Use example: build_command = build_sln_command(self.settings, "myfile.sln", targets=["SDL2_image"]) command = "%s && %s" % (tools.vcvars_command(self.settings), build_command) self.run(command) """ conan_v2_behavior("'tools.build_sln_command' is deprecated, use 'MSBuild()' helper instead") from conans.client.build.msbuild import MSBuild tmp = MSBuild(settings) output = default_output(output, fn_name='conans.client.tools.win.build_sln_command') tmp._output = output # Generate the properties file props_file_contents = tmp._get_props_file_contents(definitions) tmp_path = os.path.join(mkdir_tmp(), ".conan_properties") save(tmp_path, props_file_contents) # Build command command = tmp.get_command(sln_path, tmp_path, targets=targets, upgrade_project=upgrade_project, build_type=build_type, arch=arch, parallel=parallel, toolset=toolset, platforms=platforms, use_env=False, verbosity=verbosity) return command
def user(self): if not self._conan_user: _env_username = os.getenv("CONAN_USERNAME") if _env_username: conan_v2_behavior("Environment variable 'CONAN_USERNAME' is deprecated") 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 channel(self): if not self._conan_channel: _env_channel = os.getenv("CONAN_CHANNEL") if _env_channel: conan_v2_behavior("Environment variable 'CONAN_CHANNEL' is deprecated") 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
def __call__(self, reference): conan_v2_behavior("Old syntax for python_requires is deprecated") if not self.valid: raise ConanException("Invalid use of python_requires(%s)" % reference) try: python_req = self._look_for_require(reference) self._requires.append(python_req) return python_req.module except NotFoundException: raise ConanException('Unable to find python_requires("{}") in remotes'.format(reference))
def __init__(self, conanfile, win_bash=False, include_rpath_flags=False): """ FIXME: include_rpath_flags CONAN 2.0 to default True? Could break many packages in center """ self._conanfile = conanfile self._win_bash = win_bash self._include_rpath_flags = include_rpath_flags self.subsystem = OSInfo().detect_windows_subsystem( ) if self._win_bash else None self._deps_cpp_info = conanfile.deps_cpp_info self._os = conanfile.settings.get_safe("os") self._os_version = conanfile.settings.get_safe("os.version") self._arch = conanfile.settings.get_safe("arch") self._os_target, self._arch_target = get_target_os_arch(conanfile) self._build_type = conanfile.settings.get_safe("build_type") self._compiler = conanfile.settings.get_safe("compiler") if not self._compiler: conan_v2_behavior("compiler setting should be defined.", v1_behavior=self._conanfile.output.warn) self._compiler_version = conanfile.settings.get_safe( "compiler.version") self._compiler_runtime = conanfile.settings.get_safe( "compiler.runtime") self._libcxx = conanfile.settings.get_safe("compiler.libcxx") self._cppstd = cppstd_from_settings(conanfile.settings) # Set the generic objects before mapping to env vars to let the user # alter some value self.libs = list(self._deps_cpp_info.libs) self.libs.extend(list(self._deps_cpp_info.system_libs)) self.include_paths = list(self._deps_cpp_info.include_paths) self.library_paths = list(self._deps_cpp_info.lib_paths) self.defines = self._configure_defines() # Will go to CFLAGS and CXXFLAGS ["-m64" "-m32", "-g", "-s"] self.flags = self._configure_flags() # Only c++ flags [-stdlib, -library], will go to CXXFLAGS self.cxx_flags = self._configure_cxx_flags() # cpp standard self.cppstd_flag = cppstd_flag(conanfile.settings) # Not -L flags, ["-m64" "-m32"] self.link_flags = self._configure_link_flags() # TEST! # Precalculate -fPIC self.fpic = self._configure_fpic() # Precalculate build, host, target triplets self.build, self.host, self.target = self._get_host_build_target_flags( )
def get_name(self, generator): name = super(CppInfo, self).get_name(generator) # Legacy logic for pkg_config generator from conans.client.generators.pkg_config import PkgConfigGenerator if generator == PkgConfigGenerator.name: fallback = self._name.lower() if self._name != self._ref_name else self._ref_name if PkgConfigGenerator.name not in self.names and self._name != self._name.lower(): conan_v2_behavior("Generated file and name for {gen} generator will change in" " Conan v2 to '{name}'. Use 'self.cpp_info.names[\"{gen}\"]" " = \"{fallback}\"' in your recipe to continue using current name." .format(gen=PkgConfigGenerator.name, name=name, fallback=fallback)) name = self.names.get(generator, fallback) return name
def make(self, args="", make_program=None, target=None, vars=None): if not self._conanfile.should_build: return if not self._build_type: conan_v2_behavior("build_type setting should be defined.", v1_behavior=self._conanfile.output.warn) make_program = os.getenv( "CONAN_MAKE_PROGRAM") or make_program or "make" with environment_append(vars or self.vars): str_args = args_to_string(args) cpu_count_option = (("-j%s" % cpu_count(output=self._conanfile.output)) if "-j" not in str_args else None) self._conanfile.run("%s" % join_arguments( [make_program, target, str_args, cpu_count_option]), win_bash=self._win_bash, subsystem=self.subsystem)
def _load_profile(text, profile_path, default_folder): """ Parse and return a Profile object from a text config like representation. cwd is needed to be able to load the includes """ try: inherited_profile = Profile() cwd = os.path.dirname( os.path.abspath(profile_path)) if profile_path else None profile_parser = ProfileParser(text) # Iterate the includes and call recursive to get the profile and variables # from parent profiles for include in profile_parser.get_includes(): # Recursion !! profile, included_vars = read_profile(include, cwd, default_folder) inherited_profile.update(profile) profile_parser.update_vars(included_vars) # Apply the automatic PROFILE_DIR variable if cwd: profile_parser.vars["PROFILE_DIR"] = os.path.abspath(cwd).replace( '\\', '/') # Allows PYTHONPATH=$PROFILE_DIR/pythontools # Replace the variables from parents in the current profile profile_parser.apply_vars() # Current profile before update with parents (but parent variables already applied) doc = ConfigParser(profile_parser.profile_text, allowed_fields=[ "build_requires", "settings", "env", "scopes", "options" ]) if 'scopes' in doc._sections: conan_v2_behavior("Field 'scopes' in profile is deprecated") # Merge the inherited profile with the readed from current profile _apply_inner_profile(doc, inherited_profile) return inherited_profile, profile_parser.vars except ConanException: raise except Exception as exc: raise ConanException("Error parsing the profile text file: %s" % str(exc))
def create_options(conanfile): try: package_options = PackageOptions(getattr(conanfile, "options", None)) options = Options(package_options) default_options = getattr(conanfile, "default_options", None) if default_options: if isinstance(default_options, dict): default_values = OptionsValues(default_options) elif isinstance(default_options, (list, tuple)): conan_v2_behavior("Declare 'default_options' as a dictionary") default_values = OptionsValues(default_options) elif isinstance(default_options, six.string_types): conan_v2_behavior("Declare 'default_options' as a dictionary") default_values = OptionsValues.loads(default_options) else: raise ConanException("Please define your default_options as list, " "multiline string or dictionary") options.values = default_values return options except Exception as e: raise ConanException("Error while initializing options. %s" % str(e))
def run_configure_method(conanfile, down_options, down_ref, ref): """ Run all the config-related functions for the given conanfile object """ # Avoid extra time manipulating the sys.path for python with get_env_context_manager(conanfile, without_python=True): if hasattr(conanfile, "config"): conan_v2_behavior( "config() has been deprecated. " "Use config_options() and configure()", v1_behavior=conanfile.output.warn) with conanfile_exception_formatter(str(conanfile), "config"): conanfile.config() with conanfile_exception_formatter(str(conanfile), "config_options"): conanfile.config_options() conanfile.options.propagate_upstream(down_options, down_ref, ref) if hasattr(conanfile, "config"): with conanfile_exception_formatter(str(conanfile), "config"): conanfile.config() with conanfile_exception_formatter(str(conanfile), "configure"): conanfile.configure() conanfile.settings.validate() # All has to be ok! conanfile.options.validate() # Recipe provides its own name if nothing else is defined conanfile.provides = make_tuple(conanfile.provides or conanfile.name) _validate_fpic(conanfile) if conanfile.deprecated: from six import string_types message = "Recipe '%s' is deprecated" % conanfile.display_name if isinstance(conanfile.deprecated, string_types): message += " in favor of '%s'" % conanfile.deprecated message += ". Please, consider changing your requirements." conanfile.output.warn(message)
def _check_cppstd(settings): compiler = settings.get_safe("compiler") compiler_version = settings.get_safe("compiler.version") cppstd = settings.get_safe("cppstd") compiler_cppstd = settings.get_safe("compiler.cppstd") if not cppstd and not compiler_cppstd: return # Checks: one or the other, but not both if cppstd and compiler_cppstd: raise ConanException("Do not use settings 'compiler.cppstd' together with 'cppstd'." " Use only the former one.") if cppstd: conan_v2_behavior("Setting 'cppstd' is deprecated in favor of 'compiler.cppstd'") if compiler not in ("gcc", "clang", "apple-clang", "Visual Studio"): return # Check that we have a flag available for that value of the C++ Standard def check_flag_available(values_range, value, setting_id): available = [v for v in values_range if cppstd_flag(compiler, compiler_version, v)] if str(value) not in available: raise ConanException("The specified '%s=%s' is not available " "for '%s %s'. Possible values are %s'" % (setting_id, value, compiler, compiler_version, available)) if cppstd: check_flag_available(settings.cppstd.values_range, cppstd, "cppstd") else: check_flag_available(settings.compiler.cppstd.values_range, compiler_cppstd, "compiler.cppstd")
def set_cppflags(self, value): conan_v2_behavior( "'cpp_info.cppflags' is deprecated, use 'cxxflags' instead") self.cxxflags = value
def get_cppflags(self): conan_v2_behavior( "'cpp_info.cppflags' is deprecated, use 'cxxflags' instead") return self.cxxflags
def name(self): conan_v2_behavior("Use 'get_name(generator)' instead") return self._name
def __init__(self, conanfile, backend=None, build_type=None, append_vcvars=False): """ :param conanfile: Conanfile instance (or settings for retro compatibility) :param backend: Generator name to use or none to autodetect. Possible values: ninja,vs,vs2010,vs2015,vs2017,xcode :param build_type: Overrides default build type comming from settings """ self._conanfile = conanfile self._settings = conanfile.settings self._append_vcvars = append_vcvars self._os = self._ss("os") self._compiler = self._ss("compiler") if not self._compiler: conan_v2_behavior("compiler setting should be defined.", v1_behavior=self._conanfile.output.warn) self._compiler_version = self._ss("compiler.version") self._build_type = self._ss("build_type") self.backend = backend or "ninja" # Other backends are poorly supported, not default other. self.options = dict() if self._conanfile.package_folder: self.options['prefix'] = self._conanfile.package_folder self.options['libdir'] = DEFAULT_LIB self.options['bindir'] = DEFAULT_BIN self.options['sbindir'] = DEFAULT_BIN self.options['libexecdir'] = DEFAULT_BIN self.options['includedir'] = DEFAULT_INCLUDE # C++ standard cppstd = cppstd_from_settings(self._conanfile.settings) cppstd_conan2meson = { '98': 'c++03', 'gnu98': 'gnu++03', '11': 'c++11', 'gnu11': 'gnu++11', '14': 'c++14', 'gnu14': 'gnu++14', '17': 'c++17', 'gnu17': 'gnu++17', '20': 'c++1z', 'gnu20': 'gnu++1z' } if cppstd: self.options['cpp_std'] = cppstd_conan2meson[cppstd] # shared shared = self._so("shared") self.options[ 'default_library'] = "shared" if shared is None or shared else "static" # fpic if self._os and "Windows" not in self._os: fpic = self._so("fPIC") if fpic is not None: shared = self._so("shared") self.options['b_staticpic'] = "true" if ( fpic or shared) else "false" self.build_dir = None 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
def collect_libs(self, folder=None): conan_v2_behavior( "'self.collect_libs' is deprecated, use 'tools.collect_libs(self)' instead", v1_behavior=self.output.warn) return tools.collect_libs(self, folder=folder)
def _config_node(node, down_ref, down_options): """ update settings and option in the current ConanFile, computing actual requirement values, cause they can be overridden by downstream requires param settings: dict of settings values => {"os": "windows"} """ conanfile, ref = node.conanfile, node.ref try: # Avoid extra time manipulating the sys.path for python with get_env_context_manager(conanfile, without_python=True): if hasattr(conanfile, "config"): conan_v2_behavior( "config() has been deprecated. " "Use config_options() and configure()", v1_behavior=conanfile.output.warn) with conanfile_exception_formatter(str(conanfile), "config"): conanfile.config() with conanfile_exception_formatter(str(conanfile), "config_options"): conanfile.config_options() conanfile.options.propagate_upstream(down_options, down_ref, ref) if hasattr(conanfile, "config"): with conanfile_exception_formatter(str(conanfile), "config"): conanfile.config() with conanfile_exception_formatter(str(conanfile), "configure"): conanfile.configure() conanfile.settings.validate() # All has to be ok! conanfile.options.validate() # Update requirements (overwrites), computing new upstream if hasattr(conanfile, "requirements"): # If re-evaluating the recipe, in a diamond graph, with different options, # it could happen that one execution path of requirements() defines a package # and another one a different package raising Duplicate dependency error # Or the two consecutive calls, adding 2 different dependencies for the 2 paths # So it is necessary to save the "requires" state and restore it before a second # execution of requirements(). It is a shallow copy, if first iteration is # RequireResolve'd or overridden, the inner requirements are modified if not hasattr(conanfile, "_conan_original_requires"): conanfile._conan_original_requires = conanfile.requires.copy( ) else: conanfile.requires = conanfile._conan_original_requires.copy( ) with conanfile_exception_formatter(str(conanfile), "requirements"): conanfile.requirements() new_options = conanfile.options.deps_package_values except ConanExceptionInUserConanfileMethod: raise except ConanException as e: raise ConanException("%s: %s" % (ref or "Conanfile", str(e))) except Exception as e: raise ConanException(e) return new_options