toolchains: board up broeken window, stub libxml2 to silence ld.lld warning#9809
toolchains: board up broeken window, stub libxml2 to silence ld.lld warning#9809oharboe wants to merge 9 commits intoThe-OpenROAD-Project:masterfrom
Conversation
|
@hzeller 😿 What else can we do? |
There was a problem hiding this comment.
Code Review
This pull request addresses the issue of ld.lld dynamically linking libxml2 by introducing a stub library. This eliminates the need for the libxml2-dev dependency and resolves the "no version information available" warning. The changes involve modifying the MODULE.bazel file to include the stub and adding new files for the stub's source and documentation. I have identified one area for improvement related to the patch command in MODULE.bazel.
| """\ | ||
| cat > _stub.c << 'STUB' | ||
| #include <stdlib.h> | ||
| void *xmlFree = 0; | ||
| void *xmlAddChild(void *p, void *c) { abort(); } | ||
| void *xmlCopyNamespace(void *n) { abort(); } | ||
| void xmlDocDumpFormatMemoryEnc(void *d,void *b,void *s, | ||
| const char *e, int f) { abort(); } | ||
| void *xmlDocGetRootElement(void *d) { abort(); } | ||
| void *xmlDocSetRootElement(void *d, void *r) { abort(); } | ||
| void xmlFreeDoc(void *d) { abort(); } | ||
| void xmlFreeNode(void *n) { abort(); } | ||
| void xmlFreeNs(void *n) { abort(); } | ||
| void *xmlNewDoc(const void *v) { abort(); } | ||
| void *xmlNewNs(void *n, const void *h, const void *p) { abort(); } | ||
| void *xmlNewProp(void *n, const void *a, const void *v) { abort(); } | ||
| void *xmlReadMemory(const char *b, int sz, const char *u, | ||
| const char *e, int o) { abort(); } | ||
| void xmlSetGenericErrorFunc(void *c, void *h) { abort(); } | ||
| void *xmlStrdup(const void *s) { abort(); } | ||
| void xmlUnlinkNode(void *n) { abort(); } | ||
| STUB | ||
|
|
||
| cat > _stub.ver << 'VER' | ||
| LIBXML2_2.4.30 { | ||
| global: xmlAddChild; xmlCopyNamespace; xmlDocDumpFormatMemoryEnc; | ||
| xmlDocGetRootElement; xmlDocSetRootElement; xmlFree; | ||
| xmlFreeDoc; xmlFreeNode; xmlFreeNs; xmlNewDoc; xmlNewNs; | ||
| xmlNewProp; xmlSetGenericErrorFunc; xmlStrdup; xmlUnlinkNode; | ||
| local: *; | ||
| }; | ||
| LIBXML2_2.6.0 { | ||
| global: xmlReadMemory; | ||
| } LIBXML2_2.4.30; | ||
| VER | ||
|
|
||
| cc -shared -o lib/libxml2.so.2 \ | ||
| -Wl,--version-script=_stub.ver \ | ||
| -Wl,-soname,libxml2.so.2 \ | ||
| _stub.c \ | ||
| && rm _stub.c _stub.ver | ||
| """, |
There was a problem hiding this comment.
The patch_cmds script in MODULE.bazel compiles the stub inline. While functional, this approach tightly couples the stub's compilation details to the MODULE.bazel file. For better maintainability and separation of concerns, consider moving the compilation logic to a separate Bazel rule (e.g., a genrule in bazel/libxml2_stub/BUILD.bazel) and referencing the output of that rule in MODULE.bazel. This would make the stub more modular and easier to update or modify in the future.
Also, the patch_cmds attribute is executed during the repository fetching phase. Any errors in these commands can be difficult to debug, as they occur before the main build process. Moving the compilation to a standard Bazel rule would allow for better error reporting and debugging.
Finally, the canonical source is in bazel/libxml2_stub/, but the actual compilation happens in MODULE.bazel. This is inconsistent and could lead to confusion. Centralizing the logic in bazel/libxml2_stub/ would improve clarity.
bazel/libxml2_stub/libxml2_stub.c
Outdated
|
|
||
| #include <stdlib.h> | ||
|
|
||
| void *xmlFree = NULL; |
There was a problem hiding this comment.
warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead [modernize-deprecated-headers]
| void *xmlFree = NULL; | |
| ><cstdlib> |
bazel/libxml2_stub/libxml2_stub.c
Outdated
|
|
||
| #include <stdlib.h> | ||
|
|
||
| void *xmlFree = NULL; |
There was a problem hiding this comment.
warning: variable 'xmlFree' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void *xmlFree = NULL; | |
| static |
| #include <stdlib.h> | ||
|
|
||
| void *xmlFree = NULL; | ||
|
|
There was a problem hiding this comment.
warning: use nullptr [modernize-use-nullptr]
| ;nullptr |
bazel/libxml2_stub/libxml2_stub.c
Outdated
|
|
||
| void *xmlFree = NULL; | ||
|
|
||
| void *xmlAddChild(void *p, void *c) { abort(); } |
There was a problem hiding this comment.
warning: function 'xmlAddChild' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void *xmlAddChild(void *p, void *c) { abort(); } | |
| static |
bazel/libxml2_stub/libxml2_stub.c
Outdated
| void *xmlFree = NULL; | ||
|
|
||
| void *xmlAddChild(void *p, void *c) { abort(); } | ||
| void *xmlCopyNamespace(void *n) { abort(); } |
There was a problem hiding this comment.
warning: function 'xmlCopyNamespace' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void *xmlCopyNamespace(void *n) { abort(); } | |
| }static |
bazel/libxml2_stub/libxml2_stub.c
Outdated
| void xmlFreeNs(void *n) { abort(); } | ||
| void *xmlNewDoc(const void *v) { abort(); } | ||
| void *xmlNewNs(void *n, const void *h, const void *p) { abort(); } | ||
| void *xmlNewProp(void *n, const void *name, const void *v){ abort(); } |
There was a problem hiding this comment.
warning: function 'xmlNewProp' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void *xmlNewProp(void *n, const void *name, const void *v){ abort(); } | |
| }static |
bazel/libxml2_stub/libxml2_stub.c
Outdated
| void *xmlNewDoc(const void *v) { abort(); } | ||
| void *xmlNewNs(void *n, const void *h, const void *p) { abort(); } | ||
| void *xmlNewProp(void *n, const void *name, const void *v){ abort(); } | ||
| void *xmlReadMemory(const char *b, int sz, const char *u, |
There was a problem hiding this comment.
warning: function 'xmlReadMemory' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void *xmlReadMemory(const char *b, int sz, const char *u, | |
| }static |
bazel/libxml2_stub/libxml2_stub.c
Outdated
| void *xmlNewProp(void *n, const void *name, const void *v){ abort(); } | ||
| void *xmlReadMemory(const char *b, int sz, const char *u, | ||
| const char *e, int o) { abort(); } | ||
| void xmlSetGenericErrorFunc(void *c, void *h) { abort(); } |
There was a problem hiding this comment.
warning: function 'xmlSetGenericErrorFunc' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void xmlSetGenericErrorFunc(void *c, void *h) { abort(); } | |
| }static |
bazel/libxml2_stub/libxml2_stub.c
Outdated
| void *xmlReadMemory(const char *b, int sz, const char *u, | ||
| const char *e, int o) { abort(); } | ||
| void xmlSetGenericErrorFunc(void *c, void *h) { abort(); } | ||
| void *xmlStrdup(const void *s) { abort(); } |
There was a problem hiding this comment.
warning: function 'xmlStrdup' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void *xmlStrdup(const void *s) { abort(); } | |
| }static |
bazel/libxml2_stub/libxml2_stub.c
Outdated
| const char *e, int o) { abort(); } | ||
| void xmlSetGenericErrorFunc(void *c, void *h) { abort(); } | ||
| void *xmlStrdup(const void *s) { abort(); } | ||
| void xmlUnlinkNode(void *n) { abort(); } |
There was a problem hiding this comment.
warning: function 'xmlUnlinkNode' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void xmlUnlinkNode(void *n) { abort(); } | |
| }static |
36c072d to
96f485a
Compare
…arning avoids sudo ln hacks on Ubuntu, for instance. ld.lld dynamically links libxml2 but only uses it for Windows manifest merging. Build a versioned stub into @llvm_prebuilt lib/ via patch_cmds so the RUNPATH picks it up instead of the system library, eliminating the "no version information available" warning and the libxml2-dev dependency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
96f485a to
32ec425
Compare
| { | ||
| abort(); | ||
| } | ||
| void* xmlCopyNamespace(void* n) |
There was a problem hiding this comment.
warning: function 'xmlCopyNamespace' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void* xmlCopyNamespace(void* n) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void xmlDocDumpFormatMemoryEnc(void* d, void* b, void* s, const char* e, int f) |
There was a problem hiding this comment.
warning: function 'xmlDocDumpFormatMemoryEnc' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void xmlDocDumpFormatMemoryEnc(void* d, void* b, void* s, const char* e, int f) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void* xmlDocGetRootElement(void* d) |
There was a problem hiding this comment.
warning: function 'xmlDocGetRootElement' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void* xmlDocGetRootElement(void* d) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void* xmlDocSetRootElement(void* d, void* r) |
There was a problem hiding this comment.
warning: function 'xmlDocSetRootElement' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void* xmlDocSetRootElement(void* d, void* r) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void xmlFreeDoc(void* d) |
There was a problem hiding this comment.
warning: function 'xmlFreeDoc' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void xmlFreeDoc(void* d) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void* xmlNewProp(void* n, const void* name, const void* v) |
There was a problem hiding this comment.
warning: function 'xmlNewProp' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void* xmlNewProp(void* n, const void* name, const void* v) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void* xmlReadMemory(const char* b, int sz, const char* u, const char* e, int o) |
There was a problem hiding this comment.
warning: function 'xmlReadMemory' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void* xmlReadMemory(const char* b, int sz, const char* u, const char* e, int o) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void xmlSetGenericErrorFunc(void* c, void* h) |
There was a problem hiding this comment.
warning: function 'xmlSetGenericErrorFunc' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void xmlSetGenericErrorFunc(void* c, void* h) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void* xmlStrdup(const void* s) |
There was a problem hiding this comment.
warning: function 'xmlStrdup' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void* xmlStrdup(const void* s) | |
| }static |
| { | ||
| abort(); | ||
| } | ||
| void xmlUnlinkNode(void* n) |
There was a problem hiding this comment.
warning: function 'xmlUnlinkNode' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
| void xmlUnlinkNode(void* n) | |
| }static |
These functions are exported .so entry points — external linkage is intentional and required for the shared library stub to satisfy ld.lld's dynamic dependency on libxml2.so.2. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
This is a C file — stdlib.h is the correct header, not cstdlib. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
This is a C file — NULL is correct, nullptr is C++ only. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Address review concern about coupling compilation to MODULE.bazel: patch_cmds runs inside the downloaded archive and cannot reference workspace files, so the stub must be compiled inline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
|
Yuck. Where does this warning happen? |
The stub shared library uses Linux-specific linker flags (--version-script, -soname) that do not exist on macOS ld, causing the Mac CI build to fail. Guard the compilation with a uname check so patch_cmds is a no-op on non-Linux. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
Ubuntu 25.10 and who knows where else... this will become better, but for now we don't need Windows xml manifest parsing, so just board up the broken window. It is easier to have Claude board up this broken window than to document it. We never saw it again. 😌 |
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
toolchains_llvm skips auto-download when any toolchain_root is set. Add a separate llvm_prebuilt_macos http_archive for macOS ARM64 and a second toolchain_root entry so macOS CI gets a valid toolchain root. The libxml2 stub is Linux-only, so the macOS archive needs no patching. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
|
I still have no idea what the actual problem is. All this to solve a warning? |
Yes: users have to fix mysterious errors on Ubuntu when building with bazel without this. I think this is a shortcoming in the upstream bazel bcr llvm toolchain that will go away as bazel progresses. I'm thinking we should board up the broken window and forget all about it, surely they know upstream and they have a plan to fix it, it just takes time. As the title says: I'm boarding up a broken window. Important and useful warnings are drowned out by noise warnings and at some point nobody cares about warnings. Bad. @hzeller Thoughts? |
|
I get a ton of these: |
|
I think the amount of changes to work around this temporary glitch is not useful. It creates immediate technical debt with a lot of head-scratching of someone trying to understand what is going on. Not everything that can be hacked around with a massive hack that can be done by Claude ... is something one should be done :) What I found is, that the builds of llvm are different and sometimes link in If that doesn't work, I think for now it is ok to document that it won't work for certain versions of Ubuntu, and just recommend to comment out the |
avoids sudo ln hacks on Ubuntu, for instance.
ld.lld dynamically links libxml2 but only uses it for Windows manifest merging. Build a versioned stub into @llvm_prebuilt lib/ via patch_cmds so the RUNPATH picks it up instead of the system library, eliminating the "no version information available" warning and the libxml2-dev dependency.