Using Clang with built libstdc++ produces undefined symbol _ZSt15__once_callable - clang

I have built libstdc++ with no modifications yet:
cd gccsrcdir/libstdc++-v3/build
../configure --prefix=$PWD/../install
make && make install
I am using Ubuntu 21.10 and I set the following environment variables:
export LIBRARY_PATH=gccsrcdir/libstdc++-v3/install/lib
export LD_LIBRARY_PATH=gccsrcdir/libstdc++-v3/install/lib
export CPLUS_INCLUDE_PATH=gccsrcdir/libstdc++-v3/install/include/c++/13.0.0
When I then use the system's GCC, I get no problems. When I use the system's Clang, it produces a symbol lookup error - even with no parameters:
clang++
clang++: symbol lookup error: /lib/x86_64-linux-gnu/libicuuc.so.67: undefined symbol: _ZSt15__once_callable, version GLIBCXX_3.4.11
In fact I only need to update LD_LIBRARY_PATH to arrive here. What am I doing wrong?

The symbol -- std::__once_callable is defined in your system libstdc++.so.6 (it has version GLIBCXX_3.4.11 in my build, which means it was added in GCC-4.4.0).
Your build of libstdc++.so.6 should define this symbol as well, but for some reason does not. That is a problem -- any binary which uses this symbol will fail at runtime when using your build of libstdc++.so.6 (which is happening because you've pointed LD_LIBRARY_PATH to it).
Note: in your case it's the clang++ binary that is failing to run -- any flags you add to it (such as -femulated-tls) are irrelevant -- they only affect the binary that would have been generated IF clang++ itself didn't fail.
I just repeated your configure && make steps, and the library built this way also doesn't define this symbol.
I then repeated the configure && make, but starting from top-level GCC directory, and libstdc++.so.6 built that way does define the symbol.
Conclusion: libstdc++ is configured differently during "normal" GCC build.
The definition comes from mutex.o, which is built from ./libstdc++-v3/src/c++11/mutex.cc, and which has this chunk of code:
#ifdef _GLIBCXX_HAS_GTHREADS
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef _GLIBCXX_HAVE_TLS
__thread void* __once_callable;
__thread void (*__once_call)();
...
So it sounds like either _GLIBCXX_HAS_GTHREADS or _GLIBCXX_HAVE_TLS is not defined when doing configure && make in the libstdc++-v3 directly.
Digging further, I see that libstdc++-v3 determines _GLIBCXX_HAS_GTHREADS by trying to compile #include "gthr.h", and that file is available in libgcc/gthr.h, but not in "standard" installed GCC.
../libstdc++-v3/configure && grep _GLIBCXX_HAS_GTHREADS config.h
/* #undef _GLIBCXX_HAS_GTHREADS */
TL;DR: correctly configuring libstdc++.so is complicated, and you will be better off building complete GCC.
Once you have a complete build, you will have a libstdc++-v3 directory properly configured, and can just rebuilt in that directory:
grep _GLIBCXX_HAS_GTHREADS ./x86_64-pc-linux-gnu/libstdc++-v3/config.h
#define _GLIBCXX_HAS_GTHREADS 1

Related

How to exclude old version library in /usr/local?

Disclamer: using -nostdcincl isn't possible because it excludes needed system libraries. Here instead the problem seems to be that tthe compiler ignores my -I directives
I have installed a library (OpenCV) in ~/local on a remote machine, since I don't have sudo access there. Notice that an older version of the same library is installed in /usr/local.
I'm trying to compile this code:
g++ -DCC_DISABLE_CUDA -I/home/spm1428/CloudCache -I/home/spm1428/local/include/opencv -I/home/spm1428/local/include/opencv2 -I/usr/include/boost -I/home/spm1428/vlfeat -O3 -g -Wall -c -fopenmp -std=c++11 -c -o Descriptor.o ../Descriptors/Descriptor.cpp
However, the returned error is:
In file included from /usr/local/include/opencv2/opencv.hpp:77:0,
from /home/spm1428/CloudCache/Utilities/Utility.hpp:11,
from ../Descriptors/Descriptor.cpp:17:
/usr/local/include/opencv2/highgui/highgui.hpp:165:25: error: redeclaration of ‘IMREAD_UNCHANGED’
IMREAD_UNCHANGED =-1,
^
In file included from ../Descriptors/Descriptor.cpp:13:0:
/home/spm1428/local/include/opencv2/imgcodecs.hpp:65:8: note: previous declaration ‘cv::ImreadModes IMREAD_UNCHANGED’
IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel,
^
In file included from /usr/local/include/opencv2/opencv.hpp:77:0,
from /home/spm1428/CloudCache/Utilities/Utility.hpp:11,
from ../Descriptors/Descriptor.cpp:17:
/usr/local/include/opencv2/highgui/highgui.hpp:167:24: error: redeclaration of ‘IMREAD_GRAYSCALE’
IMREAD_GRAYSCALE =0,
I think that this happens because there is another version installed. How can I solve this?
I think this error happens for the same reason (the old version doesn't have cv::xfeatures2d::SURF).

clang-3.8 and compiler-rt vs libgcc

I have been using clang-3.5 to happily build bitcode versions of musl libc and
use the result to produce nice stand alone executables.
Recent attempts with clang-3.8 have not been so happy. It seems that
the bitcode clang-3.8 generates uses functions defined in
compiler-rt/lib/builtins
Typical examples of functions I find polluting the bitcode are mulxc3, mulsc3, and muldc3. I can solve this by linking against libgcc, or even the llvm alternative if I had any clear idea of what that was. Though I would rather prevent the problem from happening in the first place.
I have seen mention of flags like rtlib=compiler-rt etc, but have found precious little documentation on the subject.
So here are some simple questions.
Is it possible to prevent clang from using the compiler-rt/lib/builtins
in the emitted bitcode? Or if not
Does llvm produce a version of libgcc that I could use. Actually I would
probably build a bitcode version of it, but that is besides the point.
Love to hear some guidance on this.
Added 12/8/2016: So I will illustrate my issues with a particular workflow that
people can reproduce if they wish, or, more likely, just point out where I am being stupid.
So start by checking out:
musllv
and follow the instructions in the README.to compile (here I am using clang-3.8 on ubuntu 14.04)
WLLVM_CONFIGURE_ONLY=1 CC=wllvm ./configure --target=LLVM --build=LLVM
make
cd lib
extract-bc -b libc.a
you will also need the bitcode of a simple executable. I will use nweb.c here.
wllvm nweb.c -o nweb
extract-bc nweb
Now we can do things like:
clang -static -nostdlib nweb.bc libc.a.bc crt1.o libc.a -o nweb
This workflow goes smoothly for clang-3.5 but for clang-3.8 we get:
clang -static -nostdlib nweb.bc libc.a.bc crt1.o libc.a -o nweb
/tmp/libc-f734a3.o: In function `cpowl':
libc.a.bc:(.text+0xbb9a): undefined reference to `__mulxc3'
/tmp/libc-f734a3.o: In function `cpowf':
libc.a.bc:(.text+0x38f7d): undefined reference to `__mulsc3'
/tmp/libc-f734a3.o: In function `csqrt':
libc.a.bc:(.text+0x78fc3): undefined reference to `__muldc3'
/tmp/libc-f734a3.o: In function `cpow':
libc.a.bc:(.text+0xafafc): undefined reference to `__muldc3'
clang-3.8: error: linker command failed with exit code 1 (use -v to seeinvocation)
So as #paul-brannan points out we could try
clang -static -nostdlib --rtlib=compiler-rt nweb.bc libc.a.bc crt1.o libc.a -o nweb
But this is where I am probably being stupid, because I get:
clang-3.8: warning: argument unused during compilation: '--rtlib=compiler-rt'
irregardless of whether I use it as a linking or compiling flag.
OK so I finally managed to make headway on this. I built llvm-3.8.1 together with the compiler-rt project using wllvm and wllvm++.
One of the build products was libclang_rt.builtins-x86_64.a,
and from this archive I was able to extract the bitcode module
libclang_rt.builtins-x86_64.bc
using the command:
extract-bc -b libclang_rt.builtins-x86_64.a
This bitcode module has definitions for those pesky instrinsics like
__mulxc3, __mulsc3, and __muldc3.
Hallelujah!

How do you set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER for building Assimp for iOS?

When I try to build Assimp by running build_ios.sh, it tells me:
CMake Error: your C compiler: "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc" was not found. Please set CMAKE_C_COMPILER to a valid compiler path or name.
CMake Error: your CXX compiler: "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-g++" was not found. Please set CMAKE_CXX_COMPILER to a valid compiler path or name.
What I need the path to be is:
/Applications/XCode.app/Contents/Developer/Platforms/...
I've tried changing DEVROOT in build_ios.sh and IPHONE_xxxx_TOOLCHAIN.cmake, because that's what CMAKE_C_COMPILER etc seem to get generated from, but it still gives me the same errors.
Option 1:
You can set CMake variables at command line like this:
cmake -D CMAKE_C_COMPILER="/path/to/your/c/compiler/executable" -D CMAKE_CXX_COMPILER "/path/to/your/cpp/compiler/executable" /path/to/directory/containing/CMakeLists.txt
See this to learn how to create a CMake cache entry.
Option 2:
In your shell script build_ios.sh you can set environment variables CC and CXX to point to your C and C++ compiler executable respectively, example:
export CC=/path/to/your/c/compiler/executable
export CXX=/path/to/your/cpp/compiler/executable
cmake /path/to/directory/containing/CMakeLists.txt
Option 3:
Edit the CMakeLists.txt file of "Assimp": Add these lines at the top (must be added before you use project() or enable_language() command)
set(CMAKE_C_COMPILER "/path/to/your/c/compiler/executable")
set(CMAKE_CXX_COMPILER "/path/to/your/cpp/compiler/executable")
See this to learn how to use set command in CMake. Also this is a useful resource for understanding use of some of the common CMake variables.
Here is the relevant entry from the official FAQ: https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-do-i-use-a-different-compiler
The cc and cxx is located inside /Applications/Xcode.app. This should find the right paths
export CXX=`xcrun -find c++`
export CC=`xcrun -find cc`
SOLUTIONS
Sometimes the project is created before installing g++. So install g++ first and then recreate your project. This worked for me.
Paste the following line in CMakeCache.txt:
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
Note the path to g++ depends on OS. I have used my fedora path obtained using which g++

How to add directories to ld search path for a cross-compilation to ARM?

I am trying to configure util-linux to cross compile using arm-none-linux-gnueabi from CodeSourcery. My only problem so far is that it can't find my ncurses library which I compiled.
How can I add a directory to the ld search path? I've tried adding to my LIBRARY_PATH and LD_LIBRARY_PATH variables, but neither does anything. I know that I can add the -L flag to gcc and it will add to the linker path, but is there any way to do this globally, so that I can do it once, and not have to worry about it again?
Here is the output of arm-none-linux-gnueabi-gcc -print-search-dirs | grep libraries | sed 's/:/\n/g':
libraries
=/tools/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../lib/gcc/
/tools/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.1/../../../../arm-none-linux-gnueabi/lib/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.1/../../../../arm-none-linux-gnueabi/lib/
/tools/bin/../arm-none-linux-gnueabi/libc/lib/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../arm-none-linux-gnueabi/libc/lib/
/tools/bin/../arm-none-linux-gnueabi/libc/usr/lib/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../arm-none-linux-gnueabi/libc/usr/lib/
I would like to add /arm/usr/lib and /arm/usr/local/lib to my ld search path.
If you need output from any other commands, just ask!
EDIT: I just found out about the CFLAGS environment variable--do all configure scripts/makefiles honor it?
Thank you!
If the ncurses library you compiled are going to be linked to the ARM binary you are cross-compiling you can not use LD_LIBRARY_PATH! LD_LIBRARY_PATH is only used by the current run-time and is in no way used by the compiler or linker when building your application.
The use of CFLAGS depends on creator of Makefile. CFLAGS are not automatically used even if they are defined as an environment variable. Only tools like the autoconf tools can pick them up from the environment and use them automagically. In the Makefiles find something like:
$(CC) $(CFLAGS) ....
if this fragment exists then the Makefile uses the CFLAGS variable. LDFLAGS is the more appropriate environment variable to use for link-time options.

MinGW gcc error: "undefined reference to `yylloc'"

Where can I find yylloc? I have included libfl.a (-lfl) in gcc command line, added GnuWin32/bin and GnuWin32/lib directories to system variable LIB, searched through all files in GnuWin32 - neither I nor gcc can find it.
It's Bison variable, it cannot be used without Bison-generated .c file.

Resources