How to make an object file in a different folder with c++ and a makefile - c++

When I run my code I get the error
g++ -c -o main.o main.cpp
g++ -I -o obj/main.o -lm
g++ error: obj/main.o: No such file or directory
makefile:21: recipe for target 'main' failed
make: *** [main] Error 1
In my file structure I have a folder with everything in it so I am trying to make some subdirectories and organize everything a little bit. I am trying to get the object file (main.o) to go into an obj folder instead of staying in the base folder as it currently is.
I can't figure out what is going wrong in my makefile and can't find where some of this is being executed and am extremely new to c++ and make. My code is pasted below.
IDIR=../include
CC = g++
CFLAGS = -I
LDIR = ../lib
ODIR= obj
LIBS = -lm
_DEPS = add.h multiply.h
DEPS = $(patsubst %, $(IDIR)/%,$(_DEPS))
_OBJ = main.o
OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: $(OBJ)
$(CC) -c $(CFLAGS) $< -o $#
main: $(_OBJ)
$(CC) $(CFLAGS) -o$(OBJ) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
I haven't read any specific documentation as I have been teaching myself by simply searching the internet for tons of small bits from many different sources. I am using Windows 10 with visual studio code as my compiler and make g++ as my make utility. I apologize for commenting on my own question as this is my first time using Stack Overflow and didn't know I could get in trouble for commenting. I am sorry for causing a mess.

g++ -c -o obj/main.o main.cpp
you must provide the path for the output file

Related

Makefile missing include path Although the path exists and defined

