What's wrong with this makefile - c++

I am new to makefiles. I have a makefile, I want it generated a shared library from more than one .cpp files. But the following makefile only generated different .so based on the same .cpp file. Can anyone help?
SRC_DIR = $(PROJECT_BASE_DIR)/src
SRCFILES = $(wildcard $(SRC_DIR)/*.cpp)
OBJFILES = $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_TARGET_DIR)/%.$(OBJ_EXTENSION),$(SRCFILES))
...
ifeq ($(OS),$(OS_LINUX))
$(CLIENTLIB): $(OBJFILES)
gcc $(CXXFLAGS) -o $# $< $(LINKER_FLAGS)
$(OBJFILES): $(SRCFILES) ==> I believe this is the line with problem.
gcc $(CXXFLAGS) -c -o $# $<

Currently you're trying to convert all .cpp files to all .o files in one compilation step.
Change:
$(OBJFILES): $(SRCFILES) ==> I believe this is the line with problem.
gcc $(CXXFLAGS) -c -o $# $<
to:
%.$(OBJ_EXTENSION): %.cpp
gcc $(CXXFLAGS) -c -o $# $<

These are the rules I use in my makefile and they work, hope it can help you
CFILES = $(wildcard *.c)
OBJS = $(CFILES:%.c=%.o)
%.o: %.c
$(CC) $(CFLAGS) -I$(INCLUDE) $< -o $#

Related

Makfile usees same cpp file to generate objects [duplicate]

This is a part of my makefile :
SRC = ./
DIRS = src libs/maths libs/struct
BIN_DIR = ./bin/
SRC_DIRS= $(foreach dir, $(DIRS), $(addprefix $(SRC), $(dir)))
SRC_TEST= $(sort $(SRC_DIRS))
SRCS = $(foreach msrc, $(SRC_DIRS), $(wildcard $(msrc)/*.c))
DEL_PRE = $(foreach target, $(SRCS), $(notdir $(target)))
ADD_PRE = $(foreach target, $(DEL_PRE), $(addprefix $(BIN_DIR), $(target)))
OBJS = $(ADD_PRE:.c=.o)
.PHONY: all clean re
all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) $(OBJS) -o $# $(LDLIBS)
$(OBJS): $(SRCS)
$(CC) -o $# -c $<
When i use make all, i have in output :
gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c src/main.c
gcc -o bin/pears.o -c src/main.c
gcc -o bin/outil.o -c src/main.c
gcc -o bin/verif.o -c src/main.c
But i would like to have for each target, it assigned dependency :
gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c libs/maths/cosin.c
gcc -o bin/pears.o -c libs/maths/pears.c
gcc -o bin/outil.o -c libs/struct/outil.c
gcc -o bin/verif.o -c libs/struct/verif.c
How can i fix it ?
This seems like a very common misconception; I just answered effectively this same question yesterday. I'm not sure where it comes from or how to combat it.
This rule:
$(OBJS): $(SRCS)
$(CC) -o $# -c $<
does not somehow magically combine the contents of the OBJS variable and the SRCS variable to figure out how they match up. The variable references are simply expanded, and the result is this:
bin/main.o bin/cosin.o ... : src/main.c libs/maths/cosin.c ...
$(CC) -o $# -c $<
which is the same as if you'd written this:
bin/main.o : src/main.c libs/maths/cosin.c ...
$(CC) -o $# -c $<
bin/cosin.o : src/main.c libs/maths/cosin.c ...
$(CC) -o $# -c $<
...
Now, you can hopefully see why you compile the same file: in every rule you have the same prerequisites, so $< is always the first one, which is always src/main.c.
There are multiple ways to work this but if you really want to have all the source files from different directories compiled into object files in the same directory your job is harder, because there's no common pattern that will match them all. In this case the simplest thing to do is use VPATH for directory search: replace the above rule with this:
$(BIN_DIR)/%.o : %.c
$(CC) -o $# -c $<
then tell make how to find your source files, like this:
VPATH := $(sort $(dir $(SRCS))
Be aware this method can't be used for any source files that are themselves generated output that make is expected to create.

How to write specific rule for a target in makefile?

I know the title is quite ambiguous but I just don't know how to describe my problem concisely. Please edit that if you want.
Currently my makefile is like the following:
CC = g++
CFLAGS = -Wall -g
TARGET = foobar
SRC_FILES = foo.cpp bar.cpp main.cpp
OBJ_FILES := $(SRC_FILES:.cpp=.o)
$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $^ -o $#
%.o: %.cpp %.h
$(CC) $(CFLAGS) -c $<
clean:
rm -rf *.o $(TARGET)
The problem is that this structure requires main.cpp to have a main.h header file, which I don't really have. How can I handle this nicely?
GCC (and probably Clang) can build a list of dependencies for you; This way, you can simply make your object files from their source (cpp) file:
depend: .depend
.depend: $(SRC_FILES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ -MF ./.depend;
include .depend
%.o: %.cpp
$(CC) $(CFLAGS) -c $<
You might also find interest in the makedepend tool.

Makefile on different folders

I know it has already been discussed a lot, but I'm getting a bit crazy and cannot figured it out by myself.
I'm trying to learn how to create makefiles, and I'm having problems in defining a makefile for files in different folders.
This is what I would like to obtain, after compiling:
/makefile
/test.exe
/src/factorials.cpp
/src/main.cpp
/src/hello.cpp
/obj/factorials.o
/obj/main.o
/obj/hello.o
/include/functions.h
What is wrong with this makefile?
C++ = g++
FILENAME = test
SOURCES_PATH = src/
SRC = $(SOURCES_PATH)factorial.cpp $(SOURCES_PATH)main.cpp $(SOURCES_PATH)hello.cpp
OBJ = factorial.o main.o hello.o
all: test.exe
test.exe: $(OBJ)
$(C++) $(OBJ) -o $(FILENAME) -Iinclude
%.o:
$(C++) -c $(SOURCES_PATH)$*.cpp -Iinclude
clean:
rm -f test.exe
Everything goes correctly, but it gives me error trying to compile src/all.cpp. Besides, I don't know how to say to g++ to put .o files into obj/ folder.
Thanks a lot!
You should fix your .o rule as follows
obj/%.o: $(SOURCES_PATH)/%.cpp
$(CC) $(CXXFLAGS) $< -o $#
Alternatively $(vpath) can be used to resolve where make looks up the source (prerequisite) files for a target:
vpath += $(SOURCES_PATH)
obj/%.o: %.cpp
$(CC) $(CXXFLAGS) $< -o $#
So it seems I was able to obtain the result by using the following makefile
C++ = g++
FILENAME = test
OBJS = obj/factorial.o obj/hello.o obj/main.o
INC = -Iinclude/
vpath+= src
$(FILENAME): $(OBJS)
$(C++) $(OBJS) -o $# $(INC)
obj/%.o: %.cpp
$(C++) -o $# -c $< $(INC)
all: $(FILENAME)
clean:
rm -rf objs/*.o *~ $(FILENAME).exe
Thanks! :)

make objects in Makefile

I have the following Makefile:
CXX = g++
CXXFLAGS = -Wall -g
SOURCES := divisor.cpp multiplier.cpp
OBJECTS := ${SOURCES:.cpp=.o}
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
%: %.o $(OBJECTS)
$(CXX) $(CXXFLAGS) $#.o -o $#.out
$(OBJECTS): %.o: %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
clean:
rm -f *.o
What I want this make file is the following:
If I add a source file called 123.cpp to the working directory, I want it to generate its object file and then link the compiled sources specified in $(SOURCES), this means:
g++ -c -Wall -g 123.cpp
g++ multipler.o divisor.o 123.o -o 123
If multiplier.cpp or divisor.cpp has to be generated or updated, I want make to do it.
But I'm failing, because divisor.o and multiplier.o are not automatically generated
How may I achieve this?
Edit
Just to clarify, there are two types of source code files in the working directory: divisor.cpp, multipler.cpp is one type, and any other file, say, 123.cpp is the other type. In a sense, divisor.cpp and multiplier.cpp are requisites to the other source files.
I want to automate the process of compiling the prerequisites and link them when compiling the other files
g++ -c multiplier.cpp
g++ -c divisor.cpp
g++ -c -Wall -g 123.cpp
g++ multipler.o divisor.o 123.o -o 123
Use the wildcard function:
SOURCES := $(wildcard *.cpp)
Then, you can remove your "special" source files:
SPECIAL_SOURCES := divisor.cpp multiplier.cpp
SOURCES := $(filter-out $(SPECIAL_SOURCES),$(SOURCES))
And change your rules to build the stuff you actually want:
$(SPECIAL_OBJECTS) := $(SPECIAL_SOURCES:.cpp=.o)
$(BINARIES) := $(patsubst .cpp,,$(SOURCES))
$(SPECIAL_OBJECTS) : %.o : %.cpp
$(CXX) $(CXXFLAGS) -c -o $# $^
$(BINARIES) : % : %.cpp $(SPECIAL_OBJECTS)
$(CXX) $(CXXFLAGS) -o $# $^

building program with make and automatic dependencies

I have written a simple C++ program, and for the first time I want to compile and link it using a makefile. As a challenge I want to make a makefile, which lists all dependencies by itself. I am following this tutorial. My program consist of main.cpp, ext1.cpp and ext1.h. Following the tutorial, I have the following makefile
VPATH = src include
CPPFLAGS = -o include
CC = gcc
SOURCES = main.cpp \
ext1.cpp
-include $(subst .c,.d,$(SOURCES))
%.d: %.c
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
When I run this I get the message: make: *** No targets specified and no makefile found. Stop. It is not clear to me what I am missing in my case?
You are trying to do too much at once.
Step 1. Your first makefile should build the executable without attempting automatic dependency detection.
VPATH = include src
CPPFLAGS += -Iinclude
CC = gcc
exec: main.o ext1.o
$(CC) $^ -o $#
%.o: %.cc
$(CC) -c $(CPPFLAGS) $< -o $#
main.o ext1.o: ext1.h
Step 2. Once that works perfectly, you can put the header dependencies in separate files:
makefile:
VPATH = include src
CPPFLAGS += -Iinclude
CC = gcc
exec: main.o ext1.o
$(CC) $^ -o $#
%.o: %.cc
$(CC) -c $(CPPFLAGS) $< -o $#
-include *.d
main.d:
main.o : ext1.h
ext1.d:
ext1.o: ext1.h
Step 3. Once that works perfectly, you can generate the dependency files automatically:
VPATH = include src
CPPFLAGS += -Iinclude
CC = gcc
exec: main.o ext1.o
$(CC) $^ -o $#
%.o: %.cc
$(CC) -c -MMD $(CPPFLAGS) $< -o $#
-include *.d
no make file found ? what name you have given for makefile? make sure its makefile or Makefile if you are just executing command make else you can pass file name to make like this
make -f yourmakefile
and changes suggested by Petr Budnik must work