From d05c1c9dd298cb95d7feccbddb5caa043a319a01 Mon Sep 17 00:00:00 2001 From: Yoann Congal Date: Sun, 13 Apr 2025 00:52:13 +0200 Subject: [PATCH] Add a reproducibility option for building ecodes.c ecodes.c currently contains the kernel info of the build machine and the full path of the input*.h headers: This is not reproducible as output can change even is headers content do not. Downstream distributions might package ecodes.c and get non-reproducible output. To fix this: introduce a --reproducible option in the build: - in setup.py build_ecodes command - in underlying genecodes_c.py Note: These options are disabled by default so no change is expected in current builds. Signed-off-by: Yoann Congal Upstream-Status: Submitted [https://github.com/gvalkov/python-evdev/pull/242] --- setup.py | 13 ++++++++++--- src/evdev/genecodes_c.py | 17 +++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index 6b721d7..3371199 100755 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ curdir = Path(__file__).resolve().parent ecodes_c_path = curdir / "src/evdev/ecodes.c" -def create_ecodes(headers=None): +def create_ecodes(headers=None, reproducibility=False): if not headers: include_paths = set() cpath = os.environ.get("CPATH", "").strip() @@ -65,7 +65,10 @@ def create_ecodes(headers=None): print("writing %s (using %s)" % (ecodes_c_path, " ".join(headers))) with ecodes_c_path.open("w") as fh: - cmd = [sys.executable, "src/evdev/genecodes_c.py", "--ecodes", *headers] + cmd = [sys.executable, "src/evdev/genecodes_c.py"] + if reproducibility: + cmd.append("--reproducibility") + cmd.extend(["--ecodes", *headers]) run(cmd, check=True, stdout=fh) @@ -74,17 +77,21 @@ class build_ecodes(Command): user_options = [ ("evdev-headers=", None, "colon-separated paths to input subsystem headers"), + ("reproducibility", None, "hide host details (host/paths) to create a reproducible output"), ] def initialize_options(self): self.evdev_headers = None + self.reproducibility = False def finalize_options(self): if self.evdev_headers: self.evdev_headers = self.evdev_headers.split(":") + if self.reproducibility is None: + self.reproducibility = False def run(self): - create_ecodes(self.evdev_headers) + create_ecodes(self.evdev_headers, reproducibility=self.reproducibility) class build_ext(_build_ext.build_ext): diff --git a/src/evdev/genecodes_c.py b/src/evdev/genecodes_c.py index 5c2d946..24cad27 100644 --- a/src/evdev/genecodes_c.py +++ b/src/evdev/genecodes_c.py @@ -15,22 +15,27 @@ headers = [ "/usr/include/linux/uinput.h", ] -opts, args = getopt.getopt(sys.argv[1:], "", ["ecodes", "stubs"]) +opts, args = getopt.getopt(sys.argv[1:], "", ["ecodes", "stubs", "reproducibility"]) if not opts: - print("usage: genecodes.py [--ecodes|--stubs] ") + print("usage: genecodes.py [--ecodes|--stubs] [--reproducibility] ") exit(2) if args: headers = args +reproducibility = ("--reproducibility", "") in opts + # ----------------------------------------------------------------------------- macro_regex = r"#define\s+((?:KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF|UI_FF|INPUT_PROP)_\w+)" macro_regex = re.compile(macro_regex) -# Uname without hostname. -uname = list(os.uname()) -uname = " ".join((uname[0], *uname[2:])) +if reproducibility: + uname = "hidden for reproducibility" +else: + # Uname without hostname. + uname = list(os.uname()) + uname = " ".join((uname[0], *uname[2:])) # ----------------------------------------------------------------------------- @@ -138,5 +143,5 @@ elif ("--stubs", "") in opts: template = template_stubs body = os.linesep.join(body) -text = template % (uname, headers, body) +text = template % (uname, headers if not reproducibility else ["hidden for reproducibility"], body) print(text.strip())