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

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

ARCH =
#ARCH = i386
#ARCH = x86_64

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

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

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

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

################################
# 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 builtin

#USE_BUILTIN = yes

################################
# For static linking (shared object is not supported with nlcc)

LINK_STATIC = yes

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

TARGET = nlcc1

ASRCS =
CSRCS = main.c

LIBASRCS =
LIBCSRCS = builtin.c lib.c type.c argument.c objlist.c lex.c syntax.c value.c \
	model.c symbol.c struct.c union.c enum.c typedef.c defines.c area.c \
	asm.c asm_symbol.c asm_syntax.c asm_queue.c asm_format.c \
	asm_code.c asm_code_lib.c \
	asm_code_i386.c asm_code_amd64.c \
	asm_code_arm.c asm_code_mips.c asm_code_powerpc.c \
	asm_code_aarch64.c \
	asm_code_thumb.c asm_code_thumb2.c asm_code_mips16.c \
	asm_code_osecpu.c asm_code_riscv32.c asm_code_rx.c

LIB = libnlcc1.a

NLROOTDIR = ../..

NLLIBCDIR = $(NLROOTDIR)/nllibc

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

################################
# 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)

NLLIBC = $(LIBDIR)/libnlc.a
#NLLIBC = $(LIBDIR)/nllibc.o
NLCRT = $(LIBDIR)/nlcrt.o

LIBS = $(USE_NLLIBC:yes=$(NLLIBC)) \
	$(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 += $(GOPTFLAGS)

PFLAGS_STDCHEADERS_freebsd = -D__RUNETYPE_INTERNAL # for _ThreadRuneLocale
PFLAGS_STDCHEADERS_debian  = -U__GNUC__ # to avoid include stdio2.h
PFLAGS_STDCHEADERS_nllibc  = -nostdinc -I$(INCDIR)

PFLAGS  =
PFLAGS += -fno-inline
PFLAGS += $(PFLAGS_STDCHEADERS_$(STDCHEADERS))
PFLAGS += $(USE_NLLIBC:yes=-DUSE_NLLIBC -I$(INCDIR)/nllibc)
PFLAGS += $(USE_NLCRT:yes=-DUSE_NLCRT)
PFLAGS += $(CROSS:$(CROSS)=-DCROSS $(OSDEF:$(OSDEF)=-D$(OSDEF)))
PFLAGS += $(MINGW:$(MINGW)=-DMINGW)
PFLAGS += $(USE_BUILTIN:yes=-DUSE_BUILTIN)
PFLAGS += $(POPTFLAGS)

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

AFLAGS  =
AFLAGS += $(AOPTFLAGS)

LFLAGS  = -L. -lnlcc1
LFLAGS += $(LINK_STATIC:yes=-static)
LFLAGS += $(LFLAGS_CCOMPILER_$(CCOMPILER))
LFLAGS += $(USE_NLLIBC:yes=-L$(LIBDIR) -lnlc -nodefaultlibs)
LFLAGS += $(USE_NLCRT:yes=-nostartfiles)
LFLAGS += $(NLLDSCR:$(NLLDSCR)=-Wl,-T$(LIBDIR)/ldscripts/ld.scr.$(NLLDSCR))
LFLAGS += $(LOPTFLAGS)

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

HANDOVER  =
HANDOVER += CCOMPILER=$(CCOMPILER) ARCH=$(ARCH)
HANDOVER += STDCHEADERS=$(STDCHEADERS)
HANDOVER += USE_NLLIBC=$(USE_NLLIBC) USE_NLCRT=$(USE_NLCRT)
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 :		nlcc1.all

nlcc1.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) $@)

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

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

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

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

clean :		nlcc1.clean

nlcc1.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 :	$(USE_NLLIBC:yes=nllibc.clean) $(USE_NLCRT:yes=nlcrt.clean)

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

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

allclean :	nlcc1.clean nllibc.clean nlcrt.clean
