Makefile for simple C++ OpenGL program - c++

I'm trying to write a makefile for an OpenGL program written in C++ (OSX).
Right now, there is only the single file chess.cpp, but I expect to add other files to the project, so I'm trying to create a makefile that I can expand to handle new files as needed. I'm getting these errors:
clang: error: no such file or directory: 'chess.o'
clang: warning: -framework GLUT: 'linker' input unused
clang: warning: -framework OpenGL: 'linker' input unused
make: *** [chess.o] Error 1
This is the makefile that I created. It's borrowed from something that I normally use for C programs, so if it looks strange, that could be why. How can I make this work for my C++ project?
CC = g++
CFLAGS = -c -g -Wall -Wextra
DEPS =
LDFLAGS = -framework GLUT -framework OpenGL
all: chess
%.o: %.cpp $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
chess.o: chess.cpp
$(CC) -c chess.cpp chess.o $(LDFLAGS)
chess: chess.o
$(CC) -o chess.o (LDFLAGS)
clean:
rm chess
rm *.o

There's a couple of errors:
First:
%.o: %.cpp $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
This compiles all .cpp files and everything in $(DEPS) into their respective .o files.
This makes the following line redundant: (although this line appends the linker flags, which the previous does not)
chess.o: chess.cpp
$(CC) -c chess.cpp chess.o $(LDFLAGS)
Even so, the line has an error. It is missing the output file option -o. The correct syntax is:
chess.o: chess.cpp
$(CC) -c chess.cpp -o chess.o $(LDFLAGS)
And finally:
chess: chess.o
$(CC) -o chess.o (LDFLAGS)
This line is missing an input argument. Make doesn't know what to compile. Also you are using the dependency file name as output argument. The filename directly after option -o specifies the output. Also a $ is missing at (LDFLAGS). The correct syntax should read:
chess: chess.o
$(CC) chess.o -o chess $(LDFLAGS)

Related

SFML library doesn't link with makefile compilation

I have been trying to link the SFML dlls to my windows C++ project, but I can't get it to work. I always end up with:
fatal error: SFML/System.hpp: No such file or directory
I've tried a bunch of things but nothing changes the issue.
Here is my makefile:
PROGRAM = zero_flip
OBJS = src/main.o src/Math.o src/card.o src/game_board.o src/indicator.o src/ui.o
CXX = g++
CXX_FLAGS = -O0 -g -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable
LIB_DIRS = -L./Resources/libs/
LIBS = -lsfml-system -lsfml-graphics -lsfml-window -lsfml-audio
LNK_FLAGS = $(LIB_DIRS) $(LIBS)
DEPS=$(OBJS:.o=.d)
.PHONY: all clean
all: $(PROGRAM)
-include $(DEPS)
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
$(PROGRAM): $(OBJS)
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $^ -o $#
clean:
rm -f $(OBJS) $(DEPS) $(PROGRAM) && clear
The "./Resources/libs/" directory contains:
openal32.dll
sfml-audio-2.dll
sfml-audio-d-2.dll
sfml-graphics-2.dll
sfml-graphics-d-2.dll
sfml-system-2.dll
sfml-system-d-2.dll
sfml-window-2.dll
sfml-window-d-2.dll
Can anyone get me unstuck please this is driving me mad.
This is wrong:
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
This rule says it will compile a source file into an object file, but the recipe actually builds a complete executable: it will compile the source file like xxx.cpp then link it into a program named xxx.o. You need to invoke just the compiler here, not the linker, so you should not have $(LNK_FLAGS) and you need to add the -c option to tell the compiler to stop after compiling and not link.
Then you need to add an -I option to the compile line telling the compiler where to find the header files needed during compilation... in this case SFML/System.hpp.

Makefile does not evaluate OBJECTS variable

