Using -std=c++0x with gfortran - c++

I have large program which uses C, C++, and Fortran. I've always found it easiest to get this to link properly using the "gfortran" front end, even though my main is C. gfortran knows about a lot of Fortran special stuff that needs to be linked in.
Now, however, I need to include unordered_map, which with my compiler (gcc 4.4.1 on Mac OS X 10.7.5) seems to require the -std=c++0x option. I discovered and verified that by compiling a small test program with C++ only.
But if I use the -std=c++0x option with gfortran, that produces a huge number of link errors starting with:
Undefined symbols for architecture i386:
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::data() const", referenced from:
Meanwhile, if I go back to my large program, and replace the gfortran with g++ or gcc, I also get a huge number of link errors, starting with:
Undefined symbols for architecture i386:
"__gfortran_compare_string", referenced from:

I now link using g++ with the -lgfortran switch, and that lets me use -std=c++0x and doesn't leave me with undefined c++ or fortran symbols.

Related

Undefined symbols when using user operator in tensorflow-gpu>=1.15

everybody. I wrote some user operators to extend tensorflow and tried to use CMake to compile the code to different shared libraries to fit different versions of tensorflow.
It works fine with tensorflow-gpu<=1.14 but not with 1.15 and 2.0. I got the following error when loading the library.
tensorflow.python.framework.errors_impl.NotFoundError: build/lib/libtensorflow_ctext.so: undefined symbol: _ZN10tensorflow12OpDefBuilder4AttrENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
I tried nm build/lib/libtensorflow_ctext.so on 1.14 version and 2.0 version, both shared libraries have this undefined symbol in the middle.
U _ZN10tensorflow12OpDefBuilder4AttrENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
It seems that the program is going to find this symbol in the linked Tensorflow framework library libtensorflow_framework.so. I searched libtensorflow_framework.so.2 for similar symbols and found several of them.
0000000000cacc50 T _ZN10tensorflow12OpDefBuilder10DeprecatedEiSs
0000000000cace00 T _ZN10tensorflow12OpDefBuilder10SetShapeFnESt8functionIFNS_6StatusEPNS_15shape_inference16InferenceContextEEE
0000000000cacb20 T _ZN10tensorflow12OpDefBuilder13ControlOutputESs
0000000000cac980 T _ZN10tensorflow12OpDefBuilder13SetIsStatefulEv
0000000000cac970 T _ZN10tensorflow12OpDefBuilder14SetIsAggregateEv
0000000000cac960 T _ZN10tensorflow12OpDefBuilder16SetIsCommutativeEv
0000000000cac990 T _ZN10tensorflow12OpDefBuilder27SetAllowsUninitializedInputEv
0000000000cacb50 T _ZN10tensorflow12OpDefBuilder3DocESs
0000000000caca90 T _ZN10tensorflow12OpDefBuilder4AttrESs
0000000000cacac0 T _ZN10tensorflow12OpDefBuilder5InputESs
0000000000cacaf0 T _ZN10tensorflow12OpDefBuilder6OutputESs
0000000000cac830 T _ZN10tensorflow12OpDefBuilderC1ESs
0000000000cac830 T _ZN10tensorflow12OpDefBuilderC2ESs
0000000000c702d0 W _ZN10tensorflow12OpDefBuilderD1Ev
0000000000c702d0 W _ZN10tensorflow12OpDefBuilderD2Ev
The symbol _ZN10tensorflow12OpDefBuilder4AttrESs looks very similar but different in the last several letters. I don't really know what those "ESs"s and "ENSt7"s stand for.
Hints on how I could debug it are very appreciated. Here is the command to build my shared library (generated by cmake)
g++ -fPIC -shared -Wl,-soname,libtensorflow_ctext.so -o lib/libtensorflow_ctext.so src/CMakeFiles/bp_par_2d.dir/bp_par_2d.cc.o src/CMakeFiles/bp_par_2d_sv.dir/bp_par_2d_sv.cc.o src/CMakeFiles/fp_par_2d.dir/fp_par_2d.cc.o src/CMakeFiles/filter.dir/filter.cc.o cuda/CMakeFiles/bp_par_2d_cu.dir/bp_par_2d.cu.o cuda/CMakeFiles/bp_par_2d_sv_cu.dir/bp_par_2d_sv.cu.o cuda/CMakeFiles/fp_par_2d_cu.dir/fp_par_2d.cu.o cuda/CMakeFiles/filter_cu.dir/filter.cu.o tensorflow/CMakeFiles/bp_par_2d_ops.dir/bp_par_2d_ops.cu.o tensorflow/CMakeFiles/bp_par_2d_sv_ops.dir/bp_par_2d_sv_ops.cu.o tensorflow/CMakeFiles/fp_par_2d_ops.dir/fp_par_2d_ops.cu.o tensorflow/CMakeFiles/ramp_filter_ops.dir/ramp_filter_ops.cu.o CMakeFiles/tensorflow_ctext.dir/cmake_device_link.o -L/usr/lib/x86_64-linux-gnu/stubs -Wl,-rpath,/home/ltl/anaconda3/envs/tf_test/lib/python3.7/site-packages/tensorflow_core /home/ltl/anaconda3/envs/tf_test/lib/python3.7/site-packages/tensorflow_core/libtensorflow_framework.so.2 -lcudadevrt -lcudart_static -lrt -lpthread -ldl
Well, this problem is solved.
I used nm -C instruction to look inside the .so files and found that in Tensorflow>=1.15.0, the function is defined as
0000000000caca90 T tensorflow::OpDefBuilder::Attr(std::string)
while in Tensorflow<=1.14.0, the function is defined as
0000000000c96ed0 T tensorflow::OpDefBuilder::Attr(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
So, they use different settings on _GLIBCXX_USE_CXX11_ABI when compiling the shared library.
In order to be consistant and avoid those undefined symbol problems, I need to define -D_GLIBCXX_USE_CXX11_ABI=1 for early versions of Tensorflow and define -D_GLIBCXX_USE_CXX11_ABI=0 for later versions.

Why can cc compile a c++ program?

I have a makefile for macOS and Linux, which contains the following command:
cc -std=c++14 foo.cpp bar.cpp
And it compiles fine. foo.cpp and bar.cpp are, as the name suggests C++ files and it contains C++11 syntax. The compilation works fine.
Now if I include <fstream> I get hundred of linker errors. I am wondering, why that is?
Undefined symbols for architecture x86_64:
"std::__1::locale::has_facet(std::__1::locale::id&) const", referenced from:
bool std::__1::has_facet<std::__1::codecvt<char, char, __mbstate_t> >(std::__1::locale const&) in DiceInvaders-6f5dd4.o
"std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
...
Afaik, cc links to the c compiler, and I would assume due to it's auto detection it compiles it with the C++ compiler. But why does it fail with an additional C++ include?
Is there any counterpart of cc for c++ on a system? If I use g++, I would assume that command is available, and what if the user actually wanted to compile it with his compiler of preference (as in cc)?
Edit: Is $(CXX) a good replacement for cc?
Most probably cc on your system is a symlink to gcc executable. Assuming that is true:
The difference between gcc and g++, quoting the man page, is:
g++ is a program that calls GCC and automatically specifies linking against the C++ library.
So when you invoke gcc it does not link against c++ library. You can link standard c++ library manually:
gcc -lstdc++ 1.cpp
Is there any counterpart of cc for c++ on a system?
The cc command is just a convention that most system follow. It's not standardized, at least I haven't heard where, the utility c99 is standarized by posix. On my linux system with archlinux distribution with the gcc package there is also installed symlink /usr/bin/c++ to g++.

GCC not linking against libstdc++?

I'm receiving C++ build errors on Ubuntu 16.04 (g++ 5.4) that I don't understand:
The linker errors are (taken a few of them and run them through c++filt)
undefined reference to symbol 'std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const##GLIBCXX_3.4'
undefined reference to symbol 'std::condition_variable::notify_one()##GLIBCXX_3.4.11'
The command lanks I'm using are: gcc -std=c++11 -m64 -fPIC -std=c++11 ... (the ... has all the libs, etc.)
I assume I'm trying to link against /usr/lib/x86_64-linux-gnu/libstdc++.so.6. When I run strings against it, I see GLIBCXX_3.4 and GLIBCXX_3.4.11 (but I really don't know what this is indicating.)
nm shows me that the symbols (at least the condition_variable one is defined)
$ nm -DA /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | c++filt | grep condition_variable::notify_one
/usr/lib/x86_64-linux-gnu/libstdc++.so.6:00000000000b3930 T std::condition_variable::notify_one()
I've run readelf on all the libraries I'm attempting to link, and they all appear to be built for the same ABI (GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609)
Update
I noticed that the first error is resolved by explicitly linking against libstd++.so (i.e. I added stdc++ to my target_link_libraries in CMake). I was under the impression that I should never have to do this?
tl;dr: Invoke g++ rather than gcc to avoid this problem
(based on #SergeyA's comment)
GCC behaves differently depending on whether you run it as the gcc or the g++ binary. Specifically, it apparently won't automatically link against its bundled C++ standard library, libstdc++. I'm guessing it will link against its C standard library - which doesn't help you much.
So just use the appropriate binary for your language; specifying --std=c++whatever isn't enough.

Trouble compiling c++ program on Mac OSX 10.9 with opencv

I'm trying to compile a C++ program on Mac OSX 10.9 via the command line (and clang) that uses opencv (version 2.4.12) and am running into some problems.
I'm trying to compile the program by running the following in Terminal:
clang --std=c++11 -stdlib=libc++ test.cpp -L/usr/local/Cellar/opencv/2.4.12/lib -lopencv_core.2.4.12 -lopencv_ml.2.4.12 -lopencv_video.2.4.12 -lopencv_ml -lopencv_video -lc++
However I'm getting the following error:
Undefined symbols for architecture x86_64:
"cv::namedWindow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
Along with a string of other opencv functions that can't be found.
Upon doing some additional research, I found out that the problem might be associated with using libc++ instead of libstdc++ as the library. I tried switching to libstdc++ and was stuck with the following error.
fatal error: 'array' file not found
#include <array>
I researched that error and found out that for the Mac, it was because of using libstdc++ instead of libc++. Essentially, I'm kind of stuck in a loop and need some help compiling this program. Any thoughts?

C++ Compilation Issue - Undefined symbols for architecture x86_64 - Mac Os X Mountain Lion

I'm having a compilation issue which I'm unable to solve. I'm developing a cross platform C++ project coding on both Mac Os X 10.8 and Windows. The code compiles and run fine on Windows and on Mac Os X Leopard as well.
Since Apple pushes the developers to stick to the latest platform for various reasons I'm forced to develop on Mountain Lion and I'm trying to get the project to work again.
I compiled correctly all the libraries I needed (wxWidgets, etc) and I imported the project in the latest version of Eclipse. When I try to build the project it tries to compile the firts .cpp file and at the end it (why?) tries to invoke the linker resulting on a series of missing symbols for my own defined classes. None of the other .cpp files is being compiled, so it's pretty understendable why the whole process is failing.
I also tried to invoke make from CLI, with the same result. I went into the makefile and everything seems correct. It looks like a very newbie issue, I feel I'm missing something huge here.
I'm pasting below the output of the compiler, just in case some compiling guru step in. Please feel free to ask for more details.
Compiler output
Pastebin Link: Compiler output
I used PB since the output is quite large.
The relevant section are the invocation of as and collect2 soon after the compiling phase of the very first .cpp file. The missing symbols are defined in other .cpp files in the same dir.
/usr/llvm-gcc-4.2/bin/../libexec/gcc/i686-apple-darwin11/4.2.1/as -arch x86_64 -force_cpusubtype_ALL -o /var/folders/br/h6ln_j014ll56zwc8x6xjmk80000gn/T//ccSUmHal.o /var/folders/br/h6ln_j014ll56zwc8x6xjmk80000gn/T//ccn8ex81.s
/usr/llvm-gcc-4.2/bin/../libexec/gcc/i686-apple-darwin11/4.2.1/collect2 -dynamic -arch x86_64 -macosx_version_min 10.8.3 -weak_reference_mismatches non-weak -o Calcoli.o -lcrt1.10.6.o -L/usr/llvm-gcc-4.2/bin/../lib/gcc/i686-apple-darwin11/4.2.1/x86_64 -L/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/x86_64 -L/usr/llvm-gcc-4.2/bin/../lib/gcc/i686-apple-darwin11/4.2.1 -L/usr/llvm-gcc-4.2/bin/../lib/gcc -L/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1 -L/usr/llvm-gcc-4.2/bin/../lib/gcc/i686-apple-darwin11/4.2.1/../../.. -L/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/../../.. /var/folders/br/h6ln_j014ll56zwc8x6xjmk80000gn/T//ccSUmHal.o -lstdc++ -lSystem -lgcc -lSystem
The compiler output ends with the "classic" undefined symbol issue. All emphasized text*emphasized text*emphasized text
Undefined symbols for architecture x86_64:
"typeinfo for TipoPuntoCalc", referenced from:
Calcoli::setPuntoS(GTGraphicObject*) in ccSUmHal.o
"typeinfo for TipoPali", referenced from:
Calcoli::setPaloS(GTGraphicObject*) in ccSUmHal.o
"typeinfo for TipoRett", referenced from:
Calcoli::setFondazioneS(GTGraphicObject*) in ccSUmHal.o
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [Calcoli.o] Error 1
This shouldn't be an architecture related issue, since specifing i386 as target has the same result (symbol(s) not found for architecture i386).
Thank you,
Evelina
Go to your target's "Build Phases" section and verify that all the files you need to compile and link are actually included in the proper sections.
It sounds as if the compiler is not being told to include some things you need.