conan icon indicating copy to clipboard operation
conan copied to clipboard

[question] Why does conan not pass CMAKE_CXX_COMPILER to CMAKE

Open fredizzimo opened this issue 2 years ago • 8 comments

As far as I understand from reading a lot of different issues and from my own experimentation it seems like conan does not set CMAKE_CXX_COMPILER and CMAKE_C_COMPILER from the profile settings to the cmake invoked from the recipe.

I understand that you have to define CXX and CC instead, but why is that the case? I also have trouble finding any real documentation related to this other than in some of the examples here https://docs.conan.io/en/latest/reference/profiles.html. None of the issues I have seen seem to explain it either.

At first I actually thought it was the responsibility of the recipe creator to set it correctly, and I thought we had built our own recipe wrong. But after a lot of reading up I came to the above conclusion.

Since all other settings, like the standard library version and so on are passed on, I don't understand why the compiler can't be passed as well, but there clearly has to be some reason. CMake clearly has the information, since it can validate that the compiler does not match, but not automatically select the right one.

I can only think of one possible explanation, and that is that you are not able to specify a custom path to the compiler using the standard settings, but if that's the case I think the settings should be extended in some other way, or at least document this properly.

fredizzimo avatar Mar 24 '22 15:03 fredizzimo

Because those are not env-vars, those are CMake variables. No matter if you define them in the [env] (or [buildenv]) section of the profile, it will be defined in the environment, but CMake will not listen to that environment variables.

So it needs to be specified by recipes, and/or toolchains. I'd recommend to use the modern integrations (start with conan new hello/0.1 --template=cmake_lib. Then check the possible configurations that are possible for CMakeToolchain.

memsharded avatar Mar 24 '22 15:03 memsharded

No, I'm talking about the settings part.

If I set compiler=clang and compiler.version=12 I think it should pass COMPILER_CXX_COMPILER=clang++-12 and COMPILER_C_COMPILER=clang-12 automatically without having to define any custom environment variables.

It sets CMAKE_CXX_FLAGS=-stdlib=libstdc++ automatically based on the compiler.libcxx setting, so why not the compiler as well?

fredizzimo avatar Mar 24 '22 15:03 fredizzimo

Because the compiler can be different in every computer. The -stdlib=libstdc++ is constant, it is safe for Conan to add it. But clang can be clang in one computer, clang-12 in another (both in the path), or /usr/myfolder/clang in another computer (not in the path).

So Conan cannot know that, the most it can do is define the default clang and clang++, and expect it to be on the path. Otherwise, the best way to define it would be to pass CC/CXX env-vars that build systems automatically read.

That doesn't mean that we cannot improve CMakeToolchain if that makes sense. We could add a new conf that defines the compiler path, and we could have the toolchain to use it. But as defining it via env-vars seems to be more widespread, I wonder about the utility.

memsharded avatar Mar 24 '22 16:03 memsharded

Yes, that makes sense, and that was basically what I assumed could be the only possible reason as well.

I think the current behaviour is fine and that it's mostly a documentation issue, using CC to control it works with other toolchains than just cmake, so it's probably better to just keep using that.

But perhaps it could still try to set clang-12 for example and give an error if it's not in the path?

fredizzimo avatar Mar 24 '22 16:03 fredizzimo

Because the compiler can be different in every computer.

Not if the compiler is fetched by conan itself, for example with the mingw-builds package. In this case, conan is able to put the compiler into the PATH, when you use the virtualenv generator.

But still, it would be even nicer if the CMakeToolchain generator would set the CMAKE_..._COMPILER variables. Because in PATH, there could be other compilers with the same name by accident.

Sebastian-Setzer avatar Jul 06 '22 15:07 Sebastian-Setzer

This would be doable with the flexibility that CMakeToolchain, but it needs to be explicit, for example we could define a conf like tools.cmake.cmaketoolchain:cxx_compiler, that tools_requires packages could define, and the CMakeToolchain can just get its value and add it to the conan_toolchain.cmake.

Is this what you have in mind? Because "automatic" guessing it would most likely be fragile and not always do the right thing. With the new build system integrations everything should be as explicit as possible, no auto-detection or magic.

memsharded avatar Jul 06 '22 17:07 memsharded

Still looks automatic to the user, right? Only the package that provides a compiler needs to care. Yes, that's what I had in mind.

