Modernize, merge ARM macOS support from @incidentist
This commit is contained in:
commit
e313b97dc3
5 files changed
+72
-77
No files matched your search
+8
-1
@@ -1 +1,8 @@
|
||||
build-novacomd-host/
|
||||
build-*
|
||||
*.swp
|
||||
*~
|
||||
tags
|
||||
TAGS
|
||||
*.orig
|
||||
cscope.*
|
||||
*.dSYM
|
||||
@@ -1,31 +1,47 @@
|
||||
novacomd
|
||||
========
|
||||
|
||||
A 2025 build of novacomd adapted for UNIX-like hosts using libusb-compat-0.1.
|
||||
A 2026 build of novacomd for UNIX-like hosts built on top of libusb-compat-0.1. novacomd runs as a daemon or service on the host and the device.
|
||||
|
||||
Before building:
|
||||
## Dependencies
|
||||
|
||||
*This command will vary depending on your distribution.*
|
||||
> doas xbps-install -Su libusb-compat-devel
|
||||
Building from source needs a C compiler (GCC or Clang), **GNU make**, and **libusb-compat-0.1**.
|
||||
|
||||
To build:
|
||||
Get a compiler:
|
||||
|
||||
* **macOS:** Apple's Clang and make come with the Xcode Command Line Tools (`xcode-select --install`).
|
||||
* **Linux:** install your distribution's build tools (`build-essential` on Debian/Ubuntu, `base-devel` on Arch, etc.).
|
||||
|
||||
Get libusb-compat-0.1:
|
||||
|
||||
| Platform | Command |
|
||||
| --- | --- |
|
||||
| macOS (Homebrew) | `brew install libusb-compat` |
|
||||
| Debian / Ubuntu | `sudo apt install libusb-dev` |
|
||||
| Fedora | `sudo dnf install libusb-compat-0.1-devel` |
|
||||
| Arch | `sudo pacman -S libusb-compat` |
|
||||
| Void | `doas xbps-install -Su libusb-compat-devel` |
|
||||
|
||||
(On Debian/Ubuntu the libusb-0.1 development package is named `libusb-dev`; `libusb-1.0-0-dev` is a legacy, unused package.)
|
||||
|
||||
## Building
|
||||
|
||||
> ./install-novacomd-linux.sh
|
||||
|
||||
_On machines with GCC 15 or later, the following command should be run instead:_
|
||||
To force a specific compiler, set `CC`, for example:
|
||||
|
||||
> CC="gcc -std=gnu17" ./install-novacomd-linux.sh
|
||||
|
||||
To install:
|
||||
To install, copy or symlink `build-novacomd-host/novacomd` to the `/bin` directory of your Palm SDK install (usually `/opt/nova/bin`).
|
||||
|
||||
*May not require privilege escalation depending on your install location.*
|
||||
> doas mv build-novacomd-host/* /YOUR/LOCATION/HERE/
|
||||
|
||||
novacomd runs as a daemon or service on the host and the device.
|
||||
> mv build-novacomd-host/novacomd /YOUR/LOCATION/HERE/
|
||||
|
||||

|
||||
|
||||
# Copyright and License Information
|
||||
Thanks to [incidentist](https://github.com/incidentist/novacomd) for the macOS build support.
|
||||
|
||||
## Copyright
|
||||
|
||||
Unless otherwise specified, all content, including all source code files
|
||||
and documentation files in this repository are:
|
||||
|
||||
+35
-62
@@ -1,24 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build and install novacomd (NotAlexNoyle's 2025 libusb-compat fork) on a UNIX-like host.
|
||||
# Build and (optionally) install novacomd -- NotAlexNoyle's 2025 libusb-compat fork.
|
||||
#
|
||||
# Run this from the novacomd source directory (the directory that holds the makefile), or
|
||||
# point it at that directory with $NOVACOMD_SRC or the first argument. With no privileges it
|
||||
# builds only. When run as root (e.g. via sudo or doas) it builds as the invoking
|
||||
# unprivileged user and then installs the resulting binary into $INSTALL_DIR so it lands on
|
||||
# PATH.
|
||||
# Run from the novacomd source dir, or point at it with $NOVACOMD_SRC or the first argument.
|
||||
# Unprivileged: builds only. As root (sudo/doas): builds as the invoking user, then installs.
|
||||
#
|
||||
# Environment overrides:
|
||||
# NOVACOMD_SRC novacomd source directory. Default: this script's directory.
|
||||
# CC C compiler, simple whitespace-separated form only (e.g. "gcc -std=gnu17").
|
||||
# Auto-set to "gcc -std=gnu17" on GCC >= 15 when unset. Quoted/escaped
|
||||
# arguments and compiler paths containing spaces are not supported.
|
||||
# INSTALL_DIR Install location for the novacomd binary. Default: /usr/local/bin
|
||||
# JOBS Parallel make jobs (positive integer). Default: detected CPU count.
|
||||
# NOVACOMD_SRC source directory (default: this script's directory)
|
||||
# CC C compiler (default: gcc/cc + -std=gnu17 when supported; whitespace-split, no quoted args)
|
||||
# INSTALL_DIR install location (default: /usr/local/bin)
|
||||
# JOBS parallel make jobs (default: CPU count)
|
||||
#
|
||||
# Exit status: 0 on success, non-zero on any failure.
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
# Exit status: 0 on success, non-zero on failure. Public domain.
|
||||
# Author: NotAlexNoyle (alexnoyle@icloud.com)
|
||||
|
||||
set -u
|
||||
@@ -31,78 +24,60 @@ log() { printf 'novacomd-install: %s\n' "$*"; }
|
||||
err() { printf 'novacomd-install: ERROR: %s\n' "$*" >&2; }
|
||||
die() { err "$*"; exit 1; }
|
||||
|
||||
# --- locate the source tree ------------------------------------------------
|
||||
# Precedence: $1, then $NOVACOMD_SRC, then this script's own (symlink-resolved) directory.
|
||||
# --- locate the source tree ---
|
||||
# Source precedence: argument 1, then $NOVACOMD_SRC, then this script's own directory.
|
||||
self="$(readlink -f -- "${BASH_SOURCE[0]}" 2>/dev/null || printf '%s' "${BASH_SOURCE[0]}")"
|
||||
script_dir="$(cd -- "$(dirname -- "$self")" >/dev/null 2>&1 && pwd -P)"
|
||||
src_dir="${1:-${NOVACOMD_SRC:-$script_dir}}"
|
||||
cd -- "$src_dir" >/dev/null 2>&1 || die "cannot enter novacomd source directory: $src_dir"
|
||||
src_dir="$(pwd -P)"
|
||||
|
||||
if [ ! -f makefile ] && [ ! -f Makefile ]; then
|
||||
die "no makefile in $src_dir -- pass the novacomd source directory as the first argument."
|
||||
fi
|
||||
[ -f makefile ] || [ -f Makefile ] || die "no makefile in $src_dir -- pass the source directory as the first argument."
|
||||
|
||||
# --- privilege model -------------------------------------------------------
|
||||
# The toolchain (compiler + make recipes) must never run as root. When invoked as root via
|
||||
# sudo or doas, drop to the invoking user for every toolchain call; refuse if that is not
|
||||
# possible. sudo exports SUDO_USER, doas exports DOAS_USER.
|
||||
# --- privilege model ---
|
||||
# The build toolchain must never run as root; when root, drop to the invoking user for every build step.
|
||||
orig_user="${SUDO_USER:-${DOAS_USER:-}}"
|
||||
builder_prefix=()
|
||||
if (( EUID == 0 )); then
|
||||
# Resolve the invoking user to a UID and require a real, non-root account (catches UID-0
|
||||
# aliases, not just the literal name "root").
|
||||
builder_uid="$(id -u "$orig_user" 2>/dev/null || true)"
|
||||
if [ -n "$orig_user" ] && [[ "$builder_uid" =~ ^[1-9][0-9]*$ ]] \
|
||||
&& command -v runuser >/dev/null 2>&1; then
|
||||
builder_uid="$(id -u "$orig_user" 2>/dev/null || true)" # require a real, non-root account (UID > 0)
|
||||
if [ -n "$orig_user" ] && [[ "$builder_uid" =~ ^[1-9][0-9]*$ ]] && command -v runuser >/dev/null 2>&1; then
|
||||
builder_prefix=(runuser -u "$orig_user" --)
|
||||
else
|
||||
die "refusing to run the build toolchain as root. Run this script as a normal user; \
|
||||
it will only ask for elevation to install."
|
||||
die "refusing to build as root -- run as a normal user; elevation is only used to install."
|
||||
fi
|
||||
fi
|
||||
as_builder() { "${builder_prefix[@]}" "$@"; }
|
||||
|
||||
# --- preflight: build tools ------------------------------------------------
|
||||
command -v make >/dev/null 2>&1 \
|
||||
|| die "'make' not found. Install your distribution's build tools (build-essential / base-devel)."
|
||||
# --- preflight: build tools ---
|
||||
command -v make >/dev/null 2>&1 || die "'make' not found -- install your build tools (build-essential / base-devel)."
|
||||
|
||||
# --- compiler selection ----------------------------------------------------
|
||||
# GCC 15 defaults to C23, which rejects this older code; pin gnu17 there.
|
||||
# --- compiler selection ---
|
||||
# Default the compiler when CC is unset, and add -std=gnu17 only if accepted (C23-default compilers need it).
|
||||
if [ -z "${CC:-}" ]; then
|
||||
if command -v gcc >/dev/null 2>&1; then
|
||||
gcc_ver="$(as_builder gcc -dumpfullversion -dumpversion 2>/dev/null)"
|
||||
gcc_major="${gcc_ver%%.*}"
|
||||
case "$gcc_major" in
|
||||
''|*[!0-9]*) : ;; # unknown format -> leave CC unset
|
||||
*) [ "$gcc_major" -ge 15 ] && CC="gcc -std=gnu17" ;;
|
||||
esac
|
||||
if command -v gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi
|
||||
if printf 'int main(void){return 0;}\n' | as_builder $CC -std=gnu17 -fsyntax-only -xc - >/dev/null 2>&1; then
|
||||
CC="$CC -std=gnu17"
|
||||
fi
|
||||
fi
|
||||
CC="${CC:-cc}"
|
||||
|
||||
# CC may carry flags ("gcc -std=gnu17"); split into an argv array for direct invocation.
|
||||
# Split CC ("gcc -std=gnu17") into an argv array, then confirm a compiler is set and exists.
|
||||
read -r -a cc_argv <<<"$CC"
|
||||
[ "${#cc_argv[@]}" -gt 0 ] || die "CC is empty -- set it to a C compiler, e.g. CC=gcc."
|
||||
command -v "${cc_argv[0]}" >/dev/null 2>&1 || die "C compiler not found: ${cc_argv[0]}"
|
||||
|
||||
# --- preflight: libusb-compat header ---------------------------------------
|
||||
# The host transport needs libusb-compat-0.1 (<usb.h>). Probe early for a clear message.
|
||||
if ! printf '#include <usb.h>\nint main(void){return 0;}\n' \
|
||||
| as_builder "${cc_argv[@]}" -fsyntax-only -xc - >/dev/null 2>&1; then
|
||||
die "could not compile a <usb.h> probe -- the libusb-compat-0.1 dev headers are most likely
|
||||
missing. Install them, e.g.:
|
||||
# --- preflight: libusb-compat header ---
|
||||
# The host transport needs libusb-compat-0.1 (<usb.h>); probe for it up front for a clear message.
|
||||
if ! printf '#include <usb.h>\nint main(void){return 0;}\n' | as_builder "${cc_argv[@]}" -fsyntax-only -xc - >/dev/null 2>&1; then
|
||||
die "missing libusb-compat-0.1 (<usb.h>). Install it, e.g.:
|
||||
Debian/Ubuntu: sudo apt install libusb-dev
|
||||
Fedora: sudo dnf install libusb-compat-0.1-devel
|
||||
Void: doas xbps-install -Su libusb-compat-devel
|
||||
Arch: sudo pacman -S libusb-compat"
|
||||
fi
|
||||
|
||||
# --- build -----------------------------------------------------------------
|
||||
# Validate JOBS and neutralize inherited make flags so the build cannot be turned into a
|
||||
# no-op (e.g. JOBS or MAKEFLAGS carrying -n/--version, which would exit 0 without building).
|
||||
if [ -z "${JOBS:-}" ]; then
|
||||
JOBS="$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)"
|
||||
fi
|
||||
# --- build ---
|
||||
# Default JOBS to the CPU count, and clear inherited make flags that could turn the build into a no-op.
|
||||
[ -n "${JOBS:-}" ] || JOBS="$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)"
|
||||
[[ "$JOBS" =~ ^[1-9][0-9]*$ ]] || JOBS=1
|
||||
unset MAKEFLAGS MFLAGS GNUMAKEFLAGS MAKEFILES
|
||||
|
||||
@@ -111,8 +86,7 @@ as_builder make -j"$JOBS" CC="$CC" host || die "build failed -- see the compiler
|
||||
[ -f "$BUILD_BIN" ] && [ -x "$BUILD_BIN" ] || die "build reported success but $BUILD_BIN is missing."
|
||||
log "build succeeded: $BUILD_BIN"
|
||||
|
||||
# --- install ---------------------------------------------------------------
|
||||
# Only attempt the system install when running with the privilege for it.
|
||||
# --- install (root only) ---
|
||||
if (( EUID == 0 )); then
|
||||
dest="$INSTALL_DIR/$TARGET"
|
||||
[ -d "$dest" ] && die "install destination is a directory: $dest"
|
||||
@@ -122,9 +96,8 @@ if (( EUID == 0 )); then
|
||||
[ -f "$dest" ] && [ -x "$dest" ] || die "post-install check failed: $dest"
|
||||
log "installed: $dest"
|
||||
else
|
||||
# Build-only run: suggest the right elevation tool for a manual install (doas or sudo).
|
||||
elevate="sudo"
|
||||
command -v doas >/dev/null 2>&1 && elevate="doas"
|
||||
# Not root: print the manual install command using whichever elevation tool is available.
|
||||
if command -v doas >/dev/null 2>&1; then elevate="doas"; else elevate="sudo"; fi
|
||||
log "not running as root -- skipping install."
|
||||
log "to install: $elevate install -T -m 0755 '$src_dir/$BUILD_BIN' '$INSTALL_DIR/$TARGET'"
|
||||
fi
|
||||
|
||||
@@ -39,7 +39,7 @@ CFLAGS :=
|
||||
ifneq ($(MACHINE),)
|
||||
MYCFLAGS += -DMACHINE=\"$(MACHINE)\"
|
||||
endif
|
||||
HOSTCFLAGS := $(MYCFLAGS) $(CFLAGS) -Isrc
|
||||
HOSTCFLAGS := $(MYCFLAGS) $(CFLAGS) -Isrc -DPLATFORM_PTHREADS=1
|
||||
DEVICECFLAGS := $(MYCFLAGS) $(OECFLAGS) $(TARGET_CC_ARCH) -DPLATFORM_PTHREADS=1
|
||||
CPPFLAGS := -g
|
||||
ASMFLAGS :=
|
||||
@@ -62,7 +62,7 @@ DEVICELD := arm-none-linux-gnueabi-ld
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(UNAME),Linux)
|
||||
ifeq ($(UNAME), $(filter $(UNAME), Linux Darwin))
|
||||
LDFLAGS += -Wl,-rpath,. # add the local path to the program's search path
|
||||
HOSTLDLIBS += -lpthread -lusb
|
||||
HOSTPLATFORM := pthreads
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <log.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <linux/usbdevice_fs.h>
|
||||
#include "../novacom/mux.h"
|
||||
#include "device_list.h"
|
||||
|
||||
|
||||
Reference in new issue
Block a user