Closed Bug 167254 (RMCH) Opened 18 years ago Closed 5 years ago

Recursive Make Considered Harmful

Categories

(Firefox Build System :: General, enhancement, P3)

enhancement

Tracking

(Not tracked)

RESOLVED INCOMPLETE

People

(Reporter: netscape, Unassigned)

References

()

Details

(Keywords: meta)

Attachments

(2 files)

This is a problem that we've known about for years and people routinely drop a
link to this paper, http://www.tip.net.au/~millerp/rmch/recu-make-cons-harm.html
, which suggests a fix.  The fix, naturally, requires a minor overhaul of the
build system and maybe an adjustment in developer expectations.  What else is new?

For a build, we invoke make approximately 740 time for each build pass.  That
number is just the "core" Mozilla directories so it doesn't include NSPR, LDAP
or NSS.  I think we only have a 100 or so distinct modules so the goal would be
to limit us to a single make invocation per module (per pass).

Bug 163207 contains a preliminary patch to build all of transformiix from the
build & public directories.  I resorted to using cygpath to translate $< into a
proper dos-path rather than sticking with the srcfiles-must-be-in-$srcdr
limitation set in bug 141834.  The extra $(shell) invocations will slow us down
but the gain of not invoking multiple make processes should more than offset that.

One of the major decisions that will need to be made is where to stick the
object & dependency files for builds that use source files from multiple
directories.  The easiest thing would be to just place the depend files into the
build directory and the object files in their respective directory hierarchy. 
But that could be fairly confusing.

The previous decision will also be affected by what we decide to do with the
Makefiles that are no longer necessary.  Do we remove them, thereby saving time
& space, or we leave them so that developers can still built sub-sections of
their module without needing to rebuild the entire module?  Is the convenience
worth the effort of maintain multiple methods to compile a source file?
Depends on: 163207
Keywords: meta
Priority: -- → P2
Target Milestone: --- → mozilla1.3alpha
Given both strong, correct dependencies and a build system that can compute the
required set of rebuild operations quickly, I don't think many people will have
objections to just doing a module-top rebuild every time.

I know I wouldn't.
The win32 dependency generation change in attachment 98265 [details] [diff] [review] causes a 8% slowdown
in the overall build time.  The change to remove extraneous makes from xslt in
attachment 98266 [details] [diff] [review] causes a 16% speed up under both win32 & linux when just
building xslt.  Without the win32 dep changes though, the dependencies are
genearated incorrectly.  On win32, the dependency change + the xslt change
causes a 20% slowdown when building xslt.

I improved the win32 dep changes so that they only invoke $(shell cygpath) once
(attachment 98549 [details] [diff] [review]) and that brought the win32 dep + xslt build time to only 10%
slowdown. 

As always, these measurments should be taken with a grain of salt.  They are
made on a P3-650 laptop w/ 128mb ram running win2k & a P3-600 w/384mb ram
running RH7.2.  I would expect a signficantly different results from tests done
with more modern hardware.
Alias: RMCH
I attempted to convert dbm to use a single Makefile and I ran into some problems
that I briefly mentioned on IRC a couple of days ago.

1) Our primary targets (SHARED_LIBRARY & PROGRAM) assume that their sources come
from CPPSRCS, CSRCS & OBJS.  This can be worked around by introducing
LIB_CPPSRCS,  LIB_OBJS, etc to rules.mk.

2) Some of our modules build multiple test programs.  As long as these programs
are built from a single source file, we can use SIMPLE_PROGRAMS.  Otherwise, we
have to use PROGRAM to build them and we can only support one PROGRAM per
Makefile.  

3) For most of our libraries that we directly link against, we use internal
defines to indicate that we are building the libraries.  When building a program
that uses the library, we do not use those defines.  So, if we're going to build
 both the library & a program that uses that library from a single Makefile, we
need to use a separate definition list for each target.  Right now, we have no
way of adding defines to individual objects (short of adding a rule per object).

4) We have a similar problem with LIBS.  Any PROGRAM or SIMPLE_PROGRAMS would be
linked against all libraries listed in LIBS.  This may be a non-issue. 

5) EXTRA_LIBS have the same problem as above and they are also used when linking
the SHARED_LIBRARY.


So while looking at potential solutions for the above problems, I noted that
solutions look suspiciously familiar.  They started looking like the automake
syntax.  So here's my latest lament: I still don't think that automake is a
viable solution for mozilla* but I don't really want to reinvent the wheel.

* Reasons why not to use automake:
1) Additional build requirements and a signficantly more complex build
infrastructure for developers who don't regularly muck with Makefiles.
2) Perceived lack of stability.  Afaict, there have been at least 3 major
releases in the past 4 years which have also required upgrading other autotools
packages (autoconf, libtool, etc).  Because not all packages that use autotools
can be upgraded in lock-step (NSPR wants to stay with autoconf-2.1x), this
causes a major problem.
3) Perceived lack of backwards compatiblity.  The more recent releases have
required autoconf 2.5x which we do not support (see bug 104642).  It also
appears that with the changes made to some releases, you'll get a different
incompatible result from some macros than you did with previous releases.

(Note the use of perceived as I haven't actually experienced these problems. 
I've just read others complaints on mailing lists.)
I created the RMCH_20021105_BRANCH branch so that I can start getting some of
these changes out of my local tree.
Target Milestone: mozilla1.3alpha → mozilla1.4beta
I still need to pull some of those changes in from the branch but this is going
to take awhile.
Priority: P2 → P3
Target Milestone: mozilla1.4beta → Future
Product: Browser → Seamonkey
Assignee: netscape → nobody
Product: Mozilla Application Suite → Core
QA Contact: granrosebugs → build-config
Priority: P3 → --
Target Milestone: Future → ---
This works well for reducing the total number of spawned processes per build loop. The problem is that it requires make 3.80 for the $(eval) function. This would be fine with me except that MSYS doesn't ship a msys-make3.80 (only a mingw-make, which isn't the same thing at all).
Assignee: nobody → benjamin
Status: NEW → ASSIGNED
It would theoretically be possible to fix the "build multiple libraries or programs from the same makefile" using $(eval) and constructs like PROGRAM_foo_CPPSRCRS, but that sounds like overkill at least for this pass. If we can get rid of most of the intermediate static libraries that is more than enough for me.
Severity: major → minor
Priority: -- → P2
Target Milestone: --- → mozilla1.9alpha
I'm going to do some performance benchmarking with this patch, but I believe that if it performs as I think it will and we can solve the make 3.80 issue, this would be a great improvement.
Severity: minor → enhancement
Priority: P2 → P3
Target Milestone: mozilla1.9alpha1 → ---
Assignee: benjamin → nobody
Status: ASSIGNED → NEW
See Bug 623617 where we plan to implement something like comment 8.
The build team is working on a total overhaul of the build system that will encompass this. This bug doesn't need to be open any more.
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → INCOMPLETE
Product: Core → Firefox Build System
You need to log in before you can comment on or make changes to this bug.