Commit 3e3096533e for asterisk.org

commit 3e3096533e3127155c9d4a2e6846ffdcb212beaf
Author: Prashant Srivastav <p_srivastav@outlook.com>
Date:   Thu Feb 5 12:50:06 2026 +0800

    fix: Add macOS (Darwin) compatibility for building Asterisk

    - Makefile: Skip /usr/lib/bundle1.o on modern macOS (doesn't exist)
    - Makefile.rules: Skip -fno-partial-inlining for clang (gcc-only flag)
    - include/asterisk/utils.h: Use asterisk/endian.h instead of <endian.h>
    - main/Makefile: Add Darwin-specific pjproject linking with -force_load
    - main/strcompat.c: Include poll-compat.h, use ast_poll()
    - main/xml.c: Add ASTMM_LIBC ASTMM_IGNORE for libxml2 compatibility
    - res/res_pjsip/config_transport.c: Define TCP keepalive constants for macOS

    Tested on macOS Darwin 25.2.0 (Apple Silicon ARM64)

diff --git a/Makefile b/Makefile
index f0954ba7de..14dba04a25 100644
--- a/Makefile
+++ b/Makefile
@@ -289,7 +289,9 @@ MOD_SUBDIRS_MENUSELECT_TREE:=$(MOD_SUBDIRS:%=%-menuselect-tree)
 ifneq ($(findstring darwin,$(OSARCH)),)
   _ASTCFLAGS+=-D__Darwin__ -mmacosx-version-min=10.6
   _SOLINK=-mmacosx-version-min=10.6 -Wl,-undefined,dynamic_lookup
-  _SOLINK+=/usr/lib/bundle1.o
+  ifneq ($(wildcard /usr/lib/bundle1.o),)
+    _SOLINK+=/usr/lib/bundle1.o
+  endif
   SOLINK=-bundle $(_SOLINK)
   DYLINK=-Wl,-dylib $(_SOLINK)
   _ASTLDFLAGS+=-L/usr/local/lib
diff --git a/Makefile.rules b/Makefile.rules
index 7319a1a6bb..f090676f6d 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -71,7 +71,9 @@ ifneq ($(findstring darwin,$(OSARCH)),)
   endif
 endif

+# Only apply -fno-partial-inlining for real GCC, not clang masquerading as gcc
 ifeq ($(CC),gcc)
+  ifeq ($(AST_CLANG_BLOCKS),)
     # gcc version 8.2.1 and above must have partial-inlining disabled in order
     # to avoid a documented bug. Sort to make the lowest version number come
     # first. If it's the specified version then the current gcc version is equal
@@ -79,7 +81,8 @@ ifeq ($(CC),gcc)
     gcc_versions=$(shell printf "%s\n" $$(gcc -dumpversion) 8.2.1 | sort -n)
     ifeq ($(firstword $(gcc_versions)),8.2.1)
         OPTIMIZE+=-fno-partial-inlining
-	endif
+    endif
+  endif
 endif

 ifeq ($(findstring DONT_OPTIMIZE,$(MENUSELECT_CFLAGS))$(findstring CODE_COVERAGE,$(MENUSELECT_CFLAGS))$(findstring CODE_PROFILE,$(MENUSELECT_CFLAGS))$(AST_CODE_COVERAGE),no)
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index 4888f4696d..b34fce167c 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -28,7 +28,7 @@
 #include <time.h>	/* we want to override localtime_r */
 #include <unistd.h>
 #include <string.h>
-#include <endian.h>
+#include "asterisk/endian.h"

 #include "asterisk/lock.h"
 #include "asterisk/time.h"
diff --git a/main/Makefile b/main/Makefile
index f835c008f1..a91fe8708a 100644
--- a/main/Makefile
+++ b/main/Makefile
@@ -73,7 +73,9 @@ endif
 ifneq ($(findstring darwin,$(OSARCH)),)
   AST_LIBS+=-lresolv
   ASTLINK=-mmacosx-version-min=10.6 -Wl,-undefined,dynamic_lookup -force_flat_namespace
-  ASTLINK+=/usr/lib/bundle1.o
+  ifneq ($(wildcard /usr/lib/bundle1.o),)
+    ASTLINK+=/usr/lib/bundle1.o
+  endif
 else
 # These are used for all but Darwin
   ASTLINK+=-Wl,--export-dynamic
@@ -307,11 +309,28 @@ $(ASTPJ_LIB): $(ASTPJ_LIB).$(ASTPJ_SO_VERSION)
 else # Darwin
 ASTPJ_LIB:=libasteriskpj.dylib

+# Darwin-specific: use -force_load to include all symbols from static archives
+# This is equivalent to GNU ld's --whole-archive
+PJPROJECT_SRCDIR := $(ASTTOPDIR)/third-party/pjproject/source
+PJ_TARGET := aarch64-apple-darwin25.2.0
+PJPROJECT_DARWIN_LIBS := \
+-force_load $(PJPROJECT_SRCDIR)/pjsip/lib/libpjsua-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjsip/lib/libpjsip-ua-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjsip/lib/libpjsip-simple-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjsip/lib/libpjsip-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjnath/lib/libpjnath-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjmedia/lib/libpjmedia-codec-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjmedia/lib/libpjmedia-videodev-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjmedia/lib/libpjmedia-audiodev-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjmedia/lib/libpjmedia-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjlib-util/lib/libpjlib-util-$(PJ_TARGET).a \
+-force_load $(PJPROJECT_SRCDIR)/pjlib/lib/libpj-$(PJ_TARGET).a
+
 # -install_name allows library to be found if installed somewhere other than
 # /lib or /usr/lib
-$(ASTPJ_LIB): _ASTLDFLAGS+=-dynamiclib -install_name $(ASTLIBDIR)/$(ASTPJ_LIB) $(PJ_LDFLAGS)
+$(ASTPJ_LIB): _ASTLDFLAGS+=-dynamiclib -install_name $(ASTLIBDIR)/$(ASTPJ_LIB)
 $(ASTPJ_LIB): _ASTCFLAGS+=-fPIC -DAST_MODULE=\"asteriskpj\" $(PJ_CFLAGS) -DAST_NOT_MODULE
-$(ASTPJ_LIB): LIBS+=$(PJPROJECT_LIB) $(OPENSSL_LIB) $(UUID_LIB) -lm -lpthread $(RT_LIB)
+$(ASTPJ_LIB): LIBS+=$(PJPROJECT_DARWIN_LIBS) $(OPENSSL_LIB) $(UUID_LIB) -lm -lpthread $(RT_LIB) -framework Foundation -framework AppKit
 $(ASTPJ_LIB): SOLINK=$(DYLINK)

 # Special rules for building a shared library (not a dynamically loadable module)
diff --git a/main/strcompat.c b/main/strcompat.c
index 877c11c00f..d0285318ff 100644
--- a/main/strcompat.c
+++ b/main/strcompat.c
@@ -37,6 +37,7 @@
 #include <fcntl.h>          /* for fcntl(2) */

 #include "asterisk/utils.h"
+#include "asterisk/poll-compat.h"

 #define POLL_SIZE 1024

@@ -471,7 +472,7 @@ void closefrom(int n)
 			fds[i].fd = fd+i;
 			fds[i].events = 0;
 		}
