-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Further C dependency fixes #9529
Conversation
Only the "old school build" test uses --disable-dependency-generation. This is also tested on both Travis and AppVeyor, so we have good release coverage checking of this option.
The $(wildcard *.h) should only be there with --disable-dependency-generation, since otherwise gcc -MM will be determining exactly which header files should be checked.
It's the macOS default installed version still. The dependency generation inadvertently relies on behaviour introduced in GNU make 3.82 a decade ago. The fix in otherlibs/systhreads/Makefile also corrects missing NATIVE_CPPFLAGS when generating st_stubs.n.d, so st_stubs.n.o now correctly depends on caml/stacks.h instead of caml/stack.h
It's a subtly broken thing to do, as discovered on the ARM workers on Inria's CI.
No longer required, and in fact causing breakages now that -MG isn't used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first two commits ("turn on dependency checking" and "fix an undefined variable") are obviously fine. I had a question on "local headers". I am happy with the "Don't use -MG" explanation and "otherfiles" removal. What remains is the "GNU Make 3.81" one which uses too many functions for me to be able to read, you will need someone else to review it.
Makefile.common
Outdated
@@ -89,7 +89,7 @@ RUNTIME_HEADERS := $(wildcard $(ROOTDIR)/runtime/caml/*.tbl) \ | |||
REQUIRED_HEADERS := $(RUNTIME_HEADERS) $(wildcard *.h) | |||
endif | |||
|
|||
%.$(O): %.c $(RUNTIME_HEADERS) $(wildcard *.h) | |||
%.$(O): %.c $(REQUIRED_HEADERS) $(wildcard *.h) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused, if $(REQUIRED_HEADERS)
is either empty or $(RUNTIME_HEADERS) $(wildcard *.h)
, how can this make a difference given that $(wildcard *.h)
is already a dependency? (Could this be a matter of the wildcard being evaluated at a different time?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that's another artefact of the change... too many variables being renamed and refactored in the review, and the semantics get messed up!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point here is that if COMPUTE_DEPS
is false
then you want to depend on $(RUNTIME_HEADERS)
(which is everything in runtime/caml/
) and any headers in the current build directory. If COMPUTE_DEPS
is not false
, then $(DEP_CC)
will have built the .d
files indicating exactly which .h
files to depend on.
It's a relatively minor optimisation in this Makefile
, because in the directories apart from runtime
which have .c
files, changing a header file in that directory does usually rebuild everything (unixsupport.h
, for example)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't understand what this commit is or was fixing.
The question applies in fact to both the old state (as you initially submitted the PR) and the new state, after your new commit "Tighten dependencies":
- The old change looks like a no-op to me, so was it really fixing an issue? What issue? (Was the change wrong, or am I missing something?)
- With the new change you make in "Tighten dependencies", then we end up with no .h dependencies at all if COMPUTE_DEPS is false. Is that the point of the change to this file, or another beneficial change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old change in this PR accidentally a no-op, yes - while adding the empty case for $(RUNTIME_HEADERS)
I noticed that the wrong variable was being used below it, but didn't fully take in why it was all still OK.
The pattern rules are not normally supposed to mention dependencies (cf. the .cmo
and .cmx
suffix/pattern rules) - you have separate specific rules which list the dependencies. $(REQUIRED_HEADERS)
is to allow development of the compiler even with --disable-dependency-generation
(so $(COMPUTE_DEPS)
is false
). In that case, you won't have the specific dependencies for each .o
file as they're not generated. So the idea is that each .o
file depends on every single .h
file - so any change to any header rebuilds all .o
files (it's the best you can do in the absence of dependency information).
The mistake is that before I'd left one of those cases for $(COMPUTE_DEPS)
= false
in global scope.
(the reason for this is that it means that instead of requiring developers on MSVC to have GCC to work on the compiler, we recommend developers on MSVC have GCC because incremental compilation of the compiler will be faster. It also means that there is not a configuration where incremental compilation of the C sources is actually broken)
cf18bb8
to
689dedf
Compare
For the "Restore compatibility" commit. Starting with What was done before is that you wanted a single rule for generating What is now done in .dep/%.b.d: %.c | .dep
$(DEP_CC) $(OC_CPPFLAGS) $< -MT '$*.b.o' -MF $@
.dep/%.n.d: %.c | .dep
$(DEP_CC) $(OC_CPPFLAGS) $< -MT '$*.n.o' -MF $@ However, as in In |
Enough iterations over this that it's running through precheck again |
I haven't reviewed, but precheck is green and it's a MAJOR INCONVENIENCE that the trunk is broken on macOS, so I'll merge. |
Thanks, @xavierleroy (and sorry for the breakage in the first place) |
(I have notes for a few things to ping Sébastien to look over when he's back, incidentally) |
Note that this is unlikely to change anytime soon: 3.81 is the latest version under GPLv2 and Apple seems to be allergic to GPLv3. |
macOS still installs a 14 year old version of GNU make (3.81). It turns out that the changes in #9332 need a feature added a decade ago in GNU make 3.82. The fix I propose here is to remove the virtual rule in
runtime/Makefile
andotherlibs/systhreads/Makefile
which were supposed to allowmake
to realise that it's OK for sys.b.c not to exist and instead to generate the dependency rules for each case (inruntime/Makefile
this is virtually identical; inotherlibs/systhreads/Makefile
it takes nearly the same number of lines, as it happens).Triggered by #9528, various fixes:
--disable-dependency-generation
was wrong - Travis and AppVeyor both do a test using it, and now Inria's CI does virtually all of its tests with--enable-dependency-generation
. This is also more logical, as it tests more diverse tools than the--disable-dependency-generation
which only tests GNUmake
, and in a very obvious way.RUNTIME_HEADERS
inMakefile.common
which has been added to satisfy the warning.Makefile.common
so in--disable-dependency-generation
mode, C files depended on the runtime headers only - they now depend on runtime headers and the local headers--enable-dependency-generation
revealed the expected failure on macOS from Build fails on macOS after e5c8bee85e7ae2d974069d63528333ffacc1923b #9528, but also failed the ARM32 and ARM64 builds. It turns out those workers have OCaml installed on them, which revealed that using-MG
is completely flawed (cf. Specify C compiler flags correctly in win32unix Makefile #9518) and this is removed here. Doing that also revealed that the old$(otherfiles)
(which was previously used to cause Unix builds to generate the dependency information forwin32.o
and vice versa) was still there, even though that's never needed.An earlier version of this branch has already been through precheck, but this exact branch is presently precheck#371