Issue with Makefile for mysql - c++

I'm having issues linking mysql to my project. I've tried several ways that I found online (I'm new to Makefiles so bear with me) anyway, here's my makefile:
CC=g++
CFLAG=-c
INCLUDES="/Library/mysql"
all:myapp
myapp: main.o Application.o
$(CC) main.o Application.o
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
Application.o: Application.cpp $(INCLUDES)
$(CC) -lm $(INCLUDES) $(CFLAGS) Application.cpp
clean:
rm -rf *o myapp
mysql.h is #included in the Application.h file. The mysql folder is located in "/Library"
I'm running OS X Mavericks (if that's relevant).
The error is
make: *** No rule to make target `"/Library/mysql"', needed by `Application.o'. Stop.

You should use the variables CXX and CXXFLAGS for C++ compiler and flags, not CC and CFLAGS; those are for C compilers.
When you pass directories to the compiler for searching for headers, you have to prefix them with the -I flag. Also preprocessor flags are best put in the CPPFLAGS variable, so you should use:
CPPFLAGS = -I/Library/mysql
You shouldn't put directories as prefixes for targets, so don't add the $(INCLUDES) (or $(CPPFLAGS)) variable to the prerequisites list of Application.o.

Related

How do I rewrite my makefile so that I can restructure the directories of my project?

I've been working on a small game written entirely in C++ using SDL for graphics and audio. Until now all of my source files and headers have been located in the same directory as my executable, but I would like to move these to a ./src and an ./include folder.
However, I am really struggling with makefile syntax and how I would tell the compiler where to find the source and header files.
How can I tell the makefile to find source/headers/objects in subdirectories? Any improvements/mistakes for my makefile?
Here is my current makefile:
OBJS = main.o Window.o Entity.o Player.o Tile.o BoundingBox.o\
MapReader.o Button.o Zombie.o Projectile.o Pathfinder.o
CPP = g++
CPPFLAGS = -c -g
LDFLAGS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -mwindows
ZombieAttack: $(OBJS)
$(CPP) -o ZombieAttack $(OBJS) $(LDFLAGS)
main.o: main.cpp
$(CPP) $(CPPFLAGS) main.cpp
Window.o: Window.cpp
$(CPP) $(CPPFLAGS) Window.cpp
Entity.o: Entity.cpp
$(CPP) $(CPPFLAGS) Entity.cpp
Player.o: Player.cpp
$(CPP) $(CPPFLAGS) Player.cpp
Tile.o: Tile.cpp
$(CPP) $(CPPFLAGS) Tile.cpp
BoundingBox.o: BoundingBox.cpp
$(CPP) $(CPPFLAGS) BoundingBox.cpp
MapReader.o: MapReader.cpp
$(CPP) $(CPPFLAGS) MapReader.cpp
Button.o: Button.cpp
$(CPP) $(CPPFLAGS) Button.cpp
Zombie.o: Zombie.cpp
$(CPP) $(CPPFLAGS) Zombie.cpp
Projectile.o: Projectile.cpp
$(CPP) $(CPPFLAGS) Projectile.cpp
Pathfinder.o: Pathfinder.cpp
$(CPP) $(CPPFLAGS) Pathfinder.cpp
clean:
del *.o
I am using mingw for compilation and mingw32-make
If you want the binaries to be in the highest level directory, and the .h / .cpp files to be in sub directories of that, you can simply prefix the files you wish to access with target directory/filename
so for example:
MapReader.o: MapReader.cpp
$(CPP) $(CPPFLAGS) MapReader.cpp
becomes
MapReader.o: src/MapReader.cpp
$(CPP) $(CPPFLAGS) src/MapReader.cpp
In general, it's best if you try to solve the problem yourself before posting to SO. Then when you have an issue you can't solve you should ask about that issue specifically, rather than broad questions like this.
However, it is the new year!!
First, make is not the same thing as the compiler. It's not enough to teach make where to find your files, you also have to teach the compiler where to find your files. If you're going to put header files in some other directory than the sources, then you have to give options to your compiler telling it where to find those headers. Just telling make where to find them won't do anything to help the compiler.
Second, unless you really have a pressing need you should use the standard variables for things like the C++ compiler (CXX not CPP) and the flags for it (CXXFLAGS not CPPFLAGS). You should also not put the option that chooses the type of output (-c) into the general flags variable: that should go into the rule. And finally, you should make sure you keep the distinction between LDFLAGS which are flags to the linker, and LDLIBS which are libraries to link. Here you're putting all the libraries to link into LDFLAGS.
Third, you can use automatic variables wherever possible to reduce duplication.
Fourth, you can greatly simplify your makefile by using a pattern rule. In fact, GNU make provides default pattern rules that can properly build C++ files, if you use the proper variables as above, so you don't even have to define your own.
Here's a version of your original makefile, with the above variables fixes and using builtin rules to reduce duplication:
OBJS = main.o Window.o Entity.o Player.o Tile.o BoundingBox.o \
MapReader.o Button.o Zombie.o Projectile.o Pathfinder.o
CXX = g++
CXXFLAGS = -g
LDFLAGS = -mwindows
LDLIBS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer
ZombieAttack: $(OBJS)
$(CXX) -o $# $(LDFLAGS) $^ $(LDLIBS)
clean:
del *.o
That makefile should perform exactly like your original makefile if all files are in the same directory.
Now, if you want to move things around then you need to first explain to the compiler where to find your headers by adding a -I option to the compile line. If your headers are now in the include subdirectory, you can do that like this:
CXXFLAGS = -g -Iinclude
Now, if you're willing to have the object files in the same directory as the source files, then you can change the above makefile to tell make where to build them, like this:
BASE_OBJS = main.o Window.o Entity.o Player.o Tile.o BoundingBox.o \
MapReader.o Button.o Zombie.o Projectile.o Pathfinder.o
SRC = src
OBJS = $(addprefix $(SRC)/,$(BASE_OBJS))
That, along with the changes above, should allow it to work.
If you want to put the object files in some other directory than the source files, then you will no longer be able to use make's built-in rules because make cannot know where you want to put things, so you'll have to write your own pattern rule.

