Laird: I think that your question is of general interest,
so I am replying to the mailing list.

(Woops - I was interrupted, and hit send instead of
save - the first message was incomplete.)

> [Laird Nelson]
> If you check something in, isn't it because you just made a change?  And
> if you just made a change, then isn't the file modified?  And if the
> file is modified, then isn't a remake always necessary?  How will
> stripping keywords solve this problem?

Here's how I work:

(1) checkout the file
(2) make change
(3) compile and test the file

Once tests pass
(4) check in the file

The problem is that step (4) modifies the RCS/CVS keywords,
even if nothing else in the file is modified. Leading to

(5) Unnecessary remake of the file 
    (and all files that depend on it)

when I repeat the process.

I.e. showing two interleaved edit steps

(1) checkout FileA
(2) edit FileA
(3) compile and test FileA
(4) check in FileA
*1'* check out FileB
*2'* edit FileB
*3'* compile and test FileB
accompanied by
(5) unnecessary remake of FileA
    and its dependents
    if the check in updated RCS keywords
    in comments
*4'* check in FileB

If you are editting independent .c files, twice as 
many compiles are done as is necessary.

If you are editting the same file, no extra compile.

If you are editting independent .h files, not quite
twice the extra compiles are done, because there 
is usually some overlap. But, since large pieces of the
project may depend on a .h file, much more unnecesary
recompilation may be done.

If you eliminate the CVS/RCS keyword updates
using -kk or the like, the unnecessary recompile
is eliminated. CVS seems to be smart enough not
to update a file after a check in if there are no changes.



===

This is made worse by my habit of typing "make" at random
times, just in case, because I often flit between multiple workspaces,
relying on make to avoid necessary recompilations.

Then it looks like

1) checkout FileA
(2) edit FileA
(3) make: necessary recompilations
    dependent on FileA
(4) check in FileA
(5) make: unnecessary recompilations
    dependent on FileA
*1'* check out FileB
*2'* edit FileB
*3'* make: necessary recompilations 
    dependent on FileB
*4'* check in FileB
*5'* make: unecessary recompilations 
    dependent on FileB

This gives strictly 2X the number of compilations
that are necessary. If you are editting a header file,
and compilation takes 45 minutes, you can waste a
lot of time this way.

===

Another aspect is unnecessary recompilations 
when switching branches.  For example, here is my rhythm
when I am using a task branch:

        cvs update -r main-branch
        ? make
        cvs tag -b task-branch
        cvs update -r task-branch
        ? make => no unnecessary recompiles
        ++edit
        ++ compile
        ++ test
        ? make => no unnecessary recompiles
        cvs ci
        cvs update -r main-branch
        cvs update -r main-branch
        cvs update -j task-branch
        ++ if merge succeeded ci
        ? make => unnecessary recompiles

Again, 2X the compiles.

Worse if I forget myself and type "make"
after         cvs update -r main-branch
before      cvs update -j task-branch


Now, these unnecessary compiles after merging in a branch
are not strictly due to keyword changes. But they are nonetheless
annoying.

===


Restricting discussion to updating CVS keywords,
of course CVS in general cannot not update the file.

For example, if you have the keyword in a string,

        char* rcsid = "$Id: $";

the object file must get recompiled, to contain the
new string.

Even if the keyword is in a comment, it is conceivable
that a tool may grep them out and squirrel them away in
some central database. I have written such tools.

Nevertheless, the common case of having a keyword
in a comment, that does not affect any generated files,
does not require any recompilations.

===

Backdating the source file, or forward dating the object,
is not the sort of thing I would normally do.  I could quite 
happily live with the unnecessary recompilations in C 
programs. However, my C++ compiler, G++ 2.95.2, 
is so slow that for the first time in more than a decade 
I am working to improve compile time - using Lakos 
suggestions to reduce dependencies, eliminating RCS 
keywords, etc.

I have looked at Bell Labs' CIAO and ACACIA, which
locate unnecessary include file dependencies. They
report compile time improvements of 40% or so.

I have even looked at MakeHeaders, which creates
a custom, miniaml, header file for every .c++ source
file. Rejected because it doesn't handle the full C++
language.

===

At a more fundamental level - the level at which I wish I had
the time to write the right tools - one aspect of the problem is
file based dependencies in Make.  There reportedly do exist
tools that track dependencies at statement granularity
- e.g. edit a header file, and only files that depend on the
changed lines get recompiled, not any file that includes it.

===

Another fundamental aspect is that RCS/CVS embedded version
numbers are nearly always broken.

They may be accurate at initial checkout - i. you may have
checked out $Version: 5.4$

But the moment you start editting, the version number should change,
to $Version: 5.4 + not-yet-checked-in-edits$

I learned this the hard way, when I already knew it: somebody "borrowed"
one of my source files, reported a bug, and I searched for the bug
in versions preceding the version number embedded in the file.

Reply via email to