# ---------------------------------------------------------------------------
# Platform detection.
#
# The FreeBSD build is the production build and must keep working.  On
# FreeBSD "uname -s" reports "FreeBSD" and the else branch below is the
# original Makefile verbatim - same CC (clang++-devel), same CFLAGS, same
# hardcoded /usr/local/lib/mysql and /usr/lib paths, same INCDIR order.
# Only the Linux branch is new.  The source list, the object list and every
# rule below the branch are shared and unchanged.
# ---------------------------------------------------------------------------
UNAME_S := $(shell uname -s)

MAKE = gmake

INCDIR =
LIBDIR =
BINDIR = ..
OBJDIR = .obj

SVN_VERSION = 40142

# TARGET = $(BINDIR)/db_r$(SVN_VERSION)
TARGET = $(BINDIR)/db

ifeq ($(UNAME_S),Linux)

# ---------------------------------------------------------------------------
# Linux (32 bit) branch
# ---------------------------------------------------------------------------

# "clang++-devel" is a FreeBSD ports name and does not exist on Linux.
CC = g++

DBDIR = /usr/metin2/server/share/bin

# ###########################################################################
# -m32 IS LOAD BEARING.  Do not drop it.
#
# The original line was "CFLAGS += -mtune=i686" only.  -mtune is purely a
# scheduling hint: on an x86_64 host it still produces a 64 bit object.  The
# sibling game/src/Makefile does carry -m32, so db was the odd one out and
# would silently build 64 bit objects against the 32 bit libraries in
# extern/Linux40250, failing at link time with confusing "incompatible"
# messages - or worse, half-linking.
#
# 32 bit is not a preference here, it is required by the wire format: seven
# packed structs shared between db and game are simultaneously network
# packets and MySQL row layouts, and they are sized for a 4 byte long and a
# 4 byte time_t.
#
# For the same reason _TIME_BITS=64 MUST NEVER be defined: it would grow
# time_t to 8 bytes and silently add 4 bytes to each of those structs.
# -D_FILE_OFFSET_BITS=64 on its own is safe (it only affects off_t and the
# stat/seek family, none of which appear in a packed struct).
# ###########################################################################
CFLAGS = -g -Wall -w -O2 -pipe -fno-rtti -std=c++23 -fno-exceptions -pthread -D_THREAD_SAFE
CFLAGS += -mtune=i686 -m32
CFLAGS += -D_FILE_OFFSET_BITS=64

# Generate real dependency files instead of using the checked-in "Depend"
# (see the sinclude at the bottom of this file).
CFLAGS += -MMD -MP

# NOTE: db deliberately builds WITHOUT -DNDEBUG while game builds with it.
# That is upstream's choice and is kept: db's assert()s stay live, so db
# aborts rather than warns on a malformed proto/CSV row.  When triaging, an
# assert abort in db is almost always a data problem, not a port problem.

# 32 bit prebuilt dependencies (see /opt/m2port/build-deps-40250.sh).
# Same name and same override semantics as game/src/Makefile, so both
# modules can be pointed at another dependency tree with one variable.
M2_EXTERN_LINUX ?= /opt/m2port/extern/Linux40250

# Miscellaneous external libraries
INCDIR += -I../../../extern/include
LIBDIR += -L../../../extern/lib

INCDIR += -I$(M2_EXTERN_LINUX)/include
LIBDIR += -L$(M2_EXTERN_LINUX)/lib

INCDIR += -I/usr/include

LIBDIR += -L../../libthecore/lib -L../../libsql -L../../libpoly -L../../libgame/lib

# ###########################################################################
# Link order matters here in a way it did not on FreeBSD.
#
# GNU ld resolves static archives strictly left to right, so an archive has
# to appear AFTER everything that references it.  The FreeBSD line lists the
# MySQL/OpenSSL archives before -lthecore -lsql, which is backwards: libsql
# is what calls mysql_*.  It happens to work here anyway, because db's own
# objects call mysql_* directly and so pull the needed members in early -
# but that is luck, not design, and it breaks the moment db stops making a
# direct MySQL call.  The Linux branch therefore lists the project archives
# first and the external ones after, which is also the order the sibling
# modules were verified with.
#
# -ldl is new: glibc keeps dlopen in libdl, FreeBSD has it in libc.  MariaDB
# Connector/C needs it (and its NSS/getaddrinfo use is also why this binary
# must not be linked -static).
# ###########################################################################
LIBS += -lthecore -lsql -lpoly -lgame

# MariaDB Connector/C, built 32 bit.  Must not be MySQL 8, which removed
# my_bool.  libmysqlclient.a is a byte copy of libmariadb.a - never put both
# on the same link line or every mysql_* symbol is defined twice.
LIBS += $(M2_EXTERN_LINUX)/lib/libmysqlclient.a

# OpenSSL, then zlib - libmariadb.a needs all three after it.
LIBS += $(M2_EXTERN_LINUX)/lib/libssl.a $(M2_EXTERN_LINUX)/lib/libcrypto.a
LIBS += $(M2_EXTERN_LINUX)/lib/libz.a

LIBS += -pthread -lm -ldl

