seanbaxter / circle

The compiler is available for download. Get it!
http://www.circle-lang.org/
2.35k stars 72 forks source link

Incompatibility with libstdc++13 std::format (and, related, unable to locate LLVM libcxx headers) #188

Open johnsonjh opened 1 year ago

johnsonjh commented 1 year ago

Hi @seanbaxter

johnsonjh commented 1 year ago

Also, the "--print-paths" option is less than helpful in diagnosing the problem:

$ circle --std=c++20 --stdlib=libstdc++ --print-paths /dev/null
stdlib version:
  13
-isystem:
  /usr/include/c++/13
  /usr/include/c++/13/backward
  /usr/lib/gcc/x86_64-redhat-linux/13
  /usr/include/c++/13/x86_64-redhat-linux
  /usr/lib/gcc/x86_64-redhat-linux/13/include
  /usr/local/include
  /usr/include
  /usr/include/linux
-iquote:
-I:
-ML:
  /usr/lib64/libc.so.6
  /usr/lib64/libm.so.6
  /usr/lib64/libutil.so.1
  /usr/lib64/libpthread.so.0
  /usr/lib64/libstdc++.so.6
  /usr/lib64/libc++.so.1
-L:
  /usr/local/lib64/
  /usr/local/lib/
  /usr/lib64/
  /usr/lib/
  /usr/lib/gcc/x86_64-redhat-linux/13
-rpath:

$ circle --std=c++20 --stdlib=libc++ --print-paths /dev/null   
error: could not find clang-headers

Even trying to look at things with strace (e.g. strace circle --std=c++20 --stdlib=libc++ --print-paths /dev/null 2>&1 hasn't unlocked the secret yet).

johnsonjh commented 1 year ago

A little more on this ...

On a Ubuntu 20.04 container with appropriate packages installed, it all almost works:

$ circle --stdlib=libc++ --print-paths /dev/null
stdlib version:
  9
-isystem:
  /usr/lib/llvm-10/lib/clang/10.0.0/include
  /usr/local/include
  /usr/include/x86_64-linux-gnu
  /usr/include
  /usr/include/linux
-iquote:
-I:
-ML:
  /usr/lib/x86_64-linux-gnu/libc.so.6
  /usr/lib/x86_64-linux-gnu/libm.so.6
  /usr/lib/x86_64-linux-gnu/libutil.so.1
  /usr/lib/x86_64-linux-gnu/libpthread.so.0
  /usr/lib/x86_64-linux-gnu/libstdc++.so.6
  /usr/lib/x86_64-linux-gnu/libc++.so.1
-L:
  /usr/local/lib/
  /usr/lib64/
  /usr/lib/
  /usr/lib/x86_64-linux-gnu
  /lib/x86_64-linux-gnu
  /usr/lib/gcc/x86_64-linux-gnu/9
-rpath:
preprocessor: include/sir.hh:33:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
cannot find header type_traits

Seems the logic for finding the correct paths is a somewhat lacking - it's missing the include path /usr/lib/llvm-10/include/c++/v1.

I confirm that specifying -I/usr/lib/llvm-10/include/c++/v1 does work. I also tested using llvm-12, and the result is the same - the v1 directory is not in the default include path.

johnsonjh commented 1 year ago

@seanbaxter

And, also, trying to use LLVM-12 with Boost format in this application gives me a bizarre error, where llvm-10 works fine:

ODR used by: bool sir::tests::boost_format()
tests/tests++.cc:198:5
    _sir_eqland(pass, log.debug_boost(bf("Testing %1% %2%")  % "boost" % "Howdy")); 
    ^

ODR used by: boost::basic_format<char, std::char_traits<char>, std::allocator<char>>::basic_format(const char*)
/usr/include/boost/format/format_class.hpp:173:32
        internal_streambuf_t   buf_; // the internal stream buffer. 
                               ^

ODR used by: boost::io::basic_altstringbuf<char, std::char_traits<char>, std::allocator<char>>::basic_altstringbuf(unsigned)
/usr/include/boost/format/alt_sstream.hpp:57:40
            explicit basic_altstringbuf(std::ios_base::openmode mode 
                                       ^

  instantiation: /usr/include/boost/format/alt_sstream_impl.hpp:227:9
  during instantiation of function int boost::io::basic_altstringbuf<char, std::char_traits<char>, std::allocator<char>>::overflow(int)
  template arguments: [
    'Ch' = char
    'Tr' = std::char_traits<char>
      class 'char_traits' declared at /usr/lib/llvm-12/include/c++/v1/__string:354:1
    'Alloc' = std::allocator<char>
      class 'allocator' declared at /usr/lib/llvm-12/include/c++/v1/iosfwd:114:25
  ]
          basic_altstringbuf<Ch, Tr, Alloc>::  
          ^
    error: /usr/include/boost/format/alt_sstream_impl.hpp:261:45
    no viable candidates in call to 'allocate'
      object is lvalue std::allocator<char>
      argument 0 is lvalue unsigned long
      argument 1 is prvalue char*
                        newptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0); 
                                                ^
      candidate: char* std::allocator<char>::allocate(unsigned long)
      /usr/lib/llvm-12/include/c++/v1/memory:833:10
          _Tp* allocate(size_t __n) { 
               ^
        error: invalid argument count
        function expects 1 argument, 1 provided