external print function how compile - c++

I created two Files where the second File should print a std::vector.
That's my main.cpp:
#include <vector>
int main() {
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
return 0;
}
That's the print.cpp
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
template <typename T> void printVec(T vec) {
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
template void printVec< std::vector<int> >(std::vector<int> t);
I compiled those files with:
g++ -g main.cpp -o main.o
g++ -g -c print.cpp -o print.o
g++ -o main main.o print.o
and get following error
main.o: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
main.o: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o:(.fini+0x0): first defined here
main.o:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
main.o: In function `__data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): first defined here
main.o: In function `__data_start':
(.data+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o:(.data+0x0): first defined here
main.o: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o:(.init+0x0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o:(.dtors+0x0): multiple definition of `__DTOR_END__'
main.o:(.dtors+0x8): first defined here
/usr/bin/ld: error in main.o(.eh_frame); no .eh_frame_hdr table will be created.
collect2: ld returned 1 exit status
How am I supposed to get it to run?

Change:
g++ -g main.cpp -o main.o
g++ -g -c print.cpp -o print.o
g++ -o main main.o print.o
to:
g++ -g -c main.cpp -o main.o
g++ -g -c print.cpp -o print.o
g++ -o main main.o print.o
Or alternatively you can just combine all 3 operations into one (and enable warnings while you're at it):
g++ -g -Wall -o main main.cpp print.cpp

Related

Symbol not loaded into templated function

I created a shared library "A" that use an other shared library "B".
I have a problem when I link my program with the shared library "A".
When I use some function from the other shared library ("B") inside cpp file of the shared library "A", all is fine.
But when I use these functions inside .h file (inside a templated method or an inlined method) of the shared library "A", the symbol is not loaded and I get an error "undefined reference to symbol".
I used g++ 7.2.
I think the option -l forget to load the symbols used in header file.
Do you have an idea to avoid this?
Update 2:
Here a full reproducible example:
A.cpp
#include "A.h"
A.h
#ifndef A_H
# define A_H
#include <type_traits>
#include "B.h"
class A
{
public:
template <typename Type>
std::enable_if_t<std::is_arithmetic<Type>::value,void> funcA(Type value);
};
template <typename Type>
std::enable_if_t<std::is_arithmetic<Type>::value,void> A::funcA(Type value)
{
B tmp;
tmp.funcB(value);
}
#endif
B.cpp
#include "B.h"
#include <iostream>
void B::example()
{
std::cout << "works" << std::endl;
}
B.h
#ifndef B_H
# define B_H
class B
{
public:
void funcB(int value);
private:
void example();
};
inline void B::funcB(int value)
{
value += 1;
example();
}
#endif
main.cpp
#include "A.h"
int main()
{
A tmp;
tmp.funcA(5);
return 1;
}
Compile
g++ -std=c++17 -m64 -O2 -DNDEBUG -Wall -Wextra -Werror -fPIC -o A.o -c A.cpp
g++ -std=c++17 -m64 -O2 -DNDEBUG -Wall -Wextra -Werror -fPIC -o B.o -c B.cpp
g++ -std=c++17 -m64 -O2 -DNDEBUG -Wall -Wextra -Werror -fPIC -o main.o -c main.cpp
g++ -o libB.so B.o -shared
g++ -o libA.so A.o -shared -L. -lB
g++ -o application main.o -L . -lA
Error
main.o: In function `main':
main.cpp:(.text.startup+0x1a): undefined reference to `B::example()'
collect2: error: ld returned 1 exit status
Thank you,
SOLVED:
Finally, I solved my problem with this thread:
GCC 4.5 vs 4.4 linking with dependencies
Thank you!

Multiple definition of function, why isn't the guard catching this?

So I wrote a small set of logging functions in the file cerus.h. The contents of that file can be seen below. It is being included in main.cpp, model.cpp, engine.cpp and camera.cpp. As can be seen, I have include guards so I'm not sure why I'm getting this error:
Output of $ make
jed#ArchPC:~/glPlayground$ make
g++ -std=c++11 -c model.cpp -o bin/model.o
g++ -std=c++11 -c tiny_obj_loader.cc -o bin/tinyobj.o
g++ -std=c++11 -c camera.cpp -o bin/camera.o
g++ -g -std=c++11 -o main bin/main.o bin/engine.o bin/tinyobj.o bin/model.o bin/camera.o -lGL -lGLU -lglut -lSOIL -lGLEW -lglfw
bin/engine.o: In function `LOG(char const*)':
engine.cpp:(.text+0x0): multiple definition of `LOG(char const*)'
bin/main.o:main.cpp:(.text+0x0): first defined here
bin/engine.o: In function `LOGERR(char const*)':
engine.cpp:(.text+0x3d): multiple definition of `LOGERR(char const*)'
bin/main.o:main.cpp:(.text+0x3d): first defined here
bin/model.o: In function `LOG(char const*)':
model.cpp:(.text+0x0): multiple definition of `LOG(char const*)'
bin/main.o:main.cpp:(.text+0x0): first defined here
bin/model.o: In function `LOGERR(char const*)':
model.cpp:(.text+0x3d): multiple definition of `LOGERR(char const*)'
bin/main.o:main.cpp:(.text+0x3d): first defined here
bin/camera.o: In function `LOG(char const*)':
camera.cpp:(.text+0x0): multiple definition of `LOG(char const*)'
bin/main.o:main.cpp:(.text+0x0): first defined here
bin/camera.o: In function `LOGERR(char const*)':
camera.cpp:(.text+0x3d): multiple definition of `LOGERR(char const*)'
bin/main.o:main.cpp:(.text+0x3d): first defined here
collect2: error: ld returned 1 exit status
Makefile:4: recipe for target 'main' failed
make: *** [main] Error 1
cerus.h
#ifndef CERUS_H
#define CERUS_H
#include <iostream>
//Need to add Windows and Mac Includes here
// Linux Include Statements
void LOG(const char* str){
std::cout << "[INFO]" << str << "\n";
}
void LOGERR(const char* str){
std::cout << "[ERROR]" << str << "\n";
}
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GLFW/glfw3.h>
#endif
Makefile
all: main
main: bin/main.o bin/engine.o bin/model.o bin/tinyobj.o bin/camera.o cerus.h
g++ -g -std=c++11 -o main bin/main.o bin/engine.o bin/tinyobj.o bin/model.o bin/camera.o -lGL -lGLU -lglut -lSOIL -lGLEW -lglfw
bin/main.o: main.cpp cerus.h
g++ -std=c++11 -c main.cpp -o bin/main.o
bin/engine.o: engine.cpp engine.h cerus.h
g++ -std=c++11 -c engine.cpp -o bin/engine.o
bin/tinyobj.o: tiny_obj_loader.cc tiny_obj_loader.h cerus.h
g++ -std=c++11 -c tiny_obj_loader.cc -o bin/tinyobj.o
bin/model.o: model.cpp model.h cerus.h
g++ -std=c++11 -c model.cpp -o bin/model.o
bin/camera.o: camera.cpp camera.h cerus.h
g++ -std=c++11 -c camera.cpp -o bin/camera.o
clean:
rm -f bin/*.o main
If someone could explain to me why my guard isn't catching this, I would greatly appreciate the help.
EDIT: Fixed this issue by adding a file called cerus.cpp and defining my logging functions there instead of in cerus.h
This type of guard is to avoid things from being declared or defined in same translation unit.
It won't have any effect for multiple definition in different translation units (i.e. multiple source files).
In this case, you should move the definitions of functions LOG and LOGERR to another .cpp file, and put declarations of the functions in the header file.
Guards did nothing wrong, they just protect your declarations/inlines/templates.
It's the definitions that are real issue. If you have inline functions in your cpp, put them in header, same for templates. Do not include cpp files. Can't see much of your code but that is most of the cases.

g++ undefined reference to constructor , really simple code

I made a program to test my knowledge on class but I had some troubles.
foo.h:
#include <iostream>
using namespace std;
class foo
{
private:
int a;
public:
foo();
};
foo.cc:
#include <iostream>
#include "foo.h"
using namespace std;
foo::foo()
{
a = 0;
}
And main.cc:
#include<iostream>
#include "foo.h"
int main()
{
foo a;
return 0;
}
I compiled this with g++ main.cc -o main. Then I got
-bash-4.1$ g++ main.cc -o main
/tmp/cc5Hnes8.o: In function `main':
main.cc:(.text+0x10): undefined reference to `foo::foo()'
collect2: ld returned 1 exit status
I think there should be a really stupid mistake here but I really cannot find it. I've been struggling on this whole night...
Appreciate any help!
You are asking the compiler to not only translate main.cc but also perform the final link to produce the executable main. This second step cannot be done because main.cc references the function foo::foo whose definition is in foo.cc and therefore not available to the compiler. You can do this:
g++ main.cc -c -o main.o
g++ foo.cc -c -o foo.o
g++ main.o foo.o -o main
The -c flag makes the compiler perform translation only, so this separately compiles main.cc and foo.cc and then links the objects together to obtain the executable. In this way, the definition of foo::foo will end up inside foo.o and will be available at link time.
Or, you can just provide both .cc files. This basically does the same thing as the three commands above:
g++ main.cc foo.cc -o main
You should compile all source (.cc in your case) files:
g++ main.cc foo.cc -o main
When you realize the constructor of foo in foo.cc, you should compile it.
use g++ main.cc foo.cc -o main.

What is a fix for a constructor definition error?

So I have a class:
#include "Cool.h"
#include <iostream>
Cool::Cool()
{
//ctor
}
int getVar()
{
int pop = 22;
return pop;
}
and a header file:
#ifndef COOL_H
#define COOL_H
class Cool
{
public:
Cool();
int getVar();
};
#endif
But when I compile, I get an error that says
error: definition of implicitly-declared 'Cool::Cool()'
EDIT:
Don't know if it will help, but I also have a makefile:
program: main.o cool.o
g++ -o program main.o cool.o
cool.o: Cool.cpp Cool.h
g++ -c -o cool.o Cool.cpp
main.o: main.cpp cool.o
g++ main.cpp
EDIT 2: Full Error Message:
Cool.cpp:4:12: error: definition of implicitly-declared ‘Cool::Cool()’
Cool::Cool()
^
This:
cool.o: Cool.cpp Cool.h
g++ Cool.cpp
should be:
cool.o: Cool.cpp Cool.h
g++ -c -o cool.o Cool.cpp
For main.o::
main.o: main.cpp Cool.h
g++ -c -o main.o main.cpp
It is very confusing that you have the same file as both uppercase and lowercase. Does the problem persist after you rename everything to lowercase?
Solved it! I added this to the makefile:
Under main.o:
g++ -c -o main.o main.cpp

scorep qt error undefined reference to `POMP2_Assign_handle'

Trying to connect simplest OpenMP QT project with score-P:
#include <QTextStream>
#include <QDateTime>
#include <QProcess>
#include <QFile>
#include <omp.h>
int main()
{
omp_set_num_threads(200);
#pragma omp parallel for
for(int i = 0; i < 200; i ++)
{
QFile file(QString("test_file_%1").arg(i));
if(file.open(QIODevice::Append))
{
QTextStream stream(&file);
stream << QDateTime::currentDateTime().toString(Qt::ISODate) + "\n";
file.close();
}
}
}
Make some changes in *.pro:
QMAKE_CXXFLAGS += -g -fopenmp
QMAKE_LIBS += -lgomp -lpthread
QMAKE_CXX = /home/monika/scorep/bin/scorep g++
QMAKE_LINK = /home/monika/scorep/bin/scorep g++
And cathing LINK error:
/home/monika/scorep/bin/scorep g++ -c -m64 -pipe -g -fopenmp -O2 -g -pipe -Wall -Wp,- D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_CORE_LIB -I/usr/lib64/qt4/mkspecs/linux-g++-64 -I../test-scorep -I/usr/include/QtCore -I/usr/include -I../../scorep/include/opari2 -I. -I../test-scorep -I. -o main.o ../test-scorep/main.cpp
/home/monika/scorep/bin/scorep g++ -m64 -Wl,-O1 -o test-scorep main.o -lgomp -lQtCore -lpthread
main.o: In function `POMP2_Init_reg_bl9o0ezmjm8_1':
/home/monika/test/build-test-scorep-Desktop-Release/main.prep.cpp.opari.inc:15: undefined reference to `POMP2_Assign_handle'
main.o: In function `main.omp_fn.0':
/home/monika/test/test-scorep/main.cpp:10: undefined reference to `pomp_tpd_'
/home/monika/test/test-scorep/main.cpp:11: undefined reference to `POMP2_Parallel_begin'
/home/monika/test/test-scorep/main.cpp:12: undefined reference to `POMP2_For_enter'
/home/monika/test/test-scorep/main.cpp:22: undefined reference to `POMP2_Implicit_barrier_enter'
/home/monika/test/test-scorep/main.cpp:24: undefined reference to `POMP2_Implicit_barrier_exit'
/home/monika/test/test-scorep/main.cpp:25: undefined reference to `POMP2_For_exit'
/home/monika/test/test-scorep/main.cpp:27: undefined reference to `POMP2_Parallel_end'
main.o: In function `main':
/home/monika/test/test-scorep/main.cpp:14: undefined reference to `POMP2_Parallel_fork'
/home/monika/test/test-scorep/main.cpp:10: undefined reference to `pomp_tpd_'
/home/monika/test/test-scorep/main.cpp:28: undefined reference to `POMP2_Parallel_join'
If i compile simple project (with only one file) like:
/home/monika/scorep/bin/scorep g++ main.cpp
Everything work (score-P too). If I change QMAKE_CXX or QMAKE_LINK to default (g++) bulding will be well, but score-P will not work.
I tried to include pomp2_lib.h (which contains functions from unfounded list), but still no result (nothing changed).