Makefile 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #
  2. # The Makefile implements a basic make utility file for simple to
  3. # intermediate assembly, C, C++ or a mixture of these three language(s)
  4. # programs. Outputs assembly, intermediate and object files.
  5. # Copyright (C) 1989-2089 Sergey Sergeevich Tsybanov All Rights Reserved
  6. #
  7. # The Makefile compilation utility is free software: you can
  8. # redistribute it and/or modify it under the terms of the GNU General
  9. # Public License as published by the Free Software Foundation, either
  10. # version 3 of the License, or (at your option) any later version.
  11. #
  12. # The Makefile compilation utility is distributed in the hope that it
  13. # will be useful, but WITHOUT ANY WARRANTY; without even the implied
  14. # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. # See the GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with the Makefile compilation utility.
  19. # If not, see <https://www.gnu.org/licenses/>.
  20. #
  21. # Shell information
  22. SHELL = /bin/bash
  23. # Build information
  24. BUILD_TYPE ?= debug
  25. PLATFORM ?= GNU_x86_64
  26. # Directories
  27. ADIR ?= assembly
  28. BDIR ?= build
  29. EDIR ?= $(BDIR)/$(BUILD_TYPE)
  30. HDIR ?= includes
  31. IDIR ?= intermediates
  32. ODIR ?= objects
  33. SDIR ?= source
  34. # Assembler
  35. AS = as
  36. ASFLAGS ?=
  37. # C compiler
  38. CC_GNU_x86_64 ?= gcc
  39. CC_GNU_x86 ?= gcc
  40. CFLAGS_GNU_x86_64_release ?= -O3
  41. CFLAGS_GNU_x86_64_debug ?= -O0 -g -Wall -Wextra
  42. CFLAGS_GNU_x86_release ?= -O3 -m32
  43. CFLAGS_GNU_x86_debug ?= -O0 -m32 -g -Wall -Wextra
  44. CC = $(CC_$(PLATFORM))
  45. CFLAGS ?= --std=c89 $(CFLAGS_$(PLATFORM)_$(BUILD_TYPE))
  46. # C Preprocessor
  47. CPPFLAGS ?= $(addprefix -I,$(HDIR))
  48. # C++ Compiler
  49. CXX_GNU_x86_64 ?= g++
  50. CXX_GNU_x86 ?= g++
  51. CXXFLAGS_GNU_x86_64_release ?= -O3
  52. CXXFLAGS_GNU_x86_64_debug ?= -O0 -g -Wall -Wextra
  53. CXXFLAGS_GNU_x86_release ?= -O3 -m32
  54. CXXFLAGS_GNU_x86_debug ?= -O0 -m32 -g -Wall -Wextra
  55. CXX = $(CXX_$(PLATFORM))
  56. CXXFLAGS ?= --std=c++11 $(CFLAGS_$(PLATFORM)_$(BUILD_TYPE))
  57. # Linker
  58. LD = ld
  59. LDFLAGS ?=
  60. LDLIBS ?=
  61. # File names, source files and object files
  62. NAMES0 := $(shell find $(SDIR) -name *.s \
  63. | rev | cut -d'/' -f-1 | rev | cut -d'.' -f-1)
  64. NAMES1 := $(shell find $(SDIR) -name *.c \
  65. | rev | cut -d'/' -f-1 | rev | cut -d'.' -f-1)
  66. NAMES2 := $(shell find $(SDIR) -name *.cpp \
  67. | rev | cut -d'/' -f-1 | rev | cut -d'.' -f-1)
  68. OBJSO := $(patsubst %,$(ODIR)/%,$(NAMES0:=.o))
  69. OBJS1 := $(patsubst %,$(ODIR)/%,$(NAMES1:=.o))
  70. OBJS2 := $(patsubst %,$(ODIR)/%,$(NAMES2:=.o))
  71. SRC0 := $(patsubst %,$(SDIR)/%,$(NAMES0:=.s))
  72. SRC1 := $(patsubst %,$(SDIR)/%,$(NAMES1:=.c))
  73. SRC2 := $(patsubst %,$(SDIR)/%,$(NAMES2:=.cpp))
  74. # Executable
  75. ARGS =
  76. EXEC ?= hello
  77. # Various commands
  78. MKDIR := mkdir -p
  79. # Link C++ specific code?
  80. ifneq ($(SRC2), $(OBJS2))
  81. LDLIBS += -lstdc++
  82. endif
  83. # Executable recipes
  84. $(EDIR)/$(EXEC) : $(OBJS0) $(OBJS1) $(OBJS2)
  85. $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
  86. # Assembly recipes
  87. $(OBJS0) : $(SRC0) INIT
  88. $(foreach names, $(NAMES0), $(AS) $(ASFLAGS) \
  89. $(SDIR)/$(names:=.s) -o $(ODIR)/$(names:=.o);)
  90. # C recipes
  91. $(OBJS1) : $(SRC1) INIT
  92. $(foreach names, $(NAMES1), $(CC) $(CFLAGS) $(CPPFLAGS) \
  93. -E $(SDIR)/$(names:=.c) -o $(IDIR)/$(names:=.i);)
  94. $(foreach names, $(NAMES1), $(CC) $(CFLAGS) $(CPPFLAGS) \
  95. -S $(IDIR)/$(names:=.i) -o $(ADIR)/$(names:=.s);)
  96. $(foreach names, $(NAMES1), $(CC) $(CFLAGS) $(CPPFLAGS) \
  97. -c $(ADIR)/$(names:=.s) -o $(ODIR)/$(names:=.o);)
  98. # C++ recipes
  99. $(OBJS2) : $(SRC2) INIT
  100. $(foreach names, $(NAMES2), $(CXX) $(CXXFLAGS) $(CPPFLAGS) \
  101. -E $(SDIR)/$(names:=.cpp) -o $(IDIR)/$(names:=.ii);)
  102. $(foreach names, $(NAMES2), $(CXX) $(CXXFLAGS) $(CPPFLAGS) \
  103. -S $(IDIR)/$(names:=.ii) -o $(ADIR)/$(names:=.s);)
  104. $(foreach names, $(NAMES2), $(CXX) $(CXXFLAGS) $(CPPFLAGS) \
  105. -c $(ADIR)/$(names:=.s) -o $(ODIR)/$(names:=.o);)
  106. # Initialize build
  107. INIT :
  108. $(MKDIR) $(ADIR) $(EDIR) $(IDIR) $(ODIR)
  109. .PHONY : clean mostlyclean
  110. clean :
  111. $(RM) -r $(ADIR) $(BDIR) $(IDIR) $(ODIR) *~
  112. mostlyclean :
  113. $(RM) -r $(ADIR) $(IDIR) $(ODIR) *~
  114. run :
  115. @$(MAKE) && ./$(EDIR)/$(EXEC) $(ARGS)