NLL_VERSION = 20251013a

################################
# To use nlcc1

CCOMPILER = cc
#CCOMPILER = gcc
#CCOMPILER = clang
#CCOMPILER = nlcc1

ARCH =
#ARCH = i386
#ARCH = x86_64

################################
# To use readline library

#READLINE = libedit
#READLINE = editline
#READLINE = readline
READLINE = nlline
#READLINE = getline
#READLINE = fgets

READLINEDIR = /usr/local

################################
# To use header files

STDCHEADERS =
#STDCHEADERS = freebsd
#STDCHEADERS = debian
#STDCHEADERS = nllibc

TERMHEADERS = $(STDCHEADERS)

################################
# To use nllibc

#USE_NLLIBC = yes
#USE_NLTERM = yes
#USE_NLCRT = yes
#NLLDSCR = i386
#NLLDSCR = x86_64
#NLLDSCR = arm

################################
# To use curses library

USE_CURSES = yes

#CURSESDIR = /usr/local

################################
# To use frame buffer

USE_FRAMEBUF = yes

################################
# To use SDL
# (SDL1 may need not to link as static)

USE_GRAPHIC = yes
USE_AUDIO = yes
#USE_SDL1 = $(USE_GRAPHIC)$(USE_AUDIO:$(USE_GRAPHIC)=)
USE_SDL2 = $(USE_GRAPHIC)$(USE_AUDIO:$(USE_GRAPHIC)=)
#USE_SDLSIXEL = $(USE_GRAPHIC)$(USE_AUDIO:$(USE_GRAPHIC)=)

# For MinGW (Use SDL2-devel-2.26.4-mingw.zip)
#SDLDIR = ../../SDL2-2.26.4/i686-w64-mingw32
SDLDIR = /usr/local

################################
# For cross compile

#CROSS = arm-elf
#CCDIR = /usr/local/cross2-gcc494
## Target is FreeBSD
##OSDEF = __FreeBSD__
##OSABI = FreeBSD
## Target is Linux
#OSDEF = __linux__
#OSABI = none
##OSABI = linux

################################
# To use MinGW

#MINGW = mingw32

################################
# To use floating point and math library

USE_FLOATING_POINT = yes

USE_MATHLIB_DEFAULT = yes
USE_MATHLIB = $(USE_MATHLIB_DEFAULT:$(USE_NLLIBC)=)

USE_MATHBUILTIN = yes

################################
# To use system function

USE_SYSTEM_FUNCTION = yes
USE_SYSCALL_FUNCTION = yes
USE_NETWORK_FUNCTION = yes

################################
# For static linking (shared object is not supported with nlcc)
# (SDL may need not to link as static)

#LINK_STATIC = yes

################################
# Build setting

TARGET = nll

NLL_VERSION ?= $(VERSION)

ASRCS =
CSRCS = main.c

LIBASRCS =
LIBCSRCS = nlllib.c readline.c line.c constval.c variable.c value.c formula.c \
	string.c command.c label.c position.c array.c area.c stack.c memory.c \
	function.c libprintf.c argument.c term.c key.c mouse.c fileid.c \
	queueid.c framebuf.c graphic.c image.c picture.c audio.c sound.c \
	sdl.c charset.c \
	charset-font8x8.c charset-font16x16.c charset-font5x5.c \
	charset-character.c charset-character_2.c charset-character_3.c \
	nll.c
LIBCSRCS += nllmain.c
LIBCSRCS += function-ext.c

LIB = libnll.a

MANUAL = nll.1

NLROOTDIR = ..

NLLINEDIR = $(NLROOTDIR)/nlline
NLLIBCDIR = $(NLROOTDIR)/nllibc

#INSTALLDIR = /usr/local
INSTALLDIR = $(NLROOTDIR)
INCDIR = $(INSTALLDIR)/include
BINDIR = $(INSTALLDIR)/bin
LIBDIR = $(INSTALLDIR)/lib
MANDIR = $(INSTALLDIR)/man/man1

