# CPS export: giving different interface properties to CPS vs the CMake package from one build

**URL:** https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843
**Category:** Code
**Created:** [September 21, 2026, 6:21am UTC](https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843 "2026-09-21T06:21:46Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![jobor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jobor/32/1230_2.png) [@jobor](https://discourse.cmake.org/u/jobor)
#### Post date: [September 21, 2026, 6:21am UTC](https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843/1 "2026-09-21T06:21:46Z")

</div>

We’re experimenting with making a large project (Qt) generate CPS files with `install(PACKAGE_INFO)`, alongside the usual `Qt6*Config.cmake` package files, using CMake 4.4.3.

Our main problem is generator expressions in interface properties.

Some usage requirements are stored as generator expressions, for example `-fPIC` for every language except Swift:

`target_compile_options(foo INTERFACE "$<$<NOT:$<COMPILE_LANGUAGE:Swift>>:-fPIC>")`

The CPS exporter stops with a fatal error on these:

`CMake Error in CMakeLists.txt:`  
` Property "INTERFACE_COMPILE_OPTIONS" of target "foo" contains a generator`  
` expression. This is not allowed.`

Minimal reproducer (CMake 4.3 or 4.4):

```cmake
cmake_minimum_required(VERSION 3.31)
project(Repro VERSION 1.0.0 LANGUAGES CXX)
add_library(foo foo.cpp)
target_compile_options(foo INTERFACE "$<$<NOT:$<COMPILE_LANGUAGE:Swift>>:-fPIC>")
install(TARGETS foo EXPORT repro ARCHIVE DESTINATION lib)
install(EXPORT repro DESTINATION lib/cmake/Repro NAMESPACE Repro:: FILE ReproTargets.cmake)
install(PACKAGE_INFO Repro EXPORT repro DESTINATION lib/cps) # fails here

```

Clearly, these cannot go into a portable CPS file, and that is fine. Our trouble is that to make the CPS export pass, we have to remove the entry from the target, and then the normal install(EXPORT) / Qt6\*Config.cmake export loses it too, because both read the same target at generate time. So we cannot produce good CPS files and full CMake config files from one build.

We could not find a way to give the CPS export a reduced set of interface properties while the CMake config export keeps the full set.

Question 1: what is the recommended way today to give the CPS export a reduced set of interface properties while the CMake config export keeps the full set, from one build? If there is none, would a per-export override be something you would consider, for example the CPS exporter preferring a `CPS_<PROPERTY>` value when it is set?

We also have a smaller question about external dependencies. We checked and it works well when a dependency is found in `CONFIG` mode and its target namespace matches the package name: CMake writes a proper requires (with a hints path) and a CPS consumer resolves it via a nested `find_package,` even if that dependency ships no CPS itself. The cases we are unsure about are dependencies that only come from a Find module (for example `Threads::Threads` from `FindThreads`, with no `ThreadsConfig.cmake`). A CPS requires on those cannot be resolved by a consumer.

Question 2: how should a package express a dependency that is only provided by a Find module, with no config package? Should it become a raw entry in `link_libraries`, or is there another intended mechanism?

---

<div class="post-metadata">

### Author: ![smanders](https://discourse.cmake.org/user_avatar/discourse.cmake.org/smanders/32/6189_2.png) [@smanders](https://discourse.cmake.org/u/smanders)
#### Post date: [September 22, 2026, 3:54am UTC](https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843/2 "2026-09-22T03:54:53Z")

</div>

I would welcome another mechanism for dependencies only provided by a Find module, with no config package (for example: Threads). My current work-around is to produce a package that provides a `threads-config.cmake` file which calls `find_package(Threads REQUIRED BYPASS_PROVIDER)`

> <https://github.com/externpro/Threads/blob/2fd266819850101aa42de0a60a9f53c610916a41/CMakeLists.txt#L3-L19>

examine extracted .tar.xz file for `threads-config.cmake` file

> **[Releases · externpro/Threads](https://github.com/externpro/Threads/releases)**
>
> wrapper for Threads::Threads. Contribute to externpro/Threads development by creating an account on GitHub.

I do a similar thing for OpenGL and Iconv

---

<div class="post-metadata">

### Author: ![smanders](https://discourse.cmake.org/user_avatar/discourse.cmake.org/smanders/32/6189_2.png) [@smanders](https://discourse.cmake.org/u/smanders)
#### Post date: [September 22, 2026, 4:09am UTC](https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843/3 "2026-09-22T04:09:52Z")

</div>

related CMake work item [https://gitlab.kitware.com/cmake/cmake/-/work\_items/27787](https://gitlab.kitware.com/cmake/cmake/-/work_items/27787)

which mentions this promising proposal…

> So the current proposal was something along the line of a hint, “when I generated this package, I found this dependency via [CMakeConfig, pkg-config, FindModule, WrapDB, etc].”
> 
> Once we have that it becomes possible to record we found something via FindModule and search for a FindModule for that dep.

---

<div class="post-metadata">

### Author: ![jobor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jobor/32/1230_2.png) [@jobor](https://discourse.cmake.org/u/jobor)
#### Post date: [September 22, 2026, 6:29am UTC](https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843/4 "2026-09-22T06:29:36Z")

</div>

Thanks, that’s useful, and for now we could use a similar work-around.

Remains the question what we can do about genexes that aren’t representable in CPS.

---

<div class="post-metadata">

### Author: ![Matthew\_Woehlke](https://discourse.cmake.org/user_avatar/discourse.cmake.org/matthew_woehlke/32/2345_2.png) [@Matthew\_Woehlke](https://discourse.cmake.org/u/Matthew_Woehlke)
#### Post date: [October 1, 2026, 4:07pm UTC](https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843/5 "2026-10-01T16:07:32Z")

</div>

`Threads::Threads` is a somewhat poor example because that’s meant to map to [a compile feature](https://cps-org.github.io/cps/features.html#threads), although I’m not sure to what extent that is hooked up.

---

<div class="post-metadata">

### Author: ![jobor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jobor/32/1230_2.png) [@jobor](https://discourse.cmake.org/u/jobor)
#### Post date: [October 2, 2026, 11:17am UTC](https://discourse.cmake.org/t/cps-export-giving-different-interface-properties-to-cps-vs-the-cmake-package-from-one-build/15843/6 "2026-10-02T11:17:55Z")

</div>

Sure, `Threads::Threads` is a bit of a lame example. Consider `double_conversion::double_conversion` instead. QtCore finds it through a `WrapDoubleConversion` find module, which provides that target, and we have more find modules of that shape.

But anyway, the more interesting question is the first one from the original post:  
what is the recommended way today to give the CPS export a reduced set of interface properties while the CMake config export keeps the full set, from one build? If there is none, would a per-export override be something you would consider, for example the CPS exporter preferring a `CPS_<PROPERTY>` value when it is set?
