include config.mk

CFLAGS = -O2 -g
CFLAGS += -std=gnu99 -Wall -Wextra \
	-Wno-missing-field-initializers -Wstrict-prototypes \
	-fvisibility=hidden -fPIC

CC = gcc
AR = ar
PREFIX = /usr/
BINDIR = ${PREFIX}/bin
LIBDIR = ${PREFIX}/lib
INCLUDEDIR = ${PREFIX}/include
DATADIR = ${PREFIX}/share
PKGCONFIGDIR = ${LIBDIR}/pkgconfig
PLATFORM = linux

PROTOCOL_XML = ../protocol/wayland.xml
PROTOCOL_DTD = ../protocol/wayland.dtd
PROTOCOL_HEADERS = public/wayland-server-protocol.h \
	public/wayland-server-protocol-core.h \
	public/wayland-client-protocol.h \
	public/wayland-client-protocol-core.h
PROTOCOL_CODE = protocol/wayland-protocol.c
PKGCONFIG_FILES = pkgconfig/wayland-client.pc pkgconfig/wayland-server.pc pkgconfig/wayland-scanner.pc
WAYLAND_VERSION = 1.23.0
WAYLAND_VERSION_MAJOR = 1
WAYLAND_VERSION_MINOR = 23
WAYLAND_VERSION_MICRO = 0

UTIL_SRCS = util/array.c util/interface.c util/list.c util/log.c util/map.c
PROTOCOL_SRCS = protocol/closure.c protocol/connection.c protocol/marshal.c protocol/message.c ${PROTOCOL_CODE}
PLATFORM_CFLAGS != case "${PLATFORM}" in bsd) printf '%s' '-DUSE_KQUEUE -DHAVE_SYS_EVENT_H' ;; sun) printf '%s' '-DUSE_POLL' ;; *) printf '' ;; esac
PLATFORM_LIBS != case "${PLATFORM}" in sun) printf '%s' '-lsocket -lnsl' ;; *) printf '' ;; esac
OS_SRCS != case "${PLATFORM}" in bsd) printf '%s\n' os/fd.c os/socket.c os/kqueue.c ;; sun) printf '%s\n' os/fd.c os/socket.c os/poll.c ;; *) printf '%s\n' os/fd.c os/socket.c os/epoll.c ;; esac
EVENTS_SRCS != case "${PLATFORM}" in bsd) printf '%s\n' events/loop-kqueue.c ;; sun) printf '%s\n' events/loop-poll.c ;; *) printf '%s\n' events/idle.c events/loop.c events/signal.c events/source.c events/timer.c ;; esac
SERVER_SRCS = server/client.c server/display.c server/global.c server/logger.c server/memory.c server/resource.c server/signal.c server/socket.c
CLIENT_SRCS = client/display.c client/dispatch.c client/marshal.c client/proxy.c client/queue.c
SCANNER_SRCS = scanner/emit.c scanner/generator.c scanner/parser.c

UTIL_OBJS = ${UTIL_SRCS:.c=.o}
PROTOCOL_OBJS = ${PROTOCOL_SRCS:.c=.o}
OS_OBJS = ${OS_SRCS:.c=.o}
EVENTS_OBJS = ${EVENTS_SRCS:.c=.o}
SERVER_OBJS = ${SERVER_SRCS:.c=.o}
CLIENT_OBJS = ${CLIENT_SRCS:.c=.o}
SCANNER_OBJS = ${SCANNER_SRCS:.c=.o}

UTIL_LIB = libwayland-util.a
PRIVATE_LIB = libwayland-private.a
SERVER_LIB = libwayland-server.so
CLIENT_LIB = libwayland-client.so
SERVER_STATIC_LIB = libwayland-server.a
CLIENT_STATIC_LIB = libwayland-client.a
SCANNER_BIN = wayland-scanner

