I often regenerate all YNL files in the tree to make sure they
are in sync with the codegen and specs. Generator rewrites
the files unconditionally, so since make looks at file modification
time to decide what to rebuild - my next build takes longer.
We already generate the code to a tempfile most of the time,
only overwrite the target when we have to.
Before:
$ stat include/uapi/linux/netdev.h
File: include/uapi/linux/netdev.h
Size: 2307 Blocks: 8 IO Block: 4096 regular file
Access: 2023-10-27 15:19:56.
347071940 -0700
Modify: 2023-10-27 15:19:45.
089000900 -0700
Change: 2023-10-27 15:19:45.
089000900 -0700
Birth: 2023-10-27 15:19:45.
088000894 -0700
$ ./tools/net/ynl/ynl-regen.sh -f
[...]
$ stat include/uapi/linux/netdev.h
File: include/uapi/linux/netdev.h
Size: 2307 Blocks: 8 IO Block: 4096 regular file
Access: 2023-10-27 15:19:56.
347071940 -0700
Modify: 2023-10-27 15:22:18.
417968446 -0700
Change: 2023-10-27 15:22:18.
417968446 -0700
Birth: 2023-10-27 15:19:45.
088000894 -0700
After:
$ stat include/uapi/linux/netdev.h
File: include/uapi/linux/netdev.h
Size: 2307 Blocks: 8 IO Block: 4096 regular file
Access: 2023-10-27 15:22:41.
520114221 -0700
Modify: 2023-10-27 15:22:18.
417968446 -0700
Change: 2023-10-27 15:22:18.
417968446 -0700
Birth: 2023-10-27 15:19:45.
088000894 -0700
$ ./tools/net/ynl/ynl-regen.sh -f
[...]
$ stat include/uapi/linux/netdev.h
File: include/uapi/linux/netdev.h
Size: 2307 Blocks: 8 IO Block: 4096 regular file
Access: 2023-10-27 15:22:41.
520114221 -0700
Modify: 2023-10-27 15:22:18.
417968446 -0700
Change: 2023-10-27 15:22:18.
417968446 -0700
Birth: 2023-10-27 15:19:45.
088000894 -0700
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20231027223408.1865704-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
import argparse
import collections
+import filecmp
import os
import re
import shutil
if out_file is None:
self._out = os.sys.stdout
else:
- self._out = tempfile.TemporaryFile('w+')
+ self._out = tempfile.NamedTemporaryFile('w+')
self._out_file = out_file
def __del__(self):
def close_out_file(self):
if self._out == os.sys.stdout:
return
+ # Avoid modifying the file if contents didn't change
+ self._out.flush()
+ if os.path.isfile(self._out_file) and filecmp.cmp(self._out.name, self._out_file, shallow=False):
+ return
with open(self._out_file, 'w+') as out_file:
self._out.seek(0)
shutil.copyfileobj(self._out, out_file)