Why this Makefile fails to build the project? - c++

I have this Makefile:
OBJS = main_exp_par_auto.o
SOURCE = ../main/main_exp_par_auto.cpp
HEADER = ../Division_Euclidean_space.h ../Find_diameter.h ../Find_k_max.h ../Householder.h ../IO.h ../Mean_variance.h ../Point.h ../Random_generator.h ../Random_kd_forest.h ../Tree.h ../Auto_random_kd_forest.h
OUT = geraf
CXX = g++
FLAGS = -pthread -std=c++0x -DRKD_PAR -O3 -Wall
all: $(OBJS)
$(CXX) $(OBJS) -o $(OUT) $(FLAGS)
make -f makefiles/Makefile_exp_par_auto clean
# create/compile the individual files >>separately<<
main_exp_par_auto.o: main/main_exp_par_auto.cpp
$(CXX) -c main/main_exp_par_auto.cpp $(FLAGS)
.PHONY : all
# clean house
clean:
rm -f $(OBJS)
# do a bit of accounting
count:
wc $(SOURCE) $(HEADER)
and the folder looks like this:
However, I am getting:
gsamaras#gsamaras-A15:/media/gsamaras/a6cd1464-abf1-4a7b-b4a2-61f584d4cb32/gsamaras/code/C++/kd_GeRaF-master/makefiles$ make -f Makefile_exp_par_auto
make: *** No rule to make target `main/main_exp_par_auto.cpp', needed by `main_exp_par_auto.o'. Stop.
This is an old project of mine and that was supposed to be working, how to fix this?

You are invoking it from makefiles directory, whereas main directory is on the same level. It looks for main/main_exp_par_auto.cpp and fails to find it.
Invoke make like that:
make -C /media/gsamaras/a6cd1464-abf1-4a7b-b4a2-61f584d4cb32/gsamaras/code/C++/kd_GeRaF-master -f makefiles/Makefile_exp_par_auto

Related

makefile: how to generate object files to upper directory

I have a makefile as below, which can compile and link all cpp files in a same directory:
g++1x:=g++ -std=c++14 -stdlib=libc++ -MMD -MP
cflags:= -Wall -lncurses
TARGET:=matrix.out
CPPFILES:=$(wildcard *.cpp)
OBJDIRECTORY:=.obj
OBJFILES:=$(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.o)))
.PHONY: install
install: $(OBJDIRECTORY) $(TARGET)
$(OBJDIRECTORY):
mkdir -p $(OBJDIRECTORY)
$(TARGET): $(OBJFILES)
$(g++1x) $(cflags) -o $# $^ -g
$(OBJDIRECTORY)/%.o: %.cpp
#%.o: %.cpp
$(g++1x) -c -o $# $< -g
-include $(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.d)))
.PHONY: clean
clean:
rm -f $(TARGET)
rm -rf $(OBJDIRECTORY)
When I execute make, a .obj will be created and all of obj files are in it. Also an executable file will be generated too. For now everything's fine.
Now I'm trying to organise my project. My plan is to create some subdirectories and each of them contains a makefile. When I execute a makefile, it will generate obj files at some fixed path. Finally, I can execute a makefile to link main.cpp and all of obj files to get the executable file.
But I don't know how to write such a makefile for subdirectory. I've made a try as below but it doesn't work.
project
|--- main.cpp
|--- makefile
|--- subdir
|--- test.h
|--- test.cpp
|--- makefile
Here is my makefile in project/subdir:
g++1x:=g++ -std=c++14 -stdlib=libc++ -MMD -MP
cflags:= -Wall -lncurses
CPPFILES:=$(wildcard *.cpp)
OBJDIRECTORY:=../.obj
TARGET:=$(OBJDIRECTORY)/%.o
OBJFILES:=$(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.o)))
.PHONY: install
install: $(OBJDIRECTORY) $(TARGET)
$(OBJDIRECTORY):
mkdir -p $(OBJDIRECTORY)
$(TARGET): %.cpp
#%.o: %.cpp
$(g++1x) -c $# $< -g
-include $(addprefix $(OBJDIRECTORY)/,$(notdir $(CPPFILES:.cpp=.d)))
.PHONY: clean
clean:
rm $(OBJDIRECTORY)/%.o
Error:
make: *** No rule to make target ../.obj/%.o', needed byinstall'.
Stop.
Don't place files in the path's parent; turn the problem around: Have a Makefile in the root directory that $(MAKE)s the subdirs and uses the obj files there.
You have several problems here.
In your original makefile, the variable TARGET contained the string "matrix.out", and all was well.
In your subdir/makefile, the variable TARGET contains the string "../.obj/%.o", and you're asking Make to build that. The only rule it can find:
$(TARGET): %.cpp
...
doesn't help, because there is no file called "%.cpp" anywhere.
I suggest you try something like this:
install: $(OBJFILES)
$(OBJFILES): $(OBJDIRECTORY)/%.o: %.cpp $(OBJDIRECTORY)
$(g++1x) -c $# $< -g
Once you get that working, you can worry about the problem of getting the master makefile to invoke the sun-makes.

