Skip to content

[POC][CMakeConfigDeps] Multi-CONFIG CMake files mechanism - #20298

Open
franramirez688 wants to merge 8 commits into
conan-io:develop2from
franramirez688:frm/poc_multi_config
Open

[POC][CMakeConfigDeps] Multi-CONFIG CMake files mechanism#20298
franramirez688 wants to merge 8 commits into
conan-io:develop2from
franramirez688:frm/poc_multi_config

Conversation

@franramirez688

@franramirez688 franramirez688 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Changelog: Feature: Multi-CONFIG CMake files mechanism in CMakeConfigDeps.
Changelog: Feature: Property cmake_file_name accepts a string or a dict object in CMakeConfigDeps.
Docs: https://github.com/conan-io/docs/pull/XXXX
Closes: #19407

Checked on CCI repo

spirv-tools

Applying this diff, it should work locally on your native env:

diff --git a/recipes/spirv-tools/all/conanfile.py b/recipes/spirv-tools/all/conanfile.py
index 63ee667a0a..d9dcdb9749 100644
--- a/recipes/spirv-tools/all/conanfile.py
+++ b/recipes/spirv-tools/all/conanfile.py
@@ -146,7 +146,14 @@ class SpirvtoolsConan(ConanFile):
             rm(self, "*SPIRV-Tools-shared*", os.path.join(self.package_folder, "lib"))

     def package_info(self):
-        self.cpp_info.set_property("cmake_file_name", "SPIRV-Tools")
+        self.cpp_info.set_property("cmake_file_name", {
+            "SPIRV-Tools": {"components": ["spirv-tools-core"]},
+            "SPIRV-Tools-opt": {"components": ["spirv-tools-opt"]},
+            "SPIRV-Tools-link": {"components": ["spirv-tools-link"]},
+            "SPIRV-Tools-reduce": {"components": ["spirv-tools-reduce"]},
+            "SPIRV-Tools-lint": {"components": ["spirv-tools-lint"]},
+            "SPIRV-Tools-diff": {"components": ["spirv-tools-diff"]},
+        })
         self.cpp_info.set_property("pkg_config_name", "SPIRV-Tools-shared" if self.options.shared else "SPIRV-Tools")

         # SPIRV-Tools
diff --git a/recipes/spirv-tools/all/test_package/CMakeLists.txt b/recipes/spirv-tools/all/test_package/CMakeLists.txt
index 8e5e8c835..8f599056f 100644
--- a/recipes/spirv-tools/all/test_package/CMakeLists.txt
+++ b/recipes/spirv-tools/all/test_package/CMakeLists.txt
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.15)
 project(test_package)

 find_package(SPIRV-Tools REQUIRED CONFIG)
+find_package(SPIRV-Tools-opt REQUIRED CONFIG)

 add_executable(${PROJECT_NAME}_c test_package.c)
 if(TARGET SPIRV-Tools-shared)
diff --git a/recipes/spirv-tools/all/test_package/conanfile.py b/recipes/spirv-tools/all/test_package/conanfile.py
index d8eaf2ab1..98a5e384f 100644
--- a/recipes/spirv-tools/all/test_package/conanfile.py
+++ b/recipes/spirv-tools/all/test_package/conanfile.py
@@ -6,7 +6,7 @@ import os

 class TestPackageConan(ConanFile):
     settings = "os", "arch", "compiler", "build_type"
-    generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv"
+    generators = "CMakeToolchain", "CMakeConfigDeps", "VirtualRunEnv"
     test_type = "explicit"

     def layout(self):
