Search code examples
conan

Packaged build environment as build_requires of profiles, system compiler is used instead


I will try to describe my setup first:

  • conan 1.29.2
  • Official cmake/3.18.2 package
  • Custom gcc package with package_info including its bin directory in PATH and setting the CC and CXX env variables:
    def package(self):
        autotools = AutoToolsBuildEnvironment(self)
        autotools.make(target='install-strip')
    
    def package_info(self):
        bin_folder = os.path.join(self.package_folder, 'bin')
    
        self.env_info.path.append(bin_folder)
        self.env_info.CXX = os.path.join(bin_folder, 'g++')
        self.env_info.CC = os.path.join(bin_folder, 'gcc')
    
  • linux-x86_64 conan profile representing Linux 64 bit environment as follows:
    [settings]
    os=Linux
    os_build=Linux
    arch=x86_64
    arch_build=x86_64
    
  • linux-x86_64-Debug conan profile representing Linux 64 bit Release environment as follows:
    include(linux-x86_64)
    
    [settings]
    build_type=Debug
    
  • gcc-10.1.0 conan profile to build packages using my gcc package:
    [settings]
    compiler=gcc
    compiler.version=10.1
    compiler.libcxx=libstdc++11
    
    [build_requires]
    gcc/10.1.0
    
  • cmake-3.18.2 conan profile to build packages using official cmake package:
    [build_requires]
    cmake/3.18.2
    
  • default conan profile with gcc 7

If I try to build a package as follows:

$ conan create . foo/version --build=missing -pr linux-x86_64-Debug -pr cmake-3.18.2 -pr gcc-10.1.0

the resulting config is:

Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Debug
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=10.1
os=Linux
os_build=Linux
[options]
[build_requires]
*: gcc/10.1.0, cmake/3.18.2
[env]

which looks right to me...

and then conan starts building cmake package for the gcc 10.1 x86_64 config:

cmake/3.18.2: WARN: Build folder is dirty, removing it: /home/manuel/.conan/data/cmake/3.18.2/_/_/build/46c0026dddc0e0537a797652343e8e1e9d0e39e7
cmake/3.18.2: Copying sources to build folder
cmake/3.18.2: Building your package in /home/manuel/.conan/data/cmake/3.18.2/_/_/build/46c0026dddc0e0537a797652343e8e1e9d0e39e7
cmake/3.18.2: Generator cmake created conanbuildinfo.cmake
cmake/3.18.2: Calling build()

But then build fails because the cmake package cmake config is using the system compiler:

-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: called by CMake conan helper
-- Conan: called inside local cache
-- Conan: Adjusting output directories
-- Conan: Using cmake global configuration
-- Conan: Adjusting default RPATHs Conan policies
-- Conan: Adjusting language standard
-- Conan: Compiler GCC>=5, checking major version 10.1
-- Conan: Checking correct version: 7.4
CMake Error at ../conanbuildinfo.cmake:510 (message):
  Detected a mismatch for the compiler version between your conan profile
  settings and CMake:

  Compiler version specified in your conan profile: 10.1

  Compiler version detected in CMake: 7.4

  Please check your conan profile settings (conan profile show
  [default|your_profile_name])

  P.S.  You may set CONAN_DISABLE_CHECK_COMPILER CMake variable in order to
  disable this check.
Call Stack (most recent call first):
  ../conanbuildinfo.cmake:592 (conan_error_compiler_version)
  ../conanbuildinfo.cmake:695 (check_compiler_version)
  ../conanbuildinfo.cmake:249 (conan_check_compiler)
  CMakeLists.txt:9 (conan_basic_setup)

This looks very similar to https://github.com/conan-io/conan/issues/1842, but that issue is from 3 years ago.


Solution

  • Conan learned some versions ago about host and build contexts and is able to manage different configurations for those contexts. This is preferred over the old os_build and arch_build settings and packages in ConanCenter are moving towards this new feature.

    In your scenario, you are trying to build a library using packages gcc and cmake as build-requires. You are building library for the host machine and using package gcc and cmake that provide tools that should run in the build machine. Even if you are not cross-compiling, we can agree that native building is just a specific use-case where host and build are the same machine and, hence, they use the same Conan configuration.

    Back to your example. You need your profiles for the host platform, the one you want to generate your library for. These are all the profiles you have listed in your question. But you also need a profile for the build context, the profile that Conan will use to build (or retrieve) the gcc and cmake packages. For example, you might want to use a profile linux-x86_64-Debug to compile your library in debug mode, while using gcc and cmake in Release.

    Typically, the profile for your build context can be the default profile detected by Conan.

    Try this command instead of yours (note the --profile:build=default):

    conan create <library/conanfile.py> foo/version --build=missing --profile:host linux-x86_64-Debug --profile:host cmake-3.18.2 --profile:host gcc-10.1.0 --profile:build=default 
    

    Now Conan will use the new feature and assign the package to the corresponding contexts:

    • library and all its dependencies will be assigned to the host context and will use information from all the --profile:host profiles: your Debug build and Conan will add cmake and gcc as build-requires.
    • gcc and cmake, as they are build-requires in this command, will be assigned to the build context and will use the information from the --profile:build. If Conan needs to build these packages it will use the settings from that profile, not the settings for the host profiles.

    With this setup you can build all packages in a cross-building scenario in a single run: packages in the host context will use your build-requires gcc to build, while packages in the build context will use the tools defined in the --profile:build.

    Yes, in this scenario, packages in the build context will use the compiler from your system.... unless you declare [build_requires] inside the --profile:build.