CPPFLAGS = -D_POSIX_C_SOURCE=200809L \
	-DWAYLAND_VERSION=\"${WAYLAND_VERSION}\" \
	-DLIBWAYLAND_VERSION_MAJOR=${WAYLAND_VERSION_MAJOR} \
	-DLIBWAYLAND_VERSION_MINOR=${WAYLAND_VERSION_MINOR} \
	-DLIBWAYLAND_VERSION_MICRO=${WAYLAND_VERSION_MICRO} \
	-I. -Iutil -Iprotocol -Ios -Ievents -Ishared \
	-Ipublic -Iserver -Iclient -Iscanner

CFLAGS += ${PLATFORM_CFLAGS}

WAYLAND_VERSION_SUBSTS = -e "s|@WAYLAND_VERSION_MAJOR@|${WAYLAND_VERSION_MAJOR}|" \
	-e "s|@WAYLAND_VERSION_MINOR@|${WAYLAND_VERSION_MINOR}|" \
	-e "s|@WAYLAND_VERSION_MICRO@|${WAYLAND_VERSION_MICRO}|" \
	-e "s|@WAYLAND_VERSION@|${WAYLAND_VERSION}|"

PKGCONFIG_SUBSTS = -e "s|@PREFIX@|${PREFIX}|" \
	-e "s|@EXEC_PREFIX@|${PREFIX}|" \
	-e "s|@LIBDIR@|${LIBDIR}|" \
	-e "s|@INCLUDEDIR@|${INCLUDEDIR}|" \
	-e "s|@PLATFORM_LIBS@|${PLATFORM_LIBS}|" \
	-e "s|@VERSION@|${WAYLAND_VERSION}|"

all: ${UTIL_LIB} ${PRIVATE_LIB} ${SERVER_STATIC_LIB} ${CLIENT_STATIC_LIB} ${SERVER_LIB} ${CLIENT_LIB} ${SCANNER_BIN}

${UTIL_LIB}: ${UTIL_OBJS}
	rm -f $@
	${AR} rcs $@ ${UTIL_OBJS}

${PRIVATE_LIB}: ${PROTOCOL_OBJS} ${OS_OBJS}
	rm -f $@
	${AR} rcs $@ ${PROTOCOL_OBJS} ${OS_OBJS}

