Codeblocks succeeded in compiling, but gcc failes, Why? - c++

I'm using ubuntu 18.
I'v installed codeblocks ide and bare gnu gcc compiler (command line) both
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
code blocks 16.01
I wrote a very simple code to create and print a string variable
Code blocks(with inbuilt gnu gcc compiler) succeeded in compiling. But bare gcc compiler failes
I've tried by including iostream and stdio also
#include <string>
using namespace std;
int main() {
string a = "I am learning C++";
printf("%s",a.c_str());
return 0;
}
codeblocks compiles it successfully and gives the output without raising an error. As well as sololearn online compiler also
I am learning C++
I got into the folder where the cpp file is and gave following command
gcc string_var.cpp -o string_var.out
Bt the bare gcc compiler gives some long stuff of compiler errors which i can't understand
/tmp/ccen8bfp.o: In function `main':
string_var.cpp:(.text+0x20): undefined reference to `std::allocator<char>::allocator()'
string_var.cpp:(.text+0x37): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
string_var.cpp:(.text+0x43): undefined reference to `std::allocator<char>::~allocator()'
string_var.cpp:(.text+0x4f): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const'
string_var.cpp:(.text+0x74): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
string_var.cpp:(.text+0x96): undefined reference to `std::allocator<char>::~allocator()'
string_var.cpp:(.text+0xb0): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/tmp/ccen8bfp.o:(.data.rel.local.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status

The GNU Compiler Collection (GCC) can be used to compile many different languages. Some of those languages are common enough that they can use the same front-end program.
C and C++ are two such languages, and both can be compiled with the gcc front-end program. However, the gcc program by default is for C code, and because of that don't use some flags needed to build C++ programs. One such missing thing is that gcc doesn't link with the C++ standard library.
You can solve this by explicitly linking with the library:
gcc string_var.cpp -o string_var.out -lstdc++
Or, even simpler, use the front-end program for C++, g++:
g++ string_var.cpp -o string_var.out

gcc string_var.cpp -o string_var.out
gcc is a C compiler. You want to compile C++ code:
g++ string_var.cpp -o string_var.out
It just so happens that either gcc or g++ works insofar as compiling the actual code, the compiler understand that .cpp files contain C++ code, and proceeds accordingly.
However, when it times to linking the resulting object module, gcc does not provide the runtime C++ library to the linker (it still thinks it's just a C compiler, and has never heard of C++), resulting in your link failure.

Related

How to maintain compatibility between gcc 7 and gcc 9 with -Ofast

I have library which I have compiled on Ubuntu 18.04 using the version of gcc which comes bundled in the build-essential package, gcc 7.5.0.
If I then try to compile an application on Ubuntu 20.04 and link against the that library I previous built using the default gcc version, gcc 9.3.0, then I get a bunch of errors such as undefined reference to __expf_finite. Note, I do compile my original library with -Ofast as I need to take advantage of all optimizations. According to this SO question, it suggests that math-finite.h is no longer supported by the libc update.
So as a possible solution, I tried compiling my library on Ubuntu 20.04 using gcc 9.3.0 to then see if I can link against that library using an application compiled with gcc 7.5.0 on Ubuntu 18.04 (basically the reverse of the first scenario).
However, when I do this, I get ABI compat errors with std::string:
./trueface_sdk/libtf.a(ocl.cpp.o): In function `cv::ocl::Kernel::set(int, cv::ocl::KernelArg const&)':
ocl.cpp:(.text._ZN2cv3ocl6Kernel3setEiRKNS0_9KernelArgE+0x375): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
ocl.cpp:(.text._ZN2cv3ocl6Kernel3setEiRKNS0_9KernelArgE+0x49d): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../trueface_sdk/libtf.a(ocl.cpp.o): In function `oclCleanupCallback.cold':
ocl.cpp:(.text.unlikely.oclCleanupCallback+0x36): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
ocl.cpp:(.text.unlikely.oclCleanupCallback+0xcf): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
ocl.cpp:(.text.unlikely.oclCleanupCallback+0x184): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../trueface_sdk/libtf.a(ocl.cpp.o):ocl.cpp:(.text._ZN2cv3ocl6Device4ImplC2EPv[_ZN2cv3ocl6Device4ImplC5EPv]+0xb7b): more undefined references to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()' follow
../trueface_sdk/libtf.a(sqlite3.c.o):(.data.rel+0xb0): undefined reference to `fcntl64'
I also get undefined reference to fcntl64.
So what is the solution? How can I compile a library that will be compatible with multiple version of gcc?
Based on the comments, it looks like it is not compatible because of the use of the -Ofast compiler optimization flag.

undefined reference to boost::filesystem::path_traits::convert

I am trying to compile a program using cmake, and am seeing the following linker error:
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so:
undefined reference to
boost::filesystem::path_traits::convert(wchar_t const*, wchar_t
const*, std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >&, std::codecvt<wchar_t, char, __mbstate_t>
const&)' /home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so:
undefined reference to
boost::filesystem::path_traits::dispatch(boost::filesystem::directory_entry
const&, std::__cxx11::basic_string,
std::allocator >&)'
The linker command that ninja generated looks like this:
g++ -pthread -DBOOST_ALL_DYN_LINK
utility/test/CMakeFiles/utilityTest.dir/loadCSVTests.cpp.o
utility/test/CMakeFiles/utilityTest.dir/main.cpp.o
utility/test/CMakeFiles/utilityTest.dir/randomDeviceTests.cpp.o -o
utility/test/utilityTest -rdynamic
/home/quant/bin/boost_1_61_0/stage/lib/libboost_thread.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_program_options.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_serialization.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_unit_test_framework.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_system.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_filesystem.so
utility/lib/libutilityLib.a utility/testLib/libutilityTestLib.a
utility/lib/libutilityLib.a
/home/quant/bin/boost_1_61_0/stage/lib/libboost_thread.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_program_options.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_serialization.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_unit_test_framework.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_system.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_filesystem.so
-Wl,-rpath,/home/quant/bin/boost_1_61_0/stage/lib
As you can see, I am linking against boost_filesystem and boost_system, so it's not the same problem as referenced on this SO post (and the many others like it).
I am using boost 1.61, which I compiled with gcc 5.3 (the same compiler as the one I'm compiling my program with).
What am I doing wrong?
I had a similar issue, this could be because of a new ABI which is introduced from gcc 5.1.
https://github.com/openframeworks/openFrameworks/issues/4203
I fixed mine by adding "add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)" to CMakeLists.txt

To Create a DLL for C++ program in CYGWIN

I am trying to convert an Math.cpp into a dll in Cygwin.
I am trying this code in Cygwin to compile.
gcc -c Math.cpp
Now am trying to convert the .o in into .dll. For this I used the below code
gcc -shared -o Math.dll Math.o
where am getting a huge error message in cygwin which says "Math.o:Math.cpp:(.text+0x55): undefined reference to std::ios_base::Init::Init()'
Math.o:Math.cpp:(.text+0x55): relocation truncated to fit: R_X86_64_PC32 against undefined symbolstd::ios_base::Init::Init()Math.o:Math.cpp:(.text$_ZN11Mathematics5inputEv[_ZN11Mathematics5inputEv]+0x21): undefined reference to `std::basic_ostream >& std::operator<< >(std::basic_ostream >&, char const*)''",etc.
In my C++ program namespace is std;
class name is Mathematics, there are two methods input() and add() and there is a main method which calls these methods.
Use g++ rather than gcc
This will cause gcc to link with the standard C++ libary, which should resolve those symbols.

Compiling and linking C code invoking C++ function

I have a problem when invoking a C++ method from my C code. The method I need to invoke in the C++ code is not within a class. I am trying to setup a simple example and I have the following files:
//header.h
#ifdef __cplusplus
#include <iostream>
extern "C" {
#endif
int print(int i, double d);
#ifdef __cplusplus
}
#endif
//ccode.c
#include "header.h"
main() {
printf("hello");
print(2,2.3);
}
//cppcode.cc
#include "header.h"
using namespace std;
int print(int i, double d)
{
cout << "i = " << i << ", d = " << d;
}
Probably my error is in the way I am trying to compile and link this. I am doing the following:
g++ -c cppcode.cc -o cppcode.o
That goes fine.
gcc ccode.c cppcode.o -o ccode
Here I get the following errors:
cppcode.o: In function `print':
cppcode.cc:(.text+0x16): undefined reference to `std::cout'
cppcode.cc:(.text+0x1b): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
cppcode.cc:(.text+0x28): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(int)'
cppcode.cc:(.text+0x35): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
cppcode.cc:(.text+0x42): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(double)'
cppcode.o: In function `__static_initialization_and_destruction_0(int, int)':
cppcode.cc:(.text+0x6b): undefined reference to `std::ios_base::Init::Init()'
cppcode.cc:(.text+0x70): undefined reference to `std::ios_base::Init::~Init()'
collect2: ld returned 1 exit status
I assume that this happens because I am using the C compiler. What is the correct way to compile and link this small example?
The idea is that I have the C code running and just invoke the C++ functions, without having to rewrite them in C. Thanks in advance for help!
I am using Ubuntu 12.04, gcc version 4.6.3
You need to link C++ runtime library.
gcc ccode.c cppcode.o -o ccode -lstdc++
You should compile and link separately. Use g++ to link in order to get the proper standard library.
g++ -c cppcode.cc -o cppcode.o
gcc -c ccode.c -o ccode.o
g++ ccode.o cppcode.o -o ccode
The g++ compiler automatically links your program with the standard cpp library.
When you compile with gcc, the linker can find reference to that.
You have two options.
One is to compile the c file with g++. Second is to force the linkage of the standard cpp library.
Here's whats written in gcc guide:
-static-libstdc++
When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.
Run the following command:
gcc ccode.c cppcode.o -o ccode -lstdc++

undefined reference to `__stack_chk_fail'

Getting this error while compiling C++ code:
undefined reference to `__stack_chk_fail'
Options already tried:
added -fno-stack-protector while compiling - did not work, error persists
added a dummy implementation of void __stack_chk_fail(void) in my code. Still getting the same error.
Detailed Error:
/u/ac/alanger/gurobi/gurobi400/linux64/lib/libgurobi_c++.a(Env.o)(.text+0x1034): In function `GRBEnv::getPar/u/ac/alanger/gurobi/gurobi400/linux64/lib/libgurobi_c++.a(Env.o)(.text+0x1034): In function `GRBEnv::getParamInfo(GRB_StringParam, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
: undefined reference to `__stack_chk_fail'
amInfo(GRB_StringParam, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
: **undefined reference to `__stack_chk_fail'**
Earlier, I was getting 10's of such errors. Found out that there was a version mismatch between the gcc of the pre-compiled libraries I am using and the gcc version I was using to compile the code. Updated gcc and now I am getting only 2 of these errors.
Any help, please?
libgurobi_c++.a was compiled with -fno-stack-protector (obviously).
A few things come to mind:
add -fstack-protector when linking. This will make sure that libssp gets linked.
Manually link -lssp
Make your dummy version of __stack_chk_fail(void) in it's own object file and and add this .o file to your linker command AFTER libgurobi_c++.a. GCC/G++ resolves symbols from left to right during linking so despite your code having the function defined, a copy of an object containing the __stack_chk_fail symbol needs to be on the linker line to the right of libgurobi_c++.a.
In gentoo I had the same problem and i resolved creating 2 files. The first contain the option to be parsed by emerge and passed to gcc:
/etc/portage/env/nostackprotector.conf
CFLAGS="-fno-stack-protector -O2"
And the second tells which package should use this settings:
/etc/portage/package.env/nostackprotector
x11-libs/vte nostackprotector.conf
sys-libs/glibc nostackprotector.conf
www-client/chromium nostackprotector.conf
app-admin/sudo nostackprotector.conf
Just had the same issue: c++ code with an implementation of void __stack_chk_fail(void) showing several undefined reference to __stack_chk_fail errors when compiling.
My solution was to define __stack_chk_fail(void) as extern "C":
extern "C" {
__stack_chk_fail(void)
{
...
}
}
This suppressed the compilation error :)
Hope it helps!
https://wiki.ubuntu.com/ToolChain/CompilerFlags
says:
"Usually this is a result of calling ld instead of gcc during a build to perform linking"
This is what I encountered when modified the Makefile of libjpeg manually. Use gcc instead of ld solved the problem.