conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.17k stars 974 forks source link

[question] How to specify a dict-like style configuration from the command line? #16439

Closed FeignClaims closed 3 months ago

FeignClaims commented 3 months ago

What is your question?

Hi, I'm trying to use -c tools.cmake.cmaketoolchain:extra_variables to inject some cmake variables. For instance, I inject set(TEST ON) by:

conan install . -c 'tools.cmake.cmaketoolchain:extra_variables={"TEST": ON}'

However, conan issues the following error:

ERROR: conanfile.py (sample_project/0.0.1): Error in generate() method, line 105
        toolchain.generate()
        ConanException: [conf] tools.cmake.cmaketoolchain:extra_variables must be a dict-like object. The value '{"TEST": ON}' introduced is a str object

The situation is that there're ENABLE_DEVELOPER_MODE=ON|OFF and OPT_ENABLE_COVERAGE=ON|OFF I want to inject to my ci jobs respectively, but I don't want to do a cartesian product to my profiles as I generalized them with profile rendering to allow using a generic profile (#-#-#-clang-#-#) for multiple jobs and specializing some jobs with specific profiles (windows-#-x86_64-clang-#-#). Therefore, although this could be done in profiles, I'd like to inject some variables in the command line.

My question: is it possible to specify such a dict-like style configuration from the command line?

Have you read the CONTRIBUTING guide?

memsharded commented 3 months ago

Hi @FeignClaims

Thanks for your question.

This is mostly about how terminals parse the command line. The value to confs is a string that will be converted to a Python object, but the characters will be incorrectly parsed unless quoted. Please try something like:

conan install . -c tools.cmake.cmaketoolchain:extra_variables="{'TEST': 'ON'}"

In any case, please note:

FeignClaims commented 3 months ago

The value to confs is a string that will be converted to a Python object, but the characters will be incorrectly parsed unless quoted.

Oh, I forgot that the value part also needs to be enclosed in quotes. Thank you for pointing that out.

There are already built-in confs for this use case, like tools.build:skip_test. This built-in conf is already being used by the CMake integrations to disable tests, so no need to do anything special.

The TEST I wrote here is just an attempt to test the use of tools.cmake.cmaketoolchain:extra_variables. I've actually use tools.build:skip_test in my repository and it works well thanks to your team's great work.

For other use cases that you might want to manage at command-line level, it is likely that building an abstraction, like using your own user conf like -c user.myteam:myconf=value could be cleaner in many situations.

Thanks for your suggestions; I'll give it a try to see if it works for my situation.