-
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
[feature] Ability to propagate a profile from a recipe for packaged toolchains and bootstrapping #13533
Comments
Thanks for your detailed explanation and suggestions. My first thought about this proposal is that it is not a new package-type. It is probably not even a regular package with a qualifier. It seems this would be a completely new concept, flow and infrastructure. I think so because if it would be a normal package type, that means that it could be required by a normal library package def requirements(self):
if self.settings.compiler == "gcc":
self.requires("...") So it would be a chicken and egg problem. This new package concept is something that seems only make sense for Please let me know if this makes sense. This sounds like a very major feature. I am not saying that we cannot approach and consider it, actually the opposite, I have always been interested in this problem. But also, it could mean that it will take time. Stabilization of 2.0, migrating and helping the community to upgrade, and some other very important roadmap things are pending. |
Yes, I agree with this. I've never particularly liked the pattern of having Having said that, I would expect a compiler recipe to have a tool requires for itself to enable a bootstrap, something akin to: class GCC(ConanFile):
name = "gcc"
version = "11.3.0"
def build_requirements(self):
self.tool_requires("gcc/[>=5.0.0]")
def requirements(self):
self.requires("glibc/x.y.z")
self.requires("linux-headers/x.y.z")
Yep - 100% agree with your analysis here. Having said that, it's not easy to completely extricate the compiler from the runtime requirements of the application/library it's building. As mentioned, compiling a library with So, the compiler package needs a way of injecting libraries that need to be linked against in the downstream class LapackConan(ConanFile):
name = "lapack"
def requirements(self):
self.requires("gcc/12.2.0")
def build_requirements(self):
self.tool_requires("gcc/12.2.0")
def package_info(self):
...
self.cpp_info.components["blas"].set_property("cmake_target_name", "BLAS::BLAS")
self.cpp_info.components["blas"].libs = [self.get_lib_name("blas")]
self.cpp_info.components["blas"].requires = ["gcc::gfortran"]
self.cpp_info.components["lapack"].set_property("cmake_target_name", "LAPACK::LAPACK")
self.cpp_info.components["lapack"].libs = [self.get_lib_name("lapack")]
self.cpp_info.components["lapack"].requires = ["blas", "gcc::gfortran"] Obviously this could be improved to some degree with specification in the profile, but the same requirement to model the library dependencies exists either way.
Understood, I just wanted to start a conversation about this use case :) |
Does this mean that, at the moment, it's impossible to use If I have
I get this
|
It might be possible in constrained situations to coax something functional for compilers, but if it were possible at the moment you'd probably have to suffer incorrect metadata. The way to do it currently would be to
And then populate the path to the compiler in your recipe
Then use this recipe to build your packages |
Also @sykhro it is important to be in 2.0, or if you are in 1.X, then use the 2 profiles |
I've found great success with doing this:
My arm-gnu-toolchain tool package adds its compiler to the compiler list, removing the need for the user to do this themselves. It also propagates to all down stream, dependencies of the application, recompiling them as needed. |
@memsharded we're starting to see some maturity and consolidation of features in conan 2.x - do you see scope for closer consideration of this to be given some effort soon? |
I am afraid this is not yet into consideration, our backlog is already full of tons of other higher priorities, starting with new CI for ConanCenter, to things like |
Is there anything I can do to mature this idea from an implementation perspective while your team is out of resources? If I were to come up with a proof of concept for this, are you able to provide suggestions on where this would best be injected into the codebase for consideration? |
We are just beginning a journey to migrate a very large family of products to a new build environment based around Conan. And we're facing similar questions about managing our toolchain as described @samuel-emrys described in the original suggestion here. We build products using a "customized" version of GCC--specifically we generally need a newer version of GCC than what is included in many Linux distributions as the default. So we configure and build our own. Being newer than the underlying system defaults means that our binaries need both link against the GCC runtime libraries (e.g. We've been studying the Conan examples for packaging a cross-compiler toolchain (e.g. https://docs.conan.io/2/examples/cross_build/toolchain_packages.html ) which seems to address many of the issues of making a different compiler available. But the example does not help with the runtime issues similar to (1) in @samuel-emrys 's original description. Treating our compiler as a cross-compiler and using The analysis provided by @memsharded here #13533 (comment) largely squares with how we would like to manage our toolchains. We want to specify our custom compiler once in a profile and then have that propagate across all of our product code and yield the required runtime dependencies. In theory this would then let us migrate to a newer version of our compiler by updating just the host profile and sitting back as everything cascades through. We're sufficiently motivated to get to a world like this that we may be willing to help contribute with the right guidance. |
What is your suggestion?
Hi Team,
There are a few things that I would like to achieve with conan:
I've experimented with this a little with the existing gcc recipe, a glibc recipe (that I'm yet to upstream), with the lapack recipe that's currently in draft format (conan-io/conan-center-index#15556), and a PR that's up to model the libraries that gcc exposes (conan-io/conan-center-index#15128).
From this experimentation, I've identified a few requirements that we would have in this situation:
gfortran
from thegcc
recipe requires any consnumer of the library built withgfortran
to link againstlibgfortran.{a,so}
. This need can be mitigated where a shared lib is being created, then it can statically linklibgfortran.a
and consumers don't need to be aware of thelibgfortran
requirement, but this won't always be the case. This can be observed in the lapack PR above.gcc/11.3.0
to build a package, but a pre-built variant of this doesn't exist, it should look to bootstrap itself by looking to previous versions ofgcc
. Lets say it finds a prebuilt package forgcc/10.2.0
- this compiler and version should be reflected in the metadata of thegcc/11.3.0
package now, rather than what would happen at the moment which is whatever the user defined profile is (which may even vary fromgcc/11.3.0
!). Likewise, the package I'm building withgcc/11.3.0
should havegcc 11.3.0
in its package metadata, not whatever the user defined profile is. Similarly, I would expect a package compiled withgfortran
to havesettings.info.compiler=gfortran
rather thansettings.info.compiler=gcc
in its package metadata.This is a simplistic representation of some of the things that might change. It's also useful to know the
libc
that thegcc
package has been built against and the requirement that it will impart on libraries that it builds. This could be a step towards more meaningfully controlling library ABI.This would also be useful for building cross-compilers.
In the above case, if the
conf.tools.build:compiler_executables=gfortran
, thencompiler={{ package:gcc/11.3.0 }}
would evaluate tocompiler=gfortran
,compiler.version=11.3.0
. I can see that this might be difficult to infer which executable is used here, so another alternative might be to just ensure that each compiler has its own recipe/package.I think what's being highlighted here is a need for a new package type - it would not be desirable to have any package be able to override the user specified profile or act this way. Perhaps the definition of
package_type
could be extended to include a use case such as this rather than just traits propagation. I.e.,package_type=compiler
(noting that there is still a runtime requirement that compiler packages are likely to impart)There's a lot of text here and I'm sure I've been unclear about some things. Please ask any questions that would help clarify the use case and proposed interface.
Relates to:
Have you read the CONTRIBUTING guide?
The text was updated successfully, but these errors were encountered: