Skip to content

fix: complete the static link line in miniocpp.pc - #265

Merged
harshavardhana merged 1 commit into
minio:mainfrom
harshavardhana:fix/pc-static-deps
Sep 10, 2026
Merged

harshavardhana merged 1 commit into
minio:mainfrom
harshavardhana:fix/pc-static-deps

Conversation

@harshavardhana

@harshavardhana harshavardhana commented Sep 10, 2026

Copy link
Copy Markdown
Member

Description

miniocpp.pc declared only Requires: libcrypto libssl pugixml zlib, so
pkg-config --static --libs miniocpp omitted INIReader/inih and brotli, and
libs3rdma on an RDMA build. libminio.a carries undefined INIReader::* and
Brotli* symbols, so a consumer linking from the .pc alone fails with
undefined references.

The .pc cannot see target_link_libraries(), so the private dependencies are
now collected in miniocpp-deps.cmake at the resolution branch that knows which
one was picked, and emitted as Requires.private / Libs.private. A second
hardcoded list would go stale exactly the way the first one did. The WIN32
MINIO_CPP_PC_EXTRA_LIBS block is the existing precedent for the same problem.

Requires.private is preferred over a bare -l because these archives live in
the dependency's own prefix (a vcpkg tree), so only the module's own .pc
supplies the -L that finds them. The Libs.private fallback is for deps
installed into miniocpp's own libdir, which -L${libdir} already covers —
libs3rdma (already install(FILES ...)-ed beside libminio) and the
source-built libminiocpp_inih.a.

Brotli is not a dependency declared here: it reaches libminio.a through
cpp-httplib. It is emitted only when the resolved httplib actually enables
CPPHTTPLIB_BROTLI_SUPPORT, so a build against an httplib without it does not
get a Requires.private naming a module that is not installed.

Motivation

Consumers currently have to hand-maintain a parallel link list. warp keeps one
in scripts/rdma-cgo-libs.txt; bumping it to minio-cpp 1.0.0 produced three
separate build failures that a correct .pc would have prevented.

How to test

Built minio-cpp 1.0.0 + RDMA against the real vcpkg tree (x64-linux), installed
it, and linked warp using only pkg-config-derived flags:

$ pkg-config --static --libs miniocpp
-L.../prefix/lib -L.../vcpkg_installed/x64-linux/lib -lminio -ls3rdma \
 -lbrotlienc -lbrotlidec -lbrotlicommon -lm -lINIReader -linih \
 -lssl -lcrypto -ldl -pthread -lpugixml -lz

$ CGO_LDFLAGS="$(pkg-config --static --libs miniocpp) -lstdc++" \
    go build -tags=kqueue,rdma .     # exit 0

$ readelf -d warp | grep NEEDED
 libs3rdma.so.0  libm.so.6  libz.so.1  libstdc++.so.6  libgcc_s.so.1  libc.so.6

That reproduces warp's hand-maintained list exactly except -lstdc++, which
pkg-config cannot know — a cgo consumer still appends the C++ runtime.

Mutation check: deleting the two new fields from the installed .pc and
relinking fails with undefined references (exit 1), so the fields are
load-bearing.

No regression for existing consumers:

  • pkg-config --libs miniocpp (dynamic) output is byte-identical to before.
  • With the dependency .pc files absent, the new .pc fails exactly as the old
    one does, with the same message — from the pre-existing public
    Requires: libcrypto, before Requires.private is reached.

Both arches were checked for the inputs the generation depends on: the amd64 and
arm64 vcpkg trees ship the same .pc set and both httplib configs report
HTTPLIB_IS_USING_BROTLI TRUE.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • Verified end to end on a real vcpkg 1.0.0 build, both static link and readelf
  • Existing dynamic-consumer output unchanged
  • The source-built inih branch (-lminiocpp_inih) is derived from the install
    rules and OUTPUT_NAME, but was not exercised in a build here
  • Note for reviewers: miniocpp-deps.cmake is installed and included by
    miniocpp-config.cmake, so find_package(miniocpp) consumers now define
    the helper macro and run up to four extra pkg_check_modules probes at
    configure time

