conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.25k stars 980 forks source link

[question] What is the purpose of `--build-require` argument? #15020

Open pklip opened 1 year ago

pklip commented 1 year ago

What is your question?

I don't understand what using --build-require does to a conan create. I read the documentation (https://docs.conan.io/2/reference/commands/create.html?highlight=--format#using-conan-create-with-build-requirements), which states that it

allows to create the package using the configuration and settings of the “build” context, as it was a build_require

but I don't really get what implications that has.

Have you read the CONTRIBUTING guide?

memsharded commented 1 year ago

Hi @pklip

When you use some package like cmake/3.17 as a tool_requires = "cmake/3.17" of a recipe, some things happen:

If you do a conan create . --profile:host=linuxarmb --profile:build=windowsx64 for the cmake package by default the package you are creating will be put in the "host" context. In the scenario above, the "host" context is Linux-armv8, and it will build a Linux-armv8 binary. But this is not the binary that you want to use as tool-require in your scenario. Adding --build-require puts it in exactly the same place of the "build" context than the one that will be later used when this package is used by others.

fschoenm commented 1 year ago

If you do a conan create . --profile:host=linuxarmb --profile:build=windowsx64 for the cmake package by default the package you are creating will be put in the "host" context. In the scenario above, the "host" context is Linux-armv8, and it will build a Linux-armv8 binary.

Isn't that a very theoretical description? Why would you create the cmake package with an ARM host profile if you actually want to build it for Windows? I think I just don't understand the scenario.


The concept made more sense to me from the view of a cross-compiler, in which you have an additional "target" context (the machine it will produce code for). Because in that case, --build-require seems to use the specified build context for what is usually the host context and the specified host context for a new "target" context. (At least that was my interpretation. Unfortunately, it isn't very well documented yet.)

The contexts are then known in the conanfile as settings_build, settings_host, and settings_target (if applicable).

settings_build settings_host settings_target
default from -profile:build from -profile:host unknown but irrelevant
with --build-require from -profile:build from -profile:build from -profile:host

Is that the wrong way to look at it? Or is creating a "target" context just a side-effect of --build-require?

memsharded commented 1 year ago

Yes, the cmake example might be approached in a different way, by just "swapping" the build and host profile, so this wouldn't be strictly necessary. This is definitely strictly necessary when building "toolchain" packages that need the settings_target defined.

However, it can be very convenient for distributed CI builds. The conan graph build-order gives the order and information how to build the packages in a dependency graph in a distributed CI. It will give the --build-require argument in the output, because otherwise the CI should explicitly maintain a list of "tool-requires" and build them with the host and build profiles swapped. And it could become even more complicated for packages that work both as regular requires and tool-requires, like protobuf. So if we are building protobuf from source recipe, we could do:

conan create . -pr:h=linuxprofile -pr:b=windowsprofile
conan create . -pr:h=windowsprofile -pr:b=windowsprofile

or

conan create . -pr:h=linuxprofile -pr:b=windowsprofile
conan create . -pr:h=linuxprofile -pr:b=windowsprofile --build-require
fschoenm commented 1 year ago

@memsharded Ah that makes sense. Thanks for the explanation.