Makefile 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #
  2. # This Makefile implements
  3. # a basic make utility file
  4. # for this list program and
  5. # for this set_parity_print program.
  6. # Copyright (C) 1989-2089 Sergey Sergeevich Tsybanov
  7. #
  8. # This Makefile is free software:
  9. # you can redistribute it and/or
  10. # modify it under the terms of the
  11. # GNU Affero General Public License
  12. # as published by the Free Software
  13. # Foundation, either version 3 of
  14. # the License, or (at your option)
  15. # any later version.
  16. #
  17. # This Makefile is distributed in
  18. # the hope that it will be useful,
  19. # but WITHOUT ANY WARRANTY; without
  20. # even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A
  22. # PARTICULAR PURPOSE. See the
  23. # GNU Affero General Public License
  24. # for more details.
  25. #
  26. # You should have received a copy of
  27. # the GNU Affero General Public License
  28. # along with this Makefile. If not,
  29. # see <https://www.gnu.org/licenses/>.
  30. #
  31. # Shell information
  32. SHELL = /bin/bash
  33. # Build information
  34. BUILD_TYPE ?= debug
  35. PLATFORM ?= GNU_x86_64
  36. # Directories
  37. ADIR ?= assembly
  38. BDIR ?= build
  39. DDIR ?= dependencies
  40. EDIR ?= $(BDIR)/$(BUILD_TYPE)
  41. HDIR ?= includes
  42. IDIR ?= intermediates
  43. ODIR ?= objects
  44. SDIR ?= source
  45. # Assembler
  46. AS_GNU_ARM ?= arm-linux-gnueabi-as
  47. AS_GNU_x86_64 ?= as
  48. AS_GNU_x86 ?= as
  49. ASFLAGS_GNU_ARM_release ?=
  50. ASFLAGS_GNU_ARM_debug ?=
  51. ASFLAGS_GNU_x86_64_release ?=
  52. ASFLAGS_GNU_x86_64_debug ?=
  53. ASFLAGS_GNU_x86_release ?=
  54. ASFLAGS_GNU_x86_debug ?=
  55. AS = $(AS_$(PLATFORM))
  56. ASFLAGS ?= $(ASFLAGS_$(PLATFORM)_$(BUILD_TYPE))
  57. # C compiler
  58. CC_GNU_ARM ?= arm-linux-gnueabi-gcc
  59. CC_GNU_x86_64 ?= gcc
  60. CC_GNU_x86 ?= gcc
  61. CFLAGS_GNU_ARM_release ?= -O3
  62. CFLAGS_GNU_ARM_debug ?= -O0 -g -Wall -Wextra
  63. CFLAGS_GNU_x86_64_release ?= -O3
  64. CFLAGS_GNU_x86_64_debug ?= -O0 -g -Wall -Wextra
  65. CFLAGS_GNU_x86_release ?= -O3 -m32
  66. CFLAGS_GNU_x86_debug ?= -O0 -m32 -g -Wall -Wextra
  67. CC = $(CC_$(PLATFORM))
  68. CFLAGS ?= --std=gnu89 $(CFLAGS_$(PLATFORM)_$(BUILD_TYPE))
  69. # C preprocessor
  70. CPPFLAGS ?= $(addprefix -I,$(shell find $(HDIR) -type d)) -MMD -MP
  71. # C++ compiler
  72. CXX_GNU_ARM ?= arm-linux-gnueabi-g++
  73. CXX_GNU_x86_64 ?= g++
  74. CXX_GNU_x86 ?= g++
  75. CXXFLAGS_GNU_ARM_release ?= -O3
  76. CXXFLAGS_GNU_ARM_debug ?= -O0 -g -Wall -Wextra
  77. CXXFLAGS_GNU_x86_64_release ?= -O3
  78. CXXFLAGS_GNU_x86_64_debug ?= -O0 -g -Wall -Wextra
  79. CXXFLAGS_GNU_x86_release ?= -O3 -m32
  80. CXXFLAGS_GNU_x86_debug ?= -O0 -m32 -g -Wall -Wextra
  81. CXX = $(CXX_$(PLATFORM))
  82. CXXFLAGS ?= --std=gnu++11 $(CXXFLAGS_$(PLATFORM)_$(BUILD_TYPE))
  83. # Linker
  84. LD_GNU_ARM ?= arm-linux-gnueabi-ld
  85. LD_GNU_x86_64 ?= ld
  86. LD_GNU_x86 ?= ld
  87. LDFLAGS_GNU_ARM_release ?= -pthread
  88. LDFLAGS_GNU_ARM_debug ?= -pthread
  89. LDFLAGS_GNU_x86_64_release ?= -pthread
  90. LDFLAGS_GNU_x86_64_debug ?= -pthread
  91. LDFLAGS_GNU_x86_release ?= -m32 -pthread
  92. LDFLAGS_GNU_x86_debug ?= -m32 -pthread
  93. LD = $(LD_$(PLATFORM))
  94. LDFLAGS ?= $(LDFLAGS_$(PLATFORM)_$(BUILD_TYPE))
  95. LDLIBS ?=
  96. # File paths, directories, object files,
  97. # source files and dependencies
  98. PATHS0 := $(patsubst %,/%, \
  99. $(shell find $(SDIR) -name '*.s' | \
  100. cut --complement -d'/' -f1 | cut -d'.' -f-1))
  101. PATHS1 := $(patsubst %,/%, \
  102. $(shell find $(SDIR) -name '*.c' | \
  103. cut --complement -d'/' -f1 | cut -d'.' -f-1))
  104. PATHS2 := $(patsubst %,/%, \
  105. $(shell find $(SDIR) -name '*.cpp' | \
  106. cut --complement -d'/' -f1 | cut -d'.' -f-1))
  107. DIRS0 := $(shell for path in $(patsubst %,/%, \
  108. $(shell find $(SDIR) -name '*.s' | rev | \
  109. cut --complement -d'/' -f1 | rev | uniq | sort)); \
  110. do echo $$path | cut --complement -d'/' -f2; done)
  111. DIRS1 := $(shell for path in $(patsubst %,/%, \
  112. $(shell find $(SDIR) -name '*.c' | rev | \
  113. cut --complement -d'/' -f1 | rev | uniq | sort)); \
  114. do echo $$path | cut --complement -d'/' -f2; done)
  115. DIRS2 := $(shell for path in $(patsubst %,/%, \
  116. $(shell find $(SDIR) -name '*.cpp' | rev | \
  117. cut --complement -d'/' -f1 | rev | uniq | sort)); \
  118. do echo $$path | cut --complement -d'/' -f2; done)
  119. OBJS0 := $(patsubst %,$(ODIR)%,$(PATHS0:=.o))
  120. OBJS1 := $(patsubst %,$(ODIR)%,$(PATHS1:=.o))
  121. OBJS2 := $(patsubst %,$(ODIR)%,$(PATHS2:=.o))
  122. SRC0 := $(patsubst %,$(SDIR)%,$(PATHS0:=.s))
  123. SRC1 := $(patsubst %,$(SDIR)%,$(PATHS1:=.c))
  124. SRC2 := $(patsubst %,$(SDIR)%,$(PATHS2:=.cpp))
  125. DEPS0 := $(patsubst %,$(DDIR)%,$(PATHS1:=.d))
  126. DEPS1 := $(patsubst %,$(DDIR)%,$(PATHS2:=.d))
  127. # Executable
  128. ARGS =
  129. EXEC ?= executable
  130. # Various commands
  131. MKDIR := mkdir -p
  132. MV := mv
  133. # Link C++ specific code?
  134. ifneq ($(SRC2), $(OBJS2))
  135. LDLIBS += -lstdc++
  136. endif
  137. .PHONY : all clean mostlyclean run
  138. # Final recipe
  139. all : BUILD
  140. # Initialization recipe
  141. INIT :
  142. $(MKDIR) $(ADIR) $(DDIR) $(EDIR) $(HDIR) $(IDIR) \
  143. $(ODIR) $(SDIR)
  144. $(foreach dir, $(DIRS0), \
  145. $(MKDIR) $(ODIR)/$(dir);)
  146. $(foreach dir, $(DIRS1), \
  147. $(MKDIR) $(ADIR)/$(dir) $(DDIR)/$(dir) \
  148. $(IDIR)/$(dir) $(ODIR)/$(dir);)
  149. $(foreach dir, $(DIRS2), \
  150. $(MKDIR) $(ADIR)/$(dir) $(DDIR)/$(dir) \
  151. $(IDIR)/$(dir) $(ODIR)/$(dir);)
  152. # Build recipe
  153. BUILD : INIT
  154. @$(MAKE) --no-print-directory $(EDIR)/$(EXEC)
  155. # Executable recipe
  156. $(EDIR)/$(EXEC) : $(OBJS0) $(OBJS1) $(OBJS2)
  157. $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
  158. # Assembly recipe
  159. $(OBJS0) : $(SRC0)
  160. $(foreach path, $(PATHS0), $(AS) $(ASFLAGS) \
  161. $(SDIR)$(path:=.s) -o $(ODIR)$(path:=.o);)
  162. # C recipe
  163. $(OBJS1) : $(SRC1)
  164. $(foreach path, $(PATHS1), \
  165. $(CC) $(CFLAGS) $(CPPFLAGS) \
  166. -E $(SDIR)$(path:=.c) -o $(IDIR)$(path:=.i) \
  167. && $(CC) $(CFLAGS) $(CPPFLAGS) \
  168. -S $(IDIR)$(path:=.i) -o $(ADIR)$(path:=.s) \
  169. && $(CC) $(CFLAGS) $(CPPFLAGS) \
  170. -c $(ADIR)$(path:=.s) -o $(ODIR)$(path:=.o);)
  171. $(foreach dep, $(DEPS0), \
  172. $(MV) $(patsubst %,$(IDIR)/%, \
  173. $(shell echo $(dep) | cut --complement -d'/' -f1)) \
  174. $(shell echo $(dep) | rev | cut -d'/' \
  175. --complement -f1 | rev);)
  176. # C++ recipe
  177. $(OBJS2) : $(SRC2)
  178. $(foreach path, $(PATHS2), \
  179. $(CXX) $(CXXFLAGS) $(CPPFLAGS) \
  180. -E $(SDIR)$(path:=.cpp) -o $(IDIR)$(path:=.ii) \
  181. && $(CXX) $(CXXFLAGS) $(CPPFLAGS) \
  182. -S $(IDIR)$(path:=.ii) -o $(ADIR)$(path:=.s) \
  183. && $(CXX) $(CXXFLAGS) $(CPPFLAGS) \
  184. -c $(ADIR)$(path:=.s) -o $(ODIR)$(path:=.o);)
  185. $(foreach dep, $(DEPS1), \
  186. $(MV) $(patsubst %,$(IDIR)/%, \
  187. $(shell echo $(dep) | cut --complement -d'/' -f1)) \
  188. $(shell echo $(dep) | rev | cut -d'/' \
  189. --complement -f1 | rev);)
  190. # Make options
  191. clean :
  192. $(RM) -r $(ADIR) $(BDIR) $(DDIR) $(IDIR) $(ODIR) *~
  193. mostlyclean :
  194. $(RM) -r $(ADIR) $(DDIR) $(IDIR) $(ODIR) *~
  195. run :
  196. @$(MAKE) && ./$(EDIR)/$(EXEC) $(ARGS)
  197. -include $(DEPS0) $(DEPS1)