From ef6e6f492542890c1bbe8e029c6202c96a06ae50 Mon Sep 17 00:00:00 2001 From: Kevin Bradenstein Date: Sat, 5 Sep 2026 10:05:48 +0200 Subject: [PATCH] cmake: let the argp probe pass where argp-standalone needs strchrnul On macOS with Homebrew's argp-standalone, Findargp's link test for argp_parse fails with an undefined strchrnul, because libargp.a itself references that GNU extension and the platform has none. The module then stops with "does not have a symbol named argp_parse", which is not what is wrong. Probe for strchrnul first (with _GNU_SOURCE, so glibc answers correctly). Where it exists, the test is unchanged. Where it is missing, run the same argp_parse test with a local definition of strchrnul, and have ptouch-print supply that definition for the real build. On glibc nothing changes: the probe finds strchrnul and the original test runs. Checked on Debian stable in the same session. --- CMakeLists.txt | 5 +++++ cmake/Findargp.cmake | 26 +++++++++++++++++++++++++- src/ptouch-print.c | 10 ++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fad9240..c125f42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,11 @@ find_package(Git REQUIRED) find_package(PkgConfig REQUIRED) find_package(Intl REQUIRED) find_package(argp REQUIRED) +if(NOT ARGP_IN_LIBC AND NOT HAVE_STRCHRNUL) + # See cmake/Findargp.cmake: argp-standalone needs a strchrnul() the + # platform does not have, so ptouch-print.c defines one. + add_compile_definitions(NEED_STRCHRNUL=1) +endif() pkg_check_modules(LIBUSB REQUIRED libusb-1.0) diff --git a/cmake/Findargp.cmake b/cmake/Findargp.cmake index 2992977..2b13da1 100644 --- a/cmake/Findargp.cmake +++ b/cmake/Findargp.cmake @@ -62,9 +62,33 @@ if (ARGP_INCLUDE_PATH) # Check if argp_parse is available. Some implementations don't have this # symbol defined, thus they're not compatible. + # + # argp-standalone itself calls strchrnul(), a GNU extension that the + # platforms needing argp-standalone tend to lack (macOS among them). On + # those the plain link test fails with an undefined strchrnul and would + # report a perfectly good libargp as lacking argp_parse. So probe for + # strchrnul first and, where it is missing, run the argp_parse test with + # a local definition; the project then supplies the same definition. if (ARGP_LIBRARIES) set(CMAKE_REQUIRED_LIBRARIES "${ARGP_LIBRARIES}") - check_function_exists("argp_parse" ARGP_EXTERNAL) + include(CheckSymbolExists) + set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) + check_symbol_exists("strchrnul" "string.h" HAVE_STRCHRNUL) + unset(CMAKE_REQUIRED_DEFINITIONS) + if (HAVE_STRCHRNUL) + check_function_exists("argp_parse" ARGP_EXTERNAL) + else () + include(CheckCSourceCompiles) + check_c_source_compiles(" + #include + #include + char *strchrnul(const char *s, int c) { + const char *p = strchr(s, c); + return (char *)(p ? p : s + strlen(s)); + } + int main(void) { return argp_parse(0, 1, (char *[]){\"x\"}, 0, 0, 0); } + " ARGP_EXTERNAL) + endif () if (NOT ARGP_EXTERNAL) message(FATAL_ERROR "Your system ships an argp library in " "${ARGP_LIBRARIES}, but it does not have a symbol " diff --git a/src/ptouch-print.c b/src/ptouch-print.c index 5a8e81c..54a4feb 100644 --- a/src/ptouch-print.c +++ b/src/ptouch-print.c @@ -35,6 +35,16 @@ #define _(s) gettext(s) +#ifdef NEED_STRCHRNUL +/* GNU extension. argp-standalone references it, so platforms that need + argp-standalone need this too. Selected by cmake/Findargp.cmake. */ +char *strchrnul(const char *s, int c) +{ + const char *p = strchr(s, c); + return (char *)(p ? p : s + strlen(s)); +} +#endif + #define MAX_LINES 4 /* this should be calculated depending on tape size */ #define P_NAME "ptouch-print"