Makefile won't compile anything other than "kernel.c" - makefile

I've been trying to compile an OS however whenever I attempt to compile it using the make file it only compiles "kernel.c" and I can't seem to figure out why. I need help to figure what's wrong. I've tried everything I could possibly do to fix it at least from my knowledge.
Here's the code:
PROJECT_DIR= ..
CXXFLAGS= -ggdb3 -O0 -Wall -O2 -ffreestanding -nostdinc -nostdlib
CFLAGS=-std=c17
CSRCFLAGS= -O2 -Wall -Wextra
LFLAGS= -ffreestanding -O2 -nostdlib
IMG_PATH= ../
BUILD_BACK_TWO= ../../../build
CFILES= $(wildcard *.c)
OFILES= $(CFILES:.c=.o)
GCCPATH=C:/CrossCompilers/gcc-arm-10.3-2021.07-mingw-w64-i686-aarch64-none-elf
CFLAGSSTART= -ffreestanding -c
CFLAGSEND= -O2 -Wall -Wextra
GCCFLAGS= -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
GCCPATHAARCH= $(GCCPATH)/aarch64-none-elf/bin
GCCPATHBIN= $(GCCPATH)/bin
ASMCFLAGS= -f elf32 -F dwarf -g -w+all
ASM= -s
# Location of the files
THIS_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))
SRC = $(PROJECT_DIR)/src
UI_IMAGES = $(PROJECT_DIR)/images/ui
OBJ_DIR = $(PROJECT_DIR)/build/objects
ASMSOURCES = $(wildcard $(SRC)/*.s)
SOURCES = $(wildcard $(SRC)/*.c)
SOURCES = $(wildcard $(SRC)/$(ARCHDIR)/*.c)
UISOURCES = $(wildcard $(UI_IMAGES)/*.png)
OBJECTS = $(patsubst $(SRC)/%.s, $(OBJ_DIR)/%.o, $(ASMSOURCES))
OBJECTS += $(patsubst $(SRC)/%.c, $(OBJ_DIR)/%.o, $(SOURCES))
OBJECTS += $(patsubst $(SRC)/$(ARCHDIR)/*.c, $(OBJ_DIR)/$(ARCHDIR)%.o, $(SOURCES))
OBJ_KEEP = objects_keep
#Headers
HEADERS = $(PROJECT_DIR)/inc
INCLUDE = -I$(HEADERS)
#File settings
KERNEL_NEEDED=kernel8.img
BASE_KERNEL=base_kernel.img
IMG_NAME=edited_reality
$(OBJ_DIR)/%.o: $(SRC)/%.s
mkdir -p $(#D)
#echo COMPILING $^
$(GCCPATHBIN)/aarch64-none-elf-as -c $^ -o $#
$(OBJ_DIR)/%.o: $(SRC)/%.c
mkdir -p $(#D)
#echo COMPILING $^
$(GCCPATHBIN)/aarch64-none-elf-gcc -ffreestanding $(INCLUDE) $(CFLAGS) -c $^ -o $# -O2 -Wall -Wextra
$(OBJ_DIR)/$(ARCHDIR)/%.o: $(SRC)/$(ARCHDIR)/%.c
mkdir -p $(#D)
#echo COMPILING $^
$(GCCPATHBIN)/aarch64-none-elf-gcc -ffreestanding $(INCLUDE) $(CFLAGS) -c $^ -o $# -O2 -Wall -Wextra
BUILD: $(OBJECTS)
mkdir -p $(#D)
#echo COMPILING $^
$(GCCPATHBIN)/aarch64-none-elf-gcc -nostdlib -T linker.ld -o $(IMG_NAME).elf -ffreestanding -O2 -nostdlib $(OBJECTS) $(INCLUDE) -lgcc
$(GCCPATHBIN)/aarch64-none-elf-objcopy $(IMG_NAME).elf -O binary $(KERNEL_NEEDED)
clean:
rm -rf $(OBJ_DIR)
rm -rf $(IMG_NAME).elf
rm -rf $(IMG_NAME).img
start:
#echo Starting
mkdir $(OBJ_DIR)
#echo .
#echo .
#echo .
.PHONY: clean start BUILD
EDIT: I couldn't figure it out so what I'm doing is just writing a one file C++ program that will compile everything else because that is so much easier (for some reason).
Anyways thanks everyone.

It's not clear whether you mean it runs the compiler one time then stops, or whether it runs the compiler many times but always on the same file. When asking for help please cut and paste the command you typed and the output you got (or the useful parts if there's a lot of it), and describe what is wrong and what you wanted to happen.
But, I think this is just a typo:
OBJECTS += $(patsubst $(SRC)/$(ARCHDIR)/*.c, $(OBJ_DIR)/$(ARCHDIR)%.o, $(SOURCES))
Note here you use $(SRC)/$(ARCHDIR)/*.c when you mean $(SRC)/$(ARCHDIR)/%.c.
You can add things like $(info $(OBJECTS)) to see the value of various variables (or run make -p).

Related

How to let avr-gcc output *.o to separate folder in Makefile with `%.o: %.c`?

As showed in first screenshot, my ideal AVR project structure is that:
*.o, *.elf and *.hex files are in build folder.
PomoScheler.c and pinDefines.h as main files are in root folder, while other *.c and *.h are in src folder.
But *.o are always generated at the same folder as *.c like showed in second screenshot, no matter how.
(I attached my endeavors and whole Makefile below the screenshots)
Firstly, I tried build/ before $#, in vain. The terminal still the same.
# My first Makefile endeavor
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o build/$#
# Terminal command generated by Makefile (Look at the end: *.o path still same as *.c)
avr-gcc -Os -g -std=gnu99 -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -DF_CPU=1000000UL -DBAUD=9600UL -I. -I~/Developer/bin/avr8-gnu-toolchain-darwin_x86_64/avr/include -mmcu=atmega328p -c -o src/RotaryEncoder.o src/RotaryEncoder.c
Secondly, I tried to add mv $# build to explicitly move it to build folder. But nothing happened. Even echo are not displayed in Terminal.
# My second Makefile endeavor
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $#
mv $# build
echo ---------Hello---------
Thirdly, I delete $(HEADERS) and replace $< with $^ just to have a try. The mv is executed. But it cannot find *.o file this time even though I have VPATH = src:build in Makefile.
# My third Makefile endeavor
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $^ -o $#
mv $# build
# Terminal error
Assembler messages:
Fatal error: can't create build/src/RotaryEncoder.o: No such file or directory
And my whole Makefile is here. Please help me out.
# My whole Makefile
MCU = atmega328p
F_CPU = 1000000UL
BAUD = 9600UL
LIBDIR = ~/Developer/bin/avr8-gnu-toolchain-darwin_x86_64/avr/include
PROGRAMMER_TYPE = usbtiny
PROGRAMMER_ARGS =
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
##########------------------------------------------------------##########
VPATH = ./src:./build
TARGET = $(lastword $(subst /, ,$(CURDIR)))
SOURCES=$(wildcard *.c src/*.c $(LIBDIR)/*.c)
OBJECTS=$(SOURCES:.c=.o)
HEADERS=$(SOURCES:.c=.h)
CPPFLAGS = -DF_CPU=$(F_CPU) -DBAUD=$(BAUD) -I. -I$(LIBDIR)
CFLAGS = -Os -g -std=gnu99 -Wall
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS = -Wl,-Map,build/$(TARGET).map
LDFLAGS += -Wl,--gc-sections
TARGET_ARCH = -mmcu=$(MCU)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o build/$#
$(TARGET).elf: $(OBJECTS)
$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o build/$#
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex build/$< build/$#
all: $(TARGET).hex
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
clean:
rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
$(TARGET).eeprom
flash: $(TARGET).hex
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
This is clearly not right:
OBJECTS = $(SOURCES:.c=.o)
because the object files you want to create are not foo.o etc. which is what this will expand to; the object files are build/foo.o etc. So this has to be:
OBJECTS = $(patsubst %.c,build/%.o)
All of your attempts to trick make by telling it your recipe will build one target (foo.o) but actually building a totally different target (build/foo.o) are doomed to fail, regardless of whether you have the compiler do it directly, you use mv, or any other method.
If you just tell make what your recipe actually does, you will have a much simpler time of it:
build/%.o: %.c
mkdir -p $(#D)
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $^ -o $#
Probably you have similar issues with the other rules that you want to put into other directories.
You can't do this by trying to hide it from make. Make has to know where the files actually are.
BTW, VPATH cannot help here. VPATH is for finding source files, it cannot be used for finding generated files. So you could use VPATH to find your .c files but not your .o files.

How to get prerequisites with respect to the target in Makefile (GNU Make)?

Is there a way to get the prerequisite corresponding to a target in the Makefile (GNU Make)?
For instance, consider the following Makefile:
CXX = g++
CFLAGS = -Wall
MODULE_NAME = myRenderer
BUILD_DIR = bin
SOURCE_FILES = renderer/tracer.cpp renderer/lights/DiffuseLight.cpp renderer/materials/ScatterUtils.cpp
OBJECT_FILES = $(patsubst %,$(BUILD_DIR)/%, $(notdir $(SOURCE_FILES:.cpp=.o)))
$(BUILD_DIR)/$(MODULE_NAME): $(OBJECT_FILES)
$(CXX) -o $# $^
$(OBJECT_FILES): $(SOURCE_FILES)
#mkdir -p "$(BUILD_DIR)"
$(CXX) $(CFLAGS) -I. -c $< -o $#
when I run make, I can see that the following commands get executed:
g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/DiffuseLight.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/ScatterUtils.o
g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o
And obviously, this fails to build the executable as it's using only the first prerequisite i.e. renderer/tracer.cpp to generate all the object files because I am using the $< automatic variable in the recipe command for the $(OBJECT_FILES) target.
I wish to know how to fix my Makefile to be able to execute these commands:
g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
g++ -Wall -I. -c renderer/lights/DiffuseLight.cpp -o bin/DiffuseLight.o
g++ -Wall -I. -c renderer/materials/ScatterUtils.cpp -o bin/ScatterUtils.o
g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o
I cannot seem to find the right automatic variable or a way to fetch the right source file to build a given object file.
As suggested by Matt you have (at least) two options:
A compilation rule:
# $(1): source file
define MY_RULE
$$(patsubst %.cpp,$$(BUILD_DIR)/%.o,$$(notdir $(1))): $(1)
#mkdir -p "$$(BUILD_DIR)"
$$(CXX) $$(CFLAGS) -I. -c $$< -o $$#
endef
$(foreach f,$(SOURCE_FILES),$(eval $(call MY_RULE,$(f))))
Note the $$ used to escape the first expansion (see The eval Function for a detailed explanation).
The vpath directive:
vpath %.cpp $(dir $(SOURCE_FILES))
$(BUILD_DIR)/%.o: %.cpp
#mkdir -p "$(BUILD_DIR)"
$(CXX) $(CFLAGS) -I. -c $< -o $#

How to rename various file extensions to .o in makefile?

Hi I have this makefile:
CC = gcc
AS = nasm
CFLAGS = -ffreestanding -Wall -Wextra -std=c11 -m32 -nostdlib -nostdinc -fno-stack-protector
LDFLAGS = -m elf_i386 -T link.ld
ASFLAGS = -f elf32
SOURCES = $(wildcard src/*.c wildcard src/*.s)
OBJECTS = $(SOURCES:.[s|o]=.o)
INCLUDEPATH = -I inc src/include
OBJDIR = bin/obj
SRCDIR = src/
all: build
build:
ld $(LDFLAGS) $(OBJECTS) -o bin/kernel.bin
iso: build
cp bin/kernel.bin XeonOS/boot
grub-mkrescue -o XeonOS.iso XeonOS/
run: iso
quemu-system-i386 -m 512M -cdrom XeonOS.iso
clean:
rm -rf bin/*.o bin/kernel.bin
%.o: $(SRCDIR)%.c
$(CC) $(INCLUDEPATH) $(CFLAGS) $< -o $(OBJDIR)/$(OBJECTS)
%.o: $(SRCDIR)%.s
$(AS) $(ASFLAGS) $< -o $(OBJDIR)/$(OBJECTS)
And when i execute the command make run i get the following error:
ld -m elf_i386 -T link.ld src/kernel_c.c src/kernel_asm.s -o bin/kernel.bin
ld:src/kernel_c.c: file format not recognized; treating as linker script
Because the kernel_c.c and kernel_asm.s didn' change their extension to .o. How can i change the extension of both .s and .c to .o at the same time?
By the way, I will have another problem, the value of the OBJECTS variable contains the src/ directory but the object files are stored in the bin/obj folder, How can i change that?
When I had this problem last month I just did this:
SOURCES_C := $(wildcard src/*.c)
SOURCES_S := $(wildcard src/*.s)
OBJECTS := $(SOURCES_C:%.c=%.o) \
$(SOURCES_S:%.s=%.o)
I haven't looked at this too deeply but, as far as I know, that's your best bet.
Finally I used the #LightnessRacesinOrbit advice and also used patsubsr so the code is now working:
CC = gcc
AS = nasm
CFLAGS = -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs -Wall -Wextra -Werror
LDFLAGS = -m elf_i386 -T link.ld
ASFLAGS = -f elf32
C_SOURCES = $(wildcard src/*.c)
C_OBJECTS = $(patsubst %.c,%.o, $(notdir $(C_SOURCES) ))
ASM_SOURCES = $(wildcard src/*.s)
ASM_OBJECTS = $(patsubst %.s,%.o, $(notdir $(ASM_SOURCES) ))
INCLUDEPATH = -I src/include
OBJDIR = bin/obj
SRCDIR = src/
.PHONY: build
all: build
build: $(C_OBJECTS) $(ASM_OBJECTS)
ld $(LDFLAGS) $(OBJDIR)/$(ASM_OBJECTS) $(OBJDIR)/$(C_OBJECTS) -o bin/kernel.bin
iso: build
cp bin/kernel.bin XeonOS/boot
grub-mkrescue -o XeonOS.iso XeonOS/
run: iso
bochs -f bochsconfig.cfg -q
clean:
rm -rf XeonOS/boot/kernel.bin
rm -rf bin/obj/*.o bin/kernel.bin
%.o: $(SRCDIR)%.c
$(CC) $(INCLUDEPATH) $(CFLAGS) $< -o $(OBJDIR)/$#
%.o: $(SRCDIR)%.s
$(AS) $(ASFLAGS) $< -o $(OBJDIR)/$#

How to change gcc compile message in makefile

I am new to programming.
I need to help me with hiding a message in makefile.
Let me show you:
When compiling this set of files(grid.cc attribute.cc targa.cc) http://prntscr.com/67ack4
I see this message: gcc5 -Wall -O2 -pipe -mtune=i686 -c attribute.cc
And I want to defend me something like: Compilation targa.cc
And I want to defend me something like: Compilation attribute.cc
etc
etc ...
I hope you understand what I mean.
Here is my makefile :
BIN = ../libgame.a
CXX = gcc5
CFLAGS = -Wall -O2 -pipe -mtune=i686
OBJFILES = grid.o attribute.o targa.o
########################################################################################################
default:
$(CXX) $(CFLAGS) -c grid.cc
$(CXX) $(CFLAGS) -c attribute.cc
$(CXX) $(CFLAGS) -c targa.cc
ar cru $(BIN) $(OBJFILES)
ranlib $(BIN)
rm -f *.o
You can use an automake-style silent rules trick to control what is output for your commands.
To do this directly you would do this:
BIN = ../libgame.a
CXX = gcc5
CFLAGS = -Wall -O2 -pipe -mtune=i686
OBJFILES = grid.o attribute.o targa.o
########################################################################################################
default:
#echo 'Compiling grid.cc';$(CXX) $(CFLAGS) -c grid.cc
#echo 'Compiling attribute.cc';$(CXX) $(CFLAGS) -c attribute.cc
#echo 'Compiling targa.cc';$(CXX) $(CFLAGS) -c targa.cc
ar cru $(BIN) $(OBJFILES)
ranlib $(BIN)
rm -f *.o
Alternatively you could use my silent_rules.mk and use:
$(eval $(call vrule,Compile,Compiling $$(value 1))
$(call Compile,grid.cc);$(CXX) $(CFLAGS) -c grid.cc
$(call Compile,attribute.cc);$(CXX) $(CFLAGS) -c attribute.cc
$(call Compile,targa.cc);$(CXX) $(CFLAGS) -c targa.cc
to get Compiling grid.cc, Compiling attribute.cc and Compiling targa.cc messages instead. (If you were using proper targets for your object files you could use the default $(GEN) silent rule to get GEN xxx.o output automatically.

Make wildcard dependency No rule to make target needed by

I am trying to build my targets with wildcards. Here is my Makefile:
BINARY = main
LDSCRIPT = stm32f4-discovery.ld
PREFIX ?= arm-none-eabi
CC = $(PREFIX)-gcc
LD = $(PREFIX)-gcc
OBJCOPY = $(PREFIX)-objcopy
CFLAGS += -Os -g \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I$(TOOLCHAIN_DIR)/include \
-fno-common -mcpu=cortex-m4 -mthumb \
-mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4
LDSCRIPT ?= $(BINARY).ld
LDFLAGS += --static -lc -lnosys -L$(TOOLCHAIN_DIR)/lib \
-L$(TOOLCHAIN_DIR)/lib/stm32/f4 \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
-mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
OBJS += $(BINARY).o
all: images
images: $(BINARY).images
%.images: %.bin
##printf "*** $* images generated ***\n"
%.bin: %.elf
##printf " OBJCOPY $(*).bin\n"
$(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin
%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f4.a
##printf " LD $(subst $(shell pwd)/,,$(#))\n"
$(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32f4 $(LDFLAGS)
%.o: %.c Makefile
##printf " CC $(subst $(shell pwd)/,,$(#))\n"
$(Q)$(CC) $(CFLAGS) -o $# -c $<
clean:
$(Q)rm -f *.o
$(Q)rm -f *.d
$(Q)rm -f *.elf
$(Q)rm -f *.bin
-include $(OBJS:.o=.d)
When I make, I get the error:
make: *** No rule to make target `main.bin', needed by `main.images'. Stop.
I am trying to make a single image, so I can change each % to $(BINARY), and this works, but I would like to figure out why this isn't working.
You are likely missing a dependency somewhere down the chain.
Note: Some people forget that the "Makefile" itself, when placed on the dependency line - is also checked for existance. Double check that you haven't renamed it.
Like #MadScientist recommends, "make -d" will be your friend here. Use that to locate the rule/file that should have been found but was not.
I simplified your example (on Linux) and got the same type of error with:
Makefile:
all: main.out
%.out: %.elf
g++ $^ -o $#
%.elf: %.obj
mv $^ $#
%.obj: %.cpp Makefile
g++ -c $^ -o $#
Create main.cpp, see it work, then rename main.cpp to something else that it can't find, run again, see it fail.
Now rename the Makefile itself, see the same failure.

Resources