Libc++ issue on Linux

Hi folks,

I’m experiencing the same problem as described here, which was never resolved: Building ROOT with clang+libc++ on Ubuntu - #3 by pagessin

I’m using Cling master (build script included below), on Arch Linux, and I’m building my project with the clang 9 included in the Cling build.

The error I’m getting is:

Warning in cling::IncrementalParser::CheckABICompatibility():
  Failed to extract C++ standard library version.
Warning in cling::IncrementalParser::CheckABICompatibility():
  Possible C++ standard library mismatch, compiled with _LIBCPP_ABI_VERSION '1'
  Extraction of runtime standard library version was: ''
In file included from input_line_3:1:
In file included from /home/jeaye/projects/jank/build/../include/cpp/jank/prelude.hpp:12:
In file included from /home/jeaye/projects/jank/build/../include/cpp/jank/runtime/context.hpp:8:
In file included from /home/jeaye/projects/jank/build/../include/cpp/jank/result.hpp:6:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/variant.hpp:17:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/variant/variant.hpp:21:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/type_index.hpp:29:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/type_index/stl_type_index.hpp:34:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/core/demangle.hpp:32:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/cxxabi.h:129:3: error: exception specification in declaration does not match previous declaration
  __cxa_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void*) _GLIBCXX_NOTHROW;
  ^
input_line_2:4:16: note: previous declaration is here
extern "C" int __cxa_atexit(void (*f)(void*), void*, void*) ;
               ^
Segmentation fault (core dumped)

So there are a couple things to note here:

  1. Cling sees it’s built with libc++, which is good
  2. Cling fails to extract the stdlib version, which is bad
  3. There is an exception spec disconnect for __cxa_atexit, which is bad

Curiously, when I add -v to my Cling interpreter flags, I see the following:

cling version 1.0~dev
Looking for C++ headers with:
  LC_ALL=C clang-14  -O3 -DNDEBUG -xc++ -E -v /dev/null 2>&1 | sed -n -e '/^.include/,${' -e '/^ \/.*++/p' -e '}'
Found:
  /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0
  /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/x86_64-pc-linux-gnu
  /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/backward
clang version 9.0.1 (http://root.cern.ch/git/clang.git 535acc218f73a05f5602c950898dafda8a45feb7) (http://root.cern.ch/git/llvm.git c41338c59334340ee4d85a7c9bbdf49a4f59f76b)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: 
Found candidate GCC installation: /../lib/gcc/x86_64-pc-linux-gnu/10.3.0
Found candidate GCC installation: /../lib/gcc/x86_64-pc-linux-gnu/11.3.0
Found candidate GCC installation: /../lib/gcc/x86_64-pc-linux-gnu/12.2.0
Found candidate GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/10.3.0
Found candidate GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/11.3.0
Found candidate GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/12.2.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/10.3.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/10.3.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/11.3.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/12.2.0
Selected GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/12.2.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
Found CUDA installation: /opt/cuda, version 7.0
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0
 /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/x86_64-pc-linux-gnu
 /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/backward
 /usr/local/include
 /home/jeaye/projects/jank/build/cling-build/lib/clang/9.0.1/include
 /usr/include
End of search list.
Adding runtime include paths:
  "/usr/local/include:/home/jeaye/projects/jank/build/llvm/tools/cling/include:/home/jeaye/projects/jank/build/llvm/tools/clang/include:/home/jeaye/projects/jank/build/cling-build/tools/clang/include:/home/jeaye/projects/jank/build/llvm/include:/home/jeaye/projects/jank/build/cling-build/include"
Added include paths:
  /home/jeaye/projects/jank/build/llvm/tools/cling/include
  /home/jeaye/projects/jank/build/llvm/tools/clang/include
  /home/jeaye/projects/jank/build/cling-build/tools/clang/include
  /home/jeaye/projects/jank/build/llvm/include
  /home/jeaye/projects/jank/build/cling-build/include
Added include paths:
  /home/jeaye/projects/jank/include
Setting up system headers with clang:
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/jeaye/projects/jank/build/llvm/tools/cling/include
 /home/jeaye/projects/jank/build/llvm/tools/clang/include
 /home/jeaye/projects/jank/build/cling-build/tools/clang/include
 /home/jeaye/projects/jank/build/llvm/include
 /home/jeaye/projects/jank/build/cling-build/include
 /home/jeaye/projects/jank/include
 /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0
 /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/x86_64-pc-linux-gnu
 /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/backward
 /usr/local/include
 /home/jeaye/projects/jank/build/cling-build/lib/clang/9.0.1/include
 /usr/include
End of search list.
Warning in cling::IncrementalParser::CheckABICompatibility():
  Failed to extract C++ standard library version.
Warning in cling::IncrementalParser::CheckABICompatibility():
  Possible C++ standard library mismatch, compiled with _LIBCPP_ABI_VERSION '1'
  Extraction of runtime standard library version was: ''
#include "cling/Interpreter/RuntimeUniverse.h"
namespace cling { class Interpreter; namespace runtime { Interpreter* gCling=(Interpreter*)0x23f3ed0;
RuntimeOptions* gClingOpts=(RuntimeOptions*)0x23f4018;}}
extern "C" int __cxa_atexit(void (*f)(void*), void*, void*) ;
#define __dso_handle ((void*)0x23f3ed0)
extern "C" int atexit(void(*f)())  throw ()  { return __cxa_atexit((void(*)(void*))f, 0, __dso_handle); }
extern "C++" int at_quick_exit(void(*f)())  throw ()  { return __cxa_atexit((void(*)(void*))f, 0, __dso_handle); }
Added include paths:
  /home/jeaye/projects/jank/build/../include
Added include paths:
  /home/jeaye/projects/jank/build/../include/cpp
Added include paths:
  /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include
In file included from input_line_3:1:
In file included from /home/jeaye/projects/jank/build/../include/cpp/jank/prelude.hpp:12:
In file included from /home/jeaye/projects/jank/build/../include/cpp/jank/runtime/context.hpp:8:
In file included from /home/jeaye/projects/jank/build/../include/cpp/jank/result.hpp:6:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/variant.hpp:17:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/variant/variant.hpp:21:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/type_index.hpp:29:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/type_index/stl_type_index.hpp:34:
In file included from /home/jeaye/projects/jank/build/vcpkg_installed/x64-clang-static/include/boost/core/demangle.hpp:32:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/cxxabi.h:129:3: error: exception specification in declaration does not match previous declaration
  __cxa_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void*) _GLIBCXX_NOTHROW;
  ^
