From 777435c4708713f74279a02fb51910b1fbc841b4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 3 Apr 2020 17:28:18 +0530 Subject: [PATCH 1/2] 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 + '~' -args.output.write('};') +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('};') + +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) From eaef24c527833232bd4725789b0f35304de8123b Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 3 Apr 2020 17:32:51 +0530 Subject: [PATCH 2/2] meson: Fix check for builtype arguments `get_option('buildtype')` will return `'custom'` for most combinations of `-Doptimization` and `-Ddebug`, but those two will always be set correctly if only `-Dbuildtype` is set. So we should look at those options directly. For the two-way mapping between `buildtype` and `optimization` + `debug`, see this table: https://mesonbuild.com/Builtin-options.html#build-type-options --- meson.build | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 7eee560a6d..bf63c1330e 100644 --- a/meson.build +++ b/meson.build @@ -60,14 +60,17 @@ add_project_arguments('-DGTK_VERSION="@0@"'.format(meson.project_version()), lan add_project_arguments('-D_GNU_SOURCE', language: 'c') +# Use debug/optimization flags to determine whether to enable debug or disable +# cast checks gtk_debug_cflags = [] -buildtype = get_option('buildtype') -if buildtype.startswith('debug') +debug = get_option('debug') +optimization = get_option('optimization') +if debug gtk_debug_cflags += '-DG_ENABLE_DEBUG' - if buildtype == 'debug' + if optimization in ['0', 'g'] gtk_debug_cflags += '-DG_ENABLE_CONSISTENCY_CHECKS' endif -elif buildtype == 'release' +elif optimization in ['2', '3', 's'] gtk_debug_cflags += '-DG_DISABLE_CAST_CHECKS' endif