Summary by CodeRabbit

  • Bug Fixes

    • Improved static linking for pkg-config consumers by including required private dependencies.
    • Added private dependency metadata for RDMA, Brotli, and INI parsing support when applicable.
    • Ensured generated pkg-config files provide complete Requires.private and Libs.private information.
  • Build Improvements

    • Improved compatibility for applications that consume the library through static builds and pkg-config.

miniocpp.pc declared only `Requires: libcrypto libssl pugixml zlib`, so
`pkg-config --static --libs miniocpp` omitted INIReader/inih and brotli,
and libs3rdma on an RDMA build. libminio.a carries undefined INIReader
and Brotli symbols, so a consumer linking from the .pc alone failed with
undefined references, and had to hand-maintain a parallel list instead.

The .pc cannot see target_link_libraries(), so the private dependencies
are now collected in miniocpp-deps.cmake, at the resolution branch that
knows which one was picked, and emitted as Requires.private/Libs.private.
A hardcoded second list would go stale the same way the first one did.

Requires.private is preferred over a bare -l because these archives live
in the dependency's own prefix, so only the module's own .pc supplies the
-L that finds them; the Libs.private fallback is for deps installed into
miniocpp's libdir, which -L${libdir} already covers. Nothing is named
that pkg-config could not resolve at configure time, so `--libs` for
dynamic consumers is byte for byte what it was.

Brotli reaches libminio.a through cpp-httplib rather than being declared
here, so it is emitted only when the resolved httplib actually enables
CPPHTTPLIB_BROTLI_SUPPORT.
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: ec7dc439-350d-45bf-be80-03cc9d90c750

📥 Commits

Reviewing files that changed from the base of the PR and between 78e1db4 and d461161.

📒 Files selected for processing (3)
  • CMakeLists.txt
  • cmake/miniocpp-deps.cmake
  • miniocpp.pc.in

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

CMake now records private dependencies for static consumers, including RDMA, Brotli, and inih. It formats this metadata and emits optional Requires.private and Libs.private entries in the generated miniocpp.pc file.

Changes

Private pkg-config dependencies

Layer / File(s) Summary
Dependency metadata resolution
cmake/miniocpp-deps.cmake
CMake defines private dependency lists, probes pkg-config modules, detects Brotli support, and records Brotli and inih dependencies.
pkg-config generation
CMakeLists.txt, miniocpp.pc.in
CMake records RDMA linkage, formats private dependency lists, and substitutes optional private entries into miniocpp.pc.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: jiuker

Sequence Diagram(s)

sequenceDiagram
  participant CMakeDependencies
  participant PkgConfig
  participant CMakeLists
  participant MiniocppPc
  CMakeDependencies->>PkgConfig: Probe private dependency modules
  PkgConfig-->>CMakeDependencies: Return module availability
  CMakeDependencies->>CMakeLists: Record Requires.private and Libs.private
  CMakeLists->>MiniocppPc: Substitute private dependency entries
  MiniocppPc-->>CMakeLists: Generate configured pkg-config metadata
Loading

Merge Risk: ⚪ Minimal · up to d4611

Static pkg-config output now includes resolved private dependencies needed to link libminio.a, while dynamic output remains unchanged. The change is ready to merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: completing the static link flags generated by miniocpp.pc.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks each flag,
Private links now follow builds,
Brotli joins the path,
RDMA marks its library,
pkg-config records all.

Comment @coderabbitai help to get the list of available commands.

@harshavardhana
harshavardhana merged commit 92d8b2c into minio:main Sep 10, 2026
18 checks passed
@harshavardhana
harshavardhana deleted the fix/pc-static-deps branch September 10, 2026 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant