Repository: conan-io/conan

Issue:
[question] preset name != profile name
### What is your question?

For my conan profile "Release" the cmake preset ends up being "conan-release", and for "Debug" it ends up being "conan-debug". This is fine! But for "DebugASAN", it also ends up being "conan-debug" and not "conan-debugasan".

Is there some easy way I can control the preset name from the profile? Or always have it be the same?

Sorry, if this has been asked before; most things I could find where outdated or referred to Conan1.

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide


Discussion:
Hi @h-2 

Thanks for your question.

The profile file name is never used in the preset itself, if your profile file is named "Release", it is a coincidence. The presets names are taken:
- by default from the ``build_type`` setting
- It can be customized with the ``self.folders.build_folder_vars`` as ``self.folders.build_folder_vars = ["settings.os", "options.shared"]`` in recipes
- It can also be customized with the ``tools.cmake.cmake_layout:build_folder_vars`` conf from profiles.

So if your ``asan`` is something like an option in your profile, it should be easy to get it into the preset name, is this the case?
Thank you for the quick reply and the explanations.

> So if your asan is something like an option in your profile, it should be easy to get it into the preset name, is this the case?

Well, it changes the cxx_flags, but I wouldnt want to add those to the name...

Is there a way I can just do `tools.cmake.cmake_layout:build_folder_vars = profile_name` or even set it to a fixed string?


I have tried adding:
```
tools.cmake.cmake_layout:build_folder_vars = [ "profile_name" ]
```
But it doesn't work:
```
conanfile.txt: ERROR: Traceback (most recent call last):
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conans/client/generators/__init__.py", line 97, in write_generators
    generator.generate()
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conan/tools/cmake/toolchain/toolchain.py", line 269, in generate
    write_cmake_presets(self._conanfile, toolchain, self.generator, cache_variables,
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conan/tools/cmake/presets.py", line 19, in write_cmake_presets
    preset_path, preset_data = _CMakePresets.generate(conanfile, toolchain_file, generator,
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conan/tools/cmake/presets.py", line 72, in generate
    data = _CMakePresets._contents(conanfile, toolchain_file, cache_variables, generator,
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conan/tools/cmake/presets.py", line 98, in _contents
    conf = _CMakePresets._configure_preset(conanfile, generator, cache_variables, toolchain_file,
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conan/tools/cmake/presets.py", line 115, in _configure_preset
    name = _CMakePresets._configure_preset_name(conanfile, multiconfig)
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conan/tools/cmake/presets.py", line 228, in _configure_preset_name
    custom_conf, user_defined_build = get_build_folder_custom_vars(conanfile)
  File "/opt/prepare/corpus/.venv/lib/python3.10/site-packages/conan/tools/cmake/layout.py", line 84, in get_build_folder_custom_vars
    group, var = s.split(".", 1)
ValueError: not enough values to unpack (expected 2, got 1)
```

I am also not really sure how this is related to the layout of the build folder at all. It's just about the naming of the preset 🤔 
> tools.cmake.cmake_layout:build_folder_vars = profile_name

It is not possible at this moment. Note that profile name is not even a single file, as there can be (and it is common) to use multiple profiles like ``-pr=profile1 -pr=profile2 -pr=profile3``.  This would be very challenging to implement, as the profile names are not really stored and propagated, they are evaluated very early and only the ``settings``, ``options``, ``conf`` values are propagating down to the recipes and CMake helpers.

The best approach for these cases is usually to abstract the concept of sanitizers, with custom settings ore options like in https://docs.conan.io/2/reference/binary_model/extending.html#extending-the-binary-model.
Because the binary compatibility might be affected by them, so a explicit model of the sanitizer beyond the low level ``cxxflags`` is beneficial to manage different ``package_id`` binaries for the binaries with sanitization and binaries without. Or you don't want to manage this difference in your binaries?



Patch:
diff --git a/conan/tools/cmake/layout.py b/conan/tools/cmake/layout.py
index dad6ce31270..fbff89c200c 100644
--- a/conan/tools/cmake/layout.py
+++ b/conan/tools/cmake/layout.py
@@ -94,9 +94,11 @@ def get_build_folder_custom_vars(conanfile):
                     tmp = "{}_{}".format(var, value)
         elif group == "self":
             tmp = getattr(conanfile, var, None)
+        elif group == "const":
+            tmp = var
         else:
             raise ConanException("Invalid 'tools.cmake.cmake_layout:build_folder_vars' value, it has"
-                                 " to start with 'settings.' or 'options.': {}".format(s))
+                                 f" to start with 'settings.', 'options.', 'self.' or 'const.': {s}")
         if tmp:
             ret.append(tmp.lower())
 


Test patch:
diff --git a/test/integration/toolchains/cmake/test_cmaketoolchain.py b/test/integration/toolchains/cmake/test_cmaketoolchain.py
index dee27284e79..38ac9049b82 100644
--- a/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -1278,6 +1278,32 @@ def layout(self):
     assert "conan-windows-pkg-0.1-debug" in presets
 
 
+def test_build_folder_vars_constants_user():
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import cmake_layout
+
+        class Conan(ConanFile):
+            name = "dep"
+            version = "0.1"
+            settings = "os", "build_type"
+            generators = "CMakeToolchain"
+
+            def layout(self):
+                cmake_layout(self)
+        """)
+    c.save({"conanfile.py": conanfile})
+    conf = "tools.cmake.cmake_layout:build_folder_vars='[\"const.myvalue\"]'"
+    settings = " -s os=FreeBSD -s arch=armv8 -s build_type=Debug"
+    c.run("install . -c={} {}".format(conf, settings))
+    assert "cmake --preset conan-myvalue-debug" in c.out
+    assert os.path.exists(os.path.join(c.current_folder, "build", "myvalue", "Debug"))
+    presets = load(os.path.join(c.current_folder,
+                                "build/myvalue/Debug/generators/CMakePresets.json"))
+    assert "conan-myvalue-debug" in presets
+
+
 def test_extra_flags():
     client = TestClient()
     conanfile = textwrap.dedent("""