# How do you avoid target name conflicts in a multi-config setup?

**URL:** https://discourse.cmake.org/t/how-do-you-avoid-target-name-conflicts-in-a-multi-config-setup/7711
**Category:** Usage
**Tags:** os:windows
**Created:** [March 19, 2023, 7:37pm UTC](https://discourse.cmake.org/t/how-do-you-avoid-target-name-conflicts-in-a-multi-config-setup/7711 "2023-03-19T19:37:40Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![max](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/e5b9ba/32.png) [@max](https://discourse.cmake.org/u/max)
#### Post date: [March 19, 2023, 7:37pm UTC](https://discourse.cmake.org/t/how-do-you-avoid-target-name-conflicts-in-a-multi-config-setup/7711/1 "2023-03-19T19:37:40Z")

</div>

I’m forking this discussion off from [https://gitlab.kitware.com/cmake/cmake/-/issues/23482](https://gitlab.kitware.com/cmake/cmake/-/issues/23482). I’ve got some large, pre-built libraries that are released separately for the Debug and Release versions. And I would just like to hook them up in a Visual Studio multi-configuration setup. The included Find[Package].cmake do not seem to support multi-configuration setups well, but I know this should still be possible in theory. CMake is making it pretty tricky though.

Both versions of the pre-built libraries include a Fiind[Package].cmake file. They have the same name, which is the first issue. If I run find\_package([package]) twice and try to specify the paths for each version, CMake will ignore the second path because it’s silently cached the location from the first call. You can get around this with the NAMES option to alias the packages, but each config doesn’t just define itself – it defines a recursive web of targets, and none of these targets are distinguished by configuration. So the second find\_package() call will silently use the targets defined from the first call for all of the internal libraries.

Basically all I need is the ability to call find\_package() twice and distinguish targets with the same name. A namespacing system, or something. Some way to distinguish [package1].target\_foo from [package2].target\_foo. If you have any other ideas for approaching this I’d appreciate it. Changing the original library to support multi-config would be quite complicated and would not support backwards compatability.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [March 20, 2023, 4:44pm UTC](https://discourse.cmake.org/t/how-do-you-avoid-target-name-conflicts-in-a-multi-config-setup/7711/2 "2023-03-20T16:44:32Z")

</div>

There is [an issue about namespacing](https://gitlab.kitware.com/cmake/cmake/-/issues/22687) that is kind of related. However, the way CMake prefers to do this is to have a single target with multiple locations attached in configuration-specific properties (e.g., `IMPORTED_LOCATION_RELEASE` rather than just `IMPORTED_LOCATION`).

CMake will make this work _if_ the project’s artifacts don’t collide in a single build tree as the per-config properties are added in configuration-specific files when exported. So I would try making sure the artifact names are changed based on the configuration and just use a single install prefix for both.

---

<div class="post-metadata">

### Author: ![max](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/e5b9ba/32.png) [@max](https://discourse.cmake.org/u/max)
#### Post date: [March 20, 2023, 9:18pm UTC](https://discourse.cmake.org/t/how-do-you-avoid-target-name-conflicts-in-a-multi-config-setup/7711/3 "2023-03-20T21:18:47Z")

</div>

I’ve seen that namespacing discussion, and I think it would be the “right” solution here, probably the only right solution (unfortunately it doesn’t seem like it’s going to happen in the near term). Note that I’m trying to work within the confines of pre-built libraries that are externally provided, and make it backwards compatible, so given that constraint I wouldn’t be able to change how things are installed/exported. And right now the targets have the same name across debug/release and don’t annotate their build configuration in the way you describe.

The only solution I’ve found (possibly the only solution that exists without namespacing or building the library from source) is the following ridiculousness: run two separate CMake instances in a subprocess via execute\_process(). Call find\_package() in each, and recursively parse the targets via the manual examination of all target properties, heuristically determining which properties refer to targets. Prepend all targets with a namespace. Do the same for any variables that need to be surfaced. Then (because of a second restriction in CMake, that you can’t re-export imported targets with modified properties), manually write the targets to a custom CMake file, filtering out the read only properties. Do the same with the variables. Import these .cmake files in the main process.

This works, but it’s really gross and fragile, and I’m basically just creating a meta-namespacing system through string parsing. I am kind of surprised by how well it works though.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [March 20, 2023, 9:37pm UTC](https://discourse.cmake.org/t/how-do-you-avoid-target-name-conflicts-in-a-multi-config-setup/7711/4 "2023-03-20T21:37:47Z")

</div>

An alternate solution might be to use the scoping of `find_package` (though you’ll may have to fight the cache) and do something like:

```cmake
add_library(ExtDep::FullTarget IMPORTED UNKNOWN)
add_subdirectory(for-release) # find the release build, put its data onto `ExtDep::FullTarget` with `_RELEASE` suffixes
add_subdirectory(for-debug) # find the debug build and as done in `for-release`

```

This _might_ be able to skirt the recursive target problem at least.

---

<div class="post-metadata">

### Author: ![a\_toldaiev](https://discourse.cmake.org/user_avatar/discourse.cmake.org/a_toldaiev/32/5496_2.png) [@a\_toldaiev](https://discourse.cmake.org/u/a_toldaiev)
#### Post date: [November 15, 2025, 5:53pm UTC](https://discourse.cmake.org/t/how-do-you-avoid-target-name-conflicts-in-a-multi-config-setup/7711/5 "2025-11-15T17:53:02Z")

</div>

A related question: is there a common practice how to avoid name clashes on the targets for tests? E.g. when each of a couple subprojects has a target “tests” to run its tests. Should the projects prepend the test target name with `$PROJECT`? (Like [ROS does](https://docs.ros.org/en/melodic/api/catkin/html/user_guide/standards.html) apparently.) Does [the GoogleTest module](https://cmake.org/cmake/help/latest/module/GoogleTest.html) resolve name conflicts between the test target in subprojects?