else

# ---------------------------------------------------------------------------
# FreeBSD (production) branch - original Makefile, unchanged.
# ---------------------------------------------------------------------------
CC = clang++-devel

DBDIR = /usr/metin2/server/share/bin

GCC_VERSION = $(shell $(CC) --version 2>&1 | grep "(GCC)" | cut -d' ' -f3  | cut -d'.' -f1)
BSD_VERSION = $(shell uname -v 2>&1 | cut -d' ' -f2 | cut -d'.' -f1)

CFLAGS = -g -Wall -w -O2 -pipe -fno-rtti -std=c++23 -fno-exceptions -pthread -D_THREAD_SAFE
CFLAGS += -mtune=i686

# MySQL
LIBS += /usr/local/lib/mysql/libmysqlclient.a /usr/lib/libz.a

# OpenSSL
LIBS += /usr/lib/libssl.a /usr/lib/libcrypto.a

# Miscellaneous external libraries
INCDIR += -I../../../extern/include
LIBDIR += -L../../../extern/lib

INCDIR += -I/usr/local/include
INCDIR += -I/usr/include

LIBDIR += -L../../libthecore/lib -L../../libsql -L../../libpoly -L../../libgame/lib
LIBS += -lthecore -lsql -lpoly -lgame -lm

endif

# ###########################################################################
# On the deliberate ABSENCE of a libthecore include path.
#
# There is no "-I../../libthecore/include" here and none must be added.
# Every reference db makes to libthecore, libsql, libgame, libpoly and
# common goes through a relative quoted include starting at
# db/src/stdafx.h:4 ("../../libthecore/include/stdafx.h"), which resolves
# against the including file's own directory and needs no -I at all.
#
# Putting libthecore/include on the bracket-include path walks into a
# header shadowing trap on Linux: libthecore/include/stdafx.h:121 includes
# <sys/signal.h>, glibc's copy of which is literally "#include <signal.h>",
# and that would then resolve to libthecore's own project header
# libthecore/include/signal.h instead of /usr/include/signal.h - at which
# point SIGPIPE, signal() and sigaction() quietly vanish.
#
# (A sister port of a different fork has the same hazard, where it is held
# off by a typo'd "-I/../../libthecore/src" that normalises to a
# nonexistent /libthecore/src.  40250 has no such line at all, so there is
# nothing to preserve here - only something not to add.)
# ###########################################################################

$(shell if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi)

SRCS =	Config.cpp NetBase.cpp Peer.cpp PeerBase.cpp Main.cpp Lock.cpp DBManager.cpp \
		Cache.cpp LoginData.cpp ClientManager.cpp ClientManagerPlayer.cpp ClientManagerLogin.cpp \
		ClientManagerBoot.cpp ClientManagerParty.cpp ClientManagerGuild.cpp GuildManager.cpp HB.cpp \
		PrivManager.cpp MoneyLog.cpp ItemAwardManager.cpp ClientManagerEventFlag.cpp Marriage.cpp \
		Monarch.cpp BlockCountry.cpp ItemIDRangeManager.cpp ClientManagerHorseName.cpp version.cpp \
		AuctionManager.cpp ProtoReader.cpp CsvReader.cpp

OBJS = $(SRCS:%.cpp=$(OBJDIR)/%.o)

default: $(TARGET)

$(TARGET): $(OBJS)
	@echo linking $(TARGET)....
	@$(CC) $(CFLAGS) $(LIBDIR) $(OBJS) $(LIBS) -o $(TARGET)
	@touch version.cpp
	@echo "Moving $(TARGET) to $(DBDIR)"
	@mv $(TARGET) $(DBDIR)
	@echo "All done! Your db file moved to your server directory."

# Build the objects only, without linking or installing.  Used to verify the
# 32 bit port without needing the sibling libraries to be finished.
objs: $(OBJS)

$(OBJDIR)/%.o: %.cpp
	@echo compile $<
	@$(CC) $(CFLAGS) $(INCDIR) -c $< -o $@

$(OBJDIR)/version.o: version.cpp
	@$(CC) $(CFLAGS) -D__P4_VERSION__=\"$(SVN_VERSION)\" -c $< -o $@
	@echo compile $<

$(OBJDIR):
	@mkdir $(OBJDIR)

clean:
	@rm -f $(OBJS) $(BINDIR)/db_r*

dep:
	@touch Depend
	makedepend -fDepend $(INCDIR) -I/usr/include/c++/3.3 -I/usr/include/c++/4.2 -p$(OBJDIR)/ $(SRCS) 2> /dev/null

# The checked-in "Depend" file was generated by makedepend on FreeBSD and
# hardcodes FreeBSD header paths (e.g. /usr/include/sys/_null.h), which do
# not exist on Linux - including it makes make fail with "No rule to make
# target '/usr/include/sys/_null.h'" before a single file is compiled.  It
# is left on disk untouched for the FreeBSD build and simply not read here;
# the Linux branch uses the -MMD -MP dependency files instead.
ifeq ($(UNAME_S),Linux)
sinclude $(OBJDIR)/*.d
else
sinclude Depend
endif
