conan
conan copied to clipboard
[question] Why does conan not pass CMAKE_CXX_COMPILER to CMAKE
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.
- [ X ] I've read the CONTRIBUTING guide.
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
.
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?
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.
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?
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.
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.
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.
There is also an older issue discussing that topic: #9962
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.
@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?
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...
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?
I think that @memsharded should answer those.
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?
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!
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.