c++cmakeconan

How to choose Ninja as CMake generator with Conan?


While trying to follow along Conan's Getting Started guide for creating packages, I got stuck trying to run conan create . demo/testing. It continuously tries to use MinGW Makefiles as the CMake generator, but I'd like to use Ninja instead.

My recipe is as follows:

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout


class HelloConan(ConanFile):
    name = "hello"
    version = "0.1"

    # Optional metadata
    license = "<Put the package license here>"
    author = "<Put your name here> <And your email here>"
    url = "<Package recipe repository url here, for issues about the package>"
    description = "<Description of Hello here>"
    topics = ("<Put some tag here>", "<here>", "<and here>")

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}

    # Sources are located in the same place as this recipe, copy them to the recipe
    exports_sources = "CMakeLists.txt", "src/*", "include/*"

    def config_options(self):
        if self.settings.os == "Windows":
            del self.options.fPIC

    def layout(self):
        cmake_layout(self)

    def generate(self):
        tc = CMakeToolchain(self)
        tc.generate()

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

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        self.cpp_info.libs = ["hello"]

Output when running in a vcvars64.bat environment:

D:\microsoft_visual_studio\2022\Preview\VC\Auxiliary\Build>vcvars64.bat
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.2.0-pre.1.0
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
D:\Programming\hellopkg>conan create . demo/testing
Exporting package recipe
hello/0.1@demo/testing exports_sources: Copied 1 '.txt' file: CMakeLists.txt
hello/0.1@demo/testing exports_sources: Copied 1 '.cpp' file: hello.cpp
hello/0.1@demo/testing exports_sources: Copied 1 '.h' file: hello.h
hello/0.1@demo/testing: The stored package has not changed
hello/0.1@demo/testing: Exported revision: 4fc80e430f8244be40256fab755f8c43
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=clang
compiler.libcxx=libstdc++
compiler.version=13
os=Windows
os_build=Windows
[options]
[build_requires]
[env]
CC=D:/microsoft_visual_studio/2022/Preview/VC/Tools/Llvm/x64/bin/clang.exe
CXX=D:/microsoft_visual_studio/2022/Preview/VC/Tools/Llvm/x64/bin/clang++.exe
hello/0.1@demo/testing: Forced build from source
hello/0.1@demo/testing (test package): Installing package
Requirements
    hello/0.1@demo/testing from local cache - Cache
Packages
    hello/0.1@demo/testing:e12ca8b919921eecef92b328d38021194388175a - Build

Installing (downloading, building) binaries...
hello/0.1@demo/testing: WARN: Build folder is dirty, removing it: C:\Users\Zantox\.conan\data\hello\0.1\demo\testing\build\e12ca8b919921eecef92b328d38021194388175a
hello/0.1@demo/testing: Copying sources to build folder
hello/0.1@demo/testing: Building your package in C:\Users\Zantox\.conan\data\hello\0.1\demo\testing\build\e12ca8b919921eecef92b328d38021194388175a
hello/0.1@demo/testing: Generator txt created conanbuildinfo.txt
hello/0.1@demo/testing: Calling generate()
hello/0.1@demo/testing: WARN: Using the new toolchains and generators without specifying a build profile (e.g: -pr:b=default) is discouraged and might cause failures and unexpected behavior
hello/0.1@demo/testing: Aggregating env generators
hello/0.1@demo/testing: Calling build()
hello/0.1@demo/testing: CMake command: cmake -G "MinGW Makefiles" -DCMAKE_TOOLCHAIN_FILE="C:/Users/Zantox/.conan/data/hello/0.1/demo/testing/build/e12ca8b919921eecef92b328d38021194388175a/cmake-build-release/conan/conan_toolchain.cmake" -DCMAKE_INSTALL_PREFIX="C:/Users/Zantox/.conan/data/hello/0.1/demo/testing/package/e12ca8b919921eecef92b328d38021194388175a" -DCMAKE_SH="CMAKE_SH-NOTFOUND" "C:\Users\Zantox\.conan\data\hello\0.1\demo\testing\build\e12ca8b919921eecef92b328d38021194388175a\."
-- Using Conan toolchain: C:/Users/Zantox/.conan/data/hello/0.1/demo/testing/build/e12ca8b919921eecef92b328d38021194388175a/cmake-build-release/conan/conan_toolchain.cmake
-- Conan toolchain: Setting BUILD_SHARED_LIBS = OFF
-- The CXX compiler identification is Clang 13.0.0 with GNU-like command-line
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/microsoft_visual_studio/2022/Preview/VC/Tools/Llvm/x64/bin/clang++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done

The wiki specifies setting the Conan setting cmake_generator to Ninja like so:

$ conan config set general.cmake_generator=Ninja

I have confirmed that this setting is now in my conan.conf file under the [general] category, but it seems to have had no effect. Same with the CONAN_CMAKE_GENERATOR environment variable.

I tried changing the build part of the recipe to:

def build(self):
    cmake = CMake(self, generator="Ninja")
    cmake.configure()
    cmake.build()

But that only gives this error when trying to run:

ERROR: hello/0.1@demo/testing: Error in build() method, line 36
        cmake = CMake(self, generator="Ninja")
        TypeError: __init__() got an unexpected keyword argument 'generator'

For reference, I am using Python version 3.10.1 and Conan version 1.46.0


Solution

  • You are following the method signature to CMake helper imported directly from conans. However, you imported the new CMake helper designed to Conan 2.0. They are incompatible.

    You can keep the new helper, but you need to define your generator in conanbuild.conf. (Yet not documented)

    However, you also can set it directly in your CMakeToolchain constructor:

    tc = CMakeToolchain(self, generator="Ninja")
    

    But it's boring and hardcoded on your recipe, so as alternative, you can configure it directly in your global.conf file.

    echo tools.cmake.cmaketoolchain:generator=Ninja >> %USERPROFILE%\.conan\global.conf
    

    These features are experimental and should be improved soon as they will become the standard on Conan 2.0. Read the documentation in case the behavior changes.

    UPDATE:

    For Conan 2.x you can use the official example using CMake + Ninja as reference.