I am trying to compile my C++ program using make and I've come across this problem that I can't quite understand. I have 3 files in the src folder of my project: App.h, App.cpp and main.cpp. I have my Makefile located in the root folder of my project, which has the src folder that I mentioned in it. This is what my Makefile looks like:
CC=g++
SRCDIR=./src
CFLAGS=-I$(SRCDIR)
LIBS=-lSDL -lGL
_DEPS=App.h
DEPS=$(patsubst %,$(SRCDIR)/%,$(_DEPS))
_OBJ=main.o App.o
OBJ=$(patsubst %,$(SRCDIR)/%,$(_OBJ))
_SRC=main.cpp App.cpp
SRC=$(patsubst %,$(SRCDIR)/%,$(_SRC))
%.o: $(SRC) $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
tetris: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
clean:
rm -f $(SRCDIR)/*.o $(SRCDIR)/*~
When I type make into the terminal to compile, I get an error like this:
g++ -c -o src/main.o src/main.cpp -I./src
g++ -c -o src/App.o src/main.cpp -I./src
g++ -o tetris src/main.o src/App.o -I./src -lSDL -lGL
src/App.o: In function `main':
main.cpp:(.text+0x0): multiple definition of `main'
src/main.o:main.cpp:(.text+0x0): first defined here
src/main.o: In function `main':
main.cpp:(.text+0x17): undefined reference to `App::App()'
main.cpp:(.text+0x23): undefined reference to `App::onExecute()'
src/App.o: In function `main':
main.cpp:(.text+0x17): undefined reference to `App::App()'
main.cpp:(.text+0x23): undefined reference to `App::onExecute()'
collect2: error: ld returned 1 exit status
But I am sure that I only have 1 main function, and it is in the main.cpp file. What is causing this?
Look at these lines:
src/main.o: In function `main':
src/App.o: In function `main':
Those mean that main is defined both in main.o and App.o.
And above those:
g++ -c -o src/main.o src/main.cpp -I./src
g++ -c -o src/App.o src/main.cpp -I./src
See? Both object files are built using the same source!
You probably want to change this line for the object dependency:
%.o: %.c $(DEPS)
Look at the compilation lines.
You are compiling main.cpp as both main.o and App.o.
You are listing all your source files as prerequisites of the %.o pattern and using $< to only compile the first one (which happens to be main.cpp in this case.
You want %.c instead of $(SRC) there.
Related
I am developing a little program with pocketsphinx (speech to text - library).
On Windows i was using Code::Blocks as development environment and i had success to build a program.
Now i try to port my program to Linux and i am having little problems to link against pocketsphinx.
This is the Makefile:
CC = g++
CFLAGS = -Wall -std=c++11
LDFLAGS = -I/usr/local/include/sphinxbase -I/usr/local/include/pocketsphinx
OBJ = obj/Application.o obj/Main.o obj/Recorder.o
all: $(OBJ)
$(CC) -L/usr/local/lib -o bin/Eve $(OBJ) -s -lsphinxbase -lpocketsphinx
obj/Main.o: src/Main.cpp
$(CC) $(CFLAGS) $(LDFLAGS) -c src/Main.cpp -o obj/Main.o
obj/Application.o: src/Application.cpp src/Application.hpp
$(CC) $(CFLAGS) $(LDFLAGS) -c src/Application.cpp -o obj/Application.o
obj/Recorder.o: src/Recorder.cpp src/Recorder.hpp
$(CC) $(CFLAGS) $(LDFLAGS) -c src/Recorder.cpp -o obj/Recorder.o
It is the same which i was using on Windows, i just adjusted the file path.
I am receiving the following error:
$ make
g++ -Wall -std=c++11 -I/usr/local/include/sphinxbase -I/usr/local/include/pocketsphinx -c src/Application.cpp -o obj/Application.o
g++ -Wall -std=c++11 -I/usr/local/include/sphinxbase -I/usr/local/include/pocketsphinx -c src/Main.cpp -o obj/Main.o
g++ -Wall -std=c++11 -I/usr/local/include/sphinxbase -I/usr/local/include/pocketsphinx -c src/Recorder.cpp -o obj/Recorder.o
g++ -L/usr/local/lib -o bin/Eve obj/Application.o obj/Main.o obj/Recorder.o -s -lsphinxbase -lpocketsphinx
obj/Recorder.o: In function `Recorder::Recorder()':
Recorder.cpp:(.text+0x1c0): undefined reference to `ad_open_sps'
Recorder.cpp:(.text+0x20d): undefined reference to `ad_read'
Recorder.cpp:(.text+0x215): undefined reference to `cont_ad_init'
obj/Recorder.o: In function `Recorder::~Recorder()':
Recorder.cpp:(.text+0x2f3): undefined reference to `cont_ad_close'
Recorder.cpp:(.text+0x303): undefined reference to `ad_close'
obj/Recorder.o: In function `Recorder::recognizeFromMicrophone()':
Recorder.cpp:(.text+0x37a): undefined reference to `ad_start_rec'
Recorder.cpp:(.text+0x395): undefined reference to `cont_ad_calib'
Recorder.cpp:(.text+0x3f0): undefined reference to `cont_ad_read'
Recorder.cpp:(.text+0x4e6): undefined reference to `cont_ad_read'
Recorder.cpp:(.text+0x5b5): undefined reference to `ad_stop_rec'
Recorder.cpp:(.text+0x5d8): undefined reference to `ad_read'
Recorder.cpp:(.text+0x5f4): undefined reference to `cont_ad_reset'
collect2: error: ld returned 1 exit status
make: *** [all] Fehler 1
I don't think that it is a name mangling problem, since i built the lib on my own using the provided Makefile.
What can i do to link against the lib without errors?
EDIT: I figured out how to make it work. I simply modified the rule of the target "all" to this:
$(CC) -static -L/usr/local/lib -o bin/Eve $(OBJ) -s -lpocketsphinx -lsphinxbase -lsphinxad -lpthread
Functions like ad_read are defined in libsphinxad library, you need to add it to your linker command line:
g++ -static -L/usr/local/lib -o bin/Eve obj/Application.o obj/Main.o obj/Recorder.o \
-lpocketsphinx -lsphinxbase -libsphinxad
Please note that the order of libraries is important.
I have project files and I need to use an external test file named TestSuite1.cpp that includes an external header file SignalMasker.h (Was given it and it's object file SignalMasker.o) and my main header file uthreads.h.
I'm still getting undefined refrences such as:
TestSuite1.cpp:63: error: undefined reference to 'SignalMasker::~SignalMasker()'
This means my Makefile isn't including the SignalMasker.o file that resides in the same directory.
This is my Makefile:
CC = g++
FLAGS = -Wall -g
OBJECTS = uthreads.o Thread.o Scheduler.o SchedulerStarter.o TestSuite1.o
.PHONY : clean
all: test1
test1: $(OBJECTS)
g++ $(FLAGS) $(OBJECTS) SignalMasker.o -L . -o test1
TestSuite1.o : TestSuite1.cpp SignalMasker.h uthreads.h
$(CC) -c $(FLAGS) TestSuite1.cpp
uthreads.o : uthreads.cpp uthreads.h SchedulerStarter.h Scheduler.h Thread.h
$(CC) -c $(FLAGS) uthreads.cpp
Scheduler.o : Scheduler.cpp Scheduler.h Thread.h
$(CC) -c $(FLAGS) Scheduler.cpp
SchedulerStarter.o : SchedulerStarter.cpp SchedulerStarter.h Scheduler.h
$(CC) -c $(FLAGS) SchedulerStarter.cpp
Thread.o : Thread.cpp Thread.h uthreads.h translateAdd.h
$(CC) -c $(FLAGS) Thread.cpp
clean:
rm -f $(OBJECTS) *~
And now I'm getting:
~/Desktop/tests$ make
g++ -Wall -g uthreads.o Thread.o Scheduler.o SchedulerStarter.o TestSuite1.o SignalMasker.o -L . -o test1
/usr/bin/ld: error: SignalMasker.o: incompatible target
TestSuite1.cpp:36: error: undefined reference to 'SignalMasker::SignalMasker(int)'
TestSuite1.cpp:63: error: undefined reference to 'SignalMasker::~SignalMasker()'
TestSuite1.cpp:63: error: undefined reference to 'SignalMasker::~SignalMasker()'
TestSuite1.cpp:68: error: undefined reference to 'SignalMasker::SignalMasker(int)'
TestSuite1.cpp:111: error: undefined reference to 'SignalMasker::~SignalMasker()'
TestSuite1.cpp:111: error: undefined reference to 'SignalMasker::~SignalMasker()'
collect2: ld returned 1 exit status
EDIT:
I'm now pondering with the idea that maybe incompatible target means they compiled it under 64bit. My machine is 32bit
you are missing rule to compile SignalMasker.cpp in your makefile. you have to write a rule, the same way you have written for
SchedulerStarter.o, Thread.o
SignalMasker.o : SignalMasker.cpp SignalMasker.h
$(CC) -c $(FLAGS) SignalMasker.cpp
This will ensure the SignalMasker.o is generated with the same compilation flags that you build other objects. It will eliminate incompatibility issues in case of 32-bit/ 64-bit variants.
if you are copying this SignalMasker.o from elsewhere, check the compilation flags used for generating the object. Use the same flags in your makefile.
This is my makefile:
CFLAGS = -Wall -pedantic -pedantic-errors -g -lSDL -lSDL_image
CC = g++
OBJ = Point.o Personaje.o Juego.o EventHandler.o
all: main
#%.o: %.cpp %.h
# $(CC) -c $(CFLAGS) $<
bin: other $(OBJ)
Point.o: Point.cpp Point.h
$(CC) -c $(CFLAGS) $<
Personaje.o: Personaje.cpp Personaje.h
$(CC) -c $(CFLAGS) $<
Juego.o: Juego.cpp Juego.h
$(CC) -c $(CFLAGS) $<
EventHandler.o: EventHandler.cpp EventHandler.h
$(CC) -c $(CFLAGS) $<
main: $(OBJ)
cd ../vista/; make
cp ../vista/*.o .
rm ../vista/*.o
g++ $(CFLAGS) $(OBJ) Pantalla.o Imagen.o main.cpp -o main
clean:
rm *.o;
rm main
PHONY: main
When I compile with "make" I get the following errors:
EventHandler.cpp:17: undefined reference to `SDL_PollEvent'
Pantalla.o: In function `Pantalla::initialize(int, int, int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
Pantalla.cpp:6: undefined reference to `SDL_Init'
Pantalla.cpp:9: undefined reference to `SDL_SetVideoMode'
Pantalla.cpp:14: undefined reference to `SDL_WM_SetCaption'
and many other errors.
The header of "Pantalla.h" contains this line:
#include "SDL/SDL.h"
And I already installed the SDL packages.
I don't know what I'm doing wrong... please help!
CFLAGS = -Wall -pedantic -pedantic-errors -g -lSDL -lSDL_image
This isn't good. You're mixing compiler flags (warnings and debug) with linker information (which libraries you need to link to). Use two separate variables for that:
CFLAGS = -Wall -pedantic -pedantic-errors -g
LIBS = -lSDL -lSDL_image
Then when you compile (but don't link, i.e. when you generate the .o files), only use $(CFLAGS) (like you have now). But when you do link (to produce the final executable), add the linker directives.
g++ $(CFLAGS) -o main main.cpp $(OBJ) Pantalla.o Imagen.o $(LIBS)
The order you put your objects and libraries is important.
One problem is that you are using exactly the same flags for compilation and linking. The compiler doesn't use libraries; the linker doesn't know about pedantic.
A bigger problem is that your -lSDL -lSDL_image appears too early in the link command, g++ $(CFLAGS) $(OBJ) Pantalla.o Imagen.o main.cpp -o main. The linker won't look into libSDL.a or libSDL_image.a (or their equivalents) because there are no unresolved external references at the point where you specified the search. Put the -lSDL -lSDL_image options just before the -o option.
I compile one test code with g++ without any issue.
#include "Python.h"
int main(int argc, char** argv)
{
Py_Initialize();
PyRun_SimpleString("import pylab");
PyRun_SimpleString("pylab.plot(range(5))");
PyRun_SimpleString("pylab.show()");
Py_Exit(0);
}
g++ -o test test.cpp -I/usr/include/python2.7/ -lpython2.7
works fine and runs.
But when I try to embed this code into another project, it fails. It really confuses me.
Makefile is like the following.
CXX=g++
CXXFLAGS=-DIB_USE_STD_STRING -Wall -Wno-switch -g
ROOT_DIR=..
BASE_SRC_DIR=${ROOT_DIR}/PosixSocketClient
INCLUDES=-I${ROOT_DIR}/Shared/ -I${BASE_SRC_DIR} -I/usr/include/python2.7
LIBRARY=-L/usr/lib/python2.7/config
TARGET=eu
$(TARGET):
$(CXX) $(CXXFLAGS) $(INCLUDES) -o EClientSocketBase.o -c $(BASE_SRC_DIR)/EClientSocketBase.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -o EPosixClientSocket.o -c $(BASE_SRC_DIR)/EPosixClientSocket.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -o PosixTestClient.o -c PosixTestClient.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -o Main.o -c Main.cpp
$(CXX) $(LIBRARY) -lpython2.7 -o $# EClientSocketBase.o EPosixClientSocket.o PosixTestClient.o Main.o
clean:
rm -f $(TARGET) *.o
This project compiles fine and runs, the only change I made was adding the test code in the Main.cpp file. warning/error message shows:
In file included from /usr/include/python2.7/Python.h:8:0,
from Main.cpp:15:
/usr/include/python2.7/pyconfig.h:1158:0: warning: "_POSIX_C_SOURCE" redefined [enabled by default]
/usr/include/features.h:163:0: note: this is the location of the previous definition
/usr/include/python2.7/pyconfig.h:1180:0: warning: "_XOPEN_SOURCE" redefined [enabled by default]
/usr/include/features.h:165:0: note: this is the location of the previous definition
g++ -L/usr/lib/ -lpython2.7 -ldl -lutil -o eu EClientSocketBase.o EPosixClientSocket.o PosixTestClient.o Main.o
Main.o: In function main':
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:81: undefined reference toPy_Initialize'
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:82: undefined reference to PyRun_SimpleStringFlags'
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:83: undefined reference toPyRun_SimpleStringFlags'
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:84: undefined reference to PyRun_SimpleStringFlags'
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:85: undefined reference toPy_Exit'
collect2: ld returned 1 exit status
make: * [eu] Error 1
any help? thank you!
Take a look at Lucas's comment for the answer:
"To get rid of the _POSIX_C_SOURCE warning, make sure to include Python.h before all other header files."
I had the same problem. I use Boost Python, so for me I moved the include of boost/python.hpp to the first line in my .cpp file.
(Lukas, post your comment as an answer so the person who asked can mark it as the right answer, and the question won't remain 'unanswered' in StackOverflow.)
This is a bug in Python: https://bugs.python.org/issue1045893
If you include first Python.h, the compiler won't complain but GNU libc's /usr/include/features.h will override it anyway when _GNU_SOURCE is defined:
# undef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 200809L
# undef _XOPEN_SOURCE
# define _XOPEN_SOURCE 700
This is a puzzle to me:
c++ undefined reference to destructor
That's the issue, the code is the same as the link, full makefile and errors here. The linked answers did help but only to highlight that I had some headers in a place I did not expect.
makefile
CXX = g++
BIN = .
LIBS = -L.
INCLUDE = -I . -I
CXXFLAGS = -pipe # -O6
LFLAGS = -lm
GeomTest_OBJS = geomTest.o SASAGeometry.o
geomTest_source = SASAGeometry.cpp SASAGeometry.h sasa_transformMatrix.cpp sasa_transformMatrix.h geomSetup.cpp
SASAGeometry.o : SASAGeometry.cpp SASAGeometry.h sasa_transformMatrix.cpp sasa_transformMatrix.h
geomTest.o : geomSetup.cpp
geomTest : $(GeomTest_OBJS) makefile
$(CXX) -o geomTest.o -o SASAGeometry.o $(LIBS) $(INCLUDE) $(CXXFLAGS) $(geomTest_source) $(LFLAGS)
$(CXX) $(LIBS) $(INCLUDE) $(CXXFLAGS) -o $(BIN)/geomTest geomTest.o SASAGeometry.o $(LFLAGS)
clean : \rm *.o *~ p1
I have both declared and instantiated the destructor AND not (allowing the compiler to do its thing)
error
geomSetup.cpp:(.text+0x5ab): undefined reference to `SASAGeometry::~SASAGeometry()'
geomSetup.cpp:(.text+0x5cd): undefined reference to `SASAGeometry::~SASAGeometry()'
no other errors. (sorry if its preferable to bump seemingly sorted issues rather than link to them, but my effort at that didn't work)
Thanks in advance!
EDIT:
MAKE SURE TO COMPILE THE CORRECT SOURCE FILES, NOT THE OLD ONES YOU FORGOT TO COPY.
Hi #trojanfoe and #Kerrick SB, both answers made me look at my makefile and realise it was ugly. Here is the revised version. I am still getting the same 'undefined reference to destructor' error though:
makefile:
CXX = g++
BIN = .
LIBS = -L.
INCLUDE = -I.
CXXFLAGS = -pipe # -O6
LDFLAGS = -lm
GeomTest_OBJS = sasa_transformMatrix.o SASAGeometry.o geomSetup.o
SASAGeometry.o : SASAGeometry.cpp SASAGeometry.h
sasa_transformMatrix.o : sasa_transformMatrix.cpp sasa_transformMatrix.h
geomSetup.o : geomSetup.cpp
geomTest : $(GeomTest_OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $+
clean : \rm *.o *~ p1
error:
geomSetup.o: In function `main':
geomSetup.cpp:(.text+0x5ab): undefined reference to `SASAGeometry::~SASAGeometry()'
geomSetup.cpp:(.text+0x5cd): undefined reference to `SASAGeometry::~SASAGeometry()'
collect2: ld returned 1 exit status
make: *** [geomTest] Error 1
Why would the linker complain about the destructor and not the constructor or any other methods/functions in the class?
Thanks again!
Your executable output file and your object file geomTest.o have the same name! That's bound to get you into trouble when the linker overwrites the object file.
Change it to $(CXX) -o geomTest ..., or better even to $(CXX) $# ... to avoid such problems in the future.
In fact, you are misusing the linker command altogether: you just want to have one single -o option, and the objects are listed directly, without flags:
g++ -o myprog main.o foo.o bar.o
Within the Makefile, do yourself a favour and use magic macros:
myprog: main.o foo.o bar.o
$(CXX) $(LDFLAGS) -o $# $+ $(LIBRARIES)
Here -o $# matches the target name, i.e. -o myprog, and $+ matches all the dependent names, i.e. main.o foo.o bar.o.
The guiding idea behind using variables is that you should never say the same thing more than once if you can help it. So you can have myprog: $(MyObjects) as the rule, but then use $+ in the command line to avoid repetition of MyObjects. This improves locality and maintainability.
The -o SASAGeometry.o in the geomTest target looks highly suspect to me - you are overwriting one of the dependency objects (actually both dependencies).
Try this:
geomTest : $(GeomTest_OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $(GemoTest_OBJS) $(LIBS)
(note that $LDFLAGS is the conventional variable in which to hold linker flags, not $LFLAGS which is used with the lex tool).