LINUX.ORG.RU

История изменений

Исправление dimgel, (текущая версия) :

@firkax, @wandrien

  1. В сабже происходит примерно вот что:
  • Правило «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

  1. Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный 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, :

@firkax, @wandrien

  1. В сабже происходит примерно вот что:
  • Правило «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

  1. Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный 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, :

@firkax, @wandrien

  1. В сабже происходит примерно вот что:
  • Правило «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

  1. Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный 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, :

@firkax, @wandrien

  1. В сабже происходит примерно вот что:
  • Правило «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

  1. Я таки-запилил хэш-кеши. Оказалось довольно чистенько и простенько, т.е. вполне надёжно: хеши проверяем только для пререквизитов, но не для целей. А у цели беру актуальный 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`