How to rename various file extensions to .o in makefile? - 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)/$#

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.

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

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).

Makefile with pthread library?

I'm doing a project for University about UDP communication; i need compile with -pthread because i need a semaphore; i tried copy what i found on this forum, but it doesn't run..This is my makefile:
CC=gcc
CFLAGS=-Wall -Wextra -O2
SRC = create_children4.o clientUDP3.o socket_operation.o
OBJ = $(SRC:.c=.o)
all: $(OBJ)
${CC} create_children4.o socket_operation.o -o create_children4
${CC} clientUDP3.o socket_operation.o -o clientUDP3
create_children4.o: socket_operation.h
clientUDP3.o: socket_operation.h
socket_operation.o:
clean:
rm -f *.o core
cleanall:
rm -f *.o core create_children4 clientUDP3

How to make specific binary from specific object file?

Here is my makefile, i have object files in obj/ directory, and i need to compile them into binaries in bin/ folder, but somehow it doesn't work as i wanted it to work, any ideas?
SOURCES= $(wildcard *.c)
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
OBJECTS:= $(addprefix obj/,$(OBJECTS))
NAMES:= $(patsubst %.c, %, $(SOURCES))
NAMES:= $(addprefix bin/,$(NAMES))
CC=gcc
CFLAGS= -Wall -c -o
DIRS = bin obj
all: $(DIRS) $(NAMES)
$(NAMES): $(OBJECTS)
$(CC) -o $# $<
obj/%.o: %.c
$(CC) $(CFLAGS) $# $<
$(DIRS):
mkdir -p $#
clean:
rm -rf $(DIRS)
Actual output:
mkdir -p bin
mkdir -p obj
gcc -Wall -c -o obj/task1.o task1.c
gcc -Wall -c -o obj/task2.o task2.c
gcc -Wall -c -o obj/task3.o task3.c
gcc -o bin/task1 obj/task1.o
gcc -o bin/task2 obj/task1.o
gcc -o bin/task3 obj/task1.o
Expected output:
mkdir -p bin
mkdir -p obj
gcc -Wall -c -o obj/task1.o task1.c
gcc -Wall -c -o obj/task2.o task2.c
gcc -Wall -c -o obj/task3.o task3.c
gcc -o bin/task1 obj/task1.o
gcc -o bin/task2 obj/task2.o
gcc -o bin/task3 obj/task3.o
In this rule:
$(NAMES): $(OBJECTS)
$(CC) -o $# $<
each executable depends on all objects. And since $< grabs only the first prerequisite, all you see is obj/task1.o.
Do it this way:
bin/%: obj/%.o
$(CC) -o $# $<
or this way:
$(NAMES): bin/% : obj/%.o
$(CC) -o $# $<

My Makefile just doesnt work.

I have a makefile which is just not working. Can you guys help me to find where the error is? Thanks!
CC = gcc
FILES = workfile.c insert.c
TARGETS = exe
CFLAGS = -o
DBUG =
RM = rm -f
OBJS = *.o
#Master Rule
all: $(TARGETS)
#Build
exe: workfile.o insert.o
$(CC) $(CFLAGS) $(DBUG) workfile.o insert.o exe
#workfile
workfile.o: workfile.c
$(CC) $(DBUG) -c *.c
insert.o: insert.c
$(CC) $(DBUG) -c *.c
clean:
$(RM) $(TARGETS) $(OBJS)
The error is as follows
$make all
gcc -c *.c
gcc -o workfile.o insert.o exe
gcc: error: exe: No such file or directory
make: *** [exe] Error 1
I even tried changing the names of the targets. But did not help. Could not continue further.
I don't think it is a good idea to put -o in CFLAGS, I would rather to remove -o from it.
CFLAGS = -o -> CFLAGS =
Now you can work on your exe, the output path should follow -o immediately.
exe: workfile.o insert.o
$(CC) $(CFLAGS) $(DBUG) workfile.o insert.o exe
=>
exe: workfile.o insert.o
$(CC) $(CFLAGS) $(DBUG) -o exe workfile.o insert.o
So the full makefile should look like:
CC = gcc
FILES = workfile.c insert.c
TARGETS = exe
CFLAGS =
DBUG =
RM = rm -f
OBJS = *.o
#Master Rule
all: $(TARGETS)
#Build
exe: workfile.o insert.o
$(CC) $(CFLAGS) $(DBUG) -o exe workfile.o insert.o
#workfile
workfile.o: workfile.c
$(CC) $(DBUG) -o workfile.o -c workfile.c
insert.o: insert.c
$(CC) $(DBUG) -o insert.o -c insert.c
clean:
$(RM) $(TARGETS) $(OBJS)
Your CFLAGS is used wrongly. The -o option should go before exe and the CFLAGS should contain relevant flags for the compiler (-O3 -Wall -Wextra -Werror for example).
Try this:
CFLAGS = -Wall -Wextra -Werror
exe: workfile.o insert.o
$(CC) $(CFLAGS) $(DBUG) workfile.o insert.o -o exe
PS: You can strip the DBUG and stick the -g in CFLAGS when needed. This is how it is used in normal Makefiles.
Uh i got it... you have an -o in there in cflags. I think you shouldn't use -o in CFLAGS because it expects a parameter.
The important part that could be changed:
CFLAGS =
OUTFILE = fancy_exe
[...]
$(CC) $(CFLAGS) $(DBUG) workfile.o insert.o -o $(OUTFILE)
This should work better... or even skip the outfile varaible and put exe by hand.

Resources