-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src/Makefile: do not override LIBS and CFLAGS for prerequisites #245
Conversation
02389ba
to
7482eec
Compare
Notice that The only place where
So it seems like your
#...
libefisec.so : $(LIBEFISEC_OBJECTS)
libefisec.so : | libefisec.map
libefisec.so : MAP=libefisec.map
#... By the way, all other So while your patch fixes the occasional build failure, the issue is still there and the I suggest adding diff --git a/src/Makefile b/src/Makefile
index 0e423c4..bce080e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -126,7 +126,7 @@ efisecdb-static : LIBS=dl
thread-test : libefivar.so
thread-test : CFLAGS=$(HOST_CFLAGS) -I$(TOPDIR)/src/include/efivar
-thread-test : LIBS=pthread efivar
+thread-test : private LIBS=pthread efivar
deps : $(ALL_SOURCES)
@$(MAKE) -f $(SRCDIR)/include/deps.mk deps SOURCES="$(ALL_SOURCES)" |
A similar problem can be seen with In this case, the diff --git a/src/Makefile b/src/Makefile
index 0e423c4..1c0021b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -125,8 +125,8 @@ efisecdb-static : | $(GENERATED_SOURCES)
efisecdb-static : LIBS=dl
thread-test : libefivar.so
-thread-test : CFLAGS=$(HOST_CFLAGS) -I$(TOPDIR)/src/include/efivar
-thread-test : LIBS=pthread efivar
+thread-test.o : private CFLAGS=$(HOST_CFLAGS) -I$(TOPDIR)/src/include/efivar
+thread-test : private LIBS=pthread efivar
deps : $(ALL_SOURCES)
@$(MAKE) -f $(SRCDIR)/include/deps.mk deps SOURCES="$(ALL_SOURCES)" |
Oh, that's a lot trickier and way above my understanding of target-specific variables. Thank you! I'll try to read through |
Yeah, I agree that in presence of target-specific variables For example for a: a.o c.o
a: CFLAGS += -DFOO
b: b.o c.o
b: CFLAGS += -DBAR AFAIU there is no way to force I'll update the PR tomorrow. |
7482eec
to
eb9676b
Compare
Without the change `make --shuffle` build occasionally fails as: $ gcc -Og -g3 -Wall -Wextra -Werror -std=gnu11 -funsigned-char -fvisibility=hidden -specs=/build/source/src/include/gcc.specs -fno-merge-constants -L. -Wl,--build-id -Wl,--no-allow-shlib-undefined -Wl,--no-undefined-version -Wl,-z,now -Wl,-z,muldefs -Wl,-z,relro -Wl,--fatal-warnings -DLIBEFIVAR_VERSION=38 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -I/build/source/src/include/ -shared -Wl,-soname,libefisec.so.1 -Wl,--version-script=libefisec.map -o libefisec.so sec.o secdb.o esl-iter.o util.o -lefivar -lefisec -ldl /nix/store/zwqkxpi1iz66mix0kirdaq2ps6a9g9cg-binutils-2.41/bin/ld: cannot find -lefivar: No such file or directory collect2: error: ld returned 1 exit status make[1]: *** [/build/source/src/include/rules.mk:38: libefisec.so] Error 1 shuffle=721268944 Before the change 2-3 rebuild attemts were enough to trigger build failure. After the change `evivar` survived 100 rebuilds. Artem Klimov noticed that it happens because LIBS gets overridden (or not overridden) based on the traversal order `make` takes to build the prerequisites. If the order is: all -> libefivar.so then LIBS is taken from libefivar.so target, which is libefivar.so : LIBS=dl There are no prerequisites and all is fine. But if the build order starts from `efisecdb`, then: efisecdb -> libefisec.so then LIBS is taken from `efisecdb`, this is: efisecdb : $(EFISECDB_OBJECTS) | libefisec.so efisecdb : private LIBS=efivar efisec dl When these `LIBS` are propagated to `libefisec.so` we get a linking failure. Thus the fix is to mark all `LIBS` instances as `private` to make sure `LIBS` never gets leaked into prerequisites' `LIBS` use. And while at it do the same for local `MAP` and local `CFLAGS` for consistency. Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
eb9676b
to
4d65944
Compare
Got slightly better understanding how local variable overrides leak into prerequisites. Updated the PR and PR description on |
Drew a few pictures to explain the problem behind the PR a bit better: https://trofi.github.io/posts/294-an-obscure-make-shuffle-bug.html |
I'm glad to help, thank you for the mention! |
Without the change
make --shuffle
build occasionally fails as:Before the change 2-3 rebuild attemts were enough to trigger build failure.
After the change
evivar
survived 100 rebuilds.Artem Klimov noticed that it happens because LIBS gets overridden
(or not overridden) based on the traversal order
make
takes to buildthe prerequisites.
If the order is:
then LIBS is taken from libefivar.so target, which is
There are no prerequisites and all is fine.
But if the build order starts from
efisecdb
, then:then LIBS is taken from
efisecdb
, this is:When these
LIBS
are propagated tolibefisec.so
we get a linkingfailure.
Thus the fix is to mark all
LIBS
instances asprivate
to make sureLIBS
never gets leaked into prerequisites'LIBS
use. And while at itdo the same for local
MAP
and localCFLAGS
for consistency.