2026-06-10 20:30:10 +05:30
# AsciiCam cross-platform build
# Supports:
2026-06-19 12:21:35 +05:30
# Linux x86_64 (gcc, nolibc, V4L2)
# macOS ARM64 (clang, system libc, AVFoundation)
# macOS x86_64 (clang, system libc, AVFoundation)
# Windows (gcc, ststem libc, MinGW-w64)
2026-06-08 15:51:46 +05:30
UNAME_S := $( shell uname -s)
2026-06-10 20:30:10 +05:30
UNAME_M := $( shell uname -m)
2026-06-08 15:51:46 +05:30
i f e q ( $( UNAME_S ) , L i n u x )
2026-06-10 20:30:10 +05:30
PLATFORM := linux
CC := gcc
LD := gcc
2026-06-08 15:51:46 +05:30
e l s e i f e q ( $( UNAME_S ) , D a r w i n )
2026-06-10 20:30:10 +05:30
PLATFORM := macos
CC := clang
LD := clang
OBJC := clang
2026-06-19 12:21:35 +05:30
e l s e i f n e q ( , $( filter MINGW % MSYS %,$ ( UNAME_S ) ) )
PLATFORM := windows
CC := gcc
LD := gcc
2026-06-10 20:30:10 +05:30
e l s e
$( error Unsupported platform: $( UNAME_S) )
e n d i f
SRCDIR := src
LIBDIR := lib
FILTERDIR := filters
BUILDDIR := build
OBJDIR := $( BUILDDIR) /obj
2026-06-17 15:52:43 +05:30
CFLAGS_COMMON := -Wall -Wextra -O2 -Iinclude -I$( LIBDIR) -fno-stack-protector -fno-builtin -ffreestanding
2026-06-10 20:30:10 +05:30
i f e q ( $( PLATFORM ) , l i n u x )
# Linux: nolibc, V4L2, SSE4.1
CFLAGS := $( CFLAGS_COMMON) -DPLATFORM_LINUX -D__LINUX_NOLIBC__
CFLAGS += -msse4.1
2026-06-17 15:52:43 +05:30
LDFLAGS := -nostdlib -nostdinc
2026-06-10 20:30:10 +05:30
LDFLAGS += -Wl,--no-as-needed
LDFLAGS += -Wl,-dynamic-linker,/lib64/ld-linux-x86-64.so.2
LDFLAGS += -L/usr/lib/x86_64-linux-gnu # TEST: Explicit library paths
# LDFLAGS += -Wl,-rpath-link=/usr/lib/x86_64-linux-gnu
2026-06-17 15:52:43 +05:30
LDFLAGS += -ldl -lpthread -lc # FIX: lc flag pulls standard libc,but removing them will -lpthread and -ldl will fail to link because they themselves depend on libc
# TODO: custom threading library using clone() + futex to eliminate -lpthread (pthread functions) dependency
# TODO: implement an ELF loader (or statically link plugins) to eliminate -ldl (dlopen/dlsym/dlclose are part of libdl.so also glibc) dependency
2026-06-10 20:30:10 +05:30
LDFLAGS += -msse4.1
LIBSRCS := $( LIBDIR) /nl_alloc.c \
$( LIBDIR) /nl_errno.c \
$( LIBDIR) /nl_getopt.c \
$( LIBDIR) /nl_printf.c \
$( LIBDIR) /nl_start.c
PLAT_SRC := $( SRCDIR) /capture_linux.c
# Plugin shared objects
SO_EXT := so
SO_FLAGS := -fPIC -shared
e l s e i f e q ( $( PLATFORM ) , m a c o s )
# macOS: system libc + AVFoundation, supports ARM64 + x86_64
CFLAGS := $( CFLAGS_COMMON) -DPLATFORM_MACOS
OBJCFLAGS:= $( CFLAGS) -x objective-c \
-fobjc-arc \
-fmodules
ifeq ( $( UNAME_M) ,arm64)
CFLAGS += -arch arm64
LDFLAGS := -arch arm64
else
CFLAGS += -arch x86_64 -msse4.1
LDFLAGS := -arch x86_64
endif
LDFLAGS += -framework AVFoundation \
-framework CoreMedia \
-framework CoreVideo \
-framework Foundation \
-lpthread
# TODO: Update nolibc for macos support instead of system system libc, currently :
# No nolibc on macOS, uses system libc
LIBSRCS :=
PLAT_SRC := $( SRCDIR) /capture_macos.m
# Plugin shared objects
SO_EXT := dylib
SO_FLAGS := -dynamiclib
2026-06-19 12:21:35 +05:30
e l s e i f e q ( $( PLATFORM ) , w i n d o w s )
# Windows: system libc (MSVCRT via MinGW), Media Foundation.
CFLAGS := $( CFLAGS_COMMON) -DPLATFORM_WINDOWS -DWIN32_LEAN_AND_MEAN \
-DUNICODE -D_UNICODE \
-msse4.1
CFLAGS := $( filter-out -ffreestanding -fno-builtin,$( CFLAGS) )
LDFLAGS := -lmfplat -lmf -lmfreadwrite -lmfuuid -lole32 \
-loleaut32 -luuid -lstrmiids
# TODO: Update nolibc for windows support instead of system system libc, currently :
# No nolibc on Windows, uses system libc
LIBSRCS :=
PLAT_SRC := $( SRCDIR) /capture_windows.c
# Plugin shared objects
SO_EXT := dll
SO_FLAGS := -shared
2026-06-08 15:51:46 +05:30
e n d i f
2026-05-13 22:18:22 +05:30
2026-06-10 20:30:10 +05:30
CORE_SRCS := $( SRCDIR) /ascii.c \
$( SRCDIR) /main.c \
$( SRCDIR) /plugins.c \
$( SRCDIR) /thread_sharing.c \
$( SRCDIR) /timing.c
ALL_C_SRCS := $( CORE_SRCS) $( PLAT_SRC) $( LIBSRCS)
2026-05-13 22:18:22 +05:30
2026-06-10 20:30:10 +05:30
OBJECTS := $( patsubst $( SRCDIR) /%.c, $( OBJDIR) /%.o, $( CORE_SRCS) )
OBJECTS += $( patsubst $( SRCDIR) /%.c, $( OBJDIR) /%.o, $( filter $( SRCDIR) /%.c, $( PLAT_SRC) ) )
OBJECTS += $( patsubst $( SRCDIR) /%.m, $( OBJDIR) /%.o, $( filter $( SRCDIR) /%.m, $( PLAT_SRC) ) )
OBJECTS += $( patsubst $( LIBDIR) /%.c, $( OBJDIR) /lib_%.o, $( LIBSRCS) )
2026-05-13 22:18:22 +05:30
2026-06-10 20:30:10 +05:30
TARGET := $( BUILDDIR) /webcam_ascii
2026-05-13 22:18:22 +05:30
2026-06-10 20:30:10 +05:30
# Plugins
PLUGIN_SRCS := $( wildcard $( FILTERDIR) /*.c)
PLUGIN_TARGETS := $( patsubst $( FILTERDIR) /%.c, $( BUILDDIR) /%.$( SO_EXT) , $( PLUGIN_SRCS) )
.PHONY : all clean plugins info
2026-05-13 22:18:22 +05:30
2026-05-25 13:50:49 +05:30
all : $( TARGET ) plugins
2026-06-10 20:30:10 +05:30
$(TARGET) : $( OBJECTS ) | $( BUILDDIR )
$( LD) $^ -o $@ $( LDFLAGS)
@echo " LD $@ ( $( PLATFORM) / $( UNAME_M) ) "
2026-05-13 22:18:22 +05:30
2026-06-10 20:30:10 +05:30
# Compile .c
2026-05-13 22:18:22 +05:30
$(OBJDIR)/%.o : $( SRCDIR ) /%.c | $( OBJDIR )
$( CC) $( CFLAGS) -c $< -o $@
2026-06-10 20:30:10 +05:30
# Compile .m (Objective-C for macOS capture)
$(OBJDIR)/%.o : $( SRCDIR ) /%.m | $( OBJDIR )
$( OBJC) $( OBJCFLAGS) -c $< -o $@
2026-05-13 22:18:22 +05:30
2026-06-10 20:30:10 +05:30
# Compile nolibc (Linux only)
$(OBJDIR)/lib_%.o : $( LIBDIR ) /%.c | $( OBJDIR )
$( CC) $( CFLAGS) -c $< -o $@
# Plugins
2026-06-01 23:21:32 +05:30
plugins : $( PLUGIN_TARGETS )
2026-05-25 13:50:49 +05:30
2026-06-10 20:30:10 +05:30
$(BUILDDIR)/%.$(SO_EXT) : $( FILTERDIR ) /%.c | $( BUILDDIR )
i f e q ( $( PLATFORM ) , l i n u x )
$( CC) $( CFLAGS) $( SO_FLAGS) $< -o $@ .tmp && mv $@ .tmp $@
e l s e
$( CC) $( CFLAGS) $( SO_FLAGS) $< -o $@ \
-undefined dynamic_lookup
e n d i f
2026-05-25 13:50:49 +05:30
2026-06-10 20:30:10 +05:30
$(OBJDIR) :
mkdir -p $( OBJDIR)
2026-05-25 13:50:49 +05:30
$(BUILDDIR) :
mkdir -p $( BUILDDIR)
2026-05-13 22:18:22 +05:30
clean :
2026-05-19 17:28:19 +05:30
rm -rf $( BUILDDIR)
2026-06-10 20:30:10 +05:30
info :
@echo " Platform : $( PLATFORM) "
@echo " Arch : $( UNAME_M) "
@echo " CC : $( CC) "
@echo " CFLAGS : $( CFLAGS) "
@echo " LDFLAGS : $( LDFLAGS) "
@echo " Objects : $( OBJECTS) "