In the same direction, I wonder why the mingw-builds package provides a cmake target that you have to link to your own target, instead of putting the required things into the toolchain file. Isn't this exactly what the toolchain file is for? Because with the current solution, you need to link it to all the target - even the ones you depend on. So that thing appears everywhere in your CMakeLists.txt when actually you'd prefer the CMakeLists.txt toolchain-independent and let only conan (as [tools_requires] or as profile) know which compiler you use on which platform.

Sebastian-Setzer avatar Jul 07 '22 07:07 Sebastian-Setzer

There is also an older issue discussing that topic: #9962

b1ackviking avatar Aug 05 '22 04:08 b1ackviking

This would be doable with the flexibility that CMakeToolchain, but it needs to be explicit, for example we could define a conf like tools.cmake.cmaketoolchain:cxx_compiler, that tools_requires packages could define, and the CMakeToolchain can just get its value and add it to the conan_toolchain.cmake.

@memsharded, pretty please 😉 This would help a lot with the usage of CMake Presets within the IDE, which unfortunately are now useless and even make things worse as most IDEs switch to CMakePresets mode by default when the generated file is found.

mpusz avatar Sep 02 '22 08:09 mpusz

@memsharded is there a recommended way to specify the compiler so that conan and cmake end up using the same?

The options I see are to explicitly set the CMAKE_CXX_COMPILER in one of the following ways

  • use a user cmake toolchain file and specify it in the conan profile
  • setting the environment variables (CMAKE_CXX_COMPILER, ...) on the CLI or inside a profile
  • new in 1.55 using tools.build:compiler_executables

Should the tools.build:compiler_executables be added to profiles? Will this affect also the CMakePresets so that they become usable for IDEs after running conan install?

fjp avatar Jan 03 '23 15:01 fjp

use a user cmake toolchain file and specify it in the conan profile

This has some issues. For example, the gdb debugger in VSCode may not know what the compiler was.

setting the environment variables (CMAKE_CXX_COMPILER, ...) on the CLI or inside a profile

This will not work with CMake presets

new in 1.55 using tools.build.compiler_executables

I think this is the final approach. This is how my gcc12 Conan profile looks like

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=12
compiler.libcxx=libstdc++11
build_type=Release
[options]
[build_requires]
[env]
[conf]
tools.build:compiler_executables={"c": "gcc-12", "cpp": "g++-12"}

I use that approach with multiple profiles for GCC and clang for a while now, and it works great. Although, I do not know how to set it for various versions of MSVC toolchains yet...

mpusz avatar Jan 03 '23 16:01 mpusz

Thanks @mpusz for the example profile. In case of cross compiling, do you use another build profile with its own tools.build:compiler_executables (in case the compilers are different between host and build context) or a conan env setup recipe?

Do you know if the [buildenv] section together with virtualenvs is becoming "deprecated" because of this new approach? And conan is moving towards CMakePresets?

fjp avatar Jan 03 '23 16:01 fjp

I think that @memsharded should answer those.

mpusz avatar Jan 03 '23 16:01 mpusz

Do you know if the [buildenv] section together with virtualenvs is becoming "deprecated" because of this new approach? And conan is moving towards CMakePresets?

No, [buildenv] is not being deprecated. The new compiler_executables is a bit more powerful than buildenv to define the compiler, because not all build systems in all OS listen to env-vars like CC/CXX (like cmake - visual studio). So this new conf allows to directly define CMAKE_CXX_COMPILER that works for all cases. Using CC/CXX in buildenv might be perfectly valid for some cases.

Conan is using presets as a standard way to define the build information, but it is not using them internally to build, but instead extracting the information from them and applying it on the command line, to be backwards compatible with CMake 3.15. But it is expected that more users will be using presets for the dev experience.

Otherwise, I think this ticket was closed by the implementation of the compiler_executables conf?

memsharded avatar Jan 05 '23 00:01 memsharded

This was implemented for 1.56 with the tools.build:compiler_executables new conf feature, so this can be closed. Please try the new feature and open a new ticket if necessary. Thanks!

memsharded avatar Jan 05 '23 22:01 memsharded

I have updated some comments in this thread, note that the correct syntax is tools.build:compiler_executables and not tools.build.compiler_executables. Conan 2.0 should raise an error for the second one.

memsharded avatar Apr 10 '23 12:04 memsharded