${SERVER_STATIC_LIB}: ${SERVER_OBJS} ${EVENTS_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${UTIL_OBJS}
	rm -f $@
	${AR} rcs $@ ${SERVER_OBJS} ${EVENTS_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${UTIL_OBJS}

${CLIENT_STATIC_LIB}: ${CLIENT_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${UTIL_OBJS}
	rm -f $@
	${AR} rcs $@ ${CLIENT_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${UTIL_OBJS}

${SERVER_LIB}: ${SERVER_OBJS} ${EVENTS_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${UTIL_LIB}
	${CC} ${LDFLAGS} -shared -Wl,-soname,$@ -o $@ ${SERVER_OBJS} ${EVENTS_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} -L. -lwayland-util -L/usr/lib -lrt -lm -lpthread ${PLATFORM_LIBS}

${CLIENT_LIB}: ${CLIENT_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${UTIL_LIB}
	${CC} ${LDFLAGS} -shared -Wl,-soname,$@ -o $@ ${CLIENT_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} -L. -lwayland-util -L/usr/lib -lm -lpthread ${PLATFORM_LIBS}

${SCANNER_BIN}: ${SCANNER_OBJS} ${UTIL_LIB}
	${CC} ${LDFLAGS} -o $@ ${SCANNER_OBJS} -L. -lwayland-util -lexpat -lm

wayland-version.h: wayland-version.h.in
	sed ${WAYLAND_VERSION_SUBSTS} wayland-version.h.in > wayland-version.h

pkgconfig/wayland-server.pc: pkgconfig/wayland-server.pc.in
	sed ${PKGCONFIG_SUBSTS} pkgconfig/wayland-server.pc.in > pkgconfig/wayland-server.pc

pkgconfig/wayland-client.pc: pkgconfig/wayland-client.pc.in
	sed ${PKGCONFIG_SUBSTS} pkgconfig/wayland-client.pc.in > pkgconfig/wayland-client.pc

pkgconfig/wayland-scanner.pc: pkgconfig/wayland-scanner.pc.in
	sed ${PKGCONFIG_SUBSTS} pkgconfig/wayland-scanner.pc.in > pkgconfig/wayland-scanner.pc

public/wayland-server-protocol.h: ${SCANNER_BIN} ${PROTOCOL_XML}
	./${SCANNER_BIN} -s server-header ${PROTOCOL_XML} $@

public/wayland-server-protocol-core.h: ${SCANNER_BIN} ${PROTOCOL_XML}
	./${SCANNER_BIN} -s server-header -c ${PROTOCOL_XML} $@

public/wayland-client-protocol.h: ${SCANNER_BIN} ${PROTOCOL_XML}
	./${SCANNER_BIN} -s client-header ${PROTOCOL_XML} $@

public/wayland-client-protocol-core.h: ${SCANNER_BIN} ${PROTOCOL_XML}
	./${SCANNER_BIN} -s client-header -c ${PROTOCOL_XML} $@

${PROTOCOL_CODE}: ${SCANNER_BIN} ${PROTOCOL_XML}
	./${SCANNER_BIN} -s public-code ${PROTOCOL_XML} ${PROTOCOL_CODE}

.SUFFIXES: .c .o

.c.o:
	${CC} ${CFLAGS} ${CPPFLAGS} -c $< -o $@

protocol/wayland-protocol.o: protocol/wayland-protocol.c ${PROTOCOL_HEADERS}
	${CC} ${CFLAGS} ${CPPFLAGS} \
	    -include public/wayland-server-protocol.h \
	    -include public/wayland-client-protocol.h \
	    -c protocol/wayland-protocol.c -o $@

${UTIL_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${EVENTS_OBJS} ${SERVER_OBJS} ${CLIENT_OBJS} ${SCANNER_OBJS}: wayland-version.h
${SERVER_OBJS}: ${PROTOCOL_HEADERS} ${PROTOCOL_CODE}
${CLIENT_OBJS}: ${PROTOCOL_HEADERS} ${PROTOCOL_CODE}

clean:
	rm -f ${UTIL_OBJS} ${PROTOCOL_OBJS} ${OS_OBJS} ${EVENTS_OBJS} \
	      ${SERVER_OBJS} ${CLIENT_OBJS} ${SCANNER_OBJS}
	rm -f ${UTIL_LIB} ${PRIVATE_LIB} ${SERVER_LIB} ${CLIENT_LIB} \
	      ${SERVER_STATIC_LIB} ${CLIENT_STATIC_LIB} ${SCANNER_BIN}
	rm -f ${PROTOCOL_HEADERS} ${PROTOCOL_CODE} wayland-version.h ${PKGCONFIG_FILES}

install: ${PKGCONFIG_FILES}
	mkdir -p ${DESTDIR}${LIBDIR}
	install -m 644 ${SERVER_STATIC_LIB} ${DESTDIR}${LIBDIR}/
	install -m 644 ${CLIENT_STATIC_LIB} ${DESTDIR}${LIBDIR}/
	install -m 755 ${SERVER_LIB} ${DESTDIR}${LIBDIR}/
	install -m 755 ${CLIENT_LIB} ${DESTDIR}${LIBDIR}/
	mkdir -p ${DESTDIR}${BINDIR}
	install -m 755 ${SCANNER_BIN} ${DESTDIR}${BINDIR}/${SCANNER_BIN}
	mkdir -p ${DESTDIR}${PKGCONFIGDIR}
	install -m 644 ${PKGCONFIG_FILES} ${DESTDIR}${PKGCONFIGDIR}/
	mkdir -p ${DESTDIR}${INCLUDEDIR}
	install -m 644 public/wayland*.h ${DESTDIR}${INCLUDEDIR}/
	install -m 644 wayland-version.h ${DESTDIR}${INCLUDEDIR}/
	mkdir -p ${DESTDIR}${DATADIR}/wayland
	install -m 644 ${PROTOCOL_XML} ${DESTDIR}${DATADIR}/wayland/
	install -m 644 ${PROTOCOL_DTD} ${DESTDIR}${DATADIR}/wayland/

.PHONY: all clean install
