rpav / c2ffi

Clang-based FFI wrapper generator
GNU Lesser General Public License v2.1
229 stars 37 forks source link

Can't build (linking issues) on Intel/Ubuntu 20.04 #98

Open mustiboost opened 3 years ago

mustiboost commented 3 years ago

Hey guys, I get following errors during the linking stage:

[  7%] Linking CXX executable bin/c2ffi
/home/linuxbrew/.linuxbrew/bin/ld: /home/linuxbrew/.linuxbrew/lib/libLLVM-12.so: undefined reference to `std::__exception_ptr::exception_ptr::_M_release()@CXXABI_1.3.13'
/home/linuxbrew/.linuxbrew/bin/ld: /home/linuxbrew/.linuxbrew/lib/libclang-cpp.so.12: undefined reference to `std::__throw_bad_array_new_length()@GLIBCXX_3.4.29'
/home/linuxbrew/.linuxbrew/bin/ld: /home/linuxbrew/.linuxbrew/lib/libLLVM-12.so: undefined reference to `std::__exception_ptr::exception_ptr::_M_addref()@CXXABI_1.3.13'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/c2ffi.dir/build.make:275: bin/c2ffi] Error 1
make[1]: *** [CMakeFiles/Makefile2:87: CMakeFiles/c2ffi.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

I installed llvm/clang 12 via linuxbrew. Any idea what's going on?

rpav commented 3 years ago

Possibly different gcc used to build clang vs c2ffi, or trying to build c2ffi with libc++ when clang was built with libstdc++, etc.

mustiboost commented 3 years ago

I tried linking libc++ and libstdc++. Still the same problem. Then I removed llvm-12 and installed llvm/clang-10 from apt on Ubuntu to see if it makes a difference. Got the llvm-10 branch of c2ffi and now I get a different link error:

/home/linuxbrew/.linuxbrew/bin/ld: cannot find -lclang-cpp

libclang-cpp-dev is installed on my system, so I have no idea what's going on. Are you saying that I need to build llvm/clang from source to build c2ffi?

mustiboost commented 3 years ago

Ok, I solved the issue, which was really pretty basic. First, I was compiling with the gnu compiler all along instead of clang. So I made clang++ the default c++ compiler:

sudo update-alternatives --config c++

For good measure I made clang the default c compiler too (probably not needed):

sudo update-alternatives --config cc

That still did not work, so I had to install the libclang-cpp-10-dev package to compile (I had already installed all other dev packages). See error message in my previous post. That did the trick. I did the same for clang-12 (this time installed via apt instead of homebrew for linux), and that worked too. Again, libclang-cpp-12-dev needs to be installed. This is not an obvious dev package by the way. I don't think sudo apt install llvm-12 or sudo apt install clang-12 installs this package.

I know this is pretty basic, but there are lots of lisp people using this tool and not all of them may be intimately familiar with C++/C tooling, so maybe we should add this information to the section describing the build process. I think lot of people quietly give up on using this tool (and cl-autowrap) due to these issues. So, for me at least, building with gcc did not work at all. There are references to "build with gcc if clang is built with gcc" in the build description here, but I don't think people even know how to go about it with all the error messages being produced. Any thoughts?

ellisvelo commented 3 years ago

@mustiboost , I agree with you about the difficulty with llvm. I was able to build c2ffi by using the command below:

cd build && cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -G "Unix Makefiles" ..

I could only get c2ffi to link if I used clang/clang++ and the libraries provided by Ubuntu. I had tried to build LLVM 11.1.0 with gcc and with clang, but I would hit the same type of linking error.

Debian 10 with gcc/g++ (8.3.0-6) and LLVM 11.1.0: /usr/bin/ld: CMakeFiles/c2ffi.dir/src/AST.cpp.o:(.data.rel.ro._ZTIN5c2ffi16C2FFIASTConsumerE[_ZTIN5c2ffi16C2FFIASTConsumerE]+0x10): undefined reference to typeinfo for clang::ASTConsumer collect2: error: ld returned 1 exit status

@rpav , have you been able to link c2ffi with a llvm built from source or are you using the libraries provided by Ubuntu? If you are building it, can you provide how you are building it. Thanks.

rpav commented 3 years ago

I've rarely had luck with Ubuntu-provided llvm.

The real key seems to be using whatever you built llvm/clang with, because you're linking to it and it's expecting the same C++ version/ABI. E.g., if you built with g++ and libstdc++, use that.

I will often build clang with g++, then rebuild with itself and libc++ .. in that case building c2ffi with clang/libc++ is necessary.

ellisvelo commented 3 years ago

I didn't have any luck with building on Debian 10. I had built llvm with g++ and then rebuilt with clang, but that didn't work. The only thing that I didn't try was rebuilding libc++.

I ended up installing the packages from https://apt.llvm.org/ and that did work with clang++.