On Friday, 5 February 2016 at 06:05:49 UTC, Chris Wright wrote:
It doesn't know what targets I'm ultimately creating, and it
doesn't know what files have been modified that I'm about to
compile (but haven't compiled yet).
Example 1:
I compile one .c file referencing a function:
void foo(int);
That's going to end up in libfoo.so.
I compile another .c file in the same directory defining a
function:
void foo(float);
That's going to end up in libbar.so.
No bug here. (The linker should tell us if someone depends on
foo from libbar and foo from libfoo in the same executable.)
How does your putative compiler plugin handle it? Either I have
to define a build rule for every source file to specify where
to put this symbol cache (and you need to add parameters for
the plugin to look for multiple caches, because libfoo and
libbar share a lot of source files), or the plugin gives me
false positives.
Example 2:
I compile a.c:
int foo(int i) { return i + 1; }
In the course of refactoring, I delete that function from a.c
and add it
to b.c with modifications:
int foo(int i, int increment) { return i + increment; }
My build script recompiles b.c before it recompiles a.c. Your
compiler plugin produces a build error, halting my build. I
have to make clean && make in order to proceed -- and that's
assuming I know your tool doesn't work well with incremental
compilation.
The first problem might be uncommon, but the second would crop
up constantly. They have the same fix: collect the information
when you compile, evaluate it when you link.
No spurious error is generated by my proposal in your example 2,
because I specifically stated that the extra pass must be done
once, after *all* modules have been compiled.
I see, however, that this would require one of:
1) Modifying build scripts to pass the complete list of .c files
to the compiler in a single command, or
2) Modifying build scripts to run the compiler one extra time
after processing all the .c files, or
3) Run the final check at link-time.
For a C tool chain with a clean-sheet design, any of those would
handle example 2 fine. (1) or (3) could also handle example 1
without issue.
However, as you say, only (3) is backwards compatible with
existing make files and what-not. (This is not a limitation of
the C language or ABI, though.)