makefile error: “make: *** No rule to make target …” - makefile

I'm trying to use GCC (linux) with a makefile to compile my project.
I get the following error
"No rule to make target 'output/src/main.o', needed by 'test'. Stop."
This is the makefile:
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix ./output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I ./src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
%.o: %.c
#mkdir -p ./output
$(CC) $(CFLAGS) $(INCLUDES) -o $(addprefix ./output/, $#) -c $<
clean:
rm -rf ./output

This should work. Note the use of mkdir $(#D) to create output directories as needed.
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
output/%.o: %.c
#mkdir -p $(#D)
$(CC) $(CFLAGS) $(INCLUDES) -o $# -c $<
clean:
rm -rf output
Running it here with make clean test:
rm -rf output
gcc -O2 -Wall -g -I src -o output/src/hello.o -c src/hello.c
gcc output/src/hello.o -lpthread -o test

Related

No rule to make target - Makefille

I need some help understanding why my makefile is not picking up the rule to convert my .c files in .o.
NAME = push_swap
INCLUDES = -I includes -I $(LIBFT_DIR)/includes/
LIBFT_DIR = libft/
CC = gcc
CFLAGS = -Wall -Wextra -Werror
DIR_SRCS = srcs
DIR_OBJS = objs
SRCS = push_swap.c utils_1.c
OBJS = $(subst $(DIR_SRCS), $(DIR_OBJS), $(SRCS:.c=.o))
all: $(NAME)
$(OBJF):
#mkdir -p $(DIR_OBJS)
$(DIR_OBJS)/%.o : $(DIR_SRCS)/%.c | $(OBJF)
#$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
$(LIBFT):
#make -C $(LIBFT_DIR)
$(NAME): $(OBJS) $(LIBFT)
#$(CC) $(CFLAGS) -o $(NAME) $(OBJS)
clean:
rm -f $(OBJS)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re bonus
I get the following error:
make: *** No rule to make target 'push_swap.o', needed by 'push_swap'. Stop.
It's the first time I'm adding folders to my makefile and maybe I'm doing something wrong there.
Thank you.
EDIT:
Thank you all for your help.
I ended up changing a few things because I was having a hard time doing it the other way.
NAME = push_swap
INCLUDES = -I includes -I $(LIBFT_DIR)/includes/
LIBFT_DIR = libft/
CC = gcc
CFLAGS = -Wall -Wextra -Werror
DIR_SRCS = srcs/
DIR_OBJS = objs/
SRCS_FILES = push_swap utils_1
SRCS = $(addprefix $(DIR_SRCS), $(addsuffix .c, $(SRCS_FILES)))
OBJS = $(addprefix $(DIR_OBJS), $(addsuffix .o, $(SRCS_FILES)))
all: $(NAME)
$(NAME): $(OBJS) $(LIBFT)
#$(CC) $(CFLAGS) -o $(NAME) $(OBJS) $(LIBFT_DIR)libft.a
$(DIR_OBJS)%.o : $(DIR_SRCS)%.c $(OBJF)
#mkdir -p $(DIR_OBJS)
#$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
$(LIBFT):
#make -C $(LIBFT_DIR)
clean:
rm -f $(OBJS)
rm -r $(DIR_OBJS)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re
Like this it runs perfectly.
With:
SRCS = push_swap.c utils_1.c
The line:
OBJS = $(subst $(DIR_SRCS), $(DIR_OBJS), $(SRCS:.c=.o))
is replacing the $(DIR_SRCS) (srcs) value with $(DIR_OBJS) (objs), BUT the SRC values does have objs in it so:
OBJS = push_swap.o utils_1.o
And so not finding a rule for it.
Try changing to:
SRCS = $(DIR_SRCS)/push_swap.c $(DIR_SRCS)/utils_1.c

What does “linker input file unused because linking not done” mean?

This is weird. The compiler throws this warning though everything works as expected.
This is the makefile that throws the warning:
TARGET = $(notdir $(shell pwd))
LIBS = -lm -lev3dev-c
D_BIN = Build-Assets
ifeq ($(OS),Windows_NT)
LIBS := $(LIBS) -lws2_32
D_BIN := $(D_BIN)/mingw
endif
D_H = ../../source/ev3
CFLAGS = $(addprefix -I, $(D_H)) -O2 -std=gnu99 -W -Wall -Wno-comment
ifeq ($(OS),Windows_NT)
CC = gcc
else
CC = arm-linux-gnueabi-gcc
endif
ifeq ($(OS),Windows_NT)
E_BIN = .exe
else
E_BIN =
endif
F_BIN = $(TARGET)$(E_BIN)
OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard MotorControl/*.c)))
.PHONY: default all clean
default: $(F_BIN)
all: default
$(OBJECTS): $(D_BIN)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(F_BIN) $(OBJECTS)
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
clean:
-rm -f $(D_BIN)/*.o
-rm -f $(F_BIN)
I should add that I have no idea what I'm doing... I am just starting out with C and those damn makefiles are very overwhelming.
The -c option skips the final link and produces a relocatable object file:
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
This is why linker input files are not used at this stage. You should be able to remove the -c option, and the command will produce an executable as a result.

makefile with 2 executables, how?

My project is organized like this :
src/plateau.c plateau.h tuile.c tuile.h main.c
tests/tests.c
obj/
bin/
I'm trying to do a makefile with 2 executables. I can't figure out why it doesn't works.
The makefile with one executable only works fine, it looks like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
And with two executables, I tried like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu tests
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
tests: $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o tests
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
$(OBJDIR)/test_honshu.o: $(SRCDIR)/test_honshu.c
$(CC) -c -I src $(SRCDIR)/test_honshu.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
But I have the following message "no rules to make "src/test_honshu.c", necessary for "obj.test_honshu.o", do you have an idea ? Thanks !

Makefile objects from .c .cpp and .S sources

I am facing a problem with my makefile. I am trying to compile .c; .cpp and .S files from ./src/. The objects should go into ./obj/ and the binaries into ./bin/. With my current file, it tries to searches for files in ./src/, but tries to compile objectfiles for each extension. So for example, if it finds kernel.cpp, it will try to compile kernel.S and kernel.c, but they are not there, so i get an error.
Here is my code:
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.S=$(OBJDIR)/%.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
I might try to separate SRCS into SRCS_Cpp and so on... But i don't know if that's the best solution. I am pretty new to makefiles^^
I think i found the solution^^
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS_c = $(wildcard $(SRCDIR)/*.c)
SRCS_cpp = $(wildcard $(SRCDIR)/*.cpp)
SRCS_S = $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS_c:$(SRCDIR)/%.c=$(OBJDIR)/%_c.o) $(SRCS_cpp:$(SRCDIR)/%.cpp=$(OBJDIR)/%_cpp.o) $(SRCS_S:$(SRCDIR)/%.S=$(OBJDIR)/%_S.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJDIR)/%_c.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_cpp.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_S.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
Is there something i do wrong? I am trying to compile a kernel without the use of a cross-compiler^^

Object files are not created in sub directory but in main directory

I have the following code in my makefile:
#Compiler
CC = g++
IDIR = headers
SRCDIR = sources
ODIR = obj
LIBS = -lncurses
CFLAGS = -I$(IDIR)
DE = Cow.h Sheep.h
DES = $(patsubst %,$(IDIR)/%,$(DE))
_O = Cow.o Sheep.o
OB = $(patsubst %,$(ODIR)/%,$(_O))
all: make
./make
make: $(OB) $(ODIR)/main.o $(DES)
$(CC) -W -Wall -o $# $^ $(CFLAGS) $(LIBS)
$(ODIR)/%.o: $(SRCDIR)/%.c $(DES)
$(CC) -W -Wall -c -o $# $< $(CFLAGS)
$(ODIR)/main.o: $(SRCDIR)/main.cpp
$(CC) -c -o $# $< $(CFLAGS)
But when I run make in the terminal, the object files are being created, but in the project directory (where the makefile is saved) and not in the obj sub directory.

Resources