[BUILD] Install an explicit list of ext headers instead of the whole tree - #4327
Conversation
…tree ext_common installed include/opentelemetry/ext with a *.h glob, so every header under that tree shipped whether or not it was meant to. Naming the headers makes the installed surface deliberate: one reaches the package only when it is listed, which is a signal when a public header is renamed or removed. Three headers the glob installed are dropped. client/detail/default_factory.h is an internal helper included by exporter sources rather than by any public header. client/curl/http_client_curl.h and client/curl/http_operation_curl.h are the curl implementation, and the first includes the second. A consumer creates a curl client through http_client_factory_curl.h, which includes only the abstract http_client_factory.h, so neither is needed to use the package. http_server.h and socket_tools.h stay. examples/http/server.h includes the first, and examples_test builds examples/http against the install prefix whenever ext_http_curl is installed, so removing it breaks examples-build-test.
5da5792 to
cb6c264
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4327 +/- ##
==========================================
+ Coverage 80.85% 80.86% +0.02%
==========================================
Files 450 450
Lines 19215 19215
==========================================
+ Hits 15535 15537 +2
+ Misses 3680 3678 -2 🚀 New features to boost your workflow:
|
dbarker
left a comment
There was a problem hiding this comment.
Thanks for the PR and clear description! Please see feedback and requested changes below.
…all-manifest-1980 # Conflicts: # CHANGELOG.md
Review feedback on open-telemetry#4327. http_server.h and socket_tools.h are an embedded HTTP server for tests and the http example, so drop them from the ext_common manifest rather than keeping the glob's behaviour for them. The http example includes them, so it cannot build against the install prefix once they stop shipping. Disable it in the install test. That also makes the ws2_32 link on the opentelemetry_ext interface wrong: the target no longer carries a header that calls Winsock, so a package consumer inherits a link it has no use for. Move it to the seven targets that compile the server, which is the full transitive closure of the two headers over the include graph. MSVC autolinks through the pragma in socket_tools.h, so this only shows up on MinGW and GCC for Windows. Bazel's //ext:headers still globs the whole include tree and so still exposes the server, and its linkopt stays for that reason. The file move itself is tracked in open-telemetry#4332.
Review feedback on open-telemetry#4327. http_server.h and socket_tools.h are an embedded HTTP server for tests and the http example, so drop them from the ext_common manifest rather than keeping the glob's behaviour for them. The http example includes them, so it cannot build against the install prefix once they stop shipping. Disable it in the install test. That also makes the ws2_32 link on the opentelemetry_ext interface wrong: the target no longer carries a header that calls Winsock, so a package consumer inherits a link it has no use for. Move it to the seven targets that compile the server, which is the full transitive closure of the two headers over the include graph. MSVC autolinks through the pragma in socket_tools.h, so this only shows up on MinGW and GCC for Windows. Bazel's //ext:headers still globs the whole include tree and so still exposes the server, and its linkopt stays for that reason. The file move itself is tracked in open-telemetry#4332.
0b9e1ce to
25283a9
Compare
Review feedback on open-telemetry#4327. http_server.h and socket_tools.h are an embedded HTTP server for tests and the http example, so drop them from the ext_common manifest rather than keeping the glob's behaviour for them. The http example includes them, so it cannot build against the install prefix once they stop shipping. Disable it in the install test. That also makes the ws2_32 link on the opentelemetry_ext interface wrong: the target no longer carries a header that calls Winsock, so a package consumer inherits a link it has no use for. Move it to the seven targets that compile the server, which is the full transitive closure of the two headers over the include graph. MSVC autolinks through the pragma in socket_tools.h, so this only shows up on MinGW and GCC for Windows. Bazel's //ext:headers still globs the whole include tree and so still exposes the server, and its linkopt stays for that reason. The file move itself is tracked in open-telemetry#4332.
25283a9 to
b54f80f
Compare
|
All six done, thanks for the clear list.
One thing I deliberately did not change, in case it reads as an oversight: Bazel's Worth knowing about the Verified by installing Last thing: #4283 and #4294 both touch |
dbarker
left a comment
There was a problem hiding this comment.
Thanks for the changes. Looks good to me. Minor request below to the changelog entry.
Per review: the entry described the removals in prose and named only two of the five headers. It now sits under Breaking changes with every path listed, and says what a consumer that included one of them should do instead.
Every other case here compiles against headers that are present, so putting the glob back over include/opentelemetry/ext would leave all of them passing while the package quietly grew five headers again. The check runs against the include directory the installed api target points at, not the test project's own prefix.
1677154 to
ed6f6d7
Compare
get_target_property returns <VAR>-NOTFOUND when the property is unset, and list(GET) returns that string without complaint, so every EXISTS below would answer false and the check would pass having examined nothing. It now insists on a real directory first. Also drop the WITH_HTTP_CLIENT_CURL block from examples_test: the only thing under examples/ that reads it is examples/http, which this PR no longer builds there.
install(DIRECTORY) creates a destination directory for every source directory it walks and applies FILES_MATCHING to the files it finds there, so listing only file names left include/opentelemetry/ext/http/ server and .../client/detail installed with nothing in them. Excluding the two directories drops them from the walk, and the install test now asserts they are absent rather than relying on the file check alone.
|
Your approval is recorded against
Installed into a clean prefix both ways: Both guards were checked in the failing direction too. With the glob restored the install test stops at The last commit is the one furthest from what you reviewed. Say the word and I will drop it and open it separately, or squash it in, whichever you prefer. Issue for the file move is #4332. |
…all-manifest-1980
dbarker
left a comment
There was a problem hiding this comment.
Please see the requested change below to revert the latest install test change.
A list of files that should not exist has no natural end, and every entry is one more thing to keep in step with the install rules. The removal these five headers needed is already shown by the install test compiling against the package without them, and by this PR's CI run. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
The local include-what-you-use and clang-tidy runs built the exporter library, which does not compile the test file, so three findings reached CI instead. The test drops an include the log handler header already provides, takes a reference where it was copying a shared_ptr, and the scope guard declares the four special members that a user-declared destructor calls for. The guard holds a pointer to the completion now rather than a shared_ptr, so the .cc no longer names one and the include goes with it. The two async include guards were the same condition twice and are one block. Checked by building the test target against all three cmake option presets the workflows use, and against main for a baseline: include-what-you-use reports the same two blocks and no include changes on either, and clang-tidy reports the same eighteen warnings on either, with nothing on the branch that is not also on main. Comments in the completion cases now say what the code does rather than what it used to do, which is the review note on open-telemetry#4327 applied here as well. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
Two comments described a check this branch removes, which is the kind of rationale @dbarker asked to keep in the pull request and the git history rather than in the code, on open-telemetry#4327. They now describe the bodies themselves: two successes that differ only in whitespace, and a rejected item whose shard counter still reads as a success to anything reading the body as text. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
Step 2 of the plan in #4315, and a contribution to #1980.
ext_commoninstalledinclude/opentelemetry/extwith a*.hglob, so every header under that tree shipped whether or not it was meant to. This replaces the glob with a list of the headers the component installs. A header now reaches the package only when it is named, which is the signal you asked for when one is renamed or removed, and it makes each later decision about the installed surface a one line diff.No longer installed
client/detail/default_factory.h, an internal helper included by exporter sources rather than by any public header.client/curl/http_client_curl.handclient/curl/http_operation_curl.h, the curl implementation. These two go together, since the first includes the second. A consumer creates a curl client throughhttp_client_factory_curl.h, which includes only the abstracthttp_client_factory.h.server/http_server.handserver/socket_tools.h, the embedded HTTP server.The
serverandclient/detaildirectories go with them.install(DIRECTORY)creates a destination directory for every source directory it walks and applies
FILES_MATCHINGto the files it finds there, so naming files alone stillinstalled both, empty. Excluding the two directories drops them from the walk:
All five headers are a breaking change for anyone who included them from an installed package, which is why the CHANGELOG names them. The embedded server in particular has shipped for a long time, so out of tree users of it lose it here rather than when it moves.
The embedded server, and what it took to drop it
examples/http/server.hincludeshttp_server.h, andexamples_testturnedWITH_EXAMPLES_HTTPon wheneverext_http_curlwas installed, soexamples/httpwas built against the install prefix. The example is now disabled there unconditionally, per review.That variable gates exactly one thing,
add_subdirectory(http)inexamples/CMakeLists.txt, so the coverage this gives up is the http example building against the install prefix, and nothing else. The ext headers that example uses are still exercised byinstall/test/src/test_ext_http.ccandtest_ext_http_curl.cc.Dropping the headers also made the
ws2_32link on theopentelemetry_extinterface wrong: the target no longer carries a header that calls Winsock, so a package consumer would inherit a link it has no use for. It now goes on the seven targets that compile the server, which is the full transitive closure of the two headers over the include graph onmain:curl_http_test,socket_tools_test,w3c_tracecontext_http_test_server,otlp_http_exporter_test,otlp_http_log_record_exporter_test,zipkin_exporter_test, and thehttp_serverexample. Thehttp_clientexample is not among them; it uses the curl client only.Two notes on that link.
socket_tools.hcarries#pragma comment(lib, "ws2_32.lib")under_WIN32, which MSVC and clang-cl honor and MinGW's GCC does not, so every Windows job in CI resolves Winsock through the pragma and none of them can tell the difference either way. And Bazel's//ext:headersstill globs the whole include tree, so it still exposes the server and its-DEFAULTLIB:Ws2_32.liblinkopt is still load bearing. It stays.The file move itself is #4332.
Guarding it
Every other case in the install tests compiles against headers that are present, so putting the glob back over
include/opentelemetry/extwould leave all of them passing while the package quietly grew five headers again.install/test/cmake/CMakeLists.txtnow fails when any of the five is found under the include directory the installedopentelemetry-cpp::apitarget points at, and separately when either pruned directory is present.Checked both ways, for both guards. With the manifest it reports
Checking <prefix>/include for headers that must not shipand configures. With the glob restored it stops atand with the manifest kept but the two directory excludes removed, at
Verification
Installed from
mainand from this branch into separate clean prefixes and compared the whole trees, not just the headers:The five are the intended removals, nothing is added, and the thirteen that differ are all static archives, which are not byte reproducible across builds. Every installed header and every CMake config file is identical.
The install tests then pass against that prefix,
100% tests passed, 0 tests failed out of 37, overapi,sdk,ext_common,ext_http,ext_http_curl, the ostream and in memory exporters and zipkin.As a control, flipping
WITH_EXAMPLES_HTTPback on against the same prefix fails, which is the reason the line is there:That run is a Linux subset of what CI covers, nine components rather than twenty one, and it cannot exercise the
ws2_32change at all, since the pragma covers every Windows configuration CI builds. The exhaustive enumeration above is what that part rests on.Not in scope
Manifests for the other components, the
FILE_SETandVERIFY_INTERFACE_HEADER_SETSwork that needs CMake 3.24, and moving the embedded server out ofext, which is #4332.