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).
Related
I am trying to cross-compile the mosquitto example program. At first I compiled the mosquitto example on Host PC, it worked well. The makefile is as following:
CFLAGS=-Wall -ggdb -I../../lib -I../../lib/cpp
LDFLAGS=-L../../lib ../../lib/cpp/libmosquittopp.so.1 ../../lib/libmosquitto.so.1
.PHONY: all clean
all : mqtt_temperature_conversion
mqtt_temperature_conversion : main.o temperature_conversion.o
${CXX} $^ -o $# ${LDFLAGS}
main.o : main.cpp
${CXX} -c $^ -o $# ${CFLAGS}
temperature_conversion.o : temperature_conversion.cpp
${CXX} -c $^ -o $# ${CFLAGS}
clean :
-rm -f *.o mqtt_temperature_conversion
Then I add the following lines to cross compile this program:
CXX=arm-unknown-linux-gnueabi-gcc
AR=arm-unknown-linux-gnueabi-ar
AS=arm-unknown-linux-gnueabi-as
LD=arm-unknown-linux-gnueabi-ld
RANLIB=arm-unknown-linux-gnueabi-ranlib
Then it gives a error message:
/home/Tools/tool_chain/bin/../lib/gcc/arm-unknown-linux-
gnueabi/5.4.0/../../../../arm-unknown-linux-gnueabi/bin/ld: main.o:
undefined reference to symbol '_ZdlPv##GLIBCXX_3.4'
/home/Tools/tool_chain/bin/../sysroot/usr/lib/libstdc++.so.6:
error adding symbols: DSO missing from command line
I am very confused. I googled for this error, but none of them seems to be relevant. Cause when I compiled with the host PC compiler, everything works. So it should not be a lib problem.
update:
So I could not figure out what happened, then I made a test project myself. The Makefile is as follows:(I ignored the cross tool chain variabl parts to save some place)
CFLAGS=-Wall -ggdb -I../../lib -I../../lib/cpp
LDFLAGS=-L../../lib ../../lib/cpp/libmosquittopp.so.1 ../../lib/libmosquitto.so.1
mqtt: main.o
${CXX} $^ -o $# ${LDFLAGS}
main.o: main.cpp
${CXX} -c $^ -o $# ${CFLAGS}
And it worked?! I flashed it to the board the executable seems to be correct.
Now I am more confused
LD=arm-unknown-linux-gnueabi-ld
Don't use ld directly, ever. You want to use g++ as the driver that calls your linker, otherwise you will have linker problems.
LD=$(CXX)
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.
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.
so I have this structure:
simpleConnect.cpp (contains main)
Call feature_extract.cpp
feature_extract.cpp (does some things here, returns to simpleConnect)
ThesisHeader.h (has declaration of feature_extract and all the includes etc...)
Now...These files use a library called ARIA (used for mobilerobots) and a set of header files - EIGEN (for matrix manipulations etc)
I used to suggested structure by Aria as follows:
SOURCES=simpleConnect
all: $(SOURCES)
CFLAGS=-fPIC -g -Wall
ARIA_INCLUDE =-I/usr/local/Aria/include
ARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt
%: %.cpp
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) $< -o $# $(ARIA_LINK)
But I'm getting this error at the line where I call the function feature_extract:
undefined reference to 'feature_extract(......)'
collect2: ld reurned 1 exit status
As far as I can understand this is to do with me not telling the compiler that feature_extract is there....because I don't know how...
I tried adding pieces I found online but to no avail, hence I came asking here.
Could anyone be kind enough to modify the makefile so as to include that file to be able to compile?
Thank you for your time,
Patrick
This app needs `feature_extract`.
You're using "SOURCES" for something other than sources.
CFLAGS=-fPIC -g -Wall
ARIA_INCLUDE =-I/usr/local/Aria/include
ARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt
app_name: simpleConnect.cpp feature_extract.cpp
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) $^ -o $# $(ARIA_LINK)
If this works, further refinements are possible.
I managed to solve this problem, thanks to those who helped.
I ended up reading the GNU make manual, which solved my problem.
https://www.gnu.org/software/make/manual/make.pdf
This is the final makefile that ended up working:
CFLAGS=-fPIC -g -Wall
ARIA_INCLUDE =-I/usr/local/Aria/include
ARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt
edit : simpleConnect.o feature_extract.o
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) -o edit simpleConnect.o
feature_extract.o $(ARIA_LINK)
simpleConnect.o : simpleConnect.cpp ThesisHeader.h feature_extract.cpp
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) -c simpleConnect.cpp $(ARIA_LINK)
feature_extract.o : feature_extract.cpp ThesisHeader.h
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) -c feature_extract.cpp $(ARIA_LINK)
clean :
rm edit simpleConnect.o feature_extract.o
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.