################################
# End of setting

CPRES = $(CSRCS:.c=.i)
AASMS = $(ASRCS:.S=.s)
CASMS = $(CSRCS:.c=.s)
AOBJS = $(ASRCS:.S=.o)
COBJS = $(CSRCS:.c=.o)

LIBCPRES = $(LIBCSRCS:.c=.i)
LIBAASMS = $(LIBASRCS:.S=.s)
LIBCASMS = $(LIBCSRCS:.c=.s)
LIBAOBJS = $(LIBASRCS:.S=.o)
LIBCOBJS = $(LIBCSRCS:.c=.o)

SRCS = $(ASRCS) $(CSRCS)
PRES = $(CPRES)
ASMS = $(AASMS) $(CASMS)
OBJS = $(AOBJS) $(COBJS)

LIBSRCS = $(LIBASRCS) $(LIBCSRCS)
LIBPRES = $(LIBCPRES)
LIBASMS = $(LIBAASMS) $(LIBCASMS)
LIBOBJS = $(LIBAOBJS) $(LIBCOBJS)

ALLASRCS = $(ASRCS) $(LIBASRCS)
ALLCSRCS = $(CSRCS) $(LIBCSRCS)
ALLCPRES = $(CPRES) $(LIBCPRES)
ALLAASMS = $(AASMS) $(LIBAASMS)
ALLCASMS = $(CASMS) $(LIBCASMS)
ALLAOBJS = $(AOBJS) $(LIBAOBJS)
ALLCOBJS = $(COBJS) $(LIBCOBJS)

ALLSRCS = $(SRCS) $(LIBSRCS)
ALLPRES = $(PRES) $(LIBPRES)
ALLASMS = $(ASMS) $(LIBASMS)
ALLOBJS = $(OBJS) $(LIBOBJS)

POSTFIX = $(MINGW:$(MINGW)=.exe)

TARGET := $(TARGET)$(POSTFIX)

NLLINE = $(LIBDIR)/libnlline.a
NLLIBC = $(LIBDIR)/libnlc.a
#NLLIBC = $(LIBDIR)/nllibc.o
NLTERM = $(LIBDIR)/libnlterm.a
NLCRT = $(LIBDIR)/nlcrt.o

LIBS_READLINE_nlline = $(NLLINE)

LIBS  = $(LIBS_READLINE_$(READLINE))
LIBS += $(USE_NLLIBC:yes=$(NLLIBC)) $(USE_NLTERM:yes=$(NLTERM)) \
	$(USE_NLCRT:yes=$(NLCRT))

CRT = $(USE_NLCRT:yes=$(NLCRT))

PREFIX = $(CCDIR:$(CCDIR)=$(CCDIR)/bin/)$(CROSS:$(CROSS)=$(CROSS)-)$(MINGW:$(MINGW)=$(MINGW)-)

CC = $(PREFIX)$(CCOMPILER:nlcc1=cc)

CCOMPILER_cc = $(CC) -S -x c
CCOMPILER_gcc = $(CC) -S -x c
CCOMPILER_clang = $(CC) -S -x c
CCOMPILER_nlcc1 = nlbindir/nlcc1 -march=$(ARCH:-elf=)

CPP = $(CC) -E
_CC1 = $(CCOMPILER_$(CCOMPILER))
CC1 = $(_CC1:nlbindir/%=$(BINDIR)/%)
AS  = $(CC) -c
AR  = $(PREFIX)ar
LD  = $(PREFIX)ld

GFLAGS  = -O -Wall
GFLAGS += -g
#GFLAGS += -m32 # for 32bit executable
#GFLAGS += $(MINGW:$(MINGW)=-mwindows)
GFLAGS += $(GOPTFLAGS)

