diff --git a/project/common.mk b/project/common.mk
index a87d577..919d53a 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -71,6 +71,7 @@ INTERNAL_SRCS = \
 	src/internal/$(PACKAGE)_errinfo_impl.c \
 	src/internal/$(PACKAGE)_lconf_impl.c \
 	src/internal/$(PACKAGE)_libmeta_impl.c \
+	src/internal/$(PACKAGE)_m4fake_impl.c \
 	src/internal/$(PACKAGE)_mapfile_impl.c \
 	src/internal/$(PACKAGE)_objlist_impl.c \
 	src/internal/$(PACKAGE)_objmeta_impl.c \
diff --git a/project/headers.mk b/project/headers.mk
index f57eaae..6546375 100644
--- a/project/headers.mk
+++ b/project/headers.mk
@@ -14,6 +14,7 @@ INTERNAL_HEADERS = \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_install_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_lconf_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_linkcmd_impl.h \
+	$(PROJECT_DIR)/src/internal/$(PACKAGE)_m4fake_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_mapfile_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_metafile_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_mkdir_impl.h \
diff --git a/src/internal/slibtool_m4fake_impl.c b/src/internal/slibtool_m4fake_impl.c
new file mode 100644
index 0000000..4a46978
--- /dev/null
+++ b/src/internal/slibtool_m4fake_impl.c
@@ -0,0 +1,142 @@
+/*******************************************************************/
+/*  slibtool: a strong libtool implementation, written in C        */
+/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
+/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
+/*******************************************************************/
+
+#include <string.h>
+#include <limits.h>
+
+#include <slibtool/slibtool.h>
+#include "slibtool_driver_impl.h"
+#include "slibtool_snprintf_impl.h"
+#include "slibtool_errinfo_impl.h"
+#include "slibtool_visibility_impl.h"
+#include "slibtool_m4fake_impl.h"
+
+slbt_hidden int slbt_m4fake_expand_cmdarg(
+	struct slbt_driver_ctx *  dctx,
+	struct slbt_txtfile_ctx * sctx,
+	const char *              cmdname,
+	char                      (*argbuf)[PATH_MAX])
+{
+	const char **             pline;
+	size_t                    slen;
+	const char *              mark;
+	const char *              match;
+	const char *              cap;
+	int                       fquote;
+	char                      varbuf[PATH_MAX];
+	char                      strbuf[PATH_MAX];
+
+	memset(*argbuf,0,sizeof(*argbuf));
+
+	slen  = strlen(cmdname);
+	pline = sctx->txtlinev;
+	match = 0;
+
+	for (; !match && *pline; ) {
+		if (!strncmp(*pline,cmdname,slen)) {
+			if ((*pline)[slen] == '(') {
+				mark  = &(*pline)[slen];
+				cap   = ++mark;
+
+				for (fquote=0; !match && *cap; ) {
+					if (*cap == '[')
+						fquote++;
+
+					else if ((*cap == ']') && fquote)
+						fquote--;
+
+					else if ((*cap == ')') && !fquote)
+						match = cap;
+
+					if (!match)
+						cap++;
+				}
+
+				if (!match)
+					return SLBT_CUSTOM_ERROR(
+						dctx,
+						SLBT_ERR_FLOW_ERROR);
+			}
+		}
+
+		if (!match)
+			pline++;
+	}
+
+	if (!match)
+		return 0;
+
+	strncpy(strbuf,mark,cap-mark);
+	strbuf[cap-mark] = '\0';
+
+	mark = strbuf;
+	slen = strlen(mark);
+
+	if ((mark[0] == '[') && (mark[--slen] == ']')) {
+		strcpy(*argbuf,++mark);
+		(*argbuf)[--slen] = '\0';
+		return 0;
+	}
+
+	if (slbt_snprintf(
+			varbuf,sizeof(varbuf),
+			"AC_DEFUN([%s],",
+			strbuf) < 0)
+		return SLBT_BUFFER_ERROR(dctx);
+
+	slen = strlen(varbuf);
+
+	for (--pline; pline >= sctx->txtlinev; pline--) {
+		if (!strncmp(*pline,varbuf,slen)) {
+			mark  = &(*pline)[slen];
+			cap   = mark;
+			match = 0;
+
+			for (fquote=0; !match && *cap; ) {
+				if (*cap == '[')
+					fquote++;
+
+				else if ((*cap == ']') && fquote)
+					fquote--;
+
+				else if ((*cap == ')') && !fquote)
+					match = cap;
+
+				if (!match)
+					cap++;
+			}
+
+			if (!match)
+				return SLBT_CUSTOM_ERROR(
+					dctx,
+					SLBT_ERR_FLOW_ERROR);
+
+			strncpy(strbuf,mark,cap-mark);
+			strbuf[cap-mark] = '\0';
+
+			mark = strbuf;
+			slen = strlen(mark);
+
+			if ((mark[0] == '[') && (mark[--slen] == ']')) {
+				strcpy(*argbuf,++mark);
+				(*argbuf)[--slen] = '\0';
+				return 0;
+			}
+
+			if (slbt_snprintf(
+					varbuf,sizeof(varbuf),
+					"AC_DEFUN([%s],",
+					strbuf) < 0)
+				return SLBT_BUFFER_ERROR(dctx);
+
+			slen = strlen(varbuf);
+		}
+	}
+
+	strcpy(*argbuf,strbuf);
+
+	return 0;
+}
diff --git a/src/internal/slibtool_m4fake_impl.h b/src/internal/slibtool_m4fake_impl.h
new file mode 100644
index 0000000..af0de56
--- /dev/null
+++ b/src/internal/slibtool_m4fake_impl.h
@@ -0,0 +1,12 @@
+#ifndef SLIBTOOL_M4FAKE_IMPL_H
+#define SLIBTOOL_M4FAKE_IMPL_H
+
+#include <slibtool/slibtool.h>
+
+int slbt_m4fake_expand_cmdarg(
+	struct slbt_driver_ctx *  dctx,
+	struct slbt_txtfile_ctx * sctx,
+	const char *              cmdname,
+	char                      (*argbuf)[PATH_MAX]);
+
+#endif