История изменений
Исправление dimgel, (текущая версия) :
- В сабже происходит примерно вот что:
-
Правило «a:» без пререквизитов и без файла на диске таки-считается как .PHONY, и соответственно выполняется и оно само, и его зависимости.
-
И на это поведение дохрена всего завязано, что суммируется в Advanced Auto-Dependency Generation. Основная идея там такая: нам не нужен актуальный .d-файл, нам достаточно такого, чтобы триггернул перекомпиляцию.
-
В частности: если у нас есть
main.cpp
, который инклудитincl.h
, то генерируемый gcc-ёй .d-файл будет таким:
main.o: main.cpp incl.h
main.cpp:
incl.h:
Если какой-то из исходных файлов main.cpp
, incl.h
пропал, то их пустые правила триггернутся как .PHONY, что приведёт к перекомпиляции main.o
- Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный mtime до и после её компиляции. Хвастаюсь без сорцов (и даже без скринов; эх, а какие у меня цвета префиксов красивые подобраны!):
[demo]$ ls
cake cakefile.cpp cake-hashcache README.md src target
[demo]$ ./cake clean
[demo]$ ls target/
cakefile
[demo]$ ./cake-hashcache ls
EE Cache file not found.
[demo]$ time ./cake -v
>> target/cakefile -v
CC target/build/greeter/greeter.o
CC target/build/main.o
{} mkdir -p target/build
{} mkdir -p target/build/greeter
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/main.o src/main.cpp
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/greeter/greeter.o src/greeter/greeter.cpp
LL target/hello
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -o target/hello target/build/main.o target/build/greeter/greeter.o
real 0m0.131s
user 0m0.143s
sys 0m0.016s
[demo]$ target/hello world
Hello world!
[demo]$ ./cake-hashcache ls
2 entries
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ time ./cake -v
>> target/cakefile -v
real 0m0.004s
user 0m0.000s
sys 0m0.005s
[demo]$ ./cake-hashcache ls
7 entries
ffda614df6ecf3c19cee22d5b2f55989 2022-10-15 08:53:16.048930696 105 src/greeter/greeter.cpp
68318d810aae5485626518b3a8c5081d 2022-10-15 08:52:19.588150385 44 src/greeter/greeter.h
7870fb12a712dbf5751730b8b8da7ffe 2022-10-19 20:52:00.434276397 197 src/main.cpp
68cd1646da7a1f27c2df8fa5c3d53b4f 2022-10-19 20:56:33.808249551 104 target/build/greeter/greeter.d
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
bda20173f0bc8fb367cc92c16c602736 2022-10-19 20:56:33.808249551 79 target/build/main.d
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: mtime & size not changed: `src/main.cpp`
[demo]$ touch src/main.cpp
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: returning cached mtime: `src/main.cpp`
[demo]$ ./cake-hashcache rm src/main.cpp
[demo]$ ./cake
CC target/build/main.o
LL target/hello
Исправление dimgel, :
- В сабже происходит примерно вот что:
-
Правило «a:» без пререквизитов и без файла на диске таки-считается как .PHONY, и соответственно выполняется и оно само, и его зависимости.
-
И на это поведение дохрена всего завязано, что суммируется в Advanced Auto-Dependency Generation. Основная идея там такая: нам не нужен актуальный .d-файл, нам достаточно такого, чтобы триггернул перекомпиляцию.
-
В частности: если у нас есть
main.cpp
, который инклудитincl.h
, то генерируемый gcc-ёй .d-файл будет таким:
main.o: main.cpp incl.h
main.cpp:
incl.h:
Если какой-то из исходных файлов main.cpp
, incl.h
пропал, то их пустые правила триггернутся как .PHONY, что приведёт к перекомпиляции main.o
- Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный mtime до и после её компиляции. Хвастаюсь без сорцов (и даже без скринов; эх, а какие у меня цвета префиксов красивые подобраны!):
[demo]$ ls
cake cakefile.cpp cake-hashcache README.md src target
[demo]$ ./cake clean
[demo]$ ls target/
cakefile
[demo]$ ./cake-hashcache ls
EE Cache file not found.
[demo]$ time ./cake -v
>> target/cakefile -v
CC target/build/greeter/greeter.o
CC target/build/main.o
{} mkdir -p target/build
{} mkdir -p target/build/greeter
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/main.o src/main.cpp
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/greeter/greeter.o src/greeter/greeter.cpp
LL target/hello
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -o target/hello target/build/main.o target/build/greeter/greeter.o
real 0m0.131s
user 0m0.143s
sys 0m0.016s
[demo]$ target/hello world
Hello world!
[demo]$ ./cake-hashcache ls
2 entries
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ time ./cake -v
>> target/cakefile -v
real 0m0.004s
user 0m0.000s
sys 0m0.005s
[demo]$ ./cake-hashcache ls
7 entries
ffda614df6ecf3c19cee22d5b2f55989 2022-10-15 08:53:16.048930696 105 src/greeter/greeter.cpp
68318d810aae5485626518b3a8c5081d 2022-10-15 08:52:19.588150385 44 src/greeter/greeter.h
7870fb12a712dbf5751730b8b8da7ffe 2022-10-19 20:52:00.434276397 197 src/main.cpp
68cd1646da7a1f27c2df8fa5c3d53b4f 2022-10-19 20:56:33.808249551 104 target/build/greeter/greeter.d
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
bda20173f0bc8fb367cc92c16c602736 2022-10-19 20:56:33.808249551 79 target/build/main.d
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: mtime & size not changed: `src/main.cpp`
[demo]$ touch src/main.cpp
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: returning cached mtime: `src/main.cpp`
Исправление dimgel, :
- В сабже происходит примерно вот что:
-
Правило «a:» без пререквизитов и без файла на диске таки-считается как .PHONY, и соответственно выполняется и оно само, и его зависимости.
-
И на это поведение дохрена всего завязано, что суммируется в Advanced Auto-Dependency Generation. Основная идея там такая: нам не нужен актуальный .d-файл, нам достаточно такого, чтобы триггернул перекомпиляцию.
-
В частности: если у нас есть
main.cpp
, который инклудитincl.h
, то генерируемый gcc-ёй .d-файл будет таким:
main.o: main.cpp incl.h
main.cpp:
incl.h:
Если какой-то из исходных файлов main.cpp
, incl.h
пропал, то их пустые правила триггернутся как .PHONY, что приведёт к перекомпиляции main.o
- Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный mtime до и после её компиляции. Хвастаюсь без сорцов:
[demo]$ ls
cake cakefile.cpp cake-hashcache README.md src target
[demo]$ ./cake clean
[demo]$ ls target/
cakefile
[demo]$ ./cake-hashcache ls
EE Cache file not found.
[demo]$ time ./cake -v
>> target/cakefile -v
CC target/build/greeter/greeter.o
CC target/build/main.o
{} mkdir -p target/build
{} mkdir -p target/build/greeter
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/main.o src/main.cpp
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/greeter/greeter.o src/greeter/greeter.cpp
LL target/hello
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -o target/hello target/build/main.o target/build/greeter/greeter.o
real 0m0.131s
user 0m0.143s
sys 0m0.016s
[demo]$ target/hello world
Hello world!
[demo]$ ./cake-hashcache ls
2 entries
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ time ./cake -v
>> target/cakefile -v
real 0m0.004s
user 0m0.000s
sys 0m0.005s
[demo]$ ./cake-hashcache ls
7 entries
ffda614df6ecf3c19cee22d5b2f55989 2022-10-15 08:53:16.048930696 105 src/greeter/greeter.cpp
68318d810aae5485626518b3a8c5081d 2022-10-15 08:52:19.588150385 44 src/greeter/greeter.h
7870fb12a712dbf5751730b8b8da7ffe 2022-10-19 20:52:00.434276397 197 src/main.cpp
68cd1646da7a1f27c2df8fa5c3d53b4f 2022-10-19 20:56:33.808249551 104 target/build/greeter/greeter.d
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
bda20173f0bc8fb367cc92c16c602736 2022-10-19 20:56:33.808249551 79 target/build/main.d
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: mtime & size not changed: `src/main.cpp`
[demo]$ touch src/main.cpp
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: returning cached mtime: `src/main.cpp`
Исходная версия dimgel, :
- В сабже происходит примерно вот что:
-
Правило «a:» без пререквизитов и без файла на диске таки-считается как .PHONY, и соответственно выполняется и оно само, и его зависимости.
-
И на это поведение дохрена всего завязано, что суммируется в Advanced Auto-Dependency Generation. Основная идея там такая: нам не нужен актуальный .d-файл, нам достаточно такого, чтобы триггернул перекомпиляцию.
-
В частности: если у нас есть
main.cpp
, который инклудит ’incl.h`, то генерируемый gcc-ёй .d-файл будет таким:
main.o: main.cpp incl.h
main.cpp:
incl.h:
Если какой-то из исходных файлов main.cpp
, incl.h
пропал, то их пустые правила триггернутся как .PHONY, что приведёт к перекомпиляции main.o
- Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный mtime до и после её компиляции. Хвастаюсь без сорцов:
[demo]$ ls
cake cakefile.cpp cake-hashcache README.md src target
[demo]$ ./cake clean
[demo]$ ls target/
cakefile
[demo]$ ./cake-hashcache ls
EE Cache file not found.
[demo]$ time ./cake -v
>> target/cakefile -v
CC target/build/greeter/greeter.o
CC target/build/main.o
{} mkdir -p target/build
{} mkdir -p target/build/greeter
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/main.o src/main.cpp
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -MMD -MP -c -o target/build/greeter/greeter.o src/greeter/greeter.cpp
LL target/hello
>> g++ -fno-rtti -march=x86-64 -O2 -flto=auto -s -o target/hello target/build/main.o target/build/greeter/greeter.o
real 0m0.131s
user 0m0.143s
sys 0m0.016s
[demo]$ target/hello world
Hello world!
[demo]$ ./cake-hashcache ls
2 entries
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ time ./cake -v
>> target/cakefile -v
real 0m0.004s
user 0m0.000s
sys 0m0.005s
[demo]$ ./cake-hashcache ls
7 entries
ffda614df6ecf3c19cee22d5b2f55989 2022-10-15 08:53:16.048930696 105 src/greeter/greeter.cpp
68318d810aae5485626518b3a8c5081d 2022-10-15 08:52:19.588150385 44 src/greeter/greeter.h
7870fb12a712dbf5751730b8b8da7ffe 2022-10-19 20:52:00.434276397 197 src/main.cpp
68cd1646da7a1f27c2df8fa5c3d53b4f 2022-10-19 20:56:33.808249551 104 target/build/greeter/greeter.d
d8c17693514b1f28eb0bb77a0956e685 2022-10-19 20:56:33.808249551 4160 target/build/greeter/greeter.o
bda20173f0bc8fb367cc92c16c602736 2022-10-19 20:56:33.808249551 79 target/build/main.d
4c80b65c06cf59e6cc319ddeeb14e90e 2022-10-19 20:56:33.808249551 6088 target/build/main.o
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: mtime & size not changed: `src/main.cpp`
[demo]$ touch src/main.cpp
[demo]$ ./cake -vv | grep -P 'HashCache.*main.cpp'
// HashCache: returning cached mtime: `src/main.cpp`