Files
2026-09-13 13:13:33 +02:00

121 lines
5.5 KiB
Makefile

# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: acossari <acossari@student.codam.nl> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2026/08/19 10:05:52 by acossari #+# #+# #
# Updated: 2026/08/20 22:18:47 by acossari ### ########.fr #
# #
# **************************************************************************** #
NAME := webserv
SRC_DIR := src
OBJ_DIR := obj
INC_DIR := include
CXX := g++
# EXTRA_CXXFLAGS is the slot for flags added from the command line, for example
# make EXTRA_CXXFLAGS="-g3 -fsanitize=address". CXXFLAGS itself must never be
# overridden that way, it carries the warning flags that have to stay on.
CXXFLAGS := -Wall -Wextra -Werror -std=c++23 -I$(INC_DIR) $(EXTRA_CXXFLAGS)
# The C++ standard library goes inside the binary instead of being loaded from
# the system at startup. A recent compiler emits references to symbol versions
# that an older system libstdc++.so.6 does not carry, and that failure shows up
# when the program is started, not when it is linked.
LDFLAGS := -static-libstdc++ -static-libgcc
CLANG ?= clang++
CLANG_TIDY ?= clang-tidy
CLANG_FORMAT ?= clang-format
# Separate object directory and binary for the clang build. Sharing obj/ would
# link a fresh g++ object with a leftover clang one, and the error looks like a
# bug in the source instead of an old file.
CLANG_NAME := $(NAME)-clang
CLANG_OBJ_DIR := $(OBJ_DIR)/clang
# libstdc++ is the GNU library and ships with g++, libc++ is the LLVM one and
# ships with clang. On Linux clang usually sits on libstdc++ anyway, and that
# pairing cannot build this project:
#
# clang 18 with libstdc++ : std::expected not available
# clang 18 with libc++ : std::expected available
#
# So every clang pass gets libc++. g++ never sees this flag.
CLANG_STDLIB ?= -stdlib=libc++
# find returns files in filesystem order, which is not the same on every
# machine. sort keeps the compile and link lines stable, so build logs and
# clang-tidy output stay comparable.
#SRCS := $(sort $(shell find $(SRC_DIR) -type f -name '*.cpp'))
SRCS := src/Log.cpp src/main.cpp src/Server.cpp \
src/config/Config.cpp src/config/ConfigurationParser.cpp src/config/LocationConfig.cpp src/config/ServerConfig.cpp \
src/event/Epoll.cpp src/event/EventToken.cpp \
src/net/ByteBuffer.cpp src/net/Connection.cpp src/net/FileDescriptor.cpp src/net/Listener.cpp src/net/ListenerPlan.cpp src/net/PauseMask.cpp src/net/SlotPool.cpp \
src/http/Request.cpp src/http/RequestParser.cpp src/http/Response.cpp
OBJS := $(SRCS:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
# Make only knows that obj/main.o comes from src/main.cpp, so editing Log.hpp
# would leave the old main.o in place. Each .d adds the missing line, obj/main.o
# also depends on include/Log.hpp, and -include at the bottom pulls them in.
DEPS := $(OBJS:.o=.d)
HDRS := include/config/Config.hpp include/config/ConfigurationParser.hpp include/config/LocationConfig.hpp include/config/ServerConfig.hpp \
include/event/Epoll.hpp include/event/EventToken.hpp \
include/http/HttpStatus.hpp include/http/Request.hpp include/http/RequestParser.hpp include/http/Response.hpp \
include/net/ByteBuffer.hpp include/net/Connection.hpp include/net/FileDescriptor.hpp include/net/Listener.hpp include/net/ListenerPlan.hpp include/net/PauseMask.hpp include/net/SlotPool.hpp \
include/Log.hpp include/Result.hpp include/Server.hpp \
#HDRS := $(sort $(shell find $(INC_DIR) $(SRC_DIR) -type f \
# \( -name '*.hpp' -o -name '*.tpp' \)))
all: $(NAME)
$(NAME): $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) -o $(NAME)
# -MMD writes the .d file described above. -MP adds an empty rule for every
# header in it, which matters after a rename: the old .d still asks for the old
# path and make stops, having no way to build that file. The empty rule says the
# header needs no recipe, so make moves on and recompiles.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@
# Reports only, never fails the build: WarningsAsErrors is empty in .clang-tidy
# and all does not depend on this. clang-tidy parses the code itself, so it
# needs the same flags the compiler gets (everything after the --).
tidy: $(SRCS)
$(CLANG_TIDY) $(SRCS) -- $(CXXFLAGS) $(CLANG_STDLIB)
# Same sources through the other compiler and standard library, into files of
# its own, so the normal build is untouched. Worth running because the two
# compilers do not warn about the same things. Needs libc++ 18 or newer, the
# first release that ships <print>.
check-clang:
$(MAKE) --no-print-directory NAME=$(CLANG_NAME) OBJ_DIR=$(CLANG_OBJ_DIR) \
CXX=$(CLANG) EXTRA_CXXFLAGS="$(CLANG_STDLIB)"
format:
$(CLANG_FORMAT) -i $(SRCS) $(HDRS)
format-check:
$(CLANG_FORMAT) --dry-run --Werror $(SRCS) $(HDRS)
clean:
rm -rf $(OBJ_DIR)
fclean: clean
rm -f $(NAME) $(CLANG_NAME)
re: fclean all
-include $(DEPS)
.PHONY: all clean fclean re tidy check-clang format format-check