Last active
September 3, 2015 06:12
-
-
Save Redchards/8e757bfb77dc4b55e8de to your computer and use it in GitHub Desktop.
Upgraded and fixed version of the previous makefiles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This makefile has basically the same goal as the previous ones, but do a greater job. | |
# Bugs the others had are now fixed ! The compilation for a configuration will not require | |
# cleaning objs to produce its result. | |
# PROS : -Easy to use, drop in makefile | |
# -Quite configurable on its own | |
# -Manages release and debug mod automatically | |
# -Supports mix of C and C++ files without further configuration | |
# CONS : -Bad extensibility | |
# -Using a sub makefile, so less compact than the previous ones | |
# -Target dependent variables were not the great idea I thought it would be | |
# (could be replaced by a filter on MAKECMDGOALS and a list) | |
# -Some features (like analysis or bitcode compilation) are quite broken. | |
# The above method shoud some problems they have. | |
# Default structure of the project should be : | |
# ./src for the source files (subdirectories are supported) | |
# ./include for the includes files | |
# .c for C file names | |
# .cxx for C++ file names | |
# So yhea, I still got a bit of work to do on this :) | |
# The shell that the make will use to execute shell commands. | |
# It can be set to any decent shell without any problem. | |
SHELL:=/bin/bash | |
# We only define the C++ compiler, and it will take care of compiling both C and C++ files. | |
# We also set the linker (LD) to the same value, as most of the compilers do it through the same command. | |
CXX= clang++ | |
LD= $(CXX) | |
# The final executable, or library, name. | |
EXEC:= Arena | |
# Current configuration. Debug by default. | |
ALLCONFIG=debug release analysis | |
CONFIG=debug | |
# Various directory path. | |
# As nothing is hardcoded, the values can be set to the liking of the user, without breaking something. | |
LIBDIR:= lib | |
OBJDIR:= obj | |
SRCDIR:= src | |
INCLDIR:= include | |
BINDIR:= bin | |
SCANDIR:= scan | |
# Basic C and C++ flags | |
FLAGS= -W -Wall -Wextra | |
CFLAGS= $(FLAGS) -std=c11 | |
CXXFLAGS= $(FLAGS) -std=c++1y | |
# Flags used only for debug mod | |
DEBUGFLAGS:= -g -O0 | |
# Flags used only for release mod | |
RELEASEFLAGS:= -O3 | |
# Flags used only for analyzis mod | |
ANALYZERFLAGS:= --analyze -Xanalyzer -analyzer-output=html -o $(SCANDIR) | |
# Flags used only for bitcode compilation (by LLVM/clang) | |
JITFLAGS:= -emit-llvm -S -fno-use-cxa-atexit | |
# Character used to make the makefile silent. | |
SILENT:=@ | |
# Flags used to create dependencies | |
MAKEDEPEND:= -MMD | |
# Flags used by the linker | |
LDFLAGS:= | |
# This variable will determine whether we will use native or jit execution. | |
# The values are either "native" or "jit". | |
# The value "jit" is only valid for the clang compiler. | |
EXECUTION:=native | |
# Turns on/off the verbose output of the makefile. | |
# The values are either "yes" or "no" | |
VERBOSE:=no | |
# Extensions of the different types of file | |
OBJEXT:=o | |
DEPEXT:=d | |
CEXT:=c | |
CXXEXT:=cxx | |
ifeq ($(EXECUTION), jit) | |
ifeq ($(CONFIG), analysis) | |
$(warning Warning : analysis mod is independant of execution mod. No bitcode will be generated) | |
endif | |
ifeq (, $(filter $(CXX), clang clang++)) | |
$(error Error : attempt to emit llvm IR, but not using clang) | |
endif | |
CXXFLAGS+= $(JITFLAGS) | |
CFLAGS+= $(JITFLAGS) | |
LD= llvm-link | |
EXEC:= $(addprefix $(EXEC).,bc) | |
OBJEXT= bco | |
endif | |
ifeq ($(CONFIG), analysis) | |
ifeq (, $(filter $(CXX), clang clang++)) | |
$(error Error : attempt to enable analysis, but not using clang) | |
endif | |
CXXFLAGS+= $(ANALYZERFLAGS) | |
endif | |
ifeq ($(VERBOSE), yes) | |
SILENT= | |
endif | |
SRC:=$(shell find $(SRCDIR) -name '*.$(CEXT)' -o -name '*.$(CXXEXT)') | |
OBJ=$(subst src/,,$(SRC:.$(CEXT)=.$(OBJEXT))) | |
OBJ:=$(subst src/,,$(OBJ:.$(CXXEXT)=.$(OBJEXT))) | |
.SECONDEXPANSION: | |
OBJS=$(addprefix obj/$(CONFIG)/, $(OBJ)) | |
ALLOBJ=$(addprefix obj/, $(OBJ)) | |
DEPS:=$(OBJ:.$(OBJEXT)=.$(DEPEXT)) | |
# Define the path where the result will be outputted | |
OUTPATH=$(if $(filter $(CONFIG), analysis),$(SCANDIR),$(BINDIR)/$(CONFIG)) | |
export | |
# .PHONY targets. | |
.PHONY: clean cleanall debug release analysis | |
all: build-info $(EXEC) | |
# Target specific variable value. | |
# These targets are used to do less typing while invoking the make with a special config. | |
debug: override CONFIG:=debug | |
debug: override FLAGS+=$(DEBUGFLAGS) | |
debug: all | |
release: override CONFIG:=release | |
release: override FLAGS+=$(RELEASEFLAGS) | |
release: all | |
analysis: override CONFIG:=analysis | |
analysis: override FLAGS+=$(ANALYZERFLAGS) | |
analysis: all | |
# Calling submake which will do the actual compilation based on settings | |
$(EXEC): | |
$(SILENT) $(MAKE) -f Makefile.ds --no-print-directory $(BINDIR)/$(CONFIG)/$(EXEC) | |
# The clean rule is a bit aggressive, and delete everything in obj folders. | |
# Is it desired behaviour ? To me yes. | |
clean: | |
$(SILENT) rm -rf $(OBJDIR)/* | |
#rm -rf $(OBJDIR)/$(filter $(MAKECMDGOALS), $(ALLCONFIG))/*; | |
cleanall: clean | |
$(SILENT) rm -f ./build.gen | |
$(SILENT) rm -rf $(BINDIR)/* | |
# The summary of the upcoming compilation configuration printed at the begining. | |
# It could be extended, but it is sufficient like this. | |
HEADER_MSG:="COMPILATION OF PROJECT : $(EXEC)" | |
build-info: | |
@echo | |
$(shell printf "#%.0s" $$(seq 1 $$(tput cols))) | |
@echo -e "\e[1m\e[91m$(shell export HEADER_MSG=$(HEADER_MSG); printf " %.0s" $$(seq 1 $$(($$(tput cols)/2 - $${#HEADER_MSG}/2)))) $(HEADER_MSG)\e[0m" | |
@echo | |
@echo -e "Generation configuration is \e[1m\e[32m$(CONFIG)\e[0m" | |
@echo | |
@echo -e "Sources directory search path is : \e[1m\e[96m$(SRCDIR)\e[0m (SRCDIR)" | |
@echo -e "Includes directory search path is : \e[1m\e[96m$(INCLDIR)\e[0m (INCLDIR)" | |
@echo -e "Libraries directory search path is : \e[1m\e[96m$(LIBDIR)\e[0m (LIBDIR)" | |
@echo -e "Objects directory is : \e[1m\e[96m$(OBJDIR)\e[0m (OBJDIR)" | |
@echo -e "The binary output path is : \e[1m\e[96m$(OUTPATH)\e[0m" | |
@echo | |
$(shell printf "#%.0s" $$(seq 1 $$(tput cols))) | |
@echo |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
OK= | |
# This target is the main target. | |
# It will link all file generated by its dependencies together | |
-include $(addprefix obj/$(CONFIG)/,$(DEPS)) | |
$(BINDIR)/$(CONFIG)/$(EXEC) : $(OBJS) | |
ifeq ($(EXECUTION), jit) | |
$(SILENT) $(LD) $^ -o $(BINDIR)/$(CONFIG)/$(EXEC) | |
else | |
$(if $(filter $(CONFIG), analysis),\ | |
@ echo "No executable code output for analysis",\ | |
$(SILENT) echo "Linking binary ...";\ | |
mkdir -p $(BINDIR)/$(CONFIG);\ | |
$(LD) -o $(BINDIR)/$(CONFIG)/$(EXEC) $^ $(LDFLAGS)) | |
endif | |
@ echo -e "\e[1m\e[32mGeneration successful !\e[0m" | |
ifeq ($(EXECUTION), native) | |
$(SILENT) $(if $(filter $(CONFIG), release),\ | |
echo "Stripping binary ...";\ | |
strip $(BINDIR)/$(CONFIG)/$(EXEC);\ | |
echo "Done !",) | |
else | |
@ echo -e "\e[1m\e[92mBitcode generated\e[0m" | |
endif | |
@ $(if $(OK)$(filter $(CONFIG), analysis),\ | |
echo -e "Resulting file : \e[1m\e[92m$(EXEC)\e[0m";\ | |
echo -e "See the result in the following directory : \e[1m\e[96m$(OUTPATH)\e[0m",) | |
# Generation of obj file for C source | |
$(OBJDIR)/$(CONFIG)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT) | |
$(eval OK=1) | |
$(SILENT) mkdir -p $(OBJDIR)/$(CONFIG)/$(dir $*) | |
$(SILENT) $(CXX) -I$(INCLDIR) -x c -o $(OBJDIR)/$(CONFIG)/$*.$(OBJEXT) -c $< $(CFLAGS) $(MAKEDEPEND) | |
# Generation of obj file for C++ source | |
$(OBJDIR)/$(CONFIG)/%.$(OBJEXT): $(SRCDIR)/%.$(CXXEXT) | |
$(eval OK=1) | |
$(SILENT) mkdir -p $(OBJDIR)/$(CONFIG)/$(dir $*) | |
$(SILENT) $(CXX) -I$(INCLDIR) -x c++ -o $(OBJDIR)/$(CONFIG)/$*.$(OBJEXT) -c $< $(CXXFLAGS) $(MAKEDEPEND) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment