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
Related
I have a makefile which works fine for all other files, but not for the main.cpp file. When I change the main.cpp file, it does not update main.o.
here is the makefile:
CXX = g++
SRCF = main.cpp Animal.cpp
SRC = $(addprefix src/, $(SRCF))
VER = Debug
CXXFLAGS = -Wall -std=c++17
EXE = Animal
OBJF = $(subst .cpp,.o, $(SRCF))
OBJ = $(addprefix src/obj/, $(OBJF) )
#PKG = `pkg-config --libs --cflags sdl2`
$(VER)/$(EXE) : $(OBJ)
$(CXX) $(CXXFLGS) -o $# $< $(PKG)
src/obj/%.o:src/%.cpp src/%.h
$(CXX) $(CXXFLGS) -c -o $# $< $(PKG)
clean:
rm -rf $(EXE) $(OBJ)
print-% : ; #echo $* = $($*)
When I change Animal.h or Animal.cpp it updates Animals.o and the Animal executable. But why does it not work for main ?? I have specified how to update main.o in this line :-
src/obj/%.o:src/%.cpp src/%.h
$(CXX) $(CXXFLGS) -c -o $# $< $(PKG)
Please help me and thanks it advance :)
In the Introduction to Pattern Rules section of GNU Make's manual:
In order for the pattern rule to apply, its target pattern must match the file name under consideration and all of its prerequisites (after pattern substitution) must name files that exist or can be made.
Therefore, if there is no src/main.h (or can't be made), the following pattern rule will not match against src/obj/main.o:
src/obj/%.o: src/%.cpp src/%.h
$(CXX) $(CXXFLGS) -c -o $# $< $(PKG)
You need an additional pattern rule without the src/%.h prerequisite:
src/obj/%.o: src/%.cpp
$(CXX) $(CXXFLGS) -c -o $# $< $(PKG)
I have a makefile for my program but I got everything recompiled every time I run it, even if I modify nothing.
Every time I run make it recompiles simHwIntf.cpp showHelp.cpp and sendFromFile.cpp
This is my make file:
IDIR = inc
LDIR = -L/usr/lib/x86_64-linux-gnu/
SDIR = src
ODIR = obj
BINDIR = bin
LDLIBS = -luhd
OBJ = $(patsubst %,$(ODIR)/%,$(O_FILES))
CC = g++
CFLAGS = -Wall -std=c++11 -I $(IDIR) #-Werror
BINARIES= main
C_FILES = simHwIntf.cpp showHelp.cpp sendFromFile.cpp
H_FILES = simHwIntf.h
O_FILES = $(C_FILES:.cpp=.o)
all: $(BINARIES)
#echo "Make file executed"
$(BINARIES): $(O_FILES)
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(OBJ) $(LDIR) $(LDLIBS)
fileCreator: fileCreator.o
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(ODIR)/fileCreator.o
fileHandler: fileHandler.o
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(ODIR)/fileHandler.o
backYard: backYard.o
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(ODIR)/backYard.o
%.o: $(SDIR)/%.cpp $(IDIR)/$(H_FILES)
$(CC) $(CFLAGS) -c -o $(ODIR)/$# $<
clean:
-rm -rf $(ODIR)/*.o *~
distclean: clean
-rm -rf $(BINDIR)/*
Each time the output in the shell is:
g++ -Wall -std=c++11 -I inc -c -o obj/simHwIntf.o src/simHwIntf.cpp
g++ -Wall -std=c++11 -I inc -c -o obj/showHelp.o src/showHelp.cpp
g++ -Wall -std=c++11 -I inc -c -o obj/sendFromFile.o src/sendFromFile.cpp
g++ -Wall -std=c++11 -I inc -o bin/main obj/simHwIntf.o obj/showHelp.o obj/sendFromFile.o -L/usr/lib/x86_64-linux-gnu/ -luhd
Make file executed
I've already search and read this: (How do I make Makefile to recompile only changed files?) but didn't help much.
Anybody that could give me a hand with this ?
I have a doubt with the directories, maybe one or several directories are re-created each time I run make and this causes everything inside to look like new to the compiler.
Thanks
You can see what triggered the build by echoing the dependencies that changed. Add this to your %.o target :
#echo [triggered by changes in $?]
You should also use the VPATH special variable instead of specifying the sources path in your %.o target. See GNU make VPATH documentation
Please try replacing
%.o: $(SDIR)/%.cpp $(IDIR)/$(H_FILES)
$(CC) $(CFLAGS) -c -o $(ODIR)/$# $<
with
$(ODIR)/%.o: $(SDIR)/%.cpp $(IDIR)/$(H_FILES)
$(CC) $(CFLAGS) -c -o $(ODIR)/$# $<
Directories matter when you define targets.
If a define a rule
myexec: objdir/myexec.o
$(CC) $(CFLAGS) -o bindir/myexec objdir/myexec.o $(LDFLAGS)
Make believes that that this would create the file myexec in the working directory. When you rerun make the target myexec wasn't found, so it will be created again. Add the paths in the targets and it should work.
Try replacing
BINARIES= main
with
BINARIES= $(BINDIR)/main
and the rule
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(OBJ) $(LDIR) $(LDLIBS)
with
$(CC) $(CFLAGS) -o $# $^ $(LDIR) $(LDLIBS)
And change the other rules similarly.
Note, in general it is a bad idea to use $# in combination with a path when creating the target in some rule (as in $(BINDIR)/$#), because this will never create the actual target file. A bare $# should be sufficient.
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! :)
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 $# $^
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 $#