Conan: [question] Specifying a Cmake generator in a profile

Created on 22 Mar 2021  路  3Comments  路  Source: conan-io/conan

I have profiles for GCC (MSYS2), Clang (MSYS2), MSVC, and ClangCL on my x64 Windows machine for Debug and Release build types and they all work fine with Ninja except for ClangCL because Ninja doesn't support toolsets. I specified Ninja as the Cmake generator in settings.yml, but I would like to know if there is a way to specify a Cmake generator exclusively for the ClangCL profile.

triaging question

Most helpful comment

I'm so glad this is working for you!

For posterity, [conf] is identical to [env] in the way it works and would be used. It's a way for users calling Conan from the CLI to "set parameters" for functions in various places within Conan, or within tools called by Conan. Strictly speaking, [env] is capable of doing everything [conf] will do. The only problems with [env] were that it already had a primary purpose in the ecosystem, for passing parameters directly to build tools like compilers, linkers, and build systems, and also that environment variables are global. We didn't want to overload the role of the generic construct of environment variables to implement a bunch of Conan configurations, nor did we want to force the configuration item names to be super long to avoid conflict with existing environment variables. It was better to create a parallel channel for parameters to flow from users to internals, thus we created [conf]

All 3 comments

There is currently no native way to specify the cmake generator from a profile or via the CLI. Recipes can specify a preference via the CMake helper (older feature) or the CMakeToolchain (newer feature), but that's it.

https://docs.conan.io/en/latest/reference/build_helpers/cmake.html
https://docs.conan.io/en/1.31/creating_packages/toolchains/cmake.html

In the future of the CMakeToolchain, it's possible this (and many other build system choices) will be exposed via the new [conf] mechanism, similar to MSBuild Verbosity:

https://docs.conan.io/en/latest/reference/config_files/global_conf.html#tools-configurations

However, that's still experimental, and a ways off.

In the meantime, here's an example of the cmake build helper you'll find in most recipes.

   def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

If you have full control of the recipes you use, you can either specify this logic in all your recipes:

   def build(self):
        generator = "Visual Studio" if self.settings.compiler=="ClangCL" else "Ninja"
        cmake = CMake(self, generator=generator) 
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

Or you can implement environment variables as a mechanism to give yourself full control over the generator from a profile/CLI:

In the recipe:

   def build(self):
        generator = os.getenv("generator")
        if generator:
            cmake = CMake(self, generator=generator) 
        else:
            cmake = CMake(self)
        cmake.configure()
        cmake.build()

Then, you can specify a generator for all packages, or for individual ones via profile/CLI:

[env]
*:generator=Visual Studio
package_1:generator=nmake
package_2:generator=Ninja
conan create . -e *:generator="Visual Studio" -e package_1:generator=nmake -e package_2:generator=Ninja

Let me know if you are able to modify your recipes and make one of these solutions work. Otherwise, let us know if you think the future [conf] mechanism I mentioned would be a good fit.

Thank you for the elaborate reply!

I managed to get it working with the environment variable solution.

Here is my build() method:

    def build(self):
        if os.getenv("clang-cl"):
            cmake = CMake(self,
                          generator="Visual Studio 16 2019",
                          toolset="ClangCL")
        else:
            cmake = CMake(self, generator="Ninja")

        cmake.configure()
        cmake.build()

Here is my CLang profile:

[settings]
compiler=clang
compiler.version=11
compiler.runtime=MD

[options]
[build_requires]
[env]
CC=clang
CXX=clang++

Here is my ClangCL profile:

include(clang)

[settings]
[options]
[build_requires]
[env]
clang-cl=1

I like this approach because Clang and ClangCL are both just Clang, so my dependencies get compiled with Clang and I can test my Cmake configuration code with ClangCL.

Honestly, I am not entirely sure I understand the [conf] approach, for now, but this approach currently works for me and I can't wait for Conan 2 to see all the amazing solutions you come up with to these sorts of problems.

I'm so glad this is working for you!

For posterity, [conf] is identical to [env] in the way it works and would be used. It's a way for users calling Conan from the CLI to "set parameters" for functions in various places within Conan, or within tools called by Conan. Strictly speaking, [env] is capable of doing everything [conf] will do. The only problems with [env] were that it already had a primary purpose in the ecosystem, for passing parameters directly to build tools like compilers, linkers, and build systems, and also that environment variables are global. We didn't want to overload the role of the generic construct of environment variables to implement a bunch of Conan configurations, nor did we want to force the configuration item names to be super long to avoid conflict with existing environment variables. It was better to create a parallel channel for parameters to flow from users to internals, thus we created [conf]

Was this page helpful?
0 / 5 - 0 ratings

Related issues

theodelrieu picture theodelrieu  路  3Comments

zomeck picture zomeck  路  3Comments

liberforce picture liberforce  路  3Comments

omicronns picture omicronns  路  3Comments

tonka3000 picture tonka3000  路  3Comments