-		poll(fds, loopmax, 0);
+		ast_poll(fds, loopmax, 0);
 		for (i = 0; i < loopmax; i++) {
 			if (fds[i].revents == POLLNVAL) {
 				continue;
diff --git a/main/xml.c b/main/xml.c
index c3182aa4dc..fd3c959daa 100644
--- a/main/xml.c
+++ b/main/xml.c
@@ -25,6 +25,7 @@
 	<support_level>core</support_level>
  ***/

+#define ASTMM_LIBC ASTMM_IGNORE
 #include "asterisk.h"
 #include "asterisk/xml.h"
 #include "asterisk/logger.h"
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index 2acf9a9312..8be07187d0 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -22,6 +22,20 @@
 #include <pjsip.h>
 #include <pjlib.h>

+/* macOS compatibility for TCP keepalive options */
+#ifdef __APPLE__
+#include <netinet/tcp.h>
+#ifndef TCP_KEEPIDLE
+#define TCP_KEEPIDLE TCP_KEEPALIVE
+#endif
+#ifndef TCP_KEEPINTVL
+#define TCP_KEEPINTVL 0x101  /* macOS doesn't support this, use dummy value */
+#endif
+#ifndef TCP_KEEPCNT
+#define TCP_KEEPCNT 0x102    /* macOS doesn't support this, use dummy value */
+#endif
+#endif
+
 #include "asterisk/res_pjsip.h"
 #include "asterisk/res_pjsip_cli.h"
 #include "asterisk/logger.h"