[gtk: 1/3] meson: Reduce useless relinking on reconfigure



commit 777435c4708713f74279a02fb51910b1fbc841b4
Author: Nirbheek Chauhan <nirbheek centricular com>
Date:   Fri Apr 3 17:28:18 2020 +0530

    meson: Reduce useless relinking on reconfigure
    
    When we reconfigure, `configure_file()` is called again, and
    `*.gresource.xml` files are regenerated, which causes many (all?)
    binaries to be relinked. Now we only write those out if the contents
    actually changed (or if the output didn't already exist).
    
    This is exactly what Meson already does with `configure_file()` when
    `command:` is not used.
    
    While we're at it, also do the same for `gen-c-array.py` and
    `gentypefuncs.py` for completeness. Now even if the input to those
    changes, re-building of those custom targets may not result in
    relinking if the outputted C files have the same contents.

 gdk/broadway/gen-c-array.py   | 38 ++++++++++++++++++++++++++++++--------
 gdk/gen-gdk-gresources-xml.py | 21 ++++++++++++++++++---
 gsk/gen-gsk-gresources-xml.py | 21 ++++++++++++++++++---
 gtk/gen-gtk-gresources-xml.py | 21 ++++++++++++++++++---
 gtk/gentypefuncs.py           | 21 ++++++++++++++++++---
 5 files changed, 102 insertions(+), 20 deletions(-)
---
diff --git a/gdk/broadway/gen-c-array.py b/gdk/broadway/gen-c-array.py
index afffda34e5..a25d2e4159 100644
--- a/gdk/broadway/gen-c-array.py
+++ b/gdk/broadway/gen-c-array.py
@@ -1,21 +1,43 @@
 #!/usr/bin/env python3
 
+import os
 import argparse
 import sys
+import filecmp
+
+def replace_if_changed(new, old):
+  '''
+  Compare contents and only replace if changed to avoid triggering a rebuild.
+  '''
+  try:
+    changed = not filecmp.cmp(new, old, shallow=False)
+  except FileNotFoundError:
+    changed = True
+  if changed:
+    os.replace(new, old)
+  else:
+    os.remove(new)
 
 parser = argparse.ArgumentParser()
 parser.add_argument('--array-name', help='The name of the array variable')
-parser.add_argument('--output', metavar='FILE', help='Output file',
-                    type=argparse.FileType('w'),
-                    default=sys.stdout)
+parser.add_argument('--output', metavar='STRING', help='Output filename',
+                    default=None)
 parser.add_argument('input', metavar='FILE', help='The input file',
                     type=argparse.FileType('r'))
 
 args = parser.parse_args()
 
-args.output.write('static const char {}[] = {{\n'.format(args.array_name))
-for line in args.input:
-    for ch in line:
-        args.output.write('  0x{:02x},\n'.format(ord(ch)))
+if args.output is None:
+    output = sys.stdout
+else:
+    output = args.output + '~'
+
+with open(output, 'w') as f:
+    f.write('static const char {}[] = {{\n'.format(args.array_name))
+    for line in args.input:
+        for ch in line:
+            f.write('  0x{:02x},\n'.format(ord(ch)))
+    f.write('};')
 
-args.output.write('};')
+if args.output is not None:
+    replace_if_changed(output, args.output)
diff --git a/gdk/gen-gdk-gresources-xml.py b/gdk/gen-gdk-gresources-xml.py
index 694a9159aa..11c63552a9 100644
--- a/gdk/gen-gdk-gresources-xml.py
+++ b/gdk/gen-gdk-gresources-xml.py
@@ -5,6 +5,20 @@
 # Usage: gen-gdk-gresources-xml SRCDIR_GDK [OUTPUT-FILE]
 
 import os, sys
+import filecmp
+
+def replace_if_changed(new, old):
+  '''
+  Compare contents and only replace if changed to avoid triggering a rebuild.
+  '''
+  try:
+    changed = not filecmp.cmp(new, old, shallow=False)
+  except FileNotFoundError:
+    changed = True
+  if changed:
+    os.replace(new, old)
+  else:
+    os.remove(new)
 
 srcdir = sys.argv[1]
 
@@ -26,8 +40,9 @@ xml += '''
 
 if len(sys.argv) > 2:
   outfile = sys.argv[2]
-  f = open(outfile, 'w')
-  f.write(xml)
-  f.close()
+  tmpfile = outfile + '~'
+  with open(tmpfile, 'w') as f:
+    f.write(xml)
+  replace_if_changed(tmpfile, outfile)
 else:
   print(xml)
diff --git a/gsk/gen-gsk-gresources-xml.py b/gsk/gen-gsk-gresources-xml.py
index 1032d84ad9..5db5044b09 100644
--- a/gsk/gen-gsk-gresources-xml.py
+++ b/gsk/gen-gsk-gresources-xml.py
@@ -5,6 +5,20 @@
 # Usage: gen-gsk-gresources-xml OUTPUT-FILE [INPUT-FILE1] [INPUT-FILE2] ...
 
 import os, sys
+import filecmp
+
+def replace_if_changed(new, old):
+  '''
+  Compare contents and only replace if changed to avoid triggering a rebuild.
+  '''
+  try:
+    changed = not filecmp.cmp(new, old, shallow=False)
+  except FileNotFoundError:
+    changed = True
+  if changed:
+    os.replace(new, old)
+  else:
+    os.remove(new)
 
 source_shaders = []
 vulkan_compiled_shaders = []
@@ -45,8 +59,9 @@ xml += '''
 
 if len(sys.argv) > 1 and sys.argv[1] != '-':
   outfile = sys.argv[1]
-  f = open(outfile, 'w')
-  f.write(xml)
-  f.close()
+  tmpfile = outfile + '~'
+  with open(tmpfile, 'w') as f:
+    f.write(xml)
+  replace_if_changed(tmpfile, outfile)
 else:
   print(xml)
diff --git a/gtk/gen-gtk-gresources-xml.py b/gtk/gen-gtk-gresources-xml.py
index eb56d8e478..a816970a88 100644
--- a/gtk/gen-gtk-gresources-xml.py
+++ b/gtk/gen-gtk-gresources-xml.py
@@ -5,6 +5,20 @@
 # Usage: gen-gtk-gresources-xml SRCDIR_GTK [OUTPUT-FILE]
 
 import os, sys
+import filecmp
+
+def replace_if_changed(new, old):
+  '''
+  Compare contents and only replace if changed to avoid triggering a rebuild.
+  '''
+  try:
+    changed = not filecmp.cmp(new, old, shallow=False)
+  except FileNotFoundError:
+    changed = True
+  if changed:
+    os.replace(new, old)
+  else:
+    os.remove(new)
 
 srcdir = sys.argv[1]
 
@@ -78,8 +92,9 @@ xml += '''
 
 if len(sys.argv) > 2:
   outfile = sys.argv[2]
-  f = open(outfile, 'w')
-  f.write(xml)
-  f.close()
+  tmpfile = outfile + '~'
+  with open(tmpfile, 'w') as f:
+    f.write(xml)
+  replace_if_changed(tmpfile, outfile)
 else:
   print(xml)
diff --git a/gtk/gentypefuncs.py b/gtk/gentypefuncs.py
index b17b7233a1..c67c5c4a5f 100644
--- a/gtk/gentypefuncs.py
+++ b/gtk/gentypefuncs.py
@@ -4,6 +4,20 @@
 import sys
 import re
 import os
+import filecmp
+
+def replace_if_changed(new, old):
+  '''
+  Compare contents and only replace if changed to avoid triggering a rebuild.
+  '''
+  try:
+    changed = not filecmp.cmp(new, old, shallow=False)
+  except FileNotFoundError:
+    changed = True
+  if changed:
+    os.replace(new, old)
+  else:
+    os.remove(new)
 
 debug = os.getenv('GTK_GENTYPEFUNCS_DEBUG') is not None
 
@@ -50,6 +64,7 @@ for f in funcs:
 
 if debug: print (len(funcs), 'functions')
 
-ofile = open(out_file, "w")
-ofile.write(file_output)
-ofile.close()
+tmp_file = out_file + '~'
+with open(tmp_file, 'w') as f:
+    f.write(file_output)
+replace_if_changed(tmp_file, out_file)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]