{
 "number": 36106,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36106",
 "title": "bitcoin wrapper: respect CMAKE_INSTALL_BINDIR/LIBEXECDIR",
 "author": "ryanofsky",
 "author_association": "MEMBER",
 "created_at": "2026-08-27T18:28:28Z",
 "updated_at": "2026-09-10T15:38:17Z",
 "age_days": 20,
 "draft": false,
 "labels": [],
 "milestone": null,
 "base": "master",
 "head_sha": "bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4",
 "head_ref": "pr/wrapexec",
 "head_repo": "ryanofsky/bitcoin",
 "head_history": [
  {
   "t": "2026-08-27T19:53:33Z",
   "sha": "dfc786c75ec3cdb18b824547bf586642c8bda6b5"
  },
  {
   "t": "2026-09-09T01:27:47Z",
   "sha": "50450a06dceffe6d86cef529c77d81be18b7852b"
  },
  {
   "t": "2026-09-10T15:36:14Z",
   "sha": "bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4"
  }
 ],
 "additions": 113,
 "deletions": 6,
 "changed_files": 6,
 "commit_count": 2,
 "size_bucket": "M",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "approach_ack": [
     {
      "login": "hebasto",
      "url": "https://github.com/bitcoin/bitcoin/pull/36106#pullrequestreview-5079009323"
     }
    ]
   },
   "conflicts": [
    {
     "number": 36190,
     "title": "test: Check bitcoin wrapper child exit status on windows",
     "author": "Bortlesboat"
    },
    {
     "number": 36105,
     "title": "bitcoin wrapper: Fix Windows exec so wrapper waits for child process",
     "author": "ryanofsky"
    },
    {
     "number": 36022,
     "title": "test: add coverage for bitcoin wrapper argument handling",
     "author": "cyb3ralbert"
    },
    {
     "number": 32387,
     "title": "ipc: add windows support",
     "author": "ryanofsky"
    }
   ]
  }
 },
 "acks_parsed": {
  "hebasto": {
   "kind": "approach_ack",
   "hash": "dfc786c75ec3cdb18b824547bf586642c8bda6b5",
   "t": "2026-09-01T14:10:20Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 0,
  "approach_ack": 1,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "cyb3ralbert",
   "hebasto",
   "purpleKarrot"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-09-10T15:38:17Z",
  "last_reviewer_activity": "2026-09-10T10:17:34Z",
  "last_reviewer": "cyb3ralbert",
  "author_silent_days": 7,
  "waiting_on_author_days": 0,
  "days_since_update": 7
 },
 "refs": {
  "mentioned": [
   35785,
   35789,
   36022,
   36037,
   36085
  ],
  "depends_on": [],
  "fixes": [
   35785
  ],
  "linked_issues": [
   {
    "number": 35785,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "launcher does not respect CMAKE_INSTALL_LIBEXECDIR"
   }
  ],
  "references": [
   {
    "number": 35785,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "launcher does not respect CMAKE_INSTALL_LIBEXECDIR"
   },
   {
    "number": 36037,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "build: honor CMAKE_INSTALL_LIBEXECDIR in wrapper"
   },
   {
    "number": 35789,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "build: respect CMAKE_INSTALL_LIBEXECDIR in bitcoin launcher"
   },
   {
    "number": 36085,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "build: respect CMAKE_INSTALL_BINDIR and CMAKE_INSTALL_LIBEXECDIR in the launcher"
   },
   {
    "number": 36022,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "test: add coverage for bitcoin wrapper argument handling"
   }
  ],
  "conflicts": [
   36190,
   36105,
   36022,
   32387
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "CMakeLists.txt",
  "src/bitcoin.cpp",
  "test/functional/tool_bitcoin.py"
 ],
 "body": "**Problem:** On Arch Linux the installed `bitcoin` command doesn't work: `bitcoin -m node`, `bitcoin chainstate`, and similar commands all fail with `execvp failed to execute ... No such file or directory` (#35785). Arch installs the programs the wrapper runs into a different directory than the wrapper looks in.\n\n**Solution:** Make the wrapper look for those programs in the directory they were actually installed to, rather than a hardcoded one. Small change to the wrapper (`src/bitcoin.cpp`), plus build-system changes to pass it the configured install directories, and a functional test for the installed layout. Details are in the commit messages.\n\nFixes #35785. Built from earlier PRs #36037, #35789, and #36085.",
 "commits": [
  {
   "sha": "57d7e8d3ca90335758b453ae863e2f22cfc35d96",
   "date": "2026-08-24T19:18:08Z",
   "message": "test: characterize installed bitcoin wrapper libexec lookup\n\nAdd a functional test for the installed-layout executable lookup in the\n`bitcoin` wrapper. When installed in a `bin/` directory the wrapper looks\nfor internal binaries like `bitcoind` in a sibling directory under the\nsame prefix; this path is never exercised by the normal build-tree tests\nbecause every binary sits next to the wrapper there.\n\nThe test builds a fake install prefix under tmpdir, copies the wrapper\ninto `bin/` and `bitcoind` into an internal directory (not next to the\nwrapper), and runs the wrapper by absolute path with PATH cleared so a\nlookup miss cannot be satisfied by an unrelated system binary. Under\n--valgrind, resolve the valgrind executable via shutil.which() before PATH\nis blanked, since subprocess.run() resolves a bare command name against\nthe env it is given rather than the calling process's real PATH.\n\nThis characterizes current behavior \u2014 the wrapper resolves binaries from a\nhardcoded `libexec/` directory \u2014 so a following commit can change it to\nhonor CMAKE_INSTALL_LIBEXECDIR and verify the result. Also add\nCMAKE_INSTALL_BINDIR/LIBEXECDIR to test/config.ini.in, and read and\nabsolute-path-check them here, unused by this commit's still-hardcoded\ntest body, so the following commit's diff is limited to the actual\n\"bin\"/\"libexec\"/\"lib\" -> configured-value substitution.\n\nAdapted from https://github.com/bitcoin/bitcoin/pull/36037.\n\nCo-Authored-By: Avecci-Claussen <cto@greybound.tech>\nCo-Authored-By: cyb3ralbert <cyberalbert@protonmail.ch>\nCo-Authored-By: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
  },
  {
   "sha": "bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4",
   "date": "2026-08-24T19:27:13Z",
   "message": "build: respect CMAKE_INSTALL_BINDIR/LIBEXECDIR in bitcoin wrapper\n\nSwitch from hardcoded \"bin\"/\"libexec\" strings to CMAKE_INSTALL_BINDIR and\nCMAKE_INSTALL_LIBEXECDIR in the installed-layout executable lookup, so the\nwrapper works on distributions that configure non-default install\ndirectories. Previously `bitcoin -m node`, `bitcoin chainstate`, and\nsimilar subcommands failed with \"execvp failed to execute\" on Arch Linux,\nwhich sets CMAKE_INSTALL_LIBEXECDIR=lib (#35785).\n\nThread both values through bitcoin-build-config.h. Include GNUInstallDirs\nat the top level of CMakeLists.txt before the subdirectories that\nsubstitute these values into generated files, and add configure-time\nFATAL_ERROR guards for empty values (complement to the compile-time\nstatic_asserts). Remove the now-redundant include(GNUInstallDirs) from\nInstallBinaryComponent.cmake.\n\nFixes #35785.\n\nThe fix and test build on #36037, #35789, and #36085.\n\nCo-Authored-By: Avecci-Claussen <cto@greybound.tech>\nCo-Authored-By: Andrew Barnes <bortstheboat@gmail.com>\nCo-Authored-By: riba2534 <riba2534@qq.com>\nCo-Authored-By: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
  }
 ],
 "timeline": [
  {
   "t": "2026-08-27T19:53:33Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "dfc786c75ec3cdb18b824547bf586642c8bda6b5"
  },
  {
   "t": "2026-08-27T19:54:14Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "Updated 94c64d40c8e5b51122c39af9d781e360752aec11 -> dfc786c75ec3cdb18b824547bf586642c8bda6b5 ([`pr/wrapexec.1`](https://github.com/ryanofsky/bitcoin/commits/pr/wrapexec.1) -> [`pr/wrapexec.2`](https://github.com/ryanofsky/bitcoin/commits/pr/wrapexec.2), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/wrapexec.1..pr/wrapexec.2)) to fix tool_bitcoin.py installed-layout check failing in CI: pass a writable -datadir so 'bitcoin node -version' doesn't depend on the default datadir ($HOME/.bitcoin) being writable https://github.com/bitcoin/bitcoin/actions/runs/33103647138/job/98627629393"
  },
  {
   "t": "2026-08-29T03:18:28Z",
   "kind": "comment",
   "who": "purpleKarrot",
   "assoc": "MEMBER",
   "text": "Looks good. But it also has AI co-authors."
  },
  {
   "t": "2026-09-01T11:52:52Z",
   "kind": "review",
   "who": "hebasto",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "dfc786c75ec3cdb18b824547bf586642c8bda6b5",
   "text": "Concept ACK.\n\n[quoted text omitted]\nFrom the project's [AI Policy](https://github.com/bitcoin/bitcoin/blob/master/doc/AI_POLICY.md):\n[quoted text omitted]"
  },
  {
   "t": "2026-09-01T14:03:01Z",
   "kind": "review_comment",
   "who": "hebasto",
   "assoc": "MEMBER",
   "path": "src/bitcoin.cpp",
   "commit": "dfc786c75ec3cdb18b824547bf586642c8bda6b5",
   "in_reply_to": null,
   "text": "1. This limits the user's choice of values for `CMAKE_INSTALL_BINDIR` and `CMAKE_INSTALL_LIBEXECDIR`, whereas the CMake [docs](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) do not impose any such restriction. If this is strictly necessary, it should be probably documented.\n\n2. Shouldn't the check for unset or empty CMake variables be performed earlier, at the configuration stage?"
  },
  {
   "t": "2026-09-01T14:06:21Z",
   "kind": "review_comment",
   "who": "hebasto",
   "assoc": "MEMBER",
   "path": "CMakeLists.txt",
   "commit": "bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4",
   "in_reply_to": null,
   "text": "While re-inclusions of `GNUInstallDirs` are harmless, maybe consider removing the now-redundant ones to keep the code clean."
  },
  {
   "t": "2026-09-01T14:09:52Z",
   "kind": "review_comment",
   "who": "hebasto",
   "assoc": "MEMBER",
   "path": "test/functional/tool_bitcoin.py",
   "commit": "dfc786c75ec3cdb18b824547bf586642c8bda6b5",
   "in_reply_to": null,
   "text": "Using the node's datadir for the installation prefix seems counter-intuitive to me. Maybe place it directly under `self.options.tmpdir`?"
  },
  {
   "t": "2026-09-01T14:10:20Z",
   "kind": "review",
   "who": "hebasto",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "dfc786c75ec3cdb18b824547bf586642c8bda6b5",
   "text": "Approach ACK dfc786c75ec3cdb18b824547bf586642c8bda6b5.\n\nTested also with the `cmake --install` command's [`--prefix`](https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake--install-0) option.\n\nThe new test fails when the user specifies `CMAKE_INSTALL_BINDIR`:\n```console\n$ cmake -B build -DCMAKE_INSTALL_BINDIR=\"nib\"\n$ cmake --build build\n$ ./build/test/functional/tool_bitcoin.py\n2026-09-01T13:53:13.898723Z TestFramework (INFO): PRNG seed is: 6212645667151046958\n2026-09-01T13:53:13.899141Z TestFramework (INFO): Initializing test directory /tmp/bitcoin_func_test_0y4u82jq\n2026-09-01T13:53:13.899475Z TestFramework (INFO): Ensure bitcoin node command invokes bitcoind by default\n2026-09-01T13:53:13.903417Z TestFramework (INFO): Ensure bitcoin -M invokes bitcoind\n2026-09-01T13:53:13.907124Z TestFramework (INFO): Ensure bitcoin -M does not accept -ipcbind\n2026-09-01T13:53:13.910846Z TestFramework (INFO): Ensure bitcoin -m invokes bitcoin-node\n2026-09-01T13:53:13.914668Z TestFramework (INFO): Ensure bitcoin -m does accept -ipcbind\n2026-09-01T13:53:13.918495Z TestFramework (INFO): Ensure bitcoin accepts -ipcbind by default\n2026-09-01T13:53:13.922104Z TestFramework (INFO): Ensure bitcoin recognizes -ipcbind in config file\n2026-09-01T13:53:13.926035Z TestFramework (INFO): Ensure installed wrapper finds internal binaries in configured libexec/\n2026-09-01T13:53:14.046585Z TestFramework (ERROR): Unexpected exception:\nTraceback (most recent call last):\n  File \"/home/hebasto/dev/bitcoin/test/functional/test_framework/test_framework.py\", line 145, in main\n    self.run_test()\n    ~~~~~~~~~~~~~^^\n  File \"/home/hebasto/dev/bitcoin/./build/test/functional/tool_bitcoin.py\", line 92, in run_test\n    self.test_installed_layout()\n    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^\n  File \"/home/hebasto/dev/bitcoin/./build/test/functional/tool_bitcoin.py\", line 143, in test_installed_layout\n    assert_equal(result.returncode, 0)\n    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/hebasto/dev/bitcoin/test/functional/test_framework/util.py\", line 94, in assert_equal\n    raise AssertionError(\"not(%s)\" % \" == \".join(str(arg) for arg in (thing1, thing2) + args))\nAssertionError: not(1 == 0)\n2026-09-01T13:53:14.098127Z TestFramework (INFO): Not stopping nodes as test failed. The dangling processes will be cleaned up later.\n2026-09-01T13:53:14.098499Z TestFramework (WARNING): Not cleaning up dir /tmp/bitcoin_func_test_0y4u82jq\n2026-09-01T13:53:14.098707Z TestFramework (ERROR): Test failed. Test logging available at /tmp/bitcoin_func_test_0y4u82jq/test_framework.log\n2026-09-01T13:53:14.099086Z TestFramework (ERROR):\n2026-09-01T13:53:14.099412Z TestFramework (ERROR): Hint: Call /home/hebasto/dev/bitcoin/test/functional/combine_logs.py '/tmp/bitcoin_func_test_0y4u82jq' to consolidate all logs\n2026-09-01T13:53:14.099593Z TestFramework (ERROR):\n2026-09-01T13:53:14.099752Z TestFramework (ERROR): If this failure happened unexpectedly or intermittently, please file a bug and provide a link or upload of the combined log.\n2026-09-01T13:53:14.099975Z TestFramework (ERROR): https://github.com/bitcoin/bitcoin/issues\n2026-09-01T13:53:14.100138Z TestFramework (ERROR):\n```"
  },
  {
   "t": "2026-09-02T09:30:47Z",
   "kind": "comment",
   "who": "cyb3ralbert",
   "assoc": "CONTRIBUTOR",
   "text": "The fix works \u2014 I built the branch and ran the #35785 scenario to verify it. I did find two gaps in the test coverage, though: one that seems worth fixing here, and one that could be a follow-up.\n\n`test_installed_layout` derives `other_dir = \"lib\" if libexecdir != \"lib\" else \"libexec\"`, which at the default `CMAKE_INSTALL_LIBEXECDIR=libexec` is exactly the pair the old wrapper hardcodes:\n\n| `CMAKE_INSTALL_LIBEXECDIR` | wrapper            | result                               |\n| -------------------------- | ------------------ | ------------------------------------ |\n| `libexec` (default)        | this branch        | pass                                 |\n| `libexec` (default)        | before this change | **pass**                             |\n| `lib`                      | this branch        | pass                                 |\n| `lib`                      | before this change | fail \u2014 `AssertionError: not(1 == 0)` |\n\n`CMAKE_INSTALL_LIBEXECDIR` does not appear anywhere under `ci/` or `.github/`, so every job builds with the GNUInstallDirs default (`libexec`) and none of them can tell the two wrappers apart \u2014 a regression to a hardcoded directory would stay green. The `lib` value is what Arch actually uses (`-DCMAKE_INSTALL_LIBEXECDIR=lib` in its PKGBUILD), so adding it to `BITCOIN_CONFIG` in one of the existing `ci/test/00_setup_env_*.sh` jobs would make the test you already wrote cover the change. That part could go in a follow-up.\n\nThe smaller one: `run_wrapper` calls `subprocess.run([wrapper, ...])` directly, bypassing `binaries.valgrind_cmd`, so the new checks are skipped under `--valgrind` \u2014 25 ms and 63 ms against ~2 s for each neighbouring check in the same run. The same point was raised on #36022 in this file and fixed there by prefixing `self.nodes[0].binaries.valgrind_cmd`; it matters here because that command carries `--trace-children=yes`, which is \"Needed for 'bitcoin' wrapper\"."
  },
  {
   "t": "2026-09-09T01:11:08Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/bitcoin.cpp",
   "commit": "dfc786c75ec3cdb18b824547bf586642c8bda6b5",
   "in_reply_to": 3904899287,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/36106#discussion_r3904899287\n\nThanks, I expanded the comment on the static assert to note the bindir limitation and added some cmake checks for empty values. It's very likely there are more checks and improvements that can be made. This PR is just closing the biggest gap by starting to use these configuration values which were ignored before."
  },
  {
   "t": "2026-09-09T01:12:04Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "CMakeLists.txt",
   "commit": "bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4",
   "in_reply_to": 3904930108,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/36106#discussion_r3904930108\n\n[quoted text omitted]\nThanks, removed from cmake/module/InstallBinaryComponent.cmake in the latest push"
  },
  {
   "t": "2026-09-09T01:12:36Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "test/functional/tool_bitcoin.py",
   "commit": "dfc786c75ec3cdb18b824547bf586642c8bda6b5",
   "in_reply_to": 3904962575,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/36106#discussion_r3904962575\n\n[quoted text omitted]\nGood idea, that does seem better and done in latest push"
  },
  {
   "t": "2026-09-09T01:27:47Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "50450a06dceffe6d86cef529c77d81be18b7852b"
  },
  {
   "t": "2026-09-09T01:30:55Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "50450a06dceffe6d86cef529c77d81be18b7852b",
   "text": "Updated dfc786c75ec3cdb18b824547bf586642c8bda6b5 -> 50450a06dceffe6d86cef529c77d81be18b7852b ([`pr/wrapexec.2`](https://github.com/ryanofsky/bitcoin/commits/pr/wrapexec.2) -> [`pr/wrapexec.3`](https://github.com/ryanofsky/bitcoin/commits/pr/wrapexec.3), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/wrapexec.2..pr/wrapexec.3)) with review suggestions.\n\n---\n\nre: hebasto https://github.com/bitcoin/bitcoin/pull/36106#pullrequestreview-5079009323\n\n[quoted text omitted]\nGood catch, fixed by passing CMAKE_INSTALL_BINDIR to the test now.\n\n---\n\nre: cyb3ralbert https://github.com/bitcoin/bitcoin/pull/36106#issuecomment-5507461259\n\n[quoted text omitted]\nYeah it is hard to have good test coverage for build-time configuration code, but I agree it could be a good idea to change one of the CI job configurations to try setting nonstandard directories and make sure things don't break.\n\nI would definitely leave it for a followup because CI configuration changes need a different kind of review and probably a different set of reviewers than this code change.\n\n[quoted text omitted]\nThanks! Added that here as well"
  },
  {
   "t": "2026-09-10T10:17:34Z",
   "kind": "comment",
   "who": "cyb3ralbert",
   "assoc": "CONTRIBUTOR",
   "text": "Rebuilt at `50450a06` and re-ran the layouts. `-DCMAKE_INSTALL_LIBEXECDIR=lib`, the case from my earlier comment, passes.\n\nA non-default bindir passes as well: with `-DCMAKE_INSTALL_BINDIR=nib` the test fails on `dfc786c7` (`AssertionError: not(1 == 0)`) and passes here. The new empty-value checks exit 1 as intended.\n\nThe last push did introduce one regression, though: `tool_bitcoin.py` fails under `--valgrind`.\n\n```text\ncmake -B build && cmake --build build -j4 --target bitcoin bitcoind\npython3 test/functional/tool_bitcoin.py --configfile=build/test/config.ini --valgrind\n\nTestFramework (INFO): Ensure installed wrapper finds internal binaries in configured libexec/\nTestFramework (ERROR): Unexpected exception:\nTraceback (most recent call last):\n  File \".../test/functional/tool_bitcoin.py\", line 148, in test_installed_layout\n  File \".../test/functional/tool_bitcoin.py\", line 143, in run_wrapper\n  File \"/usr/lib/python3.11/subprocess.py\", line 1901, in _execute_child\nFileNotFoundError: [Errno 2] No such file or directory: 'valgrind'\n```\n\n`run_wrapper` combines two things: `env[\"PATH\"] = \"\"`, which was already there, and `binaries.valgrind_cmd`, which is new in this push. `valgrind_cmd[0]` is the bare name `\"valgrind\"` (`test_framework/util.py`), and once `env` is passed to `subprocess.run`, the executable is resolved against `env[\"PATH\"]` \u2014 which is empty. So it fails regardless of the install dirs.\n\nOn `dfc786c7` the file did pass under `--valgrind`, but the two checks took 20 ms and 63 ms, i.e. they never ran under valgrind at all \u2014 which was the point of my earlier comment.\n\nResolving valgrind before `PATH` is blanked keeps the intent of the change:\n\n```python\nvalgrind_cmd = self.nodes[0].binaries.valgrind_cmd\nif valgrind_cmd:\n    valgrind_cmd = [shutil.which(valgrind_cmd[0]), *valgrind_cmd[1:]]\nreturn subprocess.run(\n    valgrind_cmd + [str(wrapper), \"node\", f\"-datadir={datadir}\", \"-version\"],\n    capture_output=True, env=env, timeout=60)\n```\n\nWith that, `--valgrind` is green and the two checks take 1.94 s and 0.74 s, so they do run under valgrind now. Without `--valgrind` it stays green. On Windows it is a no-op \u2014 `valgrind_cmd` is empty there.\n\n**Environment:** Debian, gcc 12.2.0, Release, `BUILD_TESTS=OFF`, `ENABLE_IPC=OFF`, valgrind 3.19.0, Python 3.11."
  },
  {
   "t": "2026-09-10T15:36:14Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4"
  },
  {
   "t": "2026-09-10T15:38:17Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "Updated 50450a06dceffe6d86cef529c77d81be18b7852b -> bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4 ([`pr/wrapexec.3`](https://github.com/ryanofsky/bitcoin/commits/pr/wrapexec.3) -> [`pr/wrapexec.4`](https://github.com/ryanofsky/bitcoin/commits/pr/wrapexec.4), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/wrapexec.3..pr/wrapexec.4)) with another fix for valgrind https://github.com/bitcoin/bitcoin/pull/36106#issuecomment-5617007631 and a few test cleanups"
  }
 ],
 "labels_log": [
  {
   "t": "2026-08-27T19:54:01Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-27T21:27:16Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [],
 "text_chars": 14869,
 "text_tokens_estimate": 3717,
 "changed_paths": [
  "CMakeLists.txt",
  "cmake/bitcoin-build-config.h.in",
  "cmake/module/InstallBinaryComponent.cmake",
  "src/bitcoin.cpp",
  "test/config.ini.in",
  "test/functional/tool_bitcoin.py"
 ],
 "files": [
  {
   "path": "CMakeLists.txt",
   "add": 14,
   "del": 0
  },
  {
   "path": "cmake/bitcoin-build-config.h.in",
   "add": 10,
   "del": 0
  },
  {
   "path": "cmake/module/InstallBinaryComponent.cmake",
   "add": 0,
   "del": 1
  },
  {
   "path": "src/bitcoin.cpp",
   "add": 18,
   "del": 5
  },
  {
   "path": "test/config.ini.in",
   "add": 2,
   "del": 0
  },
  {
   "path": "test/functional/tool_bitcoin.py",
   "add": 69,
   "del": 0
  }
 ],
 "test_lines": 71,
 "git": {
  "head": "bd3d5cf57e576a48b8ebf4f06b54e4412ff315a4",
  "head_matches_backup": true,
  "base": "58a7869f860f022e6163dc3fae3106a0599830c5",
  "commits": [
   {
    "sha": "57d7e8d3ca",
    "subject": "test: characterize installed bitcoin wrapper libexec lookup",
    "files": 2,
    "add": 78,
    "del": 0
   },
   {
    "sha": "bd3d5cf57e",
    "subject": "build: respect CMAKE_INSTALL_BINDIR/LIBEXECDIR in bitcoin wrapper",
    "files": 5,
    "add": 44,
    "del": 15
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "07674685412d9ace",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}