Confused how my Makefile is remaking object files

My make file is failing to find my include directory when it tries to remake object files. For example, when I call make tests I get the output:
g++ -c -o sdl_class.o sdl_class.cpp
sdl_class.cpp:9:23: fatal error: sdl_class.h: No such file or directory
#include <sdl_class.h>
^
compilation terminated.
make: *** [sdl_class.o] Error 1
My Makefile is this:
#Originally from: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
#But will be heavily modified
IDIR =../include
CC=g++
CFLAGS=-w -I$(IDIR)
#ODIR=obj
LDIR =../lib
LIBS=-lSDL2
_DEPS = sdl_class.h SDL_image.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
OBJ = sdl_class.o tests.o
#OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
%.o: %.cpp $(DEPS)
$(CC) -c -o $# $< $(CFLAGS) $(LIBS)
tests: sdl_class.o tests.o
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
all: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f *.o *~ core $(IDIR)/*~
My understanding is that when I call make tests, that it should attempt to remake the sdl_class.o file. This should then call the %.o rule, which should try to make the object file by calling something like:
g++ -c -o sdl_class.o sdl_class.cpp -w -I../include -lSDL2
However, this is not the case as it looks like it is calling $(CC) -c -o $# $< $(CFLAGS) $(LIBS), as you can see from above.
Do I have a fundamental misunderstanding about how make builds its rules? Seems likely, this is my first Makefile. Perhaps I am confused on how compilation works in general, as I'm somewhat new to that as well.
I would say that the problem is that one or more of the files ../include/sdl_class.h or ../include/SDL_image.h does not exist. Because of that, make is deciding that your pattern rule does not match (because not all the prerequisites can be found or made) and it defaults to the built-in rule to create object files from .cpp files.
The built-in rules use the make variables CXX for the C++ compiler and CXXFLAGS for the C++ flags: the CC and CFLAGS variables are used for the C compiler. That's why your settings for CFLAGS are being ignored.
If you run make -d sdl_class.o you'll see which file make is looking for and why it decides to not use your pattern rule.
If you rewrite your rules like this it will work better:
%.o: %.cpp
$(CC) -c -o $# $< $(CFLAGS)
sdl_class.o tests.o: $(DEPS)
because make will now complain that the relevant files can't be found or created.
There are other issues, of course. You shouldn't be passing $(LIBS) to your compile command; that belongs only in your link line. And, you should probably stick to the standard variables CXX for the C++ compiler, CPPFLAGS for preprocessor flags like -I and -D, and CXXFLAGS for C++ compiler flags. Also, linker library flags like -L../lib go in LDFLAGS and linker libraries like -lSDL2 go in LDLIBS.
CC/CCFLAGS are for C compilation. You should use CXX and CXXFLAGS for C++. They are used in built-in rules and in the LINK.cc macro, making the Makefile much simpler, and thus less error prone.
CXXFLAGS = -Wall ...
prog : foo.o bar.o
$(LINK.cc) -o $# $^
see Default linker setting in Makefile for linking C++ object files

How to "make" an SDL project on linux?

Makefiles are quite confusing to me. I am attempting to "make" my project that I have worked on in Windows. The confusing part is actually constructing the make file from scratch. I would am trying to also link to the SDL2 library, and that is in a '.a' format.
Here is my code for the make file so far, I have tried multiple versions, and this is the latest:
CXX = gcc
OUT = Engine
SRC =Software-Rendering/src/
SDL_INCLUDE_DIR =Software-Rendering/lib/SDL2/include/SDL/
LIB_DIR =Software-Rendering/lib/SDL2/x86/linuxLib/
SDL = -l${LIB_DIR}libSDL -l${LIB_DIR}/libSDL2main
CPP_FILES =Bitmap.cpp Main.cpp Vector3.cpp Window.cpp
H_FILES =Bitmap.h ErrorReport.h Vector3.h Window.h
O_FILES = Bitmap.o ErrorReport.o Main.o Vector3.o Window.o
all: $(OUT)
$(OUT): $(O_FILES)
$(CXX) -o $# $^ ${SDL}
#Making all of the object files down
$(O_FILES): $(H_FILES)
$(CXX) -c $(CPP_FILES)
#Make sure we can easily clean up the directory
clean:
rm -f Engine ${O_FILES}
clean_obj:
rm -f ${O_FILES}
I decided to put the ".a" files in a special directoy in my project so whenever someone clones my repository on github all of the files for compiling and linking are already there.
Why isn't this working and how can I make it work?
Your library linking directive are wrong -- -l prefixes lib to the name you specify, and then searches through the libdir path set by the -L options. So what you want is something like:
SDL = -L$(LIB_DIR) -lSDL -lSDL2main
You can make it clearer/more standard by using the standard varnames for libraries:
LDFLAGS = -L$(LIB_DIR)
LDLIBS = -lSDL -lSDL2main
$(OUT): $(O_FILES)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
Also, get rid of the explicit command to compile source files -- the default built in rule is fine and easier to use.

Makefile Issue linking Zeromq libs on Linux

I'm working on a project and trying to compile my code. I just moved this code from windows (VC++) to linux and it worked fine on windows but I can't get it to compile on linux.
The program uses zeromq for TCP connections and I am getting multiple errors when I build. Errors of the type:
/usr/local/include/zmq.hpp:372: undefined reference to `zmq_bind'
/usr/local/include/zmq.hpp:415: undefined reference to `zmq_msg_send'
I've installed zeromq via its tarball on my linux machine, and manually added zmq.hpp to the /usr/local/include folder. I suspect that I am doing something wrong in my makefile and thats why I am getting these errors.
I am somewhat weak in creating makefiles so I would greatly appreciate if someone can take a look for me and tell me if there is an obvious issue with my makefile that is causing these issues. Here is my makefile
C = g++
DEBUG = -g
CFLAGS = -g -Wall -std=c++11
LFLAGS = -L/usr/local/lib/
INCLUDES = -I/usr/local/
LIBS = -libzmq.la
SRCS = main.cpp NetworkTestServer.cpp
OBJS = $(SRCS:.cpp=.o)
EXECUTABLE = tester
all: $(SRCS) $(EXECUTABLE)
$(EXECUTABLE): $(OBJS)
$(CC) $(EXECUTABLE) -o $(EXECUTABLE) $(LIBS)
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
clean:
$(RM) *.o *~ $(EXECUTABLE)
Thanks much
Looks to me like your LIBS definition is wrong.
Typically, the lib part is omitted, along with the extension. So, try something like:
LIBS = -lzmq
If that doesn't work, ensure that this library is contained in the location as specified by your LFLAGS variable.

How to link jsoncpp?

How can I link jsoncpp with a C++ program using g++? I tried:
g++ -o program program.cpp -L/path/to/library/files -ljsoncpp, -ljson, -llibjsoncpp
but g++ keeps saying:
/usr/bin/ld: cannot find -lsomething
You could also try using the new Amalgamated version of jsoncpp, which is new as of version 0.6.0.
The Amalgamated version allows you to use jsoncpp by adding just one directory with a couple of header files and one .cpp file to your project. You then can directly compile jsoncpp into your program with no worries about having to link to any jsoncpp libraries.
Look in /path/to/library/files to see what your *.a file is really named. On my system, I link with:
-ljson_linux-gcc-4.4.3_libmt
Some libraries will create a link from lib<name>.a to lib<name>-<version>.a for you, but I don't think that jsoncpp does this automatically. Therefore, you need to specify the complete name when linking.
You basically need to tell the path and the library.
jsoncpp library has pkg-config and you can use the command
`pkg-config --cflags path/to/jsoncpp/build/pkg-config/jsoncpp.pc`
for the include path and
`pkg-config --libs ../jsoncpp/build/pkg-config/jsoncpp.pc`
for linking (when running the command with g++ use the ). To see the single commands which is -L/libraryPath -ljsoncpp) run the commands above in the terminal without the ``.
It is easier to use this commands in a Makefile. As example my Makefile is:
CXX = g++
CXXFLAGS = -std=c++11
INC_PATH = `pkg-config --cflags ../jsoncpp/build/pkg-config/jsoncpp.pc`
LIBS = `pkg-config --libs ../jsoncpp/build/pkg-config/jsoncpp.pc`
SOURCES := $(wildcard *.cpp)
OBJDIR=obj
OBJECTS := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SOURCES))
DEPENDS := $(patsubst %.cpp,$(OBJDIR)/%.d,$(SOURCES))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: yourProjectExecutableName
clean:
$(RM) $(OBJECTS) $(DEPENDS) parking
# Linking the executable from the object files
yourProjectExecutableName: $(OBJECTS)
$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $# $(LIBS)
-include $(DEPENDS)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: %.cpp Makefile $(OBJDIR)
$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) -MMD -MP -c $< -o $#
and then in the directory of the file I run make. The final command(s) will be printed out in the Terminal