conan icon indicating copy to clipboard operation
conan copied to clipboard

[bug] conan install --build=never still tries to build on Mac

Open gsemet opened this issue 2 years ago • 10 comments

Environment details

  • Operating System+version: Mac OS Sonara
  • Compiler+version: N/A
  • Conan version: Conan version 1.60.1
  • Python version: 3.10.9

Steps to reproduce

  • here is the command I execute:
conan install --build=never --profile /some/path/to/my/profile/conan-profiles/linux-gcc.ini /some/path/to/my/recipe

my recipe has only 1 self.requires. I need this package and nothing else.

  • on a linux (in CI) with the same profile file, it just download the single requires:
conanfile.py (my-package/0.0.1-pre.20.16235860.gd0c73): Installing package
Requirements
Python requires
   base-cmake-pkg/1.0.2@otherteam/stable
   runtime-base/1.0.3@myteam/stable
   conan-packager/0.9.3@someteam/stable
   mybase/1.0.2@myteam/stable
Packages
Build requirements
   my-wanted-dependency/4.17.1-pre.61.16233726.g5f2c0@testing/dev-gsemet from 'dt-my-repository' - Downloaded
Build requirements packages
   my-wanted-dependency/4.17.1-pre.61.16233726.g5f2c0@testing/dev-gsemet:52cf33e8d00b6568dd8ffebf4f359a609065286d - Download
  • but on a Mac, it displays all the "build_requires" of the package and try to fetch them, some of them are in "cache" but some are in build, and of course the build fails

First: I need to explicitely tell conan: do not try to download build_requires for this package. You do not need it

Second: despite --build=never, it tries to "build" some package, but there is no the environment locally to build (I only want the file but a "conan download" does not do the job.

Thanks

Logs

Profile:

[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++
compiler.version=9
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

I see in the log on the mac:

Building package from source as defined by build_policy='missing'

but i have explicitely said "--build=never"

gsemet avatar Dec 05 '23 21:12 gsemet

Hi @gsemet

I am afraid this is "expected" behavior in Conan 1.X. In Conan 1.X the recipe build_policy = "missing" had highest precedence over the --build=never in the command line.

This was not possible to change this default behavior in 1.X without breaking. It has been changed already in Conan 2.0. So for Conan 1.X this wouldn't be a bug, and the recommended approach would be to remove the build_policy = "missing" from the recipe.

If the package is not built, then build-requires will not be downloaded (but if the package binary do not exist, of course it will fail), so I think the first point wouldn't be an issue.

memsharded avatar Dec 05 '23 21:12 memsharded

hi. Thanks for your anwser. But i do not have any reference to "build_policy=missing" in my recipe, i guess this is the default? So if i add build_policy = "missing" in the recipe i want to download, it will just fail if it cannot be built? it is pretty much exactly what i need.

but wouldn't this build_policy=never avoid the "conan package" command to actually build the package?

but why on macos, since i am using the exact same profile than on the linux, why does it still tries to build? I would like to have a simple self.requires("my-dependency/1.2.3@user/channel") and it fetches the package without building. The package I want to download is in settings = None`, i only want to build a single time over (the package actually only contact generated xml files).

thanks

gsemet avatar Dec 05 '23 22:12 gsemet

hi. Thanks for your anwser. But i do not have any reference to "build_policy=missing" in my recipe, i guess this is the default? So if i add build_policy = "missing" in the recipe i want to download, it will just fail if it cannot be built? it is pretty much exactly what i need.

No, this will be the equivalent to --build=missing, not failing.

but why on macos, since i am using the exact same profile than on the linux, why does it still tries to build? I would like to have a simple self.requires("my-dependency/1.2.3@user/channel") and it fetches the package without building. The package I want to download is in settings = None`, i only want to build a single time over (the package actually only contact generated xml files).

I am afraid I don't have enough information to understand what is happening. It would be good to have some reproducible example, with code that we can reproduce and check what is happening. It seems that there is something there that is causing the package_id variability, but not possible to know. Are there dependencies or options?

memsharded avatar Dec 05 '23 22:12 memsharded

There are self.requires. I have not set any options neither options… hard to share anything more…

when I am in the CI, using the same Linux env that built the wanted package, everything works fine, the package is downloaded without rebuild. In short I need a way to define the options or settings and the profile to say “whatever the local environment, download the same packageid”

gsemet avatar Dec 05 '23 22:12 gsemet

In short I need a way to define the options or settings and the profile to say “whatever the local environment, download the same packageid”

But this is the natural behavior of Conan. If the package has no options, settings nor dependencies, then the package_id is basically a constant, and it will resolve always to the same one, once built, it will always be retrieved the same. So if this doesn't happen there is anything else that is causing some variability in the package_id. But we would need at least the outputs of both commands, the first one with the package_id that is built, and the second one with the one that is "missing". Full outputs including input profiles, etc.

memsharded avatar Dec 05 '23 22:12 memsharded

I have dependencies in my recipes, but no reference to option (is it default to “None”?)

and yes have dependencies, that are written in conandata.yml. Would it is be possible that the use of this file impact the way the package id is computed in Linux or Mac ?

gsemet avatar Dec 05 '23 22:12 gsemet

Yes, definitely. Dependencies are also part of the package_id. If you create both (build=missing) binaries and list them you will see that they have different dependencies.

The way to make some package completely independent of everything is do the same as if it was a header-only library, call self.info.clear() in the package_id() method.

memsharded avatar Dec 05 '23 23:12 memsharded

Any further question here? This didn't seem a bug, but expected behavior, maybe the ticket can be closed?

memsharded avatar Feb 15 '24 16:02 memsharded

Hi. I managed to have it working correctly by forcing

conan config set general.default_python_requires_id_mode=major_mode

My pbl came from the python_requires that impacted the package_id, and i actually want to ignore any impact on non-major change.

Once default_python_requires_id_mode=major_mode is activated, the packageid was correctly computed during the download. All my package depends on a base class that may evolve (but we saw even when the version are exactly the same, packageid might also be different).

Here my recipe I got working with:

class MyPackage(Conan):
    # This library handles the `version`, `build_requirements` and `requirement` methods
    python_requires = "my-base-conan-package/[>=0.9.4]@myteam/stable"
    python_requires_extend = "nestor-conan-packager.Base"

    # Create a settingless package
    settings = None

    # Create an optionless package
    options = None

    # Ensure requires and python-requires does not impact the packageid
    # https://docs.conan.io/1/reference/conanfile/methods.html#self-info-clear
    def package_id(self):
        self.info.clear()
        # this is not enough, the global setting default_python_requires_id_mode
        # need to be set for instance to major_mode

The package generated with this recipe works (ie can be found with default_python_requires_id_mode=major_mode, but not if this setting is not set.

I would recommend to allow this feature at package level (by a field python_requires_id_mode=major_mode in the recipe class for example, or a special syntax in package_id method to allow specifying the python_requires_id_mode for each package). But i do not understand why self.info.clear() is not enough.

gsemet avatar Feb 15 '24 16:02 gsemet

I would recommend to allow this feature at package level (by a field python_requires_id_mode=major_mode in the recipe class for example, or a special syntax in package_id method to allow specifying the python_requires_id_mode for each package).

We already added the python_mode in https://github.com/conan-io/conan/pull/15453, to be released asap in Conan 2.1 to allow python_requires to define how they affect their consumers.

But i do not understand why self.info.clear() is not enough.

I think this was a bug too, it has been fixed in https://github.com/conan-io/conan/pull/15285 a few months ago for Conan 2.0.15

memsharded avatar Feb 15 '24 17:02 memsharded