1 In C, there are two kinds of include directives:
2 “#include <system.h>” and “#include "local.h"”.
3 The first searches in some system directories,
4 for example “/include/” and “/usr/include/”;
5 the second searches in the same directory of the file being compiled.
7 The build script used to decide whether to compile or not
8 by comparing the modification times
9 of the executable file and the C source file.
10 This approach does not work
11 if the file to be compiled includes local headers,
12 because, even if the “.c” file has not changed,
13 changing an included header should trigger recompilation.
15 I have improved build.sh
16 to search each “.c” file for include directives of local headers
17 and compiling that file
18 if and only if either it or one of those headers has changed.
19 There can be false positive, because the found include directive
20 can be commented out or in a string literal.
21 This is not a problem,
22 because it can only lead to an unnecessary recompilation,
23 never to a missed necessary recompilation.
25 To find the local headers, I use a sed script:
26 's_[ \t]*#include[ \t]*"\(.*\)".*_src/\1_p'.
27 “s” is for substitute and it is usually used like this: “s/old/new/”.
28 The slash is often used as a separator,
29 but I chose the underscore to avoid escaping the slash.
30 In the “old” part, I capture the string inside the quotes
31 by putting it between “\(” and “\)”;
32 in the “new” part, there is a backreference to it, “\1”.
33 To iterate on the output without breaking at spaces,
34 I set IFS to a newline,
35 which cannot appear in an include directive anyway.
40 https://stackoverflow.com/questions/1732348#1732454