i have make file which i try to make them generic
but it keeps to compline it missing include directory
this is the makefile :
CXX=g++
CPPFAGS= -Wall -O0 -g -std=c++14
INCLUDES = -I/home/vagrant/libuv/include -Isrc
LIBS_DIRS = -L/home/vagrant/libuv/build
LDFLAGS= -lssl -lcrypto
LIB_STATIC = -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
SOURCE = $(wildcard echo.cpp) \
$(wildcard src/*.cpp)
OBJ = $(SOURCE:.cpp=.o)
DEP = $(OBJ:.o=.d)
TARGET = myproj
$(TARGET) : $(OBJ)
$(CXX) $(CPPFLAGS) $(INCLUDES) -o $# $^ $(LIBS_DIRS) $(LDFLAGS) $(LIB_STATIC)
all: $(TARGET)
clean:
rm -f $(OBJ) $(TARGET)
cleandep:
rm -f $(DEP)
.PHONY:all clean cleandep
when i make : make -n :
make -n
g++ -c -o echo.o echo.cpp
g++ -c -o src/base64.o src/base64.cpp
g++ -c -o src/Server.o src/Server.cpp
g++ -c -o src/sha1.o src/sha1.cpp
g++ -c -o src/Client.o src/Client.cpp
g++ -I/home/vagrant/libuv/include -Isrc -o myproj echo.o src/base64.o src/Server.o src/sha1.o src/Client.o -L/home/vagrant/libuv/build -lssl -lcrypto -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
when i invoke make , im getting this error:
make
g++ -c -o echo.o echo.cpp
In file included from src/Server.h:9:0,
from echo.cpp:1:
src/Client.h:6:10: fatal error: uv.h: No such file or directory
#include <uv.h>
^~~~~~
compilation terminated.
make: *** [echo.o] Error 1
but the uv do exist in : /home/vagrant/libuv/include
You have no rule to build your object files: you've only defined a rule to link your object files into a final executable. As mentioned in the comments, adding $(INCLUDES) into that recipe is useless because header file directories are only used during compiling (creating object files) not linking (converting object files and libraries into executables).
Because you haven't defined your own rule to build object files, you're using make's built-in rule. But make's built-in rule doesn't know anything about a variable named INCLUDES, so that variable is not used during compilation. You can easily see this by looking at the compiler commands generated by make.
You need to either (a) create your own rule for compiling object files that uses your personal make variables, or (b) use the normal built-in variables that make expects to be used with its built-in rules.
For (b), as described in the manual, you should take your current CPPFAGS [sic] variable and rename it to CXXFLAGS, take your current INCLUDES variable and rename it CPPFLAGS, take your current LIBS_DIRS variable and rename it LDFLAGS, and take your current LDFLAGS variable and rename it to LDLIBS.
Also just to note, you have DEPS etc. but there is nothing in your makefile that does anything with them or to create them so they're useless.

makefile Recipe for target failed in Dev C++

I am using Dev C++ v5.5.3
I have just written the code for the program and the makefile was generated by Dev C++.
I don't know anything about Makefiles. Here is the makefile generated by Dev C++.
I keep getting the error "recipe for target 'Dialogs_Private.res' failed".
Please help
# Project: Dialogs
# Makefile created by Dev-C++ 5.5.3
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES = Dialogs_private.res
OBJ = Main.o $(RES)
LINKOBJ = Main.o $(RES)
LIBS = -L"C:/Program Files/Dev-Cpp/MinGW32/lib" -static-libstdc++ -static-libgcc
INCS = -I"C:/Program Files/Dev-Cpp/MinGW32/include"
CXXINCS = -I"C:/Program Files/Dev-Cpp/MinGW32/include"
BIN = Dialogs.exe
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)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
Main.o: Main.cpp
$(CPP) -c Main.cpp -o Main.o $(CXXFLAGS)
Dialogs_private.res: Dialogs_private.rc dialogResource.rc
$(WINDRES) -i Dialogs_private.rc --input-format=rc -o Dialogs_private.res -O coff
From your generated makefile we can find you are using your own resource script.
Dialogs_private.res: Dialogs_private.rc dialogResource.rc
DevC++ will generate a resource script(ProjectName_private.rc, in your case, is Dialogs_private.rc) and make a resource file(ProjectName_private.res) via that script. in your case, this generated Dialogs_private.rc file may like this:
/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */
/* DO NOT EDIT! */
#include "dialogResource.rc"
As you can see, it just included your dialogResource.rc. DevC++ will try to compile it. if your resource script have some error, then it can not be compiled. Then you will see an error that tell you recipe for target 'Dialogs_Private.res' failed .
You should check your own resource script and have a look if there is any error in your script file. For example, are you missing some resource you are going to compile but you forget to place the resource file to the correct path? After all your own resource script compiled successfully, this error will be fixed.

GNU make sometime doesn't search in folders declared in VPATH

I'm trying to build a small C++ project with GNU make (version 3.81) but i must call make two times because the first run fails. This is my project directory:
project
makefile
include
lexer.hpp
src
main.cpp
lexer.l
Following is my makefile:
CC = g++
CPPFLAGS = -I include
VPATH = include src
OBJECTS = main.o lexer.o
test: $(OBJECTS)
$(CC) $(CPPFLAGS) -lfl -o $# $^
main.o: lexer.hpp main.cpp
$(CC) -c $(CPPFLAGS) $^
lexer.o: lexer.cpp
$(CC) -c $(CPPFLAGS) $^
lexer.cpp: lexer.l
flex -t $^ > src/lexer.cpp
.PHONY: clean
clean:
rm -fR $(OBJECTS) src/lexer.cpp test
The first time i run make i get the following output where make complains about not finding the lexer.cpp file. But i don't understand why make don't seek in the folders declared in VPATH.
g++ -c -I include include/lexer.hpp src/main.cpp
flex -t src/lexer.l > src/lexer.cpp
g++ -c -I include lexer.cpp
g++: error: lexer.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
make: *** [lexer.o] Error 1
However if i call make again then lexer.cpp is found and the compilation works.
g++ -c -I include src/lexer.cpp
g++ -I include -lfl -o test main.o lexer.o
Why?
P.S. I apologize for poor english.
This rule is wrong:
lexer.cpp: lexer.l
flex -t $^ > src/lexer.cpp
This rule tells make that it will build a file lexer.cpp, and so that's what make is expecting it to do, and after the rule finishes make thinks that file is ready to go, and it will use that filename when other targets depend on it. But what the rule really does, is build src/lexer.cpp.
To write this rule correctly you'll need to write it as:
src/lexer.cpp: lexer.l
flex -t $^ > $#
(every make rule you write should always update the file $#, exactly).
However, in general VPATH is not good for finding generated files (object files, etc.: any file that is generated by make). It's only useful for finding source files (files make doesn't build itself).

Can't run program after putting the compiled file to the folder

In my Makefile I'm trying to specify, that I want to save the compiled executable file to /dvoram64/ folder. Before, when I tried to save it diretly to / everything worked all right, but now I get this message after calling make run:
ubuntu#pa2:~/Project$ make run
Makefile:37: warning: overriding commands for target `dvoram64/main'
Makefile:34: warning: ignoring old commands for target `dvoram64/main'
make: Circular dvoram64/main <- dvoram64/main dependency dropped.
mkdir -p dvoram64
g++ -Wall -pedantic -Wno-long-long -O0 -ggdb -g -c src/main.cpp -o dvoram64/main
./dvoram64/main
make: execvp: ./dvoram64/main: Permission denied
make: *** [run] Error 127
My Makefile looks like this:
#macros
CC=g++
CCFLAGS=-Wall -pedantic -Wno-long-long -O0 -ggdb -g
LBFLAGS=-lncurses -pthread
Remove=rm -rf
Objects=dvoram64/main
Doxygen=Doxyfile
RUN=./dvoram64/main
CPATH=objects/
#generates final binary and documentation
all: $(Objects) $(Doxygen)
make compile
make doc
#build into final binary
compile: $(RUN)
#run program
run: $(RUN)
$(RUN)
clean:
$(Remove) doc/
$(Remove) dvoram64
#generate documentation in '<login>/doc' folder
doc: $(Doxygen) src/*
( cd src | doxygen $(Doxygen))
#rules to make objects ----------------------------------------------------------------------------------
$(RUN): $(Objects)
$(CC) $(CCFLAGS) $(Objects) -o $(RUN) $(LBFLAGS)
dvoram64/main: src/main.cpp
mkdir -p dvoram64
$(CC) $(CCFLAGS) -c src/main.cpp -o dvoram64/main
Could anybody tell me, what causes that and how to fix it?
You have several problems. First:
RUN=./dvoram64/main
$(RUN): $(Objects)
$(CC) $(CCFLAGS) $(Objects) -o $(RUN) $(LBFLAGS)
dvoram64/main: src/main.cpp
mkdir -p dvoram64
$(CC) $(CCFLAGS) -c src/main.cpp -o dvoram64/main
You have two rules for the same target(dvoram64/main). Which do you want to use? Why do you have two? Remove one of them.
Next:
Objects=dvoram64/main
RUN=./dvoram64/main
$(RUN): $(Objects)
...
You have two variables for (essentially) the same thing, which is untidy but not illegal. But You make one the prerequisite of the other. A thing cannot be it's own prerequisite, and Make must correct the error for you. You should rethink this.
Next:
RUN=./dvoram64/main
run: $(RUN)
$(RUN)
dvoram64/main: src/main.cpp
mkdir -p dvoram64
$(CC) $(CCFLAGS) -c src/main.cpp -o dvoram64/main
You have lost track of whether dvoram64/main should be an object file or an executable file. You have two rules to build it; one builds an executable, the other an object. You name it main, which sounds like an executable file, but you put that name in a variable called Objects. And in the end you build an object file and try to execute it.
You can save yourself some trouble by keeping the makefile as free of redundancy as possible. And when the big target fails, try the little targets one at a time to narrow nown the scope of the problem.

Makefile not using include/library paths?

Well, after 3 hours of researching, I'm about to go insane, so I figure it's time to pass it off to some new eyes.
CXXFLAGS = -g -Wall
OBJS = main.o
PROG = test
INCLUDES = -I /usr/include/mysql -I /usr/local/include
LIBS = -L /usr/lib/mysql -l libmysqlclient.so.15.0.0 -L /usr/local/lib -l libmysqlpp.so.3.1.0
all: $(PROG)
${PROG}: $(OBJS)
$(CXX) $(INCLUDES) -o $(PROG) $(OBJS) $(LIBS)
clean:; $(RM) -f $(PROG) core *.o
There's something wrong with the include paths, because I get errors that mysql_version.h does not exist when it clearly does exist in /usr/include/mysql.
Checking the first part out of the ouput, it says
g++ -g -Wall -c -o main.o main.cpp
which makes me think that I've formatted something in the Makefile wrong (due to the extra spaces and lack of include/library paths). However, I've looked at dozens of manuals and articles on Makefiles and the g++ options and... no progress.
I assume this should be a simple fix. Please, please help (do you sense my despair?).
On another note, do you think specifying the library specifically is necessary? I had this stuff running in XCode just fine, but I'm trying to migrate the code to my web server... the Makefile has stopped all progress, and I figure it's something I should learn from.
In your makefile, you have added your include directives to the linking stage, not the compiling stage.
The lines
${PROG}: $(OBJS)
$(CXX) $(INCLUDES) -o $(PROG) $(OBJS) $(LIBS)
Say to make the program in ${PROG} from object files in ${OBJS} by calling the compiler in ${CXX} passing the include folders (along with your other arguments). Instead, for your variable section, do this:
INCLUDES = -I /usr/include/mysql -I /usr/local/include
CXXFLAGS = -g -Wall ${INCLUDES}
OBJS = main.o
PROG = test
LIBS = -L /usr/lib/mysql -l libmysqlclient.so.15.0.0 -L /usr/local/lib -l libmysqlpp.so.3.1.0
This way your CXXFLAGS (which are used for the compile stage) should now pickup your include directives.