You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I started this quest as @rules_foreign_cc//toolchains/private:make_tool segfaults when wildcard is used. It turned out that make was not linking against the glob() function from the source tree, but a version from some system libraries. The version from the system library is not compatible with gnulib's glob() and caused segfault.
TLDR
We need to strip -lXX flags from LDFLAGS to make autoconfig and linker sane on Darwin.
Root cause
Standard cpp toolchain includes defaults libs -lc++ (or -lstdc++) and -lm for linking flags. Which also uses -as-needed around those flags. However, Darwin's ld doesn't support the --as-needed feature, which means, all these libraries are loaded even if it's not required.
And here comes the interesting part. Those libs are presented as LDFLAGS to foreign cc build actions, and LDFLAGS almost always come before the actual object files from the target project. Take GNUMake's makefile as an example:
LINK = $(CCLD)$(AM_CFLAGS)$(CFLAGS)$(AM_LDFLAGS)$(LDFLAGS) -o $@make$(EXEEXT): $(make_OBJECTS)$(make_DEPENDENCIES)$(EXTRA_make_DEPENDENCIES)
@rm -f make$(EXEEXT)$(AM_V_CCLD)$(LINK)$(make_OBJECTS)$(make_LDADD)$(LIBS)
This means, ld will try to link against the libs defined by the cpp toolchain and then with the object files from the project. On contrast, the cc_binary will put those flags after the object files:
Those standard libraries won't be a big deal in a perfect world. However, Darwin is weird, especially the math lib (try open /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libm.tbd) re-exports a lot of symbols from other libs, including libsystem_c.dylib, which is not fully POSIX-compliant. Linking against it broke auto-config and caused segfault.
As a result, foreign_cc cannot build many projects on Darwin, while homebrew can.
The text was updated successfully, but these errors were encountered:
…ke (#37632)
When upstream `rules_foreign_cc` builds its own GNUMake, it injects
bazel's default libraries into `LDFLAGS`, which causes trouble on Darwin
in newer versions of Bazel that added `-lm` to the list of default
libraries.
As explained nicely in
bazel-contrib/rules_foreign_cc#1227, Apple's
libm re-exports a bunch of symbols and, due to linker argument order,
clobbers some symbols from make itself. We don't need any of the default
libraries in GNUMake, so disable the feature to link them.
Risk Level: low
Testing: CI
---------
Signed-off-by: Alejandro R Sedeño <[email protected]>
Signed-off-by: Alejandro R. Sedeño <[email protected]>
The patch in the Envoy commit that referenced this issue fixes GNUMake on Darwin (and everywhere else) to not link in the default bazel libraries. If applied upstream (read: here) it should fix the example described here, but that doesn't mean the same problem won't crop up building other things. At least fixing the segfault in the GNUMake that rules_foreign_cc builds for itself should help concentrate user efforts on debugging their builds and not their tools.
I started this quest as
@rules_foreign_cc//toolchains/private:make_tool
segfaults whenwildcard
is used. It turned out thatmake
was not linking against theglob()
function from the source tree, but a version from some system libraries. The version from the system library is not compatible with gnulib'sglob()
and caused segfault.TLDR
We need to strip
-lXX
flags fromLDFLAGS
to make autoconfig and linker sane on Darwin.Root cause
Standard cpp toolchain includes defaults libs
-lc++
(or-lstdc++
) and-lm
for linking flags. Which also uses-as-needed
around those flags. However, Darwin'sld
doesn't support the--as-needed
feature, which means, all these libraries are loaded even if it's not required.And here comes the interesting part. Those libs are presented as
LDFLAGS
to foreign cc build actions, andLDFLAGS
almost always come before the actual object files from the target project. Take GNUMake's makefile as an example:As well as the gettext's auto-configure script:
This means,
ld
will try to link against the libs defined by the cpp toolchain and then with the object files from the project. On contrast, thecc_binary
will put those flags after the object files:Those standard libraries won't be a big deal in a perfect world. However, Darwin is weird, especially the math lib (try
open /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libm.tbd
) re-exports a lot of symbols from other libs, includinglibsystem_c.dylib
, which is not fully POSIX-compliant. Linking against it broke auto-config and caused segfault.As a result,
foreign_cc
cannot build many projects on Darwin, whilehomebrew
can.The text was updated successfully, but these errors were encountered: