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"