PFLAGS_STDCHEADERS_freebsd = -D__RUNETYPE_INTERNAL # for _ThreadRuneLocale
PFLAGS_STDCHEADERS_debian  = -D_BITS_FLOATN_H
PFLAGS_STDCHEADERS_debian += -U__GNUC__ # to avoid include stdio2.h
PFLAGS_STDCHEADERS_centos  = -D__signed__=signed
PFLAGS_STDCHEADERS_centos += -U__GNUC__ # to avoid __typeof() in stdlib.h
PFLAGS_STDCHEADERS_nllibc  = -nostdinc -I$(INCDIR)

PFLAGS_TERMHEADERS_nllibc = -I$(INCDIR)

PFLAGS_READLINE_libedit  = -DUSE_LIBEDIT $(READLINEDIR:$(READLINEDIR)=-I$(READLINEDIR)/include)
PFLAGS_READLINE_editline = -DUSE_EDITLINE $(READLINEDIR:$(READLINEDIR)=-I$(READLINEDIR)/include)
PFLAGS_READLINE_readline = -DUSE_READLINE $(READLINEDIR:$(READLINEDIR)=-I$(READLINEDIR)/include)
PFLAGS_READLINE_nlline   = -DUSE_NLLINE -I$(INCDIR)
PFLAGS_READLINE_getline  = -DUSE_GETLINE
PFLAGS_READLINE_fgets    = -DUSE_FGETS

PFLAGS  =
PFLAGS += -fno-inline
PFLAGS += -DNLL_VERSION=\"$(NLL_VERSION)\"
PFLAGS += $(PFLAGS_STDCHEADERS_$(STDCHEADERS))
PFLAGS += $(PFLAGS_TERMHEADERS_$(TERMHEADERS))
PFLAGS += $(PFLAGS_READLINE_$(READLINE))
PFLAGS += $(USE_NLLIBC:yes=-DUSE_NLLIBC -I$(INCDIR)/nllibc)
PFLAGS += $(USE_NLTERM:yes=-DUSE_NLTERM)
PFLAGS += $(USE_NLCRT:yes=-DUSE_NLCRT)
PFLAGS += $(USE_CURSES:yes=-DUSE_CURSES $(CURSESDIR:$(CURSESDIR)=-I$(CURSESDIR)/include))
PFLAGS += $(USE_FRAMEBUF:yes=-DUSE_FRAMEBUF)
PFLAGS += $(USE_GRAPHIC:yes=-DUSE_GRAPHIC)
PFLAGS += $(USE_AUDIO:yes=-DUSE_AUDIO)
PFLAGS += $(USE_SDL1:yes=-DUSE_SDL1 $(SDLDIR:$(SDLDIR)=-I$(SDLDIR)/include))
PFLAGS += $(USE_SDL2:yes=-DUSE_SDL2 $(SDLDIR:$(SDLDIR)=-I$(SDLDIR)/include))
PFLAGS += $(USE_SDLSIXEL:yes=-DUSE_SDLSIXEL -DUSE_SDL1 $(SDLDIR:$(SDLDIR)=-I$(SDLDIR)/include))
PFLAGS += $(CROSS:$(CROSS)=-DCROSS $(OSDEF:$(OSDEF)=-D$(OSDEF)))
PFLAGS += $(MINGW:$(MINGW)=-DMINGW)
PFLAGS += $(USE_FLOATING_POINT:yes=-DUSE_FLOATING_POINT)
PFLAGS += $(USE_MATHLIB:yes=-DUSE_MATHLIB)
PFLAGS += $(USE_MATHBUILTIN:yes=-DUSE_MATHBUILTIN)
PFLAGS += $(USE_SYSTEM_FUNCTION:yes=-DUSE_SYSTEM_FUNCTION)
PFLAGS += $(USE_SYSCALL_FUNCTION:yes=-DUSE_SYSCALL_FUNCTION)
PFLAGS += $(USE_NETWORK_FUNCTION:yes=-DUSE_NETWORK_FUNCTION)
PFLAGS += $(POPTFLAGS)

