Alexandre Lision | 8af73cb | 2013-12-10 14:11:20 -0500 | [diff] [blame] | 1 | ifeq ($(LIBDIR),) |
| 2 | LIBDIR = ../lib |
| 3 | endif |
| 4 | ifeq ($(BINDIR),) |
| 5 | BINDIR = ../bin |
| 6 | endif |
| 7 | |
| 8 | # |
| 9 | # The name(s) of output lib file(s) (e.g. libapp.a). |
| 10 | # |
| 11 | LIB := $($(APP)_LIB) |
| 12 | SHLIB = $($(APP)_SHLIB) |
| 13 | SONAME = $($(APP)_SONAME) |
| 14 | |
| 15 | ifeq ($(SHLIB_SUFFIX),so) |
| 16 | SHLIB_OPT := -shared -Wl,-soname,$(SHLIB) |
| 17 | else ifeq ($(SHLIB_SUFFIX),dylib) |
| 18 | SHLIB_OPT := -dynamiclib -undefined dynamic_lookup -flat_namespace |
| 19 | else |
| 20 | SHLIB_OPT := |
| 21 | endif |
| 22 | |
| 23 | # |
| 24 | # The name of output executable file (e.g. app.exe). |
| 25 | # |
| 26 | EXE = $($(APP)_EXE) |
| 27 | |
| 28 | # |
| 29 | # Source directory |
| 30 | # |
| 31 | SRCDIR = $($(APP)_SRCDIR) |
| 32 | |
| 33 | # |
| 34 | # Output directory for object files (i.e. output/target) |
| 35 | # |
| 36 | OBJDIR = output/$(app)-$(TARGET_NAME) |
| 37 | |
| 38 | ifeq ($(OS_NAME),linux-kernel) |
| 39 | export $(APP)_CFLAGS += -DKBUILD_MODNAME=$(app) -DKBUILD_BASENAME=$(app) |
| 40 | endif |
| 41 | |
| 42 | |
| 43 | # |
| 44 | # OBJS is ./output/target/file.o |
| 45 | # |
| 46 | OBJS = $(foreach file, $($(APP)_OBJS), $(OBJDIR)/$(file)) |
| 47 | OBJDIRS := $(sort $(dir $(OBJS))) |
| 48 | |
| 49 | # |
| 50 | # FULL_SRCS is ../src/app/file1.c ../src/app/file1.S |
| 51 | # |
| 52 | FULL_SRCS = $(foreach file, $($(APP)_OBJS), $(SRCDIR)/$(basename $(file)).m $(SRCDIR)/$(basename $(file)).c $(SRCDIR)/$(basename $(file)).cpp $(SRCDIR)/$(basename $(file)).S) |
| 53 | |
| 54 | # |
| 55 | # When generating dependency (gcc -MM), ideally we use only either |
| 56 | # CFLAGS or CXXFLAGS (not both). But I just couldn't make if/ifeq to work. |
| 57 | # |
| 58 | DEPFLAGS = $($(APP)_CXXFLAGS) $($(APP)_CFLAGS) |
| 59 | |
| 60 | # Dependency file |
| 61 | DEP_FILE := .$(app)-$(TARGET_NAME).depend |
| 62 | |
| 63 | |
| 64 | print_common: |
| 65 | @echo "###" |
| 66 | @echo "### DUMPING MAKE VARIABLES (I WON'T DO ANYTHING ELSE):" |
| 67 | @echo "###" |
| 68 | @echo APP=$(APP) |
| 69 | @echo OBJDIR=$(OBJDIR) |
| 70 | @echo OBJDIRS=$(OBJDIRS) |
| 71 | @echo OBJS=$(OBJS) |
| 72 | @echo SRCDIR=$(SRCDIR) |
| 73 | @echo FULL_SRCS=$(FULL_SRCS) |
| 74 | @echo $(APP)_CFLAGS=$($(APP)_CFLAGS) |
| 75 | @echo $(APP)_CXXFLAGS=$($(APP)_CXXFLAGS) |
| 76 | @echo $(APP)_LDFLAGS=$($(APP)_LDFLAGS) |
| 77 | @echo DEPFLAGS=$(DEPFLAGS) |
| 78 | @echo CC=$(CC) |
| 79 | @echo AR=$(AR) |
| 80 | @echo AR_FLAGS=$(AR_FLAGS) |
| 81 | @echo RANLIB=$(RANLIB) |
| 82 | |
| 83 | print_bin: print_common |
| 84 | @echo EXE=$(subst /,$(HOST_PSEP),$(BINDIR)/$(EXE)) |
| 85 | @echo BINDIR=$(BINDIR) |
| 86 | |
| 87 | print_lib: print_common |
| 88 | ifneq ($(LIB),) |
| 89 | @echo LIB=$(subst /,$(HOST_PSEP),$(LIBDIR)/$(LIB)) |
| 90 | endif |
| 91 | ifneq ($(SHLIB),) |
| 92 | @echo SHLIB=$(subst /,$(HOST_PSEP),$(LIBDIR)/$(SHLIB)) |
| 93 | endif |
| 94 | ifneq ($(SONAME),) |
| 95 | @echo SONAME=$(subst /,$(HOST_PSEP),$(LIBDIR)/$(SONAME)) |
| 96 | endif |
| 97 | @echo LIBDIR=$(LIBDIR) |
| 98 | |
| 99 | ifneq ($(LIB),) |
| 100 | $(subst /,$(HOST_PSEP),$(LIBDIR)/$(LIB)): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP) |
| 101 | if test ! -d $(LIBDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)),$(HOST_MKDIR)); fi |
| 102 | $(AR) $(AR_FLAGS) $@ $(OBJS) |
| 103 | $(RANLIB) $@ |
| 104 | endif |
| 105 | |
| 106 | ifneq ($(SHLIB),) |
| 107 | $(subst /,$(HOST_PSEP),$(LIBDIR)/$(SHLIB)): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP) |
| 108 | if test ! -d $(LIBDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)),$(HOST_MKDIR)); fi |
| 109 | $(LD) $(LDOUT)$(subst /,$(HOST_PSEP),$@) \ |
| 110 | $(subst /,$(HOST_PSEP),$(OBJS)) $($(APP)_LDFLAGS) $(SHLIB_OPT) |
| 111 | endif |
| 112 | |
| 113 | ifneq ($(SONAME),) |
| 114 | $(subst /,$(HOST_PSEP),$(LIBDIR)/$(SONAME)): $(subst /,$(HOST_PSEP),$(LIBDIR)/$(SHLIB)) |
| 115 | ln -sf $(SHLIB) $@ |
| 116 | endif |
| 117 | |
| 118 | ifneq ($(EXE),) |
| 119 | $(subst /,$(HOST_PSEP),$(BINDIR)/$(EXE)): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP) |
| 120 | if test ! -d $(BINDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(BINDIR)),$(HOST_MKDIR)); fi |
| 121 | $(LD) $(LDOUT)$(subst /,$(HOST_PSEP),$(BINDIR)/$(EXE)) \ |
| 122 | $(subst /,$(HOST_PSEP),$(OBJS)) $($(APP)_LDFLAGS) |
| 123 | endif |
| 124 | |
| 125 | $(OBJDIR)/$(app).o: $(OBJDIRS) $(OBJS) |
| 126 | $(CROSS_COMPILE)ld -r -o $@ $(OBJS) |
| 127 | |
| 128 | $(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o |
| 129 | @echo Creating kbuild Makefile... |
| 130 | @echo "# Our module name:" > $(OBJDIR)/Makefile |
| 131 | @echo 'obj-m += $(app).o' >> $(OBJDIR)/Makefile |
| 132 | @echo >> $(OBJDIR)/Makefile |
| 133 | @echo "# Object members:" >> $(OBJDIR)/Makefile |
| 134 | @echo -n '$(app)-objs += ' >> $(OBJDIR)/Makefile |
| 135 | @for file in $($(APP)_OBJS); do \ |
| 136 | echo -n "$$file " >> $(OBJDIR)/Makefile; \ |
| 137 | done |
| 138 | @echo >> $(OBJDIR)/Makefile |
| 139 | @echo >> $(OBJDIR)/Makefile |
| 140 | @echo "# Prevent .o files to be built by kbuild:" >> $(OBJDIR)/Makefile |
| 141 | @for file in $($(APP)_OBJS); do \ |
| 142 | echo ".PHONY: `pwd`/$(OBJDIR)/$$file" >> $(OBJDIR)/Makefile; \ |
| 143 | done |
| 144 | @echo >> $(OBJDIR)/Makefile |
| 145 | @echo all: >> $(OBJDIR)/Makefile |
| 146 | @echo -e "\tmake -C $(KERNEL_DIR) M=`pwd`/$(OBJDIR) modules $(KERNEL_ARCH)" >> $(OBJDIR)/Makefile |
| 147 | @echo Invoking kbuild... |
| 148 | make -C $(OBJDIR) |
| 149 | |
| 150 | ../lib/$(app).ko: $(LIB) $(OBJDIR)/$(app).ko |
| 151 | cp $(OBJDIR)/$(app).ko ../lib |
| 152 | |
| 153 | $(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m |
| 154 | $(CC) $($(APP)_CFLAGS) \ |
| 155 | $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \ |
| 156 | $(subst /,$(HOST_PSEP),$<) |
| 157 | |
| 158 | $(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c |
| 159 | $(CC) $($(APP)_CFLAGS) \ |
| 160 | $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \ |
| 161 | $(subst /,$(HOST_PSEP),$<) |
| 162 | |
| 163 | $(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S |
| 164 | $(CC) $($(APP)_CFLAGS) \ |
| 165 | $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \ |
| 166 | $(subst /,$(HOST_PSEP),$<) |
| 167 | |
| 168 | $(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp |
| 169 | $(CXX) $($(APP)_CXXFLAGS) \ |
| 170 | $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \ |
| 171 | $(subst /,$(HOST_PSEP),$<) |
| 172 | |
| 173 | $(OBJDIRS): |
| 174 | $(subst @@,$(subst /,$(HOST_PSEP),$@),$(HOST_MKDIR)) |
| 175 | |
| 176 | $(LIBDIR): |
| 177 | $(subst @@,$(subst /,$(HOST_PSEP),$@),$(HOST_MKDIR)) |
| 178 | |
| 179 | $(BINDIR): |
| 180 | $(subst @@,$(subst /,$(HOST_PSEP),$@),$(HOST_MKDIR)) |
| 181 | |
| 182 | clean: |
| 183 | $(subst @@,$(subst /,$(HOST_PSEP),$(OBJDIR)/*),$(HOST_RMR)) |
| 184 | $(subst @@,$(subst /,$(HOST_PSEP),$(OBJDIR)),$(HOST_RMDIR)) |
| 185 | ifeq ($(OS_NAME),linux-kernel) |
| 186 | rm -f ../lib/$(app).o |
| 187 | endif |
| 188 | |
| 189 | gcov-report: |
| 190 | for file in $(FULL_SRCS); do \ |
| 191 | gcov $$file -n -o $(OBJDIR); \ |
| 192 | done |
| 193 | |
| 194 | realclean: clean |
| 195 | ifneq ($(LIB),) |
| 196 | $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)/$(LIB)),$(HOST_RM)) |
| 197 | endif |
| 198 | ifneq ($(SHLIB),) |
| 199 | $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)/$(SHLIB)),$(HOST_RM)) |
| 200 | endif |
| 201 | ifneq ($(SONAME),) |
| 202 | $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)/$(SONAME)),$(HOST_RM)) |
| 203 | endif |
| 204 | ifneq ($(EXE),) |
| 205 | $(subst @@,$(subst /,$(HOST_PSEP),$(BINDIR)/$(EXE)),$(HOST_RM)) |
| 206 | endif |
| 207 | $(subst @@,$(DEP_FILE),$(HOST_RM)) |
| 208 | ifeq ($(OS_NAME),linux-kernel) |
| 209 | rm -f ../lib/$(app).ko |
| 210 | endif |
| 211 | |
| 212 | depend: |
| 213 | $(subst @@,$(DEP_FILE),$(HOST_RM)) |
| 214 | for F in $(FULL_SRCS); do \ |
| 215 | if test -f $$F; then \ |
| 216 | echo "$(OBJDIR)/" | tr -d '\n' >> $(DEP_FILE); \ |
| 217 | if $(CC) -M $(DEPFLAGS) $$F | sed '/^#/d' >> $(DEP_FILE); then \ |
| 218 | true; \ |
| 219 | else \ |
| 220 | echo 'err:' >> $(DEP_FILE); \ |
| 221 | rm -f $(DEP_FILE); \ |
| 222 | exit 1; \ |
| 223 | fi; \ |
| 224 | fi; \ |
| 225 | done; |
| 226 | |
| 227 | dep: depend |
| 228 | |
| 229 | -include $(DEP_FILE) |
| 230 | |