openwall / john

John the Ripper jumbo - advanced offline password cracker, which supports hundreds of hash and cipher types, and runs on many operating systems, CPUs, GPUs, and even some FPGAs
https://www.openwall.com/john/
Other
10k stars 2.07k forks source link

gcc -MMD allows to find dependencies for Makefile.in #3842

Open AlekseyCherepanov opened 5 years ago

AlekseyCherepanov commented 5 years ago

Modifying Makefile.in I found it hard to account nested dependencies when .h file includes more .h files.

@rofl0r pointed out to me that it is possible to ask gcc to list dependencies of .c file onto .h files.

For example, my list of dependencies included all .h files included in .c file:

showformats.o:  showformats.c showformats.h loader.h options.h config.h dynamic.h
$ gcc -E -MMD showformats.c > /dev/null
$ cat showformats.d
showformats.o: showformats.c loader.h params.h arch.h list.h formats.h \
 misc.h jumbo.h omp_autotune.h options.h getopt.h common.h memory.h \
 john_mpi.h config.h dynamic.h simd-intrinsics.h pseudo_intrinsics.h \
 aligned.h simd-intrinsics-load-flags.h

So dependencies in Makefile.in might be improved.

AlekseyCherepanov commented 5 years ago

IIRC I saw another solution for includes from .h files: make fake target (IIRC .m file) for every header file that depends onto the header and onto targets of included header files; .c files depend onto fake targets of header files; files are just touched to build fake targets. I cannot find any standard description for such approach.

magnumripper commented 3 years ago

The gcc-generated list lacks a number of entries, such as os-autoconf.h

$ gcc -E -MMD john.c >/dev/null
$ cat john.d
john.o: john.c os.h params.h arch.h openssl_local_overrides.h misc.h \
 jumbo.h path.h memory.h list.h tty.h options.h loader.h formats.h \
 omp_autotune.h getopt.h common.h john_mpi.h signals.h idle.h dyna_salt.h \
 logger.h status.h recovery.h config.h bench.h charset.h single.h \
 wordlist.h prince.h inc.h mask.h mkv.h mkvlib.h subsets.h external.h \
 compiler.h batch.h dynamic.h simd-intrinsics.h pseudo_intrinsics.h \
 aligned.h simd-intrinsics-load-flags.h dynamic_compiler.h fake_salts.h \
 listconf.h crc32.h regex.h unicode.h gpu_common.h opencl_common.h \
 john_build_rule.h fmt_externs.h fmt_registers.h

$ ./plugin_deps.pl john.c | fold -s
john.o: john.c autoconfig.h os.h os-autoconf.h jumbo.h arch.h params.h 
openssl_local_overrides.h misc.h path.h memory.h list.h tty.h options.h 
loader.h formats.h omp_autotune.h getopt.h common.h john_mpi.h signals.h idle.h 
dyna_salt.h logger.h status.h recovery.h config.h bench.h fuzz.h charset.h 
single.h wordlist.h prince.h inc.h mask.h mkv.h mkvlib.h subsets.h external.h 
compiler.h batch.h dynamic.h simd-intrinsics.h pseudo_intrinsics.h aligned.h 
simd-intrinsics-load-flags.h dynamic_compiler.h fake_salts.h listconf.h crc32.h 
regex.h unicode.h gpu_common.h gpu_sensors.h opencl_common.h 
../run/opencl/opencl_device_info.h ztex_common.h john_build_rule.h 
fmt_externs.h fmt_registers.h

This is because things like this will be parsed:

#if AC_BUILT
#include "os-autoconf.h"
#else
(...)
#endif

That's not how plugin_deps.pl does it - it will ignore the #if ... #else and include everything (both sides). The gcc way is better, in that for example a non-OpenCL (re)build will ignore changed OpenCL source files.