0
votes

I have this structure for my project:

root
|____Makefile
|
|___src
|     |____*.cpp  
|
|___includes
|      |___*.h
|
|___obj
|___tmp
|___bin

The problem is that when i try to make i got this error:

g++ -std=c++11 obj/book.o -o bin/main
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

My main.cpp is inside src than i have a file .h where i declare a struct and some function and a .cpp where i define everything. In the main and in the cpp i do

#include "../includes/myfile.h"

How i can compile and fix this problem? Here is my makefile:

CXX = g++
CXXFLAGS = -std=c++11 -I..
LDFLAGS = -std=c++11
EXECUTABLE= bin/main
SOURCES = $(wildcard src/*.cpp)
HEADERS = $(wildcard includes/*.h)
OBJECTS = $(patsubst src/%.cpp, obj/%.o, $(SOURCES))

BASE = $(USER)

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CXX) $(LDFLAGS) $< -o $@

obj/%.o: src/%.cpp
    $(CXX) -c $(CXXFLAGS) $< -o $@

clean: 
    rm $(OBJECTS)

rmproper:
    rm $(OBJECTS) $(EXECUTABLE)

pdf:
    a2ps Readme.txt makefile $(HEADERS) $(SOURCES) -o /tmp/out.ps
    ps2pdf /tmp/out.ps $(BASE).pdf

zip:
    zip $(BASE).zip Readme.txt makefile $(HEADERS) $(SOURCES)
1
It seems you're linking a single object file into a single executable file, and that object file (and the source file the generated it) doesn't have a main function. Are youre Makefile supposed to build and link multiple source (and object) files? Is the output you show the full build log? If you remove the object files and build again, can you copy-paste the full output into your question? - Some programmer dude
The problem is here: $(EXECUTABLE): $(OBJECTS) $(CXX) $(LDFLAGS) $< -o $@. $< is the first prerequisite, i.e. the first object file. What you want is $^ to list all object files. - Johan Boulé
In $(EXECUTABLE): $(OBJECTS) rule, I believe you want to replace $< with $^. The former is "the first file from the list", the latter is "all files from the list". - Igor Tandetnik
@JohanBoulé Should be easier to write an actual answer now. :) - Some programmer dude
In a nutshell: you are not linking the object file defining the function. See the other comments. - Jesper Juhl

1 Answers

5
votes

The problem is here:

$(EXECUTABLE): $(OBJECTS)
    $(CXX) $(LDFLAGS) $< -o $@

$< is the first prerequisite, i.e. the first object file in your $(OBJECTS) list (which happens to be book.o according to your error message). What you want to pass is the whole list of object files, which can be accomplished by using either $^, or even $(OBJECTS) in place of $<.