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

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.

Related

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

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

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^^

change of header file detection for makefile

My makefile doesn't detect changes in header files. How can i add this functionality to my makefile? Here is my makefile:
CPP = g++
CC = gcc
RES =
OBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LINKOBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LIBS =
INCS = -I"lib1/inc" -I"lib2/inc"
CXXINCS = -I"lib1/inc" -I"lib2/inc"
BIN = out
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)
obj/main.o: main.c
$(CC) -c main.c -o obj/main.o $(CFLAGS)
obj/customfunc1.o: lib1/customfunc1.c
$(CC) -c lib1/customfunc1.c -o obj/customfunc1.o $(CFLAGS)
obj/customfunc2.o: lib2/customfunc2.c
$(CC) -c lib2/customfunc2.c -o obj/customfunc2.o $(CFLAGS)
Header files must be listed together with other dependencies. E.g.:
CPP = g++
CC = gcc
RES =
OBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LINKOBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LIBS =
INCS = -I"lib1/inc" -I"lib2/inc"
CXXINCS = -I"lib1/inc" -I"lib2/inc"
BIN = out
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)
obj/main.o: main.c header1.h header2.h
$(CC) -c main.c -o obj/main.o $(CFLAGS)
obj/customfunc1.o: lib1/customfunc1.c lib1/header.h
$(CC) -c lib1/customfunc1.c -o obj/customfunc1.o $(CFLAGS)
obj/customfunc2.o: lib2/customfunc2.c lib2/header.h
$(CC) -c lib2/customfunc2.c -o obj/customfunc2.o $(CFLAGS)

Resources