-
Notifications
You must be signed in to change notification settings - Fork 981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[poc] Add wrappers|shims around executables #7324
Conversation
… poc/xbuild-exec-wrapper
855850b
to
d4b89a2
Compare
In the context of this PR, there are a couple of related issues we need to talk about:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this somehow taking care of the shared libraries issue?
environment context for the build() method (two profiles approach): with the shims it is no longer needed to populate the environment with everything coming from the build-requires, only the PATH to the shims folder is needed. If we stop populating the environment automatically, we need to provide a way to explicitly activate it (I know there is an issue about it, but I cannot find it).
Not sure about that, what if the build require doesn't have any executable but indeed is populating some environment variables? (like configuration or whatever). Probably the only thing to change (as a good practice for shims) is to avoid modifying the env.PATH
from the build require.
There is a problem if we populate automatically the environment, and it is demonstrated in the tests added to this PR: if two different build-requires (of the same recipe) populate the same variable (here the In MacOS it will be the same for the DYLD_LIBRARY_PATH, if we do isolate the graphs from different build-requires, they could depend on different versions of the same library without conflicting. We cannot append everything to the environment, only the first dynamic library will be found and used (DLL Hell). Together with shims (no need to populate the PATH or DYLD...) we can force the user to activate explicitly the environment, something like: you can activate the environment of a build-requires and run other commands using that environment.
|
I understand and agree but still, we cannot stop populating the environment of the requirements always. Maybe only when they declare an
WDYT? |
I can't say. I'd need real examples of dynamic build-requires that need to inject their environment variables into the recipes they apply to. At first, I'd say that if the recipe is coupled with the build-requires (it is hardcoded/listed in the recipe itself) it is ok to activate the environment explicitly, what examples do we have for the other type of build-requires? |
Nothing comes to my mind right now that you will consider it like the best practice. But people are reading env vars from build requires for sure. Declaring toolchains maybe. Just saying that the model as you described is not complete because you never know when the user really wants to propagate the env or not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems a good step, lets talk about the strategy, I am thinking that having it as a generator could have advantages.
import textwrap | ||
|
||
|
||
class LocalWorkflowTestCase(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused?
conan_file.info.env_values.add(name, value, package_name) | ||
|
||
|
||
def _classify_dependencies(node): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably this deserves a previous refactor in a previous PR.
# I need the shims for the executables in the build-requires (only two-profiles approach) | ||
if self._cache.config.shims_enabled: | ||
logger.info("SHIMS: Writing shims for build-requires") | ||
_, _, build_deps = _classify_dependencies(node) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if the refactor is done, this could be moved later, so classify_dependencies()
is called just one? It would be a bit more natural.
""") | ||
|
||
|
||
def _generate_shim(name, conanfile, settings_os, output_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a new Generator like the toolchains? something you can parameterize and control too?
} | ||
""") | ||
|
||
lib_h = textwrap.dedent(""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe use gen_function_xxxx()
if possible.
|
Changelog: (Feature | Fix | Bugfix): Describe here your pull request
Docs: https://github.com/conan-io/docs/pull/XXXX
Note.- Highly experimental, just an idea, the implementation should follow another way.In this POC I'm creating wrappers around the executables declared in the
cpp_info
object. This is intended mainly for build requirements, with this approach the environment from one build_requires won't pollute the environment from other build_requires (thinking that build-requires are isolated graphs and they don't conflict with each other), this is a problem not only for envvars that contain values and might collide, but to ensure that they will use the proper shared libraries. It also solves the issue with Macos and SIP, from within CMake it is possible to callprotoc
and the wrapper will take care of adding the values toDY/LD_LIBRARIES_PATH
and shared libraries will be found.Protoc scenario reproduced here: https://github.com/jgsogo/conan-xbuild-scenarios/tree/master/protobuf
To think about (maybe restrictions):
This should only be about "final" applications, if
build_requires
expand isolated graphs, each wrapper should activate the environment for that graph (yes, there might be collisions inside the same graph, but these ones are up to the user).The graph is resolved in runtime with the inputs of the user, these environments need to be created at
conan install <consumer>
time, they cannot be created when the package itself is installed (unless we check the lockfile).Is it legit to use
env_info
to propagate data to consumers? I mean, maybe the wrapper should activate all the environment, and noenv_info
is populated with data from the build_requires (only thePATH
to these wrappers). If the user want to propagate data, they should useuser_info
field.Other alternatives/approaches:
shimgen
: https://github.com/chocolatey/shimgenThis PR (or similar) would: