-1

I have tried the advice on makefile error: undefined reference to main and http://nuclear.mutantstargoat.com/articles/make/. I moved into the directory my makefile was at, ran it and got multiple undefined reference errors.:

My file directory looks like this

makefile
Version3Box (Directory)
    SharedCppFiles (Directory)
        Box.cpp (#include "Box.h")
    SharedHeaders (Directory)
        Box.h   (#include <SFML/Graphics.hpp>)
    Snake   (Directory)
        CppFiles (Directory)
            GridPiece.cpp (#include "Box.cpp", "Box.h", "GridPiece.h")
            main.cpp      (#include "Box.h", "GridPiece.cpp", "GridPiece.h")
        Headers (Directory)
            GridPiece.h   (#include "Box.h")

And here is my makefile:

# Specify the final target name
EXE := SnakeGame

# Specify the source files
# Effectively list all source files in the current directory
SRC := $(wildcard *.cpp) \
       $(wildcard ../*.cpp)

#From the source file list, get the corresponding object file list
OBJ := $(SRC:.cpp=.o)

# From the object file list, get the dependency file list to handle automatic recompilation
# when a header file is modified
DEP := $(OBJ:.o=.d)

# Specify preprocessor flags (This is a built-in variable)
CPPFLAGS := -I../Include
# Required flags to enable the automatic dependency generation by the compiler
CPPFLAGS += -MMD -MP

# Specify compiler flags (This is a built-in variable)
# Basic Warning Flags
CFLAGS := -Wall -W -pedantic

# Specify linker flags (This is a built-in variable)
LDFLAGS := -L../lib -Llib/sfml/lib -lsfml-graphics -lsfml-window -lsfml-system

#Specify linker libraries (This is a built-in variable)
LDLIBS := -lm

# Tell make that these target are not real files
.PHONY: all clean

# Now the standard primary rule
all: $(EXE)

# How do we make $(EXE) ? Remember the recipe describe the linking phase
$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

# Let's clean up the mess
clean:
    $(RM) $(EXE) $(OBJ) $(DEP)

# Don't forget to include the dependency files to let make know when to recompile
-include $(DEP)

Can someone please help me trouble shoot this code, or generate a different makefile similar to this one? I am trying to learn how to write a better makefile too compared to what I am currently capable of. Thank you so much!

Sorry that I'm adding another undefined reference to main question on SO.

Kalkirin
  • 23
  • 4
  • Please post a [mcve]. – melpomene Jan 05 '19 at 20:45
  • `CC` is a C compiler and `CFLAGS` are flags for a C compiler. Your code is written in C++, so you should be using `CXX` as the variable for the compiler and `CXXFLAGS` for the flags for the compiler. In particular, your link line uses `$(CC)` so it attempts to link with the C compiler, but that fails because your code is C++ code and using C++ standard library functions, none of which are available if you link your program as a C program. – MadScientist Jan 05 '19 at 21:24

3 Answers3

0

The linker complains about a missing main function.

here: (.text+0x20): undefined reference to `main'

Where do you think, is a main function? In which file? it looks usualy like this:

int main(int argc, char* argv[]) {
    ...
}

with the updated error messages, it looks like the standard c++ library is not linked. Add "-lstdc++" to LDFLAGS

LDFLAGS := -L../lib -Llib/sfml/lib -lsfml-graphics -lsfml-window -lsfml-system -lstdc++
Jörg Beyer
  • 3,631
  • 21
  • 35
  • Is it a problem with my SRC definition? – Kalkirin Jan 05 '19 at 20:46
  • could the issue be here: OBJ := $(SRC:.cpp=.o) ? Maybe because of the relative paths you are using? – Jörg Beyer Jan 05 '19 at 20:47
  • I changed the SRC definition to "SRC := $(wildcard Version3Box/Snake/*.cpp) \ $(wildcard Version3Box/*.cpp)", and the makefile started to work for 3 lines, but then I got blasted with literally 100 different undefined reference messages and it failed. – Kalkirin Jan 05 '19 at 20:49
  • My main function is in main.cpp. The program wouldn't compile without it. However, I thought the code above was supposed to find my main function. – Kalkirin Jan 05 '19 at 20:54
  • compiling without a main function is not an issue (libraries for example have no main). Linking is, where it breaks. Please show the new error messages. – Jörg Beyer Jan 05 '19 at 20:55
  • I updated my post with the new error messages when I run the makefile in the Version3Box/Snake directory (the directory my makefile is in) – Kalkirin Jan 05 '19 at 21:06
  • looks like a missing lib std c++. add "-lstdc++" to the libs. – Jörg Beyer Jan 05 '19 at 21:09
  • Not working. I'm just going to delete the post and try to build a simple makefile like all: hello hello: main.o factorial.o hello.o [tab] g++ main.o factorial.o hello.o -o hello main.o: main.cpp functions.h [tab] g++ -c main.cpp factorial.o: factorial.cpp [tab] g++ -c factorial.cpp hello.o: hello.cpp [tab] g++ -c hello.cpp clean: [tab] rm -f *.o when I figure out how to make it work. I was failing at that too earlier. – Kalkirin Jan 05 '19 at 21:14
  • never mind won't delete. I'll just leave this abomination for all to see. Thanks for trying to help! – Kalkirin Jan 05 '19 at 21:23
0

in cc -L../lib -Llib/sfml/lib -lsfml-graphics -lsfml-window -lsfml-system -lm -o SnakeGame there is no object file, so at least the main is missing, you cannot just give libs

in g++ Version3Box/Snake/main.cpp Version3Box/Box.cpp Version3Box/Snake/GridPiece.cpp -o SnakeGame -Llib/sfml/lib -lsfml-graphics -lsfml-window -lsfml-system that time there are cpp file to produce objects

There are no object in the first version because as melpomene says the sources are not found, and they are not found because you do make -f Version3Box/Snake/makefile rather than (cd Version3Box/Snake/ ; make -f makefile) so SRC := $(wildcard *.cpp) $(wildcard ../*.cpp) look in the current directory rather than under Version3Box/Snake as you supposed

bruno
  • 32,421
  • 7
  • 25
  • 37
  • 2
    Presumably `$(OBJ)` is empty because `$(SRC)` is empty. – melpomene Jan 05 '19 at 20:45
  • How do I fix this? – Kalkirin Jan 05 '19 at 20:53
  • @Kalkirin Start by creating a [mcve]. Also, why do you have a makefile in a subdirectory instead of at the top level of your project? – melpomene Jan 05 '19 at 20:55
  • @Kalkirin as I say in the edited version of my answer go into the directory before to do the make. Please update and reread my answer – bruno Jan 05 '19 at 20:55
  • When I cd Version3Box/Snake ; make -f makefile... I no longer get an undefined reference to main, but I get blasted with 50 - 100 new undefined reference errors to functions. – Kalkirin Jan 05 '19 at 20:59
  • melpomene - I have absolutely no idea how makefiles work atm. I can just do incredibly simple ones. But this project is going to get fairly complex, so I need better makefiles – Kalkirin Jan 05 '19 at 21:00
  • the Makefile is strange, searching in the current directory and in the parent directory. It is better to have a makefile in each directory, doing libs except in the directory where the main is and producing the exe also using the other libs – bruno Jan 05 '19 at 21:02
  • with the information we have (you give) it is difficult to help you more, at least you know why you have the error about the missing _main_ – bruno Jan 05 '19 at 21:04
  • I have absolutely no idea how to do that, and have not found a tutorial teaching me how to do that yet. I updated my post with new error messages – Kalkirin Jan 05 '19 at 21:05
  • @Kalkirin you have to do the make and look what is made and what is missing to reach the goal, again we have nothing to say you "do that and all will be ok" except what I said in the answer – bruno Jan 05 '19 at 21:07
0

I'll continue to edit this answer as I figure out the problem. I will be studying the GNU Make Manual (https://www.gnu.org/software/make/manual/make.html#Recursion) to figure out this problem.

Edit: Here is the working makefile that successfully compiles and runs my program

# Specify the final target name
EXE := SnakeGame

# Specify the paths for make to search and find files
vpath %.h Version3Box/SharedHeaders:Version3Box/Snake/Headers
vpath %.cpp Version3Box/SharedCppFiles:Version3Box/Snake/CppFiles

# Specify preprocessor flags (This is a built-in variable)
CPPFLAGS := -I../Include
# Required flags to enable the automatic dependency generation by the compiler
CPPFLAGS += -MMD -MP

# Specify compiler flags (This is a built-in variable)
# Basic Warning Flags
CXXFLAGS := -Wall -W -pedantic

# Specify linker flags (This is a built-in variable)
LDFLAGS := -L../lib -lstdc++ -Llib/sfml/lib -lsfml-graphics -lsfml-window -lsfml-system

#Specify linker libraries (This is a built-in variable)
LDLIBS := -lm

# Specify all of the objects used in compilation and infer recipes
objects = main.o Box.o GridPiece.o

# The compiling rule
SnakeGame : $(objects)
    $(CXX) $(CXXFLAGS) -o $(EXE) $(objects) $(LDFLAGS) $(LDLIBS)

# Dependency of each file
$(objects) : Box.h
main.o GridPiece.o : GridPiece.h

# Remove each intermediate file generated
.PHONY : clean
clean :
    rm $(objects) *.d
Kalkirin
  • 23
  • 4