Skip to content

Split lib target types in their own export groups - #4494

Merged
Cyan4973 merged 1 commit into
meta:devfrom
LecrisUT:maint-cmake
Dec 1, 2025
Merged

Cyan4973 merged 1 commit into
meta:devfrom
LecrisUT:maint-cmake

Conversation

@LecrisUT

Copy link
Copy Markdown
Contributor

This allows for the non-primary library to be missing in the Config.cmake file, e.g. if the devel files have a separate static-devel package

This allows for the non-primary library to be missing in the Config.cmake file, e.g. if the devel files have a separate static-devel package

Signed-off-by: Cristian Le <git@lecris.dev>
@opoplawski

Copy link
Copy Markdown

Could the developers please comment on this? This would be very helpful for Fedora packaging.

@Cyan4973 Cyan4973 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a solid attempt at separating the CMake export targets:

  • zstdTargets_shared.cmake - exports libzstd_shared
  • zstdTargets_static.cmake - exports libzstd_static
  • zstdTargets.cmake - exports the interface libzstd target

This allows Linux distros to package static libraries separately (e.g., libzstd-static-devel) without breaking the main package's CMake config.

The core idea is correct and solves a real packaging problem.
However:

  • The interface target (zstd::libzstd) may still break. If libzstd was configured to link against libzstd_static (when BUILD_SHARED_LIBS=OFF), but zstdTargets_static.cmake is missing, then using zstd::libzstd will fail at CMake configure time. The PR doesn't fully handle this dependency chain.

  • Consumer guidance is missing. Users should know:

    • Use zstd::libzstd_shared if you explicitly want the shared library
    • Use zstd::libzstd_static if you explicitly want the static library
    • Use zstd::libzstd for the default (respects BUILD_SHARED_LIBS at zstd build time)
    • Check if(TARGET zstd::libzstd_static) before using it

foreach(lib_suffix IN ITEMS "_shared" "_static")
include("${CMAKE_CURRENT_LIST_DIR}/zstdTargets${lib_suffix}.cmake" OPTIONAL)
endforeach()
include("${CMAKE_CURRENT_LIST_DIR}/zstdTargets.cmake")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is not optional: the libzstd interface target's dependency is baked in at build time.
That's fine, but the files it depends on can be split at package time. There's a hidden assumption that whoever packages zstd will keep the dependency chain intact.

The edge case described (building with BUILD_SHARED_LIBS=OFF then stripping the static package) is unlikely.
But it could be worth adding a runtime check in zstdConfig.cmake.in that the target libzstd depends on actually exists.

@LecrisUT

LecrisUT commented Dec 1, 2025

Copy link
Copy Markdown
Contributor Author
  • but zstdTargets_static.cmake is missing, then using zstd::libzstd will fail at CMake configure time

This is a downstream packaging issue. I would bot recommend upstream to carry the logic to support this as it will be hard to test cover this and it can hide various other issues. Downstream already need to be fully aware of all the building logic to produce and separate the artifacts, at which point they should be checking how each config.cmake are being consumed

  • Consumer guidance is missing.

Honestly only zstd::libzstd. A project even allowimg to link to either shared or static at their choosing is an extremely niche usecase that should be deprecated in modern CMake designs. The packager should be the one to control it and if the user needs more control they should be consuming with FetchContent instead.


The goal here is to merely unblock the downstream packaging with optional components (i.e. if the consumer only links to libzstd or a specific _shared target (from libzstd-devel) it should work even if the complement (libzstd-static-devel) is not present), not to document or dictate a new way for the user to consume it. I believe I kept that intact when I wrote the PR, but time has passed and I don't remember the full details of these, but I can re-review as needed.

If you wish to refactor the consumer interface then sure thing, I can give some detailed tips amd reviews on that, but I don't think it should be in this PR.

@Cyan4973

Cyan4973 commented Dec 1, 2025

Copy link
Copy Markdown
Contributor

The rationale behind this logic is that, since the primary consumers of this niche capability are package managers,
they are expected to be aware of the package’s internal details and are responsible for avoiding the aforementioned edge case.
This reasoning is justifiable.

Regarding refactoring, I had considered utilizing the COMPONENT option (e.g., cmake --install . --component shared).
However, this would constitute a more substantial refactor and is better suited for a future pull request.

@Cyan4973 Cyan4973 self-assigned this Dec 1, 2025
@Cyan4973

Cyan4973 commented Dec 1, 2025 •

Copy link
Copy Markdown
Contributor

Note: CI errors reported here are unrelated.
Just a side effect of compiler version update on mingw vm, which is already fixed in #4497.

@LecrisUT

LecrisUT commented Dec 1, 2025

Copy link
Copy Markdown
Contributor Author

Regarding refactoring, I had considered utilizing the COMPONENT option (e.g., cmake --install . --component shared).
However, this would constitute a more substantial refactor and is better suited for a future pull request.

Do you mean COMPONENTS in find_package()? COMPONENT in install() is only useful if the artifact may not be present after a build, say if a target is not in ALL, but if you end up down that path, I expect there are a bunch of other issues you should address first before that. More recommended to keep the build-system vanilla then to chase that rabbit.

COMPONENTS in find_package() may be a valid design, but again, would be good not to abuse it too much.

@Cyan4973
Cyan4973 merged commit 9e23edc into meta:dev Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants