LoopPerfect / buckaroo

The decentralized package manager for C++ and friends 🏝️
https://buckaroo.pm
MIT License
933 stars 33 forks source link

Features (WIP). #345

Closed tarik02 closed 5 years ago

tarik02 commented 5 years ago

An ability to pass parameters (features) to dependencies and to use them in BUCK configs. Features comes with condition system allowing to disable dependencies based on dependencies.

Description

Features can be set for each dependency. Here is an example:

[[dependency]]
package = "github.com/buckaroo-pm/glfw"
version = "branch=master"

  [[dependency.feature]]
  name = "profile"
  value = "core"

  [[dependency.feature]]
  name = "api"
  value = { gl = "3.2", gles = "" }

  [[dependency.feature]]
  name = "extensions"
  value = [
    "GL_EXT_framebuffer_multisample",
    "GL_EXT_texture_filter_anisotropic"
  ]

GLAD library itself has a generator script which can be called using gen_rule from BUCK. So, features will allow to configure the script.

Feature types

Current implementation will have these types:

Conditions

Conditions are the way to disable some of dependencies based on passed features. Example:

[[dependency]]
package = "github.com/buckaroo-pm/host-pthread"
version = "branch=master"
condition = "use_threads"

condition field can be array, then the dependency will be enabled when at least one of conditions are true.

Condition text is python-like expression, but with very limited syntax.

Condition evaluation

If a feature used in condition is not specified, the condition will be false. List of operators:

condition = "feature1" # for boolean features
condition = "feature >= 5" # for integers/versions
condition = "feature = 'abc'" # for previous ones/strings
condition = "feature contains 'something'" # for arrays (has value)/dicts (has key)
condition = "feature contains ['something', 'something']" # the same, but a few operands (all should satishfy the condition)
condition = "feature = 'abc > 5 and abc < 10'"
condition = "feature = 'abc > 5 or def > 10'"
condition = "feature = 'abc > 5 or (abc > 2 and def > 10)"

Also, there can be single not prefix which inverts the result of condition evaluation. Example:

condition = "not 'something' in feature"

Related Issue

Closes #344

Motivation and Context

It is very useful feature to pass some parameters to universal dependencies. This is very common in C++ code, especially in cross-platform libraries.

Useful links:

How Has This Been Tested?

Still WIP

Types of changes

Checklist:

Progress:

CLAassistant commented 5 years ago

CLA assistant check
All committers have signed the CLA.

njlr commented 5 years ago

From https://docs.bazel.build/versions/master/skylark/language.html:

The following basic types are supported: None, bool, dict, function, int, list, string. On top of that, two new types are specific to Bazel: depset and struct.

So the types of features must be limited to these. For example, no floats.

tarik02 commented 5 years ago

There is a problem with the way how to collect features from packages, e.g. if there is two packages containing the same dependency with different features. Also, there should be some way to collect features from all manifests.

nikhedonia commented 5 years ago

There is a problem with the way how to collect features from packages, e.g. if there is two packages containing the same dependency with different features

This is the nature of the beast. It is similar to conflicting version constraints.

Things to consider:

In the C/C++ world there are two kind of features: additive and exclusive features. An example for additive features is -DWITH_GTK in OpenCV. Other flags may be exclusive eg. -DWITH_RTTI may be exclusive as they may change the ABI.

If we encounter different feature requirements that are additive then we can merge the features.

If we encounter a different exclusive features we have a conflict. In this case the user needs to intervene as there is no obvious way how to resolve this situation. Ways the user can resolve this are:

The later one is not implemented in Buckaroo yet. However we can override configurations in Buck quite easily using the buck build -c <cell>//feature=value syntax. If we provide an option to ignore feature conflicts this conflict could be manually resolved by the user at build-time.

Whether we should allow this kind of practice is probably an important discussion to have...

0Grit commented 5 years ago

Is this something that should be handled in package management, or should it be done in build management?

tarik02 commented 5 years ago

Have no idea how to continue this PR. Sorry.