Makefile directories error

Im using this code in the makefile, all is going good but the last line.
My code folder looks like this:
Project/bin -> For executable files
Project/build -> For .o files
Project/include -> For .hpp files
Project/src -> For .cpp files
Makefile path: Project/Makefile
# Compiler #
CC = g++
DEBUG = -g
LFLAGS =
CFLAGS = -Wall
# Directories #
SRCDIR = src/
INCDIR = include/
BUILDDIR = build/
BINDIR = bin/
# Objects #
OBJ_NAMES = main.o dfa.o dfaException.o state.o
OBJS = $(addprefix $(BUILDDIR), $(OBJ_NAMES))
# Output #
TARGET = $(BINDIR)pract3
$(TARGET): $(OBJS)
$(CC) $(CCFLAGS) $(LFLAGS) $(OBJS) -o $(TARGET)
$(BUILDDIR)%.o: $(SRCDIR)%.cpp
$(CC) $(CCFLAGS) $(LFLAGS) -c $< -o $(BUILDDIR)$($(notdir $<):.cpp=.o)
The problem is in "$(BUILDDIR)$($(notdir $<):.cpp=.o)". What Im trying to do here is:
$< contains "src/mysrc.cpp" so with $(notdir $<) I get
"mysrc.cpp"
Now, I want to change the file extension to .o, so I use $($(notdir $<):.cpp=.o) And I should get "mysrc.o". But this part is not working:
g++ -c src/main.cpp -o build/
Assembler messages:
Fatal error: can't create build/: Permission denied
Makefile:25: recipe for target 'build/main.o' failed
make: *** [build/main.o] Error 1
I use $(BUILDDIR) To get "build/mysrc.o"
Why does $($(notdir $<):.cpp=.o) somehow delete the file name ?
And now that Im here. I've learned to use make some days ago. Is there something that I should improve here ?
$(notdir) operates on strings.
$(X:Y=Z) operates on the value of the X variable.
So follow your expansions when $< is src/mysrc.cpp
$($(notdir $<):.cpp=.o)
becomes
$(mysrc.cpp:.cpp=.o)
Is that how you would write that?
No, you would write $(<:.cpp=.o).
So invert your operations.
$(notdir $(<:.cpp=.o))
Or, even better and simpler than that just use $# since that's the target you are building and what you want to create.
$(CC) $(CCFLAGS) $(LFLAGS) -c $< -o $#

Makefile fails with error no rule to make target

I'm struggling to create a working make file.
My structure
root/Makefile
root/src/main.cpp
root/include/
My code
# Define compiler
CC = g++
# Compiler flags
CFLAGS = -g -Wall
# Build target executable
DIR = /src
INCLUDES = ../include
TARGET = main
all: $(TARGET)
$(TARGET): $(TARGET).cpp
cd $(DIR) &
$(CC) $(CFLAGS) -I $(INCLUDES) -o $(TARGET) $(TARGET).cpp
clean:
cd $(DIR) &
$(RM) $(TARGET)
My Error
make: *** No rule to make target main.cpp', needed bymain'. Stop.
EDIT
Inside my main.cpp I have this line at the top which is meant to be found by my Makefile: #include "pugixml.hpp"
I think this should work for you.
All paths are given relative to the folder the Makefile is in. That means the source folder needs to be specified for the source dependencies.
# Define compiler
CC = g++
# Compiler flags
CFLAGS = -g -Wall
# Build target executable
SRC = src
INCLUDES = include
TARGET = main
all: $(TARGET)
$(TARGET): $(SRC)/$(TARGET).cpp
$(CC) $(CFLAGS) -I $(INCLUDES) -o $# $^
clean:
$(RM) $(TARGET)
Use tabs (not spaces) for the commands.
$# resolves to the target (main in this case).
$^ resolves to all of the dependencies (src/main.cpp in this case).
No need to cd into the source folder.