-- Conan: Configuring Targets for spirv-tools-opt
-- Conan: Configuring Targets for spirv-tools-core
-- Conan: Target declared imported STATIC library 'SPIRV-Tools-static'
-- Conan: Target declared alias 'SPIRV-Tools' for 'SPIRV-Tools-static'
-- Conan: Target declared imported STATIC library 'SPIRV-Tools-opt'
-- Configuring done (0.8s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/frannchuti/develop/conan-center-index/recipes/spirv-tools/all/test_package/build/apple-clang-17-armv8-gnu17-release

spirv-tools/1.4.350.0 (test package): Running CMake.build()
spirv-tools/1.4.350.0 (test package): RUN: cmake --build "/Users/frannchuti/develop/conan-center-index/recipes/spirv-tools/all/test_package/build/apple-clang-17-armv8-gnu17-release" -- -j14
[ 25%] Building C object CMakeFiles/test_package_c.dir/test_package.c.o
[ 50%] Building CXX object CMakeFiles/test_package_cpp.dir/test_package.cpp.o
[ 75%] Linking C executable test_package_c
[ 75%] Built target test_package_c
[100%] Linking CXX executable test_package_cpp
ld: warning: ignoring duplicate libraries: '-lc++'
[100%] Built target test_package_cpp


======== Testing the package: Executing test ========
spirv-tools/1.4.350.0 (test package): Running test()
spirv-tools/1.4.350.0 (test package): RUN: ./test_package_c

spirv-tools/1.4.350.0 (test package): RUN: ./test_package_cpp
OpCapability Linkage
OpCapability Shader
OpMemoryModel Logical GLSL450
%int = OpTypeInt 32 1
%int_42 = OpConstant %int 42
$ tree
tree
.
├── . . . 
├── SPIRV-Tools-diff-Targets-release.cmake
├── SPIRV-Tools-diffConfig.cmake
├── SPIRV-Tools-diffConfigVersion.cmake
├── SPIRV-Tools-diffTargets.cmake
├── SPIRV-Tools-link-Targets-release.cmake
├── SPIRV-Tools-linkConfig.cmake
├── SPIRV-Tools-linkConfigVersion.cmake
├── SPIRV-Tools-linkTargets.cmake
├── SPIRV-Tools-lint-Targets-release.cmake
├── SPIRV-Tools-lintConfig.cmake
├── SPIRV-Tools-lintConfigVersion.cmake
├── SPIRV-Tools-lintTargets.cmake
├── SPIRV-Tools-opt-Targets-release.cmake
├── SPIRV-Tools-optConfig.cmake
├── SPIRV-Tools-optConfigVersion.cmake
├── SPIRV-Tools-optTargets.cmake
├── SPIRV-Tools-reduce-Targets-release.cmake
├── SPIRV-Tools-reduceConfig.cmake
├── SPIRV-Tools-reduceConfigVersion.cmake
├── SPIRV-Tools-reduceTargets.cmake
├── SPIRV-Tools-Targets-release.cmake
├── SPIRV-ToolsConfig.cmake
├── SPIRV-ToolsConfigVersion.cmake
└── SPIRV-ToolsTargets.cmake

Comment on lines +893 to +898
# A dependency might be split into several CMake config files (root +
# cmake_file_name dict groups), each one needs its own _DIR entry.
for cmake_filename, cmake_file_info in self._cmakedeps.get_cmake_filenames_info(dep).items():
extra_variants = self._cmakedeps.get_property("cmake_file_name_variants", dep,
custom_props=cmake_file_info.get("properties"),
check_type=list) or []

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge diff, but there are a couple of changes over here. One of them is these lines

Comment on lines +905 to +911
cmake_file_name_prop = self._cmakedeps.get_property(
"cmake_file_name", dep, custom_props=cmake_file_info.get("properties"))
is_cmake_filename_defined = (
isinstance(cmake_file_name_prop, str)
or (isinstance(cmake_file_name_prop, dict)
and cmake_filename in cmake_file_name_prop)
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this evaluation is the other one. The rest of the diff is only indentation changes

@franramirez688
franramirez688 marked this pull request as ready for review August 31, 2026 11:40
@czoido

czoido commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

I noticed that when a dependency's cmake_file_name dict covers 100% of its components (like the example given here for spirv-tools), the aggregated pkg::pkg target never gets generated. So any consumer that requires the package without pointing at a specific component ends up linking against a target that doesn't exist.

Would it make sense to raise an exception at generate time (something like "package X has no default target, point cpp_info.requires at a specific component")? At least consumers would get an actionable Conan error instead of a confusing CMake one three layers down.

@memsharded memsharded left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is overall looking good, but maybe it would still be worth to decouple a preparation PR that takes into account for the indents and other similar refactor preparation and small generalizations, to be able to introduce the pure multi-file more cleanly.

# have a context-independent filename. When the same package is both requires and
# tool_requires, keep the host-context version so legacy variables (<pkg>_LIBRARIES,
# ...) are preserved.
for cmake_filename, cmake_file_info in self.get_cmake_filenames_info(dep).items():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this is also just an indent, but difficult to read the diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] Investigate config file creation per component in CMakeConfigDeps

3 participants