I am trying to build a Makefile that will build a shared library with g++ and I find that it is not evaluating the OBJECTS variable. This is on Ubuntu 18.04 and all the files are in the same current directory. Secondly it is completely skipping the source file compilation and proceeding directly to evaluate the linking instruction. As a clarification I am using GNU Make 4.1
Here is what I get when I type make all
g++ -shared -pthread -o tree.so
g++: fatal error: no input files
compilation terminated.
Makefile:12: recipe for target 'tree.so' failed
make: *** [tree.so] Error 1
Here is my Makefile code
CC=g++
CFLAGS = -I/usr/local/include -Wall -std=c++17 -O3 -march=native -Ofast -ftree-vectorize
LIBS=-shared -pthread
SOURCES=$(wildcard *.cpp)
OBJECTS=$(wildcard *.o)
TARGET=tree.so
all:$(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(LIBS) -o $(OBJECTS) $(TARGET)
$(OBJECTS):$(SOURCES)
$(CC) -c -g $(CFLAGS) $(SOURCES)
clean:
rm -f $(OBJECTS) $(TARGET)
If you only have the *.cpp files in your directories, then there is not any *.o yet, so your $(wildcard *.o) will expand to nothing.
What you want is to get the *.cpp files and compute the corresponding *.o files:
OBJECTS=$(patsubst %.cpp,%.o,$(SOURCES))
or equivalently:
OBJECTS=$(SOURCES:.cpp=.o)
Now, your compiler command is not the best one, because if you touch any source file all will be compiled. You can use instead:
$(OBJECTS): %.o: %.cpp
$(CC) -c -g $(CFLAGS) $< -o $#
So that only the touched files are actually rebuilt.
Also you have the linking command wrong. It should be:
$(TARGET) : $(OBJECTS)
$(CC) $(LIBS) -o $(TARGET) $(OBJECTS)
because the argument to the -o option is the output file, that is the target.

"make" fails when using pattern matching

I'm trying to create a generic make file so that I can compile my project independently of how many files I add to it and where I decide to put them in the project tree.
In my step by step approach I cam to this makefile which works fine.
CC=g++
OBJECTS=main.o board.o
VPATH=src:\
src/board:\
include/board:\
build:\
bin
boardG : main.o board.o
$(CC) -o bin/boardG build/main.o build/board.o
main.o : main.cpp board.hpp
$(CC) -c -I include $< -o build/$#
board.o : board.cpp board.hpp
$(CC) -c -I include $< -o build/$#
This version will do the job just fine. See output below:
me#01:~/code/projects/boardG$ make
g++ -c -I include src/main.cpp -o build/main.o
g++ -c -I include src/board/board.cpp -o build/board.o
g++ -o bin/boardG build/main.o build/board.o
The problem here is that I will have to create one rule for each .cpp file. Which is precisely what I try to avoid. Hence I tried to adapt the version above using matching patterns like this:
CC=g++
OBJECTS=main.o board.o
VPATH=src:\
src/board:\
include/board:\
build:\
bin
boardG : main.o board.o
$(CC) -o bin/boardG build/main.o build/board.o
%.o : %.cpp %.hpp
$(CC) -c -I include $< -o build/$#
When I run make now I get the follwing output:
me#01:~/code/projects/boardG$ make
g++ -c -o main.o src/main.cpp
src/main.cpp:2:27: fatal error: board/board.hpp: No such file or directory
compilation terminated.
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1
My project has the follwing structure/files in it.
./bin/
./build/
./include/board/board.hpp
./src/main.cpp
./src/board/board.cpp
./makefile
I'm wondering why make would change the command when using pattern matching? Or, and probably more accurately, what am I doing wrong that makes make fail?
Just avoid using VPATH when it comes to object files. What's happening is that make is actually using the built-in rule for %.o and not using your rule at all.
If you prefix all your objects with the directory, this should work:
CC=g++
OBJDIR = build
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/board.o
VPATH = src:\
src/board:\
include/board:\
bin/boardG : $(OBJECTS)
$(CC) -o $# $^
$(OBJDIR)/%.o : %.cpp %.hpp
$(CC) -c -I include $< -o $#
Here is a helpful resource, which more or less exactly describes the problem you've run into.

How do I create a makefile for SDL2/C++ on Windows?

As the title states I'm trying to create a makefile for compiling C++ programs using SDL2 on Windows. I have MinGW installed and working. I'm using Sublime 2 as my environment. Here's what I have so far:
CXX = g++
CXXFLAGS = -std=c++0x -g -O3 -w -Wl,-subsystem,windows
INCLFLAGS = -IC:\Libraries\i686-w64-mingw32\include\SDL2
LDFLAGS = -LC:\Libraries\i686-w64-mingw32\lib -lmingw32 -lSDL2main -lSDL2
OBJECTS = main.o
TARGET = 1_hellosdl
$(TARGET) : $(OBJECTS)
$(CXX) $(INCLFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $(TARGET) $(OBJECTS)
main.o :
clean:
rm -rf $(OBJECTS) $(TARGET)
remake:
clean $(TARGET)
Right now when I compile I get the following error:
g++ -std=c++0x -g -O3 -w -Wl,-subsystems,windows -c -o main.o main.cpp
In file included from main.cpp:1:0:
main.hpp:4:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
So the issue is that g++ can't find the SDL include file when it tries to compile main.cpp. I get that this is because $(INCLFLAGS) isn't being added to the line under main.o :.
Optimally, I'd like to specify INCLFLAGS implicitly similar to CXXFLAGS and LDFLAGS, but based on this it doesn't look like it's possible.
Is there a way to do this using an implicit variable or, failing that, what's the best alternative? Is there anything else I am doing wrong?
I managed to solve this by moving $(INCLFLAGS) into $(CXXFLAGS):
INCLFLAGS = -IC:\Libraries\i686-w64-mingw32\include\SDL2
CXXFLAGS = $(INCLFLAGS) -std=c++0x -g -O3 -w -Wl,-subsystem,windows
Additionally, I had to move $(LDFLAGS) to the end in order for it to link correctly:
$(TARGET) : $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS) $(LDFLAGS)

g++ consolidation: ld: fatal: file main.o: unknown file type

I'm scanning the web and all my project files for solution but still can't find the answer why my linker won't finish the job. Everything smoothly compiles into .o files, but the last make command fails. And here is the Makefile content:
CXX = g++
CXXFLAGS = -Wall -pedantic -c
OBJS = main.o operacje.o porownaj.o
dzialania: $(OBJS)
$(CXX) $^ -o $#
main.o: main.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $^ -o $#
operacje.o: operacje.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $^ -o $#
porownaj.o: porownaj.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $^ -o $#
clean:
rm -f *o
and again, here is the mistake that pops out:
g++ main.o operacje.o porownaj.o -o dzialania
ld: fatal: file main.o: unknown file type
ld: fatal: file processing errors. No output written to dzialania
*** Error code 1
make: Fatal error: Command failed for target `dzialania'
I'm sure it's some kind of a basic mistake but after staring at the file for a few hours I won't notice it anyway. Maybe some of you folks with notice the bug with a fresh eye.
btw. it's my first post after long-term passive lurking, I hope I did everything right. Thanks in advance!
#edit1 OK, I did all the suggested corrections
#edit2 Seems like the problem is caused by improper module division of my program. I'll rearrange it's structure and let you know if it works then. Thanks for all the support!
#edit3 OK, I changed the structure of my program and everything runs smooth, Thanks again!
Try using $< instead of $^ in your rules to compile main.o, operacje.o, and porownaj.o:
main.o: main.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $< -o $#
operacje.o: operacje.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $< -o $#
porownaj.o: porownaj.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $< -o $#
That will cause make to compile only the corresponding .cpp file. When you use $^ the header files are passed to the g++ command which tells the compiler to create precompiled headers for them - that's what's ending up in main.o instead of the object file for main.cpp.
GNU make variable definitions like CC = g++, or CFLAGS = -Wall -pedantic etc.. should each be on its own line:
CC = g++
CFLAGS = -Wall -pedantic
OBJS = main.o operacje.o porownaj.o
BTW, you probably mean
CXX = g++
CXXFLAGS = -Wall -pedantic
You certainly don't want -c explicitly in your CFLAGS or CXXFLAGS; you really should remove it.
Also, recipes should be after its rule, so you want
dzialania: $(OBJS)
$(LINK.cc) $^ -o $#
operacje.o: operacje.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) -c $< -o $#
The several spaces are actually a single tab character.
Run make -p to understand the rules known by make; see also this answer and that one.
Take time to read GNU make documentation.