+# Assemble: create object files from assembler source files.
+$1/%.o : %.S $1/asflags.txt $1/compiler.txt | $(BEGIN)
+ @mkdir -p $$(@D)
+ @$(SILENT) || printf "$$(MSG_ASSEMBLING) $$<" | $$(AWK_CMD)
+ $$(eval CMD=$$(CC) -c $$(ALL_ASFLAGS) $$< -o $$@)
+ @$$(BUILD_CMD)
+
+$1/force:
+
+$1/cflags.txt: $1/force
+ echo '$$(ALL_CFLAGS)' | cmp -s - $$@ || echo '$$(ALL_CFLAGS)' > $$@
+
+$1/cppflags.txt: $1/force
+ echo '$$(ALL_CPPFLAGS)' | cmp -s - $$@ || echo '$$(ALL_CPPFLAGS)' > $$@
+
+$1/asflags.txt: $1/force
+ echo '$$(ALL_ASFLAGS)' | cmp -s - $$@ || echo '$$(ALL_ASFLAGS)' > $$@
+
+$1/ldflags.txt: $1/force
+ echo '$$(LDFLAGS)' | cmp -s - $$@ || echo '$$(LDFLAGS)' > $$@
+
+$1/obj.txt: $1/force
+ echo '$$(OBJ)' | cmp -s - $$@ || echo '$$(OBJ)' > $$@
+
+$1/compiler.txt: $1/force
+ $$(CC) --version | cmp -s - $$@ || $$(CC) --version > $$@
+endef
+
+# We have to use static rules for the .d files for some reason
+DEPS = $(patsubst %.o,%.d,$(OBJ))
+# Keep the .d files
+.PRECIOUS: $(DEPS)
+# Empty rule to force recompilation if the .d file is missing
+$(DEPS):
+
+# Since the object files could be in two different folders, generate
+# separate rules for them, rather than having too generic rules
+$(eval $(call GEN_OBJRULE,$(OBJDIR)))
+$(eval $(call GEN_OBJRULE,$(KBOBJDIR)))
+