input_line_2:4:16: note: previous declaration is here
extern "C" int __cxa_atexit(void (*f)(void*), void*, void*) ;
               ^
Segmentation fault (core dumped)

For completeness, here’s the ldd for my binary:

	linux-vdso.so.1 (0x00007ffe23f80000)
	libc++abi.so.1 => /usr/lib/libc++abi.so.1 (0x00007fb36c615000)
	libjankcling.so => /home/jeaye/projects/jank/build/libjankcling.so (0x00007fb368800000)
	libc++.so.1 => /usr/lib/libc++.so.1 (0x00007fb3686fd000)
	libm.so.6 => /usr/lib/libm.so.6 (0x00007fb368615000)
	libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fb36c5f5000)
	libc.so.6 => /usr/lib/libc.so.6 (0x00007fb36842e000)
	libz.so.1 => /usr/lib/libz.so.1 (0x00007fb36c5d9000)
	libncursesw.so.6 => /usr/lib/libncursesw.so.6 (0x00007fb36c565000)
	libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fb368000000)
	/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fb36c68b000)

I’m using a vcpkg cmake triplet to compile for x64-clang-static:

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_BUILD_TYPE release)

set(VCPKG_CMAKE_SYSTEM_NAME Linux)
set(VCPKG_CXX_FLAGS "${VCPKG_CXX_FLAGS} -stdlib=libc++")
set(VCPKG_C_FLAGS "${VCPKG_C_FLAGS}")

Finally, the Cling build script:

#!/usr/bin/env bash

set -xeuo pipefail

export CC=clang
export CXX=clang++

srcdir="${1:-$PWD}"

# Cling latest
llvm_url="http://root.cern.ch/git/llvm.git"
llvm_branch="cling-patches"
clang_url="http://root.cern.ch/git/clang.git"
clang_branch="cling-patches"
cling_url="http://root.cern.ch/git/cling.git"
cling_branch="master"

function prepare()
{
  if [ ! -d "$srcdir/llvm" ];
  then
    git clone -b "${llvm_branch}" --single-branch "${llvm_url}" "${srcdir}"/llvm
  fi

  if [ ! -d "$srcdir/clang" ];
  then
    git clone -b "${clang_branch}" --single-branch "${clang_url}" "${srcdir}"/clang
  fi

  if [ ! -d "$srcdir/cling" ];
  then
    git clone -b "${cling_branch}" --single-branch "${cling_url}" "${srcdir}"/cling
  fi

  if [ ! -h "$srcdir/llvm/tools/clang" ];
  then
    ln -sf "$srcdir/clang" "$srcdir/llvm/tools/clang"
  fi

  if [ ! -h "$srcdir/llvm/tools/cling" ];
  then
    ln -sf "$srcdir/cling" "$srcdir/llvm/tools/cling"
  fi
}

function build()
{
  mkdir -p "$srcdir/cling-build"
  cd "$srcdir/cling-build"

  cmake -DCMAKE_BUILD_TYPE=Release \
        -DLLVM_TARGETS_TO_BUILD="host;NVPTX" \
        -DLLVM_BUILD_LLVM_DYLIB=OFF \
        -DLLVM_ENABLE_RTTI=ON \
        -DLLVM_ENABLE_FFI=ON \
        -DLLVM_BUILD_DOCS=OFF \
        -DLLVM_ENABLE_SPHINX=OFF \
        -DLLVM_ENABLE_DOXYGEN=OFF \
        -DLLVM_ENABLE_LIBCXX=ON \
        -DFFI_INCLUDE_DIR=$(pkg-config --cflags-only-I libffi | cut -c3-) \
        -DCLING_CXX_HEADERS=ON \
        "$srcdir/llvm"

  make -j32 -C tools/clang
  make -j32 -C tools/cling
}

prepare
build

I’m sure @Axel and/or @vvassilev will help

Yeah I think I know what it is, but apart from a temporary hack (adding noexcept to the declaration in lib/Interpreter/Interpreter.cpp - or was it CIFactory.cpp?) I cannot offer anything yet. We will need to check in code whether the function is noexcept and then add that string. I will try that next week, but you’re very welcome to suggest a PR along these lines yourself!

Cheers, Axel