(#14211) docs: split some policies by the implicated method

* docs: split some policies by the implicated method

* fix broken link

* fix broken link

* Apply suggestions from code review

Co-authored-by: Francisco Ramírez <franchuti688@gmail.com>
Co-authored-by: SSE4 <tomskside@gmail.com>

Co-authored-by: Francisco Ramírez <franchuti688@gmail.com>
Co-authored-by: SSE4 <tomskside@gmail.com>
This commit is contained in:
Chris Mc
2022-11-21 09:45:43 -08:00
committed by GitHub
parent 9969cbe97f
commit e70b881101
7 changed files with 99 additions and 76 deletions

View File

@@ -0,0 +1,128 @@
# `ConanFile` Attributes
The `ConanFile` class has a lot of different properties that can help consumers search for projects, help the client build packages for different configurations
or are known by ConanCenter's build service and have special meaning.
<!-- toc -->
## Contents
* [Settings](#settings)
* [Options](#options)
* [Recommended Names](#recommended-names)
* [Predefined Options and Known Defaults](#predefined-options-and-known-defaults)
* [Options to Avoid](#options-to-avoid)<!-- endToc -->
## Settings
All recipes should list the four settings `os`, `arch`, `compiler` and `build_type` so Conan will compute a different package ID
for each combination. There are some particular cases for this general rule:
* **Recipes for _header only_ libraries** might omit the `settings` attribute, but in any case they should add
```python
def package_id(self):
self.info.clear()
```
* **Recipes that provide applications** (`b2`, `cmake`, `make`,...) that are generally used as a _build requires_, must list all
the settings as well, but they should remove the `compiler` one in the corresponding method unless the recipe provides also
libraries that are consumed by other packages:
```python
def package_id(self):
del self.info.settings.compiler
```
Removing the `compiler` setting reduces the number of configurations generated by the CI, reducing the time and workload and, at the
same time, demonstrates the power of Conan behind the package ID logic.
> **Note** Intentionally, the `build_type` setting should not be removed from the package ID in this case. Preserving this
> setting will ensure that the package ID for Debug and Release configurations will be different and both binaries can be
> available in the Conan cache at the same time. This enable consumers to switch from one configuration to the other in the case
> they want to run or to debug those executables.
## Options
Recipes can list any number of options with any meaning, and defaults are up to the recipe itself. The CI cannot enforce anything
in this direction. However, there are a couple of options that have a special meaning for the CI.
### Recommended Names
Adding options is often needed to toggle specific library features on/off. Regardless of the default, there is a strong preference for using positive naming for options. In order to avoid the fragmentation, we recommend using the following naming conventions for such options:
- enable_<feature> / disable_<feature>
- with_<dependency> / without_<dependency>
- use_<feature>
The actual recipe code then may look like:
```py
options = {"enable_locales": [True, False]} # Changes which files are compiled in to the library
default_options = {"enable_locales": True}
```
```py
options = {"with_zlib": [True, False]} # Will add a `self.requires` with more deps to link against
default_options = {"with_zlib": True}
```
```py
options = {"use_tzdb": [True, False]} # Might install more headers to expose more features
default_options = {"use_tzdb": True}
```
Having the same naming conventions for the options helps consumers. It allows users to specify options with wildcards: `-o *:with_threads=True`. Therefore, the `with_threads` options will be enabled for all packages in the graph that support it.
### Predefined Options and Known Defaults
ConanCenter supports many combinations, these are outline in the [supported configurations](../supported_platforms_and_configurations.md) document for each platform.
By default recipes should use `shared=False` with `fPIC=True`. If support, `header_only=False` is the default.
Usage of each option should follow the rules:
* `shared` (with values `True` or `False`). The CI inspects the recipe looking for this option. The **default should be `shared=False`** and will
generate all the configurations with values `shared=True` and `shared=False`.
> **Note**: The CI applies `shared=True` only to the package being built, while every other requirement will `shared=False`. To consume everything as a shared library you will set `--build=always` and/or `-o *:shared=True`)
> It's important to keep this in mind when trying to consume shared packages from ConanCenter
> as their requirements were linked inside the shared library. See [FAQs](../faqs.md#how-to-consume-a-graph-of-shared-libraries) for more information.
* `fPIC` (with values `True` or `False`). The **default should be `fPIC=True`** and will generate all the configurations with values `fPIC=True` and `fPIC=False`.
This option does not make sense on all the support configurations so it should be removed.
```python
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
```
* `header_only` (with values `True` or `False`). The **default should be `header_only=False`**. If the CI detects this option, it will generate all the
configurations for the value `header_only=False` and add one more configuration with `header_only=True`. **Only one package**
will be generated for `header_only=True`, so it is crucial that the package is actually a _header only_ library, with header files only (no libraries or executables inside).
Recipes with such option should include the following in their `package_id` method
```python
def package_id(self):
if self.options.header_only:
self.info.clear()
```
ensuring that, when the option is active, the recipe ignores all the settings and only one package ID is generated.
### Options to Avoid
* `build_testing` should not be added, nor any other related unit test option. Options affect the package ID, therefore, testing should not be part of that.
Instead, use Conan config [skip_test](https://docs.conan.io/en/latest/reference/config_files/global_conf.html#tools-configurations) feature:
```python
def generate(self):
tc = CMakeToolChain(self)
tc.variables['BUILD_TESTING'] = not self.conf.get("tools.build:skip_test", default=true, check_type=bool)
```
The `skip_test` configuration is supported by [CMake](https://docs.conan.io/en/latest/reference/build_helpers/cmake.html#test) and [Meson](https://docs.conan.io/en/latest/reference/build_helpers/meson.html#test).