[PATCHv2] native/cross: Add ar wrapper for determinism

Message ID 20211124053110.3715667-1-jacob.kroon@gmail.com
State Accepted, archived
Commit 59922c95fcb20c66634c5677012d490be2246b0b
Headers show
Series [PATCHv2] native/cross: Add ar wrapper for determinism | expand

Commit Message

Jacob Kroon Nov. 24, 2021, 5:31 a.m. UTC
Add a wrapper around ar calls for native/cross recipes. This wrapper adds
the -D option so that deterministic archives are built for native/cross
output. This improves the changes of hash equivalence matches and hence
build artefact reuse.

We don't need this in the target case since we compile binutils-cross
with an option making this the default. We need a wrapper since we need
to remove the "u" option and replace it with "D" but also allow things like
"--version" to continue to work too.

Signed-off-by: Jacob Kroon <jacob.kroon@gmail.com>
---

Changes in v2:
 * Don't modify arguments if 'U' is given, instead print a message to
   stderr that non-deterministic mode is requested

 meta/classes/cross.bbclass  |  2 ++
 scripts/cross-intercept/ar  |  1 +
 scripts/native-intercept/ar | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 120000 scripts/cross-intercept/ar
 create mode 100755 scripts/native-intercept/ar

Patch

diff --git a/meta/classes/cross.bbclass b/meta/classes/cross.bbclass
index 3e6a2f60b9..9d951076a7 100644
--- a/meta/classes/cross.bbclass
+++ b/meta/classes/cross.bbclass
@@ -93,3 +93,5 @@  python do_addto_recipe_sysroot () {
 }
 addtask addto_recipe_sysroot after do_populate_sysroot
 do_addto_recipe_sysroot[deptask] = "do_populate_sysroot"
+
+PATH:prepend = "${COREBASE}/scripts/cross-intercept:"
diff --git a/scripts/cross-intercept/ar b/scripts/cross-intercept/ar
new file mode 120000
index 0000000000..bc68ffd7a2
--- /dev/null
+++ b/scripts/cross-intercept/ar
@@ -0,0 +1 @@ 
+../native-intercept/ar
\ No newline at end of file
diff --git a/scripts/native-intercept/ar b/scripts/native-intercept/ar
new file mode 100755
index 0000000000..dcc623e3ed
--- /dev/null
+++ b/scripts/native-intercept/ar
@@ -0,0 +1,32 @@ 
+#!/usr/bin/env python3
+#
+# Wrapper around 'ar' that defaults to deterministic archives
+
+import os
+import shutil
+import sys
+
+# calculate path to the real 'ar'
+path = os.environ['PATH']
+path = path.replace(os.path.dirname(sys.argv[0]), '')
+real_ar = shutil.which('ar', path=path)
+
+if len(sys.argv) == 1:
+    os.execl(real_ar, 'ar')
+
+# modify args to mimic 'ar' configured with --default-deterministic-archives
+argv = sys.argv
+if argv[1].startswith('--'):
+    # No modifier given
+    None
+else:
+    # remove the optional '-'
+    if argv[1][0] == '-':
+        argv[1] = argv[1][1:]
+    if 'U' in argv[1]:
+        sys.stderr.write("ar: non-deterministic mode requested\n")
+    else:
+        argv[1] = argv[1].replace('u', '')
+        argv[1] = 'D' + argv[1]
+
+os.execv(real_ar, argv)