From cecc16da34e24cd025b9736b255ee4d735a9a4d2 Mon Sep 17 00:00:00 2001 From: Michael Field Date: Fri, 25 Sep 2026 14:27:38 -0700 Subject: [PATCH 1/3] [transports] Make Linux-specific transports optional build configs Configure MTD and SPI transports with target_compatible_with and Bazel config_setting rules matching the D-Bus backend pattern, enabled by default on Linux via .bazelrc. Signed-off-by: Michael Field --- .bazelrc | 3 +++ BUILD | 13 ++++++++++--- MODULE.bazel | 1 + examples/BUILD | 17 +++++++---------- examples/htool.c | 10 ---------- examples/htool.h | 3 +++ examples/htool_mtd.c | 16 ++++++++++++++-- examples/htool_spi.c | 34 ++++++++++++++++++++++++++++++++-- examples/meson.build | 2 +- transports/BUILD | 26 ++++++++++++++++++++++++++ 10 files changed, 97 insertions(+), 28 deletions(-) diff --git a/.bazelrc b/.bazelrc index d56c6e5..f0ad3b6 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,3 +1,6 @@ +build --enable_platform_specific_config +build:linux --define=mtd_backend=true +build:linux --define=spi_backend=true build --stamp --workspace_status_command '$(pwd)/print_git_commit.sh' build:asan --copt=-fsanitize=address --linkopt=-fsanitize=address build:msan --copt=-fsanitize=memory --linkopt=-fsanitize=memory diff --git a/BUILD b/BUILD index 4749c97..38a1ede 100644 --- a/BUILD +++ b/BUILD @@ -45,10 +45,17 @@ cc_library( ":libhoth_transports_headers", ":libhoth_transports_headers_legacy", "//transports:libhoth_device", - "//transports:libhoth_mtd", - "//transports:libhoth_spi", "//transports:libhoth_usb", - ], + ] + select({ + "//transports:dbus_backend": ["//transports:libhoth_dbus"], + "//conditions:default": [], + }) + select({ + "//transports:mtd_backend": ["//transports:libhoth_mtd"], + "//conditions:default": [], + }) + select({ + "//transports:spi_backend": ["//transports:libhoth_spi"], + "//conditions:default": [], + }), ) alias( diff --git a/MODULE.bazel b/MODULE.bazel index 5964e1c..c75c046 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,4 +11,5 @@ libusb_ext = use_extension("//:libusb_extension.bzl", "libusb_extension") use_repo(libusb_ext, "libusb") bazel_dep(name = "googletest", version = "1.15.2") +bazel_dep(name = "platforms", version = "0.0.11") bazel_dep(name = "rules_cc", version = "0.1.4") diff --git a/examples/BUILD b/examples/BUILD index a8fea54..b2be645 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -24,13 +24,6 @@ cc_library( ], ) -config_setting( - name = "dbus_backend", - define_values = { - "dbus_backend": "true", - }, -) - cc_library( name = "htool_cmd", srcs = ["htool_cmd.c"], @@ -275,13 +268,17 @@ cc_binary( "//protocol:update_session", "//protocol:util", "//transports:libhoth_device", - "//transports:libhoth_mtd", - "//transports:libhoth_spi", "//transports:libhoth_usb", "//transports:libhoth_usb_device", "@libusb", ] + select({ - ":dbus_backend": ["//transports:libhoth_dbus"], + "//transports:dbus_backend": ["//transports:libhoth_dbus"], + "//conditions:default": [], + }) + select({ + "//transports:mtd_backend": ["//transports:libhoth_mtd"], + "//conditions:default": [], + }) + select({ + "//transports:spi_backend": ["//transports:libhoth_spi"], "//conditions:default": [], }), ) diff --git a/examples/htool.c b/examples/htool.c index 5d5d0c9..0a563ca 100644 --- a/examples/htool.c +++ b/examples/htool.c @@ -71,7 +71,6 @@ #include "protocol/spi_proxy.h" #include "protocol/util.h" #include "transports/libhoth_device.h" -#include "transports/libhoth_spi.h" void htool_report_error(const char* cmd_name, libhoth_error err) { if (err == HOTH_SUCCESS) { @@ -710,15 +709,6 @@ struct libhoth_device* htool_libhoth_device(void) { return result; } -int htool_tpm_spi_probe(const struct htool_invocation* inv) { - struct libhoth_device* dev = htool_libhoth_spi_device(); - if (!dev) { - return -1; - } - - return libhoth_tpm_spi_probe(dev); -} - int htool_external_usb_host_check_presence(const struct htool_invocation* inv) { struct libhoth_device* dev = htool_libhoth_device(); if (!dev) { diff --git a/examples/htool.h b/examples/htool.h index 1e983d7..44ae52c 100644 --- a/examples/htool.h +++ b/examples/htool.h @@ -28,6 +28,7 @@ extern "C" { void htool_report_error(const char* cmd_name, libhoth_error err); +struct htool_invocation; struct libhoth_device; struct libhoth_device* htool_libhoth_dbus_device(void); @@ -36,6 +37,8 @@ struct libhoth_device* htool_libhoth_spi_device(void); struct libhoth_device* htool_libhoth_usb_device(void); struct libhoth_device* htool_libhoth_device(void); +int htool_tpm_spi_probe(const struct htool_invocation* inv); + #ifdef __cplusplus } #endif diff --git a/examples/htool_mtd.c b/examples/htool_mtd.c index 361e2ca..d2c156d 100644 --- a/examples/htool_mtd.c +++ b/examples/htool_mtd.c @@ -12,17 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + +#ifdef MTD_BACKEND + #include #include #include -#include #include #include -#include "../transports/libhoth_mtd.h" #include "host_commands.h" #include "htool.h" #include "htool_cmd.h" +#include "transports/libhoth_mtd.h" struct libhoth_device* htool_libhoth_mtd_device(void) { static struct libhoth_device* result; @@ -60,3 +63,12 @@ struct libhoth_device* htool_libhoth_mtd_device(void) { } return result; } + +#else + +struct libhoth_device* htool_libhoth_mtd_device(void) { + fprintf(stderr, "This build doesn't have the MTD backend.\n"); + return NULL; +} + +#endif // MTD_BACKEND diff --git a/examples/htool_spi.c b/examples/htool_spi.c index 198da09..56598fc 100644 --- a/examples/htool_spi.c +++ b/examples/htool_spi.c @@ -12,17 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + +#ifdef SPI_BACKEND + #include #include #include -#include #include #include -#include "../transports/libhoth_spi.h" #include "host_commands.h" #include "htool.h" #include "htool_cmd.h" +#include "transports/libhoth_spi.h" struct libhoth_device* htool_libhoth_spi_device(void) { static struct libhoth_device* result; @@ -90,3 +93,30 @@ struct libhoth_device* htool_libhoth_spi_device(void) { } return result; } + +int htool_tpm_spi_probe(const struct htool_invocation* inv) { + (void)inv; + struct libhoth_device* dev = htool_libhoth_spi_device(); + if (!dev) { + return -1; + } + + return libhoth_tpm_spi_probe(dev); +} + +#else + +#include "htool.h" + +struct libhoth_device* htool_libhoth_spi_device(void) { + fprintf(stderr, "This build doesn't have the SPI backend.\n"); + return NULL; +} + +int htool_tpm_spi_probe(const struct htool_invocation* inv) { + (void)inv; + fprintf(stderr, "This build doesn't have the SPI backend.\n"); + return -1; +} + +#endif // SPI_BACKEND diff --git a/examples/meson.build b/examples/meson.build index 2a50baf..316c4ae 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -8,7 +8,7 @@ git_version_h = vcs_tag( incdir = libhoth_include_dirs link_with = [libhoth.get_static_lib()] -c_args = [] +c_args = ['-DMTD_BACKEND', '-DSPI_BACKEND'] if get_option('dbus_backend') link_with += libhoth_dbus diff --git a/transports/BUILD b/transports/BUILD index 1e58321..4680e97 100644 --- a/transports/BUILD +++ b/transports/BUILD @@ -16,10 +16,33 @@ cc_library( hdrs = ["libhoth_ec.h"], ) +config_setting( + name = "dbus_backend", + define_values = { + "dbus_backend": "true", + }, +) + +config_setting( + name = "mtd_backend", + define_values = { + "mtd_backend": "true", + }, +) + +config_setting( + name = "spi_backend", + define_values = { + "spi_backend": "true", + }, +) + cc_library( name = "libhoth_mtd", srcs = ["libhoth_mtd.c"], hdrs = ["libhoth_mtd.h"], + defines = ["MTD_BACKEND"], + target_compatible_with = ["@platforms//os:linux"], deps = [ ":libhoth_device", ":libhoth_ec", @@ -31,6 +54,8 @@ cc_library( name = "libhoth_spi", srcs = ["libhoth_spi.c"], hdrs = ["libhoth_spi.h"], + defines = ["SPI_BACKEND"], + target_compatible_with = ["@platforms//os:linux"], deps = [ ":libhoth_device", ":libhoth_ec", @@ -57,6 +82,7 @@ cc_library( hdrs = ["libhoth_dbus.h"], defines = ["DBUS_BACKEND"], linkopts = ["-lsystemd"], + target_compatible_with = ["@platforms//os:linux"], deps = [ ":libhoth_device", "//protocol:libhoth_status", From 9d9919a15e12d40f2644a1c3f6a62570b16abadf Mon Sep 17 00:00:00 2001 From: Michael Field Date: Fri, 25 Sep 2026 14:28:48 -0700 Subject: [PATCH 2/3] Add initial macOS Bazel build support Configure libusb for Darwin, use POSIX getentropy() for DFU nonce generation, and set minimum macOS version in .bazelrc. Signed-off-by: Michael Field --- .bazelrc | 1 + external/libusb.BUILD | 27 ++++++++++++++++++++++----- external/libusb.patch | 26 +++++++++++++++----------- protocol/dfu_hostcmd.c | 5 ++--- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/.bazelrc b/.bazelrc index f0ad3b6..a13d9ac 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,6 +1,7 @@ build --enable_platform_specific_config build:linux --define=mtd_backend=true build:linux --define=spi_backend=true +build:macos --macos_minimum_os=11.0 build --stamp --workspace_status_command '$(pwd)/print_git_commit.sh' build:asan --copt=-fsanitize=address --linkopt=-fsanitize=address build:msan --copt=-fsanitize=memory --linkopt=-fsanitize=memory diff --git a/external/libusb.BUILD b/external/libusb.BUILD index b6c1ad5..762d346 100644 --- a/external/libusb.BUILD +++ b/external/libusb.BUILD @@ -11,14 +11,21 @@ cc_library( "libusb/sync.c", "libusb/os/events_posix.h", "libusb/os/events_posix.c", - "libusb/os/linux_usbfs.h", - "libusb/os/linux_usbfs.c", - "libusb/os/linux_netlink.c", "libusb/os/threads_posix.h", "libusb/os/threads_posix.c", "libusb/version.h", "libusb/version_nano.h", - ], + ] + select({ + "@bazel_tools//src/conditions:darwin": [ + "libusb/os/darwin_usb.h", + "libusb/os/darwin_usb.c", + ], + "//conditions:default": [ + "libusb/os/linux_usbfs.h", + "libusb/os/linux_usbfs.c", + "libusb/os/linux_netlink.c", + ], + }), includes = [ "libusb", ], @@ -30,6 +37,16 @@ cc_library( "-isystem", "external/{}/libusb".format(repo_name()), "-isystem", "external/{}".format(repo_name()), ], - linkopts = ["-lpthread"], + linkopts = select({ + "@bazel_tools//src/conditions:darwin": [ + "-lobjc", + "-framework", "IOKit", + "-framework", "CoreFoundation", + "-framework", "Security", + ], + "//conditions:default": [ + "-lpthread", + ], + }), visibility = ["//visibility:public"], ) diff --git a/external/libusb.patch b/external/libusb.patch index 9e973a0..9528df0 100644 --- a/external/libusb.patch +++ b/external/libusb.patch @@ -1,20 +1,11 @@ --- /dev/null 2022-07-08 13:48:05.860119333 -0700 +++ config.h 2022-07-14 11:50:33.978861376 -0700 -@@ -0,0 +1,40 @@ +@@ -0,0 +1,44 @@ +#define DEFAULT_VISIBILITY __attribute__ ((visibility ("default"))) -+#define HAVE_ASM_TYPES_H 1 +#define HAVE_CLOCK_GETTIME 1 -+#define HAVE_DECL_EFD_CLOEXEC 1 -+#define HAVE_DECL_EFD_NONBLOCK 1 -+#define HAVE_DECL_TFD_CLOEXEC 1 -+#define HAVE_DECL_TFD_NONBLOCK 1 +#define HAVE_DLFCN_H 1 -+#define HAVE_EVENTFD 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_NFDS_T 1 -+#define HAVE_PIPE2 1 -+#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1 -+#define HAVE_PTHREAD_SETNAME_NP 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 @@ -23,7 +14,6 @@ +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TYPES_H 1 -+#define HAVE_TIMERFD 1 +#define HAVE_UNISTD_H 1 +#define LT_OBJDIR ".libs/" +#define PACKAGE "libusb-1.0" @@ -38,6 +28,20 @@ +#define STDC_HEADERS 1 +#define VERSION "1.0.26" +#define _GNU_SOURCE 1 ++#if defined(__APPLE__) ++#define HAVE_PTHREAD_THREADID_NP 1 ++#elif defined(__linux__) ++#define HAVE_ASM_TYPES_H 1 ++#define HAVE_DECL_EFD_CLOEXEC 1 ++#define HAVE_DECL_EFD_NONBLOCK 1 ++#define HAVE_DECL_TFD_CLOEXEC 1 ++#define HAVE_DECL_TFD_NONBLOCK 1 ++#define HAVE_EVENTFD 1 ++#define HAVE_PIPE2 1 ++#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1 ++#define HAVE_PTHREAD_SETNAME_NP 1 ++#define HAVE_TIMERFD 1 ++#endif +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/protocol/dfu_hostcmd.c b/protocol/dfu_hostcmd.c index 24d9a50..bad5f6a 100644 --- a/protocol/dfu_hostcmd.c +++ b/protocol/dfu_hostcmd.c @@ -20,9 +20,8 @@ #include "protocol/status.h" static int generate_random_nonce(struct hoth_dfu_session_id* session_id) { - ssize_t ret = getrandom(&session_id->nonce, sizeof(session_id->nonce), 0); - if (ret == -1) { - perror("getrandom"); + if (getentropy(&session_id->nonce, sizeof(session_id->nonce)) != 0) { + perror("getentropy"); return -1; } return 0; From 7badaa63dfeadd49723b82d8d6bde0cb6835c137 Mon Sep 17 00:00:00 2001 From: Michael Field Date: Fri, 25 Sep 2026 14:28:48 -0700 Subject: [PATCH 3/3] Add macOS CI workflow Add build-macos GitHub Actions job to build and run Bazel tests on macOS. Signed-off-by: Michael Field --- .github/workflows/main.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8c58d74..1184dc5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,3 +52,25 @@ jobs: - name: Bazel tests run: | bazel test ... + + build-macos: + runs-on: 'macos-15' + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + # No -Werror yet: format strings such as "%lx" for uint64_t and the + # upstream libusb darwin backend both emit warnings on macOS. + - name: Build with Bazel + run: | + bazel build ... + + - name: Smoke test htool + run: | + bazel-bin/examples/htool --version + + - name: Bazel tests + run: | + bazel test --test_output=errors ...