CFLAGS  =
CFLAGS += $(USE_NLLIBC:yes=-fno-builtin)
CFLAGS += $(USE_NLLIBC:yes=-fno-stack-protector)
CFLAGS += $(COPTFLAGS)

AFLAGS  =
AFLAGS += $(AOPTFLAGS)

LFLAGS_READLINE_libedit  = $(READLINEDIR:$(READLINEDIR)=-L$(READLINEDIR)/lib) -ledit
LFLAGS_READLINE_editline = $(READLINEDIR:$(READLINEDIR)=-L$(READLINEDIR)/lib) -leditline
LFLAGS_READLINE_readline = $(READLINEDIR:$(READLINEDIR)=-L$(READLINEDIR)/lib) -lreadline
LFLAGS_READLINE_nlline   = -L$(LIBDIR) -lnlline

LFLAGS  = -L. -lnll
LFLAGS += $(LINK_STATIC:yes=-static)
LFLAGS += $(LFLAGS_CCOMPILER_$(CCOMPILER))
LFLAGS += $(LFLAGS_READLINE_$(READLINE))
LFLAGS += $(USE_NLLIBC:yes=-L$(LIBDIR) -lnlc -nodefaultlibs)
LFLAGS += $(USE_NLTERM:yes=-L$(LIBDIR) -lnlterm)
LFLAGS += $(USE_NLCRT:yes=-nostartfiles)
LFLAGS += $(USE_CURSES:yes=$(CURSESDIR:$(CURSESDIR)=-L$(CURSESDIR)/lib) -lcurses)
#LFLAGS += $(USE_SDL1:yes=$(MINGW:$(MINGW)=-lmingw32 -lSDLmain  $(LINK_STATIC:yes=-lSDL.dll))  -lSDL  $(SDLDIR:$(SDLDIR)=-L$(SDLDIR)/lib))
#LFLAGS += $(USE_SDL2:yes=$(MINGW:$(MINGW)=-lmingw32 -lSDL2main $(LINK_STATIC:yes=-lSDL2.dll)) -lSDL2 $(SDLDIR:$(SDLDIR)=-L$(SDLDIR)/lib))
LFLAGS += $(USE_SDL1:yes=`$(SDLDIR:$(SDLDIR)=$(SDLDIR)/bin/)sdl-config  --$(LINK_STATIC:yes=static-)libs` $(MINGW:$(MINGW)=-mno-windows))
LFLAGS += $(USE_SDL2:yes=`$(SDLDIR:$(SDLDIR)=$(SDLDIR)/bin/)sdl2-config --$(LINK_STATIC:yes=static-)libs` $(MINGW:$(MINGW)=-mno-windows))
LFLAGS += $(USE_SDLSIXEL:yes=-lsixel $(SDLDIR:$(SDLDIR)=-L$(SDLDIR)/lib))
LFLAGS += $(NLLDSCR:$(NLLDSCR)=-Wl,-T$(LIBDIR)/ldscripts/ld.scr.$(NLLDSCR))
LFLAGS += $(MINGW:$(MINGW)=-lwsock32 -lws2_32)
LFLAGS += $(USE_MATHLIB:yes=-lm)
LFLAGS += $(LOPTFLAGS)

ARFLAGS = ruc
#ARFLAGS = rDc
ARFLAGS += $(AROPTFLAGS)

HANDOVER  =
HANDOVER += CCOMPILER=$(CCOMPILER) ARCH=$(ARCH)
HANDOVER += STDCHEADERS=$(STDCHEADERS) TERMHEADERS=$(TERMHEADERS)
HANDOVER += USE_NLLIBC=$(USE_NLLIBC) USE_NLTERM=$(USE_NLTERM)
HANDOVER += USE_NLCRT=$(USE_NLCRT)
#HANDOVER += USE_CURSES=$(USE_CURSES) CURSESDIR=$(CURSESDIR)
HANDOVER += CROSS=$(CROSS) CCDIR=$(CCDIR) OSDEF=$(OSDEF) OSABI=$(OSABI)
HANDOVER += MINGW=$(MINGW)
HANDOVER += HANDOVER_CC="$(CC)" HANDOVER_CPP="$(CPP)" HANDOVER_CC1="$(_CC1)"
HANDOVER += HANDOVER_AS="$(AS)" HANDOVER_AR="$(AR)" HANDOVER_LD="$(LD)"

