# PRIVATE-becomes-PUBLIC behaviour for static libraries

**URL:** https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430
**Category:** Code
**Tags:** os:windows
**Created:** [August 12, 2024, 2:19pm UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430 "2024-08-12T14:19:51Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![malaterre](https://discourse.cmake.org/user_avatar/discourse.cmake.org/malaterre/32/1971_2.png) [@malaterre](https://discourse.cmake.org/u/malaterre)
#### Post date: [August 12, 2024, 2:19pm UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430/1 "2024-08-12T14:19:51Z")

</div>

Hi there,

AFAIK the following code:

`target_link_libraries(dcmimage PRIVATE ${PNG_LIBRARIES})`

imply that the PNG libraries will be added on the link line when linking against `dcmimage`. As such it is a expected behavior to have:

```auto
> cat cmake\DCMTKTargets.cmake
[...]
# Create imported target DCMTK::dcmimage
add_library(DCMTK::dcmimage STATIC IMPORTED)

set_target_properties(DCMTK::dcmimage PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:DCMTK::oflog>;\$<LINK_ONLY:DCMTK::dcmdata>;\$<LINK_ONLY:DCMTK::dcmimgle>;\$<\$<NOT:\$<CONFIG:DEBUG>>:C:/builds/acme-clinical/dicom/dcmtk/obj/vcpkg_installed/x64-windows-static/lib/libpng16.lib>;\$<\$<CONFIG:DEBUG>:C:/builds/acme-clinical/dicom/dcmtk/obj/vcpkg_installed/x64-windows-static/debug/lib/libpng16d.lib>"
)

```

My issue is that those full paths are messing up my third party project linking against DCMTK, since the file `C:/builds/acme-clinical/dicom/dcmtk/obj/vcpkg_installed/x64-windows-static/lib/libpng16.lib` is part of one gitlab project while I am building from another one ?

What should I be using here instead (Is there a REALLY\_PRIVATE keyword for target\_link\_libraries…) ?

Thanks for suggestion

---

<div class="post-metadata">

### Author: ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)
#### Post date: [August 12, 2024, 4:17pm UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430/2 "2024-08-12T16:17:03Z")

</div>

> those full paths

It is strange that you get full absolute paths there. I also use vcpkg for resolving 3rd-party dependencies in my projects, and I also link to PNG in one of those projects, but what I get is:

```cmake
set_target_properties(mMap PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:someThing>;\$<LINK_ONLY:jpeg-turbo::turbojpeg-static>;\$<LINK_ONLY:draco::draco>;\$<LINK_ONLY:png>;..." # and so on
)

```

It probably has to do with the way you link to PNG, because I see you are linking to its actual libraries (_`${PNG_LIBRARIES}`_) instead of its CMake target.

> Is there a REALLY\_PRIVATE

As far as I know, there is no such thing, and I probably misunderstood what you are asking here, but it is possible to “hack” this linking out from your library’s exported CMake config with something like this:

```cmake
# a dirty hack to remove a target from INTERFACE_LINK_LIBRARIES when it isn't actually needed
#
# from CMake 3.27 there is $<COMPILE_ONLY:...>, which should be better way
#
get_target_property(YOUR_PROJECT_INTERFACE_LINK_LIBRARIES ${PROJECT_NAME} INTERFACE_LINK_LIBRARIES)
if(NOT "${YOUR_PROJECT_INTERFACE_LINK_LIBRARIES}" STREQUAL "YOUR_PROJECT_INTERFACE_LINK_LIBRARIES-NOTFOUND")
    list(REMOVE_ITEM YOUR_PROJECT_INTERFACE_LINK_LIBRARIES [=[$<LINK_ONLY:TARGET_YOU_WANT_TO_REMOVE>]=])
    set_target_properties(YOUR_PROJECT
        PROPERTIES
            INTERFACE_LINK_LIBRARIES "${YOUR_PROJECT_INTERFACE_LINK_LIBRARIES}"
    )
endif()

```

but then in consuming project you will for sure encounter linking problems, as PNG symbols will be missing at the “final” linking.

Either way, hopefully you won’t need to go this way, as your problem is likely because of linking “directly” to the libraries instead of the target.

---

<div class="post-metadata">

### Author: ![malaterre](https://discourse.cmake.org/user_avatar/discourse.cmake.org/malaterre/32/1971_2.png) [@malaterre](https://discourse.cmake.org/u/malaterre)
#### Post date: [August 13, 2024, 7:04am UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430/3 "2024-08-13T07:04:48Z")

</div>

> [@retif](#):
>
> It probably has to do with the way you link to PNG, because I see you are linking to its actual libraries (_`${PNG_LIBRARIES}`_) instead of its CMake target.

Indeed ! If I change the following line (\*):

`DCMTK_TARGET_LINK_LIBRARIES(dcmimage ${LIBTIFF_LIBS} ${LIBPNG_LIBS})`

into:

`DCMTK_TARGET_LINK_LIBRARIES(dcmimage ${LIBTIFF_LIBS} PNG::PNG)`

then everything works as expected (private remains private). thanks for the trick.

Just for my own curiosity where did you see it documented ? This change in behavior does not seems obvious from:

- [https://cmake.org/cmake/help/latest/module/FindPNG.html](https://cmake.org/cmake/help/latest/module/FindPNG.html)

Thanks

(\*) [git.dcmtk.org Git - dcmtk.git/blob - dcmimage/libsrc/CMakeLists.txt](https://git.dcmtk.org/?p=dcmtk.git;a=blob;f=dcmimage/libsrc/CMakeLists.txt;hb=HEAD#l28)

---

<div class="post-metadata">

### Author: ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)
#### Post date: [August 13, 2024, 8:14am UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430/4 "2024-08-13T08:14:02Z")

</div>

> where did you see it documented

That isn’t something specific to the PNG’s `Find*` module, it is how [target\_link\_libraries()](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) works in general - there is an explanation there about what one can link to (_targets versus libraries_).

---

<div class="post-metadata">

### Author: ![malaterre](https://discourse.cmake.org/user_avatar/discourse.cmake.org/malaterre/32/1971_2.png) [@malaterre](https://discourse.cmake.org/u/malaterre)
#### Post date: [August 13, 2024, 9:36am UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430/5 "2024-08-13T09:36:18Z")

</div>

> [@malaterre](#):
>
> then everything works as expected (private remains private). thanks for the trick.

This is incorrect. `PNG::PNG` will be properly propagated (PRIVATE-becomes-PUBLIC), but the major change is that the full path is not hard-coded anymore. I can build yet another vcpkg/PNG in my third party application (same exact ABI) and then my original symptoms are now solved.

---

<div class="post-metadata">

### Author: ![malaterre](https://discourse.cmake.org/user_avatar/discourse.cmake.org/malaterre/32/1971_2.png) [@malaterre](https://discourse.cmake.org/u/malaterre)
#### Post date: [August 13, 2024, 2:55pm UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430/6 "2024-08-13T14:55:12Z")

</div>

One last thing for whoever will read this.

After the above change, the following will fails:

```auto
find_package(DCMTK)
add_library(foobar DCMTK::dcmimage)

```

The error will read something like:

```auto
-- Configuring done
CMake Error at CMakeLists.txt:2 (add_library):
  Target "foobar" links to target "PNG::PNG" but the target was not found.
  Perhaps a find_package() call is missing for an IMPORTED target, or an
  ALIAS target is missing?
-- Generating done

```

Pay attention that will be required to add the missing `find_package` not before the `add_library` call, but before the actual `find_package(DCMTK)`.

Hopefully useful for someone else.

---

<div class="post-metadata">

### Author: ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)
#### Post date: [August 13, 2024, 3:32pm UTC](https://discourse.cmake.org/t/private-becomes-public-behaviour-for-static-libraries/11430/7 "2024-08-13T15:32:53Z")

</div>

That’s hardly any news 🙂  
This is just how CMake packages/configs work by design: either project maintainer takes care of this in the package config with `find_dependency()`, or his users will have to add `find_package()` in their projects.
