Repository: conan-io/conan

Issue:
[feature] Highlight requirements when they are invalid or missing
### What is your suggestion?

It would be desirable to display missing and invalid words in red or yellow in the command output, like these:


![image](https://github.com/conan-io/conan/assets/26503843/a2d5cb79-b729-43cf-8cf6-f84c6a257a5d)


![image](https://github.com/conan-io/conan/assets/26503843/01a97edc-3369-4df2-b07e-6644b355a841)

This will improve the usability experience by showing which packages are invalid on a first presentation.

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide

Discussion:
perseoGI: > For this, I might think that the information bit be a bit too repeated? Not something bothersome, just wanted to note it

Yayaya, definitely we may consider changing a little bit the error output.
Having colorful output is useful but some users may not use terminals supporting colorized outputs, CIs, plugins, etc.

What do you suggest @RubenRBS ?  



Patch:
diff --git a/conan/cli/printers/graph.py b/conan/cli/printers/graph.py
index 404ca7c97..5790f8e84 100644
--- a/conan/cli/printers/graph.py
+++ b/conan/cli/printers/graph.py
@@ -1,5 +1,5 @@
 from conan.api.output import ConanOutput, Color, LEVEL_VERBOSE
-from conans.client.graph.graph import RECIPE_CONSUMER, RECIPE_VIRTUAL, CONTEXT_BUILD, BINARY_SKIP,\
+from conans.client.graph.graph import BINARY_INVALID, BINARY_MISSING, RECIPE_CONSUMER, RECIPE_VIRTUAL, CONTEXT_BUILD, BINARY_SKIP,\
     BINARY_PLATFORM
 
 
@@ -122,13 +122,18 @@ def print_graph_packages(graph):
         output.info(title, Color.BRIGHT_YELLOW)
         for pref, (status, remote) in sorted(reqs_to_print.items(), key=repr):
             name = pref.repr_notime() if status != BINARY_PLATFORM else str(pref.ref)
-            msg = f"{tab}{name} - {status}"
-            if remote is not None and status != BINARY_SKIP:
-                msg += f" ({remote.name})"
+            msg = f"{tab}{name} - "
             if status == BINARY_SKIP:
                 skipped_requires.append(str(pref.ref))
-                output.verbose(msg, Color.BRIGHT_CYAN)
+                output.verbose(f"{msg}{status}", Color.BRIGHT_CYAN)
+            elif status == BINARY_MISSING or status == BINARY_INVALID:
+                output.write(msg, Color.BRIGHT_CYAN)
+                output.writeln(status, Color.BRIGHT_RED)
             else:
+                # Support python36
+                msg += status
+                if remote:
+                    msg += f" ({remote.name})"
                 output.info(msg, Color.BRIGHT_CYAN)
 
     _format_requires("Requirements", requires)
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index ae023a009..5d1f34051 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -23,11 +23,12 @@ from conans.model.version import Version
 from conans.util.files import load
 
 
-class Block(object):
-    def __init__(self, conanfile, toolchain):
+class Block:
+    def __init__(self, conanfile, toolchain, name):
         self._conanfile = conanfile
         self._toolchain = toolchain
         self._context_values = None
+        self._name = name
 
     @property
     def values(self):
@@ -44,7 +45,8 @@ class Block(object):
         if context is None:
             return
 
-        template = Template(self.template, trim_blocks=True, lstrip_blocks=True)
+        template = f"########## '{self._name}' block #############\n" + self.template + "\n\n"
+        template = Template(template, trim_blocks=True, lstrip_blocks=True)
         return template.render(**context)
 
     def context(self):
@@ -56,8 +58,10 @@ class Block(object):
 
 
 class VSRuntimeBlock(Block):
-    template = textwrap.dedent("""
-        # Definition of VS runtime, defined from build_type, compiler.runtime, compiler.runtime_type
+    template = textwrap.dedent("""\
+        # Definition of VS runtime CMAKE_MSVC_RUNTIME_LIBRARY, from settings build_type,
+        # compiler.runtime, compiler.runtime_type
+
         {% set genexpr = namespace(str='') %}
         {% for config, value in vs_runtimes.items() %}
             {% set genexpr.str = genexpr.str +
@@ -67,6 +71,7 @@ class VSRuntimeBlock(Block):
         if(NOT "${POLICY_CMP0091}" STREQUAL NEW)
             message(FATAL_ERROR "The CMake policy CMP0091 must be NEW, but is '${POLICY_CMP0091}'")
         endif()
+        message(STATUS "Conan toolchain: Setting CMAKE_MSVC_RUNTIME_LIBRARY={{ genexpr.str  }}")
         set(CMAKE_MSVC_RUNTIME_LIBRARY "{{ genexpr.str }}")
         """)
 
@@ -116,9 +121,11 @@ class VSRuntimeBlock(Block):
 
 
 class VSDebuggerEnvironment(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Definition of CMAKE_VS_DEBUGGER_ENVIRONMENT from "bindirs" folders of dependencies
+        # for execution of applications with shared libraries within the VS IDE
+
         {% if vs_debugger_path %}
-        # Definition of CMAKE_VS_DEBUGGER_ENVIRONMENT
         set(CMAKE_VS_DEBUGGER_ENVIRONMENT "{{ vs_debugger_path }}")
         {% endif %}
         """)
@@ -166,7 +173,9 @@ class VSDebuggerEnvironment(Block):
 
 
 class FPicBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Defining CMAKE_POSITION_INDEPENDENT_CODE for static libraries when necessary
+
         {% if fpic %}
         message(STATUS "Conan toolchain: Setting CMAKE_POSITION_INDEPENDENT_CODE={{ fpic }} (options.fPIC)")
         set(CMAKE_POSITION_INDEPENDENT_CODE {{ fpic }} CACHE BOOL "Position independent code")
@@ -185,11 +194,16 @@ class FPicBlock(Block):
 
 
 class GLibCXXBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Definition of libcxx from 'compiler.libcxx' setting, defining the
+        # right CXX_FLAGS for that libcxx
+
         {% if set_libcxx %}
+        message(STATUS "Conan toolchain: Defining libcxx as C++ flags: {{ set_libcxx }}")
         string(APPEND CONAN_CXX_FLAGS " {{ set_libcxx }}")
         {% endif %}
         {% if glibcxx %}
+        message(STATUS "Conan toolchain: Adding glibcxx compile definition: {{ glibcxx }}")
         add_compile_definitions({{ glibcxx }})
         {% endif %}
         """)
@@ -200,7 +214,9 @@ class GLibCXXBlock(Block):
 
 
 class SkipRPath(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Defining CMAKE_SKIP_RPATH
+
         {% if skip_rpath %}
         set(CMAKE_SKIP_RPATH 1 CACHE BOOL "rpaths" FORCE)
         # Policy CMP0068
@@ -216,7 +232,10 @@ class SkipRPath(Block):
 
 
 class ArchitectureBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define C++ flags, C flags and linker flags from 'settings.arch'
+
+        message(STATUS "Conan toolchain: Defining architecture flag: {{ arch_flag }}")
         string(APPEND CONAN_CXX_FLAGS " {{ arch_flag }}")
         string(APPEND CONAN_C_FLAGS " {{ arch_flag }}")
         string(APPEND CONAN_SHARED_LINKER_FLAGS " {{ arch_flag }}")
@@ -231,7 +250,10 @@ class ArchitectureBlock(Block):
 
 
 class LinkerScriptsBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Add linker flags from tools.build:linker_scripts conf
+
+        message(STATUS "Conan toolchain: Defining linker script flag: {{ linker_script_flags }}")
         string(APPEND CONAN_EXE_LINKER_FLAGS {{ linker_script_flags }})
         """)
 
@@ -248,7 +270,9 @@ class LinkerScriptsBlock(Block):
 
 
 class CppStdBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define the C++ and C standards from 'compiler.cppstd' and 'compiler.cstd'
+
         {% if cppstd %}
         message(STATUS "Conan toolchain: C++ Standard {{ cppstd }} with extensions {{ cppstd_extensions }}")
         set(CMAKE_CXX_STANDARD {{ cppstd }})
@@ -285,7 +309,9 @@ class CppStdBlock(Block):
 
 
 class SharedLibBock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define BUILD_SHARED_LIBS for shared libraries
+
         message(STATUS "Conan toolchain: Setting BUILD_SHARED_LIBS = {{ shared_libs }}")
         set(BUILD_SHARED_LIBS {{ shared_libs }} CACHE BOOL "Build shared libraries")
         """)
@@ -299,7 +325,9 @@ class SharedLibBock(Block):
 
 
 class ParallelBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define VS paralell build /MP flags
+
         string(APPEND CONAN_CXX_FLAGS " /MP{{ parallel }}")
         string(APPEND CONAN_C_FLAGS " /MP{{ parallel }}")
         """)
@@ -318,12 +346,18 @@ class ParallelBlock(Block):
 
 class AndroidSystemBlock(Block):
 
-    template = textwrap.dedent("""
-        # New toolchain things
+    template = textwrap.dedent("""\
+        # Define Android variables ANDROID_PLATFORM, ANDROID_STL, ANDROID_ABI, etc
+        # and include(.../android.toolchain.cmake) from NDK toolchain file
+
+        # New Android toolchain definitions
+        message(STATUS "Conan toolchain: Setting Android platform: {{ android_platform }}")
         set(ANDROID_PLATFORM {{ android_platform }})
         {% if android_stl %}
+        message(STATUS "Conan toolchain: Setting Android stl: {{ android_stl }}")
         set(ANDROID_STL {{ android_stl }})
         {% endif %}
+        message(STATUS "Conan toolchain: Setting Android abi: {{ android_abi }}")
         set(ANDROID_ABI {{ android_abi }})
         {% if android_use_legacy_toolchain_file %}
         set(ANDROID_USE_LEGACY_TOOLCHAIN_FILE {{ android_use_legacy_toolchain_file }})
@@ -363,7 +397,9 @@ class AndroidSystemBlock(Block):
 
 
 class AppleSystemBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define Apple architectures, sysroot, deployment target, bitcode, etc
+
         # Set the architectures for which to build.
         set(CMAKE_OSX_ARCHITECTURES {{ cmake_osx_architectures }} CACHE STRING "" FORCE)
         # Setting CMAKE_OSX_SYSROOT SDK, when using Xcode generator the name is enough
@@ -469,7 +505,9 @@ class AppleSystemBlock(Block):
 
 
 class FindFiles(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define paths to find packages, programs, libraries, etc.
+
         {% if find_package_prefer_config %}
         set(CMAKE_FIND_PACKAGE_PREFER_CONFIG {{ find_package_prefer_config }})
         {% endif %}
@@ -618,7 +656,9 @@ class FindFiles(Block):
 
 
 class PkgConfigBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define pkg-config from 'tools.gnu:pkg_config' executable and paths
+
         {% if pkg_config %}
         set(PKG_CONFIG_EXECUTABLE {{ pkg_config }} CACHE FILEPATH "pkg-config executable")
         {% endif %}
@@ -643,7 +683,9 @@ class PkgConfigBlock(Block):
 
 
 class UserToolchain(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Include one or more CMake user toolchain from tools.cmake.cmaketoolchain:user_toolchain
+
         {% for user_toolchain in paths %}
         include("{{user_toolchain}}")
         {% endfor %}
@@ -662,7 +704,10 @@ class UserToolchain(Block):
 class ExtraFlagsBlock(Block):
     """This block is adding flags directly from user [conf] section"""
 
-    _template = textwrap.dedent("""
+    _template = textwrap.dedent("""\
+        # Include extra C++, C and linker flags from configuration tools.build:<type>flags
+        # and from CMakeToolchain.extra_<type>_flags
+
         # Conan conf flags start: {{config}}
         {% if cxxflags %}
         string(APPEND CONAN_CXX_FLAGS{{suffix}} "{% for cxxflag in cxxflags %} {{ cxxflag }}{% endfor %}")
@@ -753,7 +798,9 @@ class ExtraFlagsBlock(Block):
 
 
 class CMakeFlagsInitBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Define CMAKE_<XXX>_FLAGS from CONAN_<XXX>_FLAGS
+
         foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
             string(TOUPPER ${config} config)
             if(DEFINED CONAN_CXX_FLAGS_${config})
@@ -782,12 +829,13 @@ class CMakeFlagsInitBlock(Block):
         if(DEFINED CONAN_EXE_LINKER_FLAGS)
           string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${CONAN_EXE_LINKER_FLAGS}")
         endif()
-
         """)
 
 
 class TryCompileBlock(Block):
-    template = textwrap.dedent("""
+    template = textwrap.dedent("""\
+        # Blocks after this one will not be added when running CMake try/checks
+
         get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
         if(_CMAKE_IN_TRY_COMPILE)
             message(STATUS "Running toolchain IN_TRY_COMPILE")
@@ -821,14 +869,12 @@ class CompilersBlock(Block):
 
 
 class GenericSystemBlock(Block):
-    template = textwrap.dedent("""
-        ########## generic_system block #############
+    template = textwrap.dedent("""\
         # Definition of system, platform and toolset
-        #############################################
+
         {% if cmake_sysroot %}
         set(CMAKE_SYSROOT {{ cmake_sysroot }})
         {% endif %}
-
         {% if cmake_system_name %}
         # Cross building
         set(CMAKE_SYSTEM_NAME {{ cmake_system_name }})
@@ -947,7 +993,8 @@ class GenericSystemBlock(Block):
         return os_host in ('iOS', 'watchOS', 'tvOS', 'visionOS') or (
                 os_host == 'Macos' and (arch_host != arch_build or os_build != os_host))
 
-    def _get_darwin_version(self, os_name, os_version):
+    @staticmethod
+    def _get_darwin_version(os_name, os_version):
         # version mapping from https://en.wikipedia.org/wiki/Darwin_(operating_system)
         version_mapping = {
             "Macos": {
@@ -1063,8 +1110,11 @@ class GenericSystemBlock(Block):
                 "winsdk_version": winsdk_version,
                 "gen_platform_sdk_version": gen_platform_sdk_version}
 
+
 class ExtraVariablesBlock(Block):
-    template = textwrap.dedent(r"""
+    template = textwrap.dedent("""\
+        # Definition of extra CMake variables from tools.cmake.cmaketoolchain:extra_variables
+
         {% if extra_variables %}
         {% for key, value in extra_variables.items() %}
         set({{ key }} {{ value }})
@@ -1072,7 +1122,7 @@ class ExtraVariablesBlock(Block):
         {% endif %}
     """)
 
-    CMAKE_CACHE_TYPES = ["BOOL","FILEPATH", "PATH", "STRING", "INTERNAL"]
+    CMAKE_CACHE_TYPES = ["BOOL", "FILEPATH", "PATH", "STRING", "INTERNAL"]
 
     def get_exact_type(self, key, value):
         if isinstance(value, str):
@@ -1096,27 +1146,30 @@ class ExtraVariablesBlock(Block):
                     raise ConanException(f'tools.cmake.cmaketoolchain:extra_variables "{key}" invalid type "{var_type}" for cache variable. Possible types: {", ".join(self.CMAKE_CACHE_TYPES)}')
                 # Set docstring as variable name if not defined
                 docstring = value.get("docstring") or key
-                force_str = " FORCE" if is_force else "" # Support python < 3.11
+                force_str = " FORCE" if is_force else ""  # Support python < 3.11
                 return f"{var_value} CACHE {var_type} \"{docstring}\"{force_str}"
             else:
                 if is_force:
                     raise ConanException(f'tools.cmake.cmaketoolchain:extra_variables "{key}" "force" is only allowed for cache variables')
                 return var_value
 
-
     def context(self):
         # Reading configuration from "tools.cmake.cmaketoolchain:extra_variables"
-        extra_variables = self._conanfile.conf.get("tools.cmake.cmaketoolchain:extra_variables", default={}, check_type=dict)
+        extra_variables = self._conanfile.conf.get("tools.cmake.cmaketoolchain:extra_variables",
+                                                   default={}, check_type=dict)
         parsed_extra_variables = {}
         for key, value in extra_variables.items():
             parsed_extra_variables[key] = self.get_exact_type(key, value)
         return {"extra_variables": parsed_extra_variables}
 
+
 class OutputDirsBlock(Block):
 
     @property
     def template(self):
-        return textwrap.dedent("""
+        return textwrap.dedent("""\
+           # Definition of CMAKE_INSTALL_XXX folders
+
            {% if package_folder %}
            set(CMAKE_INSTALL_PREFIX "{{package_folder}}")
            {% endif %}
@@ -1152,6 +1205,81 @@ class OutputDirsBlock(Block):
                 "default_res": self._get_cpp_info_value("resdirs")}
 
 
+class VariablesBlock(Block):
+    @property
+    def template(self):
+        return textwrap.dedent("""\
+            # Definition of CMake variables from CMakeToolchain.variables values
+
+            {% macro iterate_configs(var_config, action) %}
+            {% for it, values in var_config.items() %}
+                {% set genexpr = namespace(str='') %}
+                {% for conf, value in values -%}
+                set(CONAN_DEF_{{ conf }}{{ it }} "{{ value }}")
+                {% endfor %}
+                {% for conf, value in values -%}
+                    {% set genexpr.str = genexpr.str +
+                                          '$<IF:$<CONFIG:' + conf + '>,${CONAN_DEF_' + conf|string + it|string + '},' %}
+                    {% if loop.last %}{% set genexpr.str = genexpr.str + '""' -%}{%- endif -%}
+                {% endfor %}
+                {% for i in range(values|count) %}{% set genexpr.str = genexpr.str + '>' %}
+                {% endfor %}
+                set({{ it }} {{ genexpr.str }} CACHE STRING
+                    "Variable {{ it }} conan-toolchain defined")
+            {% endfor %}
+            {% endmacro %}
+            # Variables
+            {% for it, value in variables.items() %}
+            {% if value is boolean %}
+            set({{ it }} {{ "ON" if value else "OFF"}} CACHE BOOL "Variable {{ it }} conan-toolchain defined")
+            {% else %}
+            set({{ it }} "{{ value }}" CACHE STRING "Variable {{ it }} conan-toolchain defined")
+            {% endif %}
+            {% endfor %}
+            # Variables  per configuration
+            {{ iterate_configs(variables_config, action='set') }}
+            """)
+
+    def context(self):
+        return {"variables": self._toolchain.variables,
+                "variables_config": self._toolchain.variables.configuration_types}
+
+
+class PreprocessorBlock(Block):
+    @property
+    def template(self):
+        return textwrap.dedent("""\
+        # Preprocessor definitions from CMakeToolchain.preprocessor_definitions values
+
+        {% for it, value in preprocessor_definitions.items() %}
+        {% if value is none %}
+        add_compile_definitions("{{ it }}")
+        {% else %}
+        add_compile_definitions("{{ it }}={{ value }}")
+        {% endif %}
+        {% endfor %}
+        # Preprocessor definitions per configuration
+        {% for name, values in preprocessor_definitions_config.items() %}
+        {%- for (conf, value) in values %}
+        {% if value is none %}
+        set(CONAN_DEF_{{conf}}_{{name}} "{{name}}")
+        {% else %}
+        set(CONAN_DEF_{{conf}}_{{name}} "{{name}}={{value}}")
+        {% endif %}
+        {% endfor %}
+        add_compile_definitions(
+        {%- for (conf, value) in values %}
+        $<$<CONFIG:{{conf}}>:${CONAN_DEF_{{conf}}_{{name}}}>
+        {%- endfor -%})
+        {% endfor %}
+        """)
+
+    def context(self):
+        return {"preprocessor_definitions": self._toolchain.preprocessor_definitions,
+                "preprocessor_definitions_config":
+                    self._toolchain.preprocessor_definitions.configuration_types}
+
+
 class ToolchainBlocks:
     def __init__(self, conanfile, toolchain, items=None):
         self._blocks = OrderedDict()
@@ -1159,7 +1287,7 @@ class ToolchainBlocks:
         self._toolchain = toolchain
         if items:
             for name, block in items:
-                self._blocks[name] = block(conanfile, toolchain)
+                self._blocks[name] = block(conanfile, toolchain, name)
 
     def keys(self):
         return self._blocks.keys()
@@ -1173,6 +1301,16 @@ class ToolchainBlocks:
             del self._blocks[arg]
 
     def select(self, name, *args):
+        """
+        keep the blocks provided as arguments, remove the others, except pre-existing "variables"
+        and "preprocessor", to not break behavior
+        """
+        self._conanfile.output.warning("CMakeToolchain.select is deprecated. Use blocks.enabled()"
+                                       " instead", warn_tag="deprecated")
+        to_keep = [name] + list(args) + ["variables", "preprocessor"]
+        self._blocks = OrderedDict((k, v) for k, v in self._blocks.items() if k in to_keep)
+
+    def enabled(self, name, *args):
         """
         keep the blocks provided as arguments, remove the others
         """
@@ -1182,7 +1320,7 @@ class ToolchainBlocks:
     def __setitem__(self, name, block_type):
         # Create a new class inheriting Block with the elements of the provided one
         block_type = type('proxyUserBlock', (Block,), dict(block_type.__dict__))
-        self._blocks[name] = block_type(self._conanfile, self._toolchain)
+        self._blocks[name] = block_type(self._conanfile, self._toolchain, name)
 
     def __getitem__(self, name):
         return self._blocks[name]
diff --git a/conan/tools/cmake/toolchain/toolchain.py b/conan/tools/cmake/toolchain/toolchain.py
index 0692751eb..6d834ec9b 100644
--- a/conan/tools/cmake/toolchain/toolchain.py
+++ b/conan/tools/cmake/toolchain/toolchain.py
@@ -9,11 +9,12 @@ from conan.internal import check_duplicated_generator
 from conan.tools.build import use_win_mingw
 from conan.tools.cmake.presets import write_cmake_presets
 from conan.tools.cmake.toolchain import CONAN_TOOLCHAIN_FILENAME
-from conan.tools.cmake.toolchain.blocks import ExtraVariablesBlock, ToolchainBlocks, UserToolchain, GenericSystemBlock, \
+from conan.tools.cmake.toolchain.blocks import ExtraVariablesBlock, ToolchainBlocks, UserToolchain, \
+    GenericSystemBlock, \
     AndroidSystemBlock, AppleSystemBlock, FPicBlock, ArchitectureBlock, GLibCXXBlock, VSRuntimeBlock, \
     CppStdBlock, ParallelBlock, CMakeFlagsInitBlock, TryCompileBlock, FindFiles, PkgConfigBlock, \
     SkipRPath, SharedLibBock, OutputDirsBlock, ExtraFlagsBlock, CompilersBlock, LinkerScriptsBlock, \
-    VSDebuggerEnvironment
+    VSDebuggerEnvironment, VariablesBlock, PreprocessorBlock
 from conan.tools.cmake.utils import is_multi_configuration
 from conan.tools.env import VirtualBuildEnv, VirtualRunEnv
 from conan.tools.intel import IntelCC
@@ -56,39 +57,18 @@ class Variables(OrderedDict):
                     data[key] = str(var).replace('"', '\\"')
 
 
-class CMakeToolchain(object):
+class CMakeToolchain:
 
     filename = CONAN_TOOLCHAIN_FILENAME
 
-    # TODO: Clean this macro, do it explicitly for variables
-    _template = textwrap.dedent("""
-        {% macro iterate_configs(var_config, action) %}
-            {% for it, values in var_config.items() %}
-                {% set genexpr = namespace(str='') %}
-                {% for conf, value in values -%}
-                set(CONAN_DEF_{{ conf }}{{ it }} "{{ value }}")
-                {% endfor %}
-                {% for conf, value in values -%}
-                    {% set genexpr.str = genexpr.str +
-                                          '$<IF:$<CONFIG:' + conf + '>,${CONAN_DEF_' + conf|string + it|string + '},' %}
-                    {% if loop.last %}{% set genexpr.str = genexpr.str + '""' -%}{%- endif -%}
-                {% endfor %}
-                {% for i in range(values|count) %}{% set genexpr.str = genexpr.str + '>' %}
-                {% endfor %}
-                set({{ it }} {{ genexpr.str }} CACHE STRING
-                    "Variable {{ it }} conan-toolchain defined")
-            {% endfor %}
-        {% endmacro %}
-
+    _template = textwrap.dedent("""\
         # Conan automatically generated toolchain file
         # DO NOT EDIT MANUALLY, it will be overwritten
 
         # Avoid including toolchain file several times (bad if appending to variables like
         #   CMAKE_CXX_FLAGS. See https://github.com/android/ndk/issues/323
         include_guard()
-
         message(STATUS "Using Conan toolchain: ${CMAKE_CURRENT_LIST_FILE}")
-
         if(${CMAKE_VERSION} VERSION_LESS "3.15")
             message(FATAL_ERROR "The 'CMakeToolchain' generator only works with CMake >= 3.15")
         endif()
@@ -97,41 +77,6 @@ class CMakeToolchain(object):
         {{ conan_block }}
         {% endfor %}
 
-        # Variables
-        {% for it, value in variables.items() %}
-        {% if value is boolean %}
-        set({{ it }} {{ "ON" if value else "OFF"}} CACHE BOOL "Variable {{ it }} conan-toolchain defined")
-        {% else %}
-        set({{ it }} "{{ value }}" CACHE STRING "Variable {{ it }} conan-toolchain defined")
-        {% endif %}
-        {% endfor %}
-        # Variables  per configuration
-        {{ iterate_configs(variables_config, action='set') }}
-
-        # Preprocessor definitions
-        {% for it, value in preprocessor_definitions.items() %}
-        {% if value is none %}
-        add_compile_definitions("{{ it }}")
-        {% else %}
-        add_compile_definitions("{{ it }}={{ value }}")
-        {% endif %}
-        {% endfor %}
-        # Preprocessor definitions per configuration
-        {% for name, values in preprocessor_definitions_config.items() %}
-        {%- for (conf, value) in values %}
-        {% if value is none %}
-        set(CONAN_DEF_{{conf}}_{{name}} "{{name}}")
-        {% else %}
-        set(CONAN_DEF_{{conf}}_{{name}} "{{name}}={{value}}")
-        {% endif %}
-        {% endfor %}
-        add_compile_definitions(
-        {%- for (conf, value) in values %}
-        $<$<CONFIG:{{conf}}>:${CONAN_DEF_{{conf}}_{{name}}}>
-        {%- endfor -%})
-        {% endfor %}
-
-
         if(CMAKE_POLICY_DEFAULT_CMP0091)  # Avoid unused and not-initialized warnings
         endif()
         """)
@@ -171,7 +116,9 @@ class CMakeToolchain(object):
                                        ("pkg_config", PkgConfigBlock),
                                        ("rpath", SkipRPath),
                                        ("shared", SharedLibBock),
-                                       ("output_dirs", OutputDirsBlock)])
+                                       ("output_dirs", OutputDirsBlock),
+                                       ("variables", VariablesBlock),
+                                       ("preprocessor", PreprocessorBlock)])
 
         # Set the CMAKE_MODULE_PATH and CMAKE_PREFIX_PATH to the deps .builddirs
         self.find_builddirs = True
@@ -188,10 +135,7 @@ class CMakeToolchain(object):
 
         blocks = self.blocks.process_blocks()
         ctxt_toolchain = {
-            "variables": self.variables,
-            "variables_config": self.variables.configuration_types,
-            "preprocessor_definitions": self.preprocessor_definitions,
-            "preprocessor_definitions_config": self.preprocessor_definitions.configuration_types,
+
             "conan_blocks": blocks
         }
 


Test patch:
diff --git a/test/unittests/tools/cmake/test_cmaketoolchain.py b/test/unittests/tools/cmake/test_cmaketoolchain.py
index 3d66adada..8ba5ff7f0 100644
--- a/test/unittests/tools/cmake/test_cmaketoolchain.py
+++ b/test/unittests/tools/cmake/test_cmaketoolchain.py
@@ -58,10 +58,16 @@ def test_remove(conanfile):
     assert "_CMAKE_IN_TRY_COMPILE" in content
 
 
-def test_filter(conanfile):
+def test_select_blocks(conanfile):
     toolchain = CMakeToolchain(conanfile)
     toolchain.blocks.select("generic_system")
     content = toolchain.content
+    assert "########## 'generic_system' block #############" in content
+    assert "########## 'cmake_flags_init' block #############" not in content
+    assert "########## 'libcxx' block #############" not in content
+    # These are not removed by default, to not break behavior
+    assert "########## 'variables' block #############" in content
+    assert "########## 'preprocessor' block #############" in content
     assert 'CMAKE_SYSTEM_NAME' in content
     assert "CMAKE_CXX_FLAGS_INIT" not in content
     assert "_CMAKE_IN_TRY_COMPILE" not in content
@@ -70,10 +76,24 @@ def test_filter(conanfile):
     toolchain = CMakeToolchain(conanfile)
     toolchain.blocks.select("generic_system", "cmake_flags_init")
     content = toolchain.content
+    assert "########## 'generic_system' block #############" in content
+    assert "########## 'cmake_flags_init' block #############" in content
+    assert "########## 'libcxx' block #############" not in content
+    # These are not removed by default, to not break behavior
+    assert "########## 'variables' block #############" in content
+    assert "########## 'preprocessor' block #############" in content
     assert 'CMAKE_SYSTEM_NAME' in content
     assert "CMAKE_CXX_FLAGS_INIT" in content
     assert "_CMAKE_IN_TRY_COMPILE" not in content
 
+    # remove multiple
+    toolchain = CMakeToolchain(conanfile)
+    toolchain.blocks.enabled("generic_system")
+    content = toolchain.content
+    assert "########## 'generic_system' block #############" in content
+    assert "########## 'variables' block #############" not in content
+    assert "########## 'preprocessor' block #############" not in content
+
 
 def test_dict_keys(conanfile):
     toolchain = CMakeToolchain(conanfile)