.SUFFIXES:
.SUFFIXES: $(POSTFIX) .o .s .i .c .S
.PRECIOUS: $(ALLPRES) $(ALLASMS)

all :		nll.all

nll.all :	$(TARGET)

pres :		$(ALLPRES)

asms :		$(ALLASMS)

objs :		$(ALLOBJS)

.S.s :
		$(CPP) $(GFLAGS) $(PFLAGS) $< -o $@

.c.i :
		$(CPP) $(GFLAGS) $(PFLAGS) $< -o $@

.i.s :
		$(CC1) $(GFLAGS) $(CFLAGS) $< -o $@

.s.o :
		$(AS) $(GFLAGS) $(AFLAGS) $< -o $@
		$(OSABI:$(OSABI)=elfedit --output-osabi=$(OSABI) $@)

# clear default .c.o rule
# (useless because of priority definition of .SUFFIXES)

# for BSD make
.c.o :

# for GNU make
%.o :		%.c

lib :		$(LIB)

libs :		$(LIBS)

$(ALLCPRES) $(ALLAASMS) :	$(LIBS)

$(LIB) :	$(LIBOBJS)
		$(AR) $(ARFLAGS) $(LIB) $(LIBOBJS)
		$(OSABI:$(OSABI)=elfedit --output-osabi=$(OSABI) $@)

$(TARGET) :	$(OBJS) $(LIB) $(LIBS)
		$(CC) $(CRT) $(OBJS) $(GFLAGS) $(LFLAGS) -o $@
		$(OSABI:$(OSABI)=elfedit --output-osabi=$(OSABI) $@)

$(NLLINE) :
		$(MAKE) -C $(NLLINEDIR) $(HANDOVER) lib.all
		$(MAKE) -C $(NLLINEDIR) $(HANDOVER) lib.install

$(NLLIBC) :
		$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) lib.all
		$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) lib.install

$(NLTERM) :
		$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) term.all
		$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) term.install

$(NLCRT) :
		$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) crt.all
		$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) crt.install

install :	$(TARGET) $(MANUAL)
		mkdir -p $(BINDIR) $(MANDIR)
		cp $(TARGET) $(BINDIR)
		cp $(MANUAL) $(MANDIR)

uninstall :
		mkdir -p $(BINDIR) $(MANDIR)
		cd $(BINDIR) ; rm -f $(TARGET)
		cd $(MANDIR) ; rm -f $(MANUAL)

clean :		nll.clean

nll.clean :	pres.clean asms.clean objs.clean lib.clean libs.clean
		rm -f $(TARGET)

pres.clean :
		rm -f $(ALLPRES)

asms.clean :
		rm -f $(ALLASMS)

objs.clean :
		rm -f $(ALLOBJS)

lib.clean :
		rm -f $(LIB)

libs.clean :	$(READLINE).clean $(USE_NLLIBC:yes=nllibc.clean) $(USE_NLTERM:yes=nlterm.clean) $(USE_NLCRT:yes=nlcrt.clean)

libedit.clean :

editline.clean :

readline.clean :

nlline.clean :
		-$(MAKE) -C $(NLLINEDIR) $(HANDOVER) lib.clean

getline.clean :

fgets.clean :

nllibc.clean :
		-$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) lib.clean

nlterm.clean :
		-$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) term.clean

nlcrt.clean :
		-$(MAKE) -C $(NLLIBCDIR) $(HANDOVER) crt.clean

allclean :	nll.clean nlline.clean nllibc.clean nlterm.clean nlcrt.clean
