# Overwriting link dependencies - possible?

**URL:** https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495
**Category:** Code
**Created:** [February 4, 2026, 10:44am UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495 "2026-02-04T10:44:04Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![ingolf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/i/977dab/32.png) [@ingolf](https://discourse.cmake.org/u/ingolf)
#### Post date: [February 4, 2026, 10:44am UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/1 "2026-02-04T10:44:04Z")

</div>

Hi,

please have a look at the following situation:

- there is some (static) library named `libraryA`
- there is another (static) library named `libraryB` which has a link time dependency on `libraryA` (specified via `target_link_libraries(libraryB PRIVATE libraryA)`)
- there is a third (static) library named `libraryAmockup` which contains mockup versions of the functions in `libraryA` (with the same interface)
- there is an executable named `test_executable` which has a link time dependency on `libraryB` (specified via `target_link_libraries(test_executable PRIVATE libraryB)`)
- `test_executable` does not directly use functionality from `libraryA`

As `test_executable` is for testing purposes, I’d like to link with `libraryAmockup` rather than `libraryA`.

Is it possible to (reliably) exchange the dependencies _only for the `test_executable` target_? I.e. use `libraryB -> libraryAmockup` when linking `test_executable` and `libraryB -> libraryA` in all other situations.

Kind regards  
Ingolf

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [February 4, 2026, 12:45pm UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/2 "2026-02-04T12:45:20Z")

</div>

Maybe the [INTERFACE\_LINK\_LIBRARIES\_DIRECT](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.html) and [INTERFACE\_LINK\_LIBRARIES\_DIRECT\_EXCLUDE](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE.html) properties can be helpful for your case.

---

<div class="post-metadata">

### Author: ![ingolf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/i/977dab/32.png) [@ingolf](https://discourse.cmake.org/u/ingolf)
#### Post date: [February 4, 2026, 4:45pm UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/3 "2026-02-04T16:45:22Z")

</div>

Thanks, @marc.chevrier, for this suggestion. I had not yet been aware of `INTERFACE_LINK_LIBRARIES_DIRECT` and `INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE`.

I might misunderstand the documentation, so please correct me if applicable: I’d have to set the `INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` property of **`libraryB`** to `libraryA` and then explicitly link `test_executable` with `libraryAmockup`. The consequence would be that _all_ normal users (aka dependent targets) of `libraryB` would get into trouble if they don’t know that they have to link with `libraryA` (which should be an implementation detail of `libraryB` which is usually dealt with by the normal CMake transitive closure).

My goal was to keep the normal transitive closure mechanism for users of `libraryB` and override it only when linking that special `test_executable`.

Kind regards  
Ingolf

---

<div class="post-metadata">

### Author: ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)
#### Post date: [February 4, 2026, 8:52pm UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/4 "2026-02-04T20:52:56Z")

</div>

You do not need to change the dependency of libB if the mock symbols are linked before libB. The linker should only pull in the symbols from libA if such a symbol is needed by libB but not mocked.

So you just need to make sure that your mock of libA appears before libB in the linker command but linked either dynamic or the whole library.

---

<div class="post-metadata">

### Author: ![ingolf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/i/977dab/32.png) [@ingolf](https://discourse.cmake.org/u/ingolf)
#### Post date: [February 5, 2026, 9:50am UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/5 "2026-02-05T09:50:32Z")

</div>

@hsattler wrote:

> So you just need to make sure that your mock of libA appears before libB in the linker command but linked either dynamic or the whole library.

Is there a way (in CMake) to _reliably_ have `libraryAmockup` injected before the first occurence of `libraryB` and any `libraryA` occurrences (which might be caused by different dependencies)?

(I’d also need to wrap linking of `libraryAmockup` in a `--whole-archive`/`--no-whole-archive` pair (I’m using a GNU toolchain), but I know how to do that.)

Kind regards  
Ingolf

---

<div class="post-metadata">

### Author: ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)
#### Post date: [February 5, 2026, 4:43pm UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/6 "2026-02-05T16:43:02Z")

</div>

> [@ingolf](#):
>
> Is there a way (in CMake) to _reliably_ have `libraryAmockup` injected before the first occurence of `libraryB` and any `libraryA` occurrences (which might be caused by different dependencies)?

The link order given by target\_link\_libraries() is kept.

By the way, is there a reason you use static libraries?

---

<div class="post-metadata">

### Author: ![ingolf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/i/977dab/32.png) [@ingolf](https://discourse.cmake.org/u/ingolf)
#### Post date: [February 6, 2026, 10:13am UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/7 "2026-02-06T10:13:24Z")

</div>

Hi @hsattler,

you wrote:

> The link order given by target\_link\_libraries() is kept.

Yes, you are right. I was assuming (wrongly) that CMake would delay linking if several involved targets depend on the same target, i.e. that for instance in the case `e->{l1,l2}`, `l2->l1` CMake would link `l2` first and then `l1` because both `e` and `l2` depend on `l1`. But apparently CMake just links `l1` several times.

> By the way, is there a reason you use static libraries?

I link _libraries_ because the tests operate on the _interfaces_ of the library under test (operating the public interface and mocking subordinates). The libraries are _static_ because it’s an embedded environment without support for shared/dynamic libraries.

Kind regards  
Ingolf

---

<div class="post-metadata">

### Author: ![Flumbrix](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/aeb1de/32.png) [@Flumbrix](https://discourse.cmake.org/u/Flumbrix)
#### Post date: [February 10, 2026, 7:13pm UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/8 "2026-02-10T19:13:38Z")

</div>

I think that one possible way to achieve that would be to split the libraries to few more targets. This is based on an assumption that the compilation units / source files of `libraryB` only depend on access to the public headers of `libraryA`. And that users of `libraryB` should be “forced” to use `libraryA` implementation instead of providing their own.

I implemented a structure like this once before when we had a need to test implementations in static libraries, and we wanted to mock the implementations of dependant libraries. Which feels to me like exactly what you are trying to achieve.

The structure with targets would look like this:

```cmake
# Convenience interface library for accessing headers of libraryA without
# pulling in an implementation
add_library(libraryAheaders INTERFACE)
target_include_directories(libraryAheaders INTERFACE ${pathToLibAHeaders})

# Actual libraryA implementation
add_library(libraryA STATIC libAsource.cc)
target_link_libraries(libraryA PUBLIC libraryAheaders)

# Implementation of libraryB with dependency only to libraryA headers
add_library(libraryBimpl STATIC libBsource.cc)
target_link_libraries(libraryB PRIVATE libraryAheaders)

# Mock of libraryA
add_library(libraryAmockup STATIC libAmock.cc)
target_link_libraries(libraryAmockup PUBLIC libraryAheaders)

# Test executable for libraryB implementation using libraryAmockup
add_executable(test_executable testSource.cc)
target_link_libraries(test_executable PRIVATE libraryBimpl libraryAmockup)

# LibraryB to be used by consumers.
add_library(libraryB INTERFACE)
target_link_libraries(libraryB INTERFACE libraryBimpl libraryA)

```

The `libraryB` there could also be a static library implementing initialization or similar logic that connects `libraryBimpl` explicitly to `libraryA`. In which case the `test_executable` should contain similar logic for connecting `libraryBimpl` to `libraryAmockup`.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [February 14, 2026, 6:01am UTC](https://discourse.cmake.org/t/overwriting-link-dependencies-possible/15495/9 "2026-02-14T06:01:33Z")

</div>

> [@hsattler](#):
>
> The link order given by target\_link\_libraries() is kept.

That’s not guaranteed. CMake will reconstruct a linker command line according to the dependency graph constructed by the project. While CMake might currently preserve the order of things you specify in `target_link_libraries()` calls, there’s no guarantee that a future CMake version won’t order the linker command line differently. The only guarantee is that inter-target dependencies specified by the project will be honoured.

The project should not rely on the ordering of items given to `target_link_libraries()`. If certain things need to appear in a specific order, the project should enforce that by wrapping the grouped items with `SHELL:...`. But that can’t be used to order CMake _targets_, only raw linker command line options.

I think the underlying problem you have here is that you’re trying to set up a dependency relationship without telling CMake about it. More accurately, you’re trying to switch out one or more dependencies with different things, but not tell CMake about that. You could potentially achieve what you’re after using generator expressions that evaluate to the real libraries when used with one set of targets, or to the mock libraries for others. The generator expression could look at a property on the consuming target to work out which of the two cases it should expand to. But it is likely to get a bit involved. You have to work out the expansion for the top level target (executable or shared library), not necessarily the immediate consumer. I think you’re basically looking for the link seaming technique, or at least some variation of it.