(GNU) Make: How does one set up a basic system?

I would like to try to establish a very small system of Makefiles. I have the following set up, but something is not quite right (this has been pieced together from reading a few SO posts about the topic, though somewhat project-specific, and some websites. I must not be catching something fundamental in having a "Makefile" call sub-makefiles.
This is even simpler than having the main Makefile call files in different subdirectories. Here are the following files I have prepared:
Makefile:
all:
$(MAKE) -f ./make_system.mk
$(MAKE) -f ./make_crc.mk
make_system.mk:
G = -g ## debug option
CC = gcc ## compiler
SRCS = source.c sink.c gateway.c
EXES = source sink gateway
OBJS = source.o sink.o gateway.o
CFLG =
LFLG =
LIB = #-lsocket -lnsl -lpthread
all: $(EXES)
%.o: %.c %.h
$(CC) -c $G $(CFLG) $<
source: source.o
$(CC) -o source source.o $(LIB) $(LFLG)
sink: sink.o
$(CC) -o sink sink.o $(LIB) $(LFLG)
gateway: gateway.o
$(CC) -o gateway gateway.o $(LIB) $(LFLG)
clean:
/bin/rm -f core *.o $(EXES) *~
make_crc.mk:
CC = gcc
CFLAGS = -g
LFLAGS =
HDR = crcmode.h
SRC = crcmodel.c crctest.c
OBJ = crcmodel.o crctest.o
EXE = crctest
all: $(EXE)
%.o: %.c %.h
$(CC) -c $(CLFAGS) $<
$(EXE): $(OBJ)
$(CC) $(LFLAGS) $(OBJ) -o $(EXE)
clean:
/bin/rm -f *.o *~ core $(EXE)
How would I set up Makefile to call the smaller sub-makefiles (of type *.mk)? This is a basic but important first step towards working with larger scale makefile systems (there is the manual to consult, though I do not think it has explicit basic examples). If someone who has done this could show me a small Makefile vignette, this would be greatly appreciated (again, this makefile system can exist within the same local directory).
Note: The individual makefiles "make_system" and "make_crc" work fine when they are themselves named "Makefile", but I want to try to call them as separate sub-makefiles with one single overall Makefile.
ADDENDUM (to solution below):
Once I implemented Carl's solution shown below, I realized that you need to always include some form of "make clean" or at least enter at in the command line before calling your Makefile. Otherwise, you see the appropriate output "nothing to be done". This was something I knew before, but neglected to do this time around (easy check: just look at your directory and you will see you have executables in the environment/directory).
I you want to "forward" the target, you'll need to do it explicitly. Something like this example should work (though I can't test easily right now, sorry):
default: all
%:
$(MAKE) -f ./make_system.mk $#
$(MAKE) -f ./make_crc.mk $#

Help with Makefile: No rule to make target

CC = g++
CFLAGS = -Wall
RM = /bin/rm -rf
BIN_DIR =
ifeq "$(DEBUG)" "1"
BIN_DIR = Debug
else
BIN_DIR = Release
endif
OBJS = \
$(BIN_DIR)/Unit.o
$(BIN_DIR)/%.o: src/%.c
#echo Building "$#"
#g++ -c "$<" -o"$#"
all: $(OBJS)
clean:
$(RM) $(BIN_DIR)
.PHONY: all clean
However, when I try to build my project this, it gives me the error:
make: *** No rule to make target 'Release/Unit.o', needed by 'all'. Stop.
I am new to writing makefiles from scratch and so this might be a stupid question, but any help is appreciated!
The problem is here:
$(BIN_DIR)/%.o: src/%.c
#echo Building "$#"
#g++ -c "#<" -o"$#"
I think that's more like this :
$(BIN_DIR)%.o: %.c
$(CC) -o $# -c $< $(CFLAGS)
As Sean Bright already pointed out, changing
#g++ -c "#<" -o"$#"
to
#g++ -c "$<" -o"$#"
also makes the Makefile work for me (ming32-make: GNU Make 3.81)
Since you had the Makefile on the same level as the source file (inside the src directory), your rule were failing.