# Providing a dependency package::component only once if package::package (all components) has already provided

**URL:** <https://discourse.cmake.org/t/providing-a-dependency-package-component-only-once-if-package-package-all-components-has-already-provided/15315>\
**Category:** Code\
**Created:** [November 17, 2025, 1:25pm UTC](https://discourse.cmake.org/t/providing-a-dependency-package-component-only-once-if-package-package-all-components-has-already-provided/15315 "2025-11-17T13:25:57Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)\
**Post date:** [November 17, 2025, 1:25pm UTC](https://discourse.cmake.org/t/providing-a-dependency-package-component-only-once-if-package-package-all-components-has-already-provided/15315/1 "2025-11-17T13:25:57Z")

</div>

This is a bit an exotic situation which should be clearer with the example of using OpenSSL.

I’m making a first library, let say `A` that uses only one OpenSSL components, for instance OpenSSL::SSL.  
I’m then making a second library `B` that uses possibly all OpenSSL components (Crypto, SSL,…). But what I’m doing in this case is that I automatically create an OpenSSL::OpenSSL target that interfaces all the components (see [Difficulties using a third-party cmake projects: missing \<package\>\_INCLUDE\_DIR(S) (and other) - #9 by adaldev](https://discourse.cmake.org/t/difficulties-using-a-third-party-cmake-projects-missing-package-include-dir-s-and-other/15298/9)):

```cmake
get_property(ImportedTargets DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY IMPORTED_TARGETS)
list(FILTER ImportedTargets INCLUDE REGEX "^${PackName}::")

if(ImportedTargets)

	# Creating the main component
	add_library(${PackName}::${PackName} INTERFACE IMPORTED)
	# Adding the found components as dependencies
	if(ImportedTargets)
		target_link_libraries(${PackName}::${PackName} INTERFACE ${ImportedTargets})
	endif()

endif()

```

For each library, a configuration file is automatically created using this template:

```cmake
include(CMakeFindDependencyMacro)
foreach(_lib_ IN ITEMS @REQUIRED_DEPENDENCIES@)
	if(_lib_ MATCHES "::")
		# Dependency to a single component
		string(REPLACE "::" ";" _parts "${_lib_}")
		list(GET _parts 0 Package)
		list(GET _parts 1 Component)

		# Check if the component was not already imported
		if(NOT TARGET ${_lib_})
			# Import the specified component
			find_dependency(${Package} REQUIRED COMPONENTS ${Component})
		endif()
	else()
		# Full package
		find_dependency(${_lib_} REQUIRED)
	endif()
endforeach()

# include the generated target file
include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_NAME@Targets.cmake")

```

Where `REQUIRED_DEPENDENCIES` is the list of dependencies for the library being created:

| library | REQUIRED\_DEPENDENCIES |
| --- | --- |
| A | OpenSSL::SSL |
| B | OpenSSL |

Thus, if I create an application `App` linking both `A` and `B`, I think that `OpenSSL::SSL` is imported twice. How can I avoid to import again `OpenSSL::SSL` in `App`, when `OpenSSL::OpenSSL` has already been imported?

NB maybe it’s just a misconception on my part as the `find_dependency` are used to set paths right and the actual binary import is done elsewhere. Thus, maybe I’m only doing unnecessary `find_package` calls but no multiple “addition” of the `OpenSSL::SSL` binaries to `App`

Regards,  
A.

---

<div class="post-metadata">

**Author:** ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)\
**Post date:** [November 17, 2025, 1:50pm UTC](https://discourse.cmake.org/t/providing-a-dependency-package-component-only-once-if-package-package-all-components-has-already-provided/15315/2 "2025-11-17T13:50:21Z")

</div>

If it actually tried to import the same target multiple times, you’d get an error.  
Also linking the same target multiple times will get de-duplicated.

`find_dependency` uses `find_package` under the hood, and this thing already provides  
caching. That means finding the same dependency more than once should do nothing.  
If the config modules are written correctly, after you find `OpenSSL`, finding `OpenSSL::SSL` should be a no-op. If the order is reversed, it may be a no-op or it should only find the parts it hasn’t found the last time.

So, unless I’m mistaken of course, you don’t need to worry too much about this. Maybe just do a couple of tests to see if there are any erros.
