I'm using YouCompleteMe Vim plugin for text completion (installed through Vundle). YouCompleteMe uses Clang for text completion for C-family languages (C, C++, Objective-C, Objective-C++). However, after YouCompleteMe update (via :VundleUpdate
in Vim) YouCompleteMe ceased to work.
In short, the question is: How can I compile Clang against a custom glibc version? Debian Wheezy ships with glibc 2.13, and it seems that newest Clang version requires at least glibc 2.15 (explanation in more detail below). Just in case, I'm using Debian Wheezy, x86-64 and a custom Linux kernel version 4.0.0-rc6.
So I downloaded LLVM from the git mirror according to the instructions on LLVM website:
$ mkdir ~/code $ cd ~/code/llvm_source_tree $ git clone http://llvm.org/git/llvm.git $ cd ~/code/llvm_source_tree/llvm/tools $ git clone http://llvm.org/git/clang.git $ cd ~/code/llvm_source_tree/llvm/projects $ git clone http://llvm.org/git/compiler-rt.git $ git clone http://llvm.org/git/test-suite.git $ cd ~/code/llvm_source_tree/llvm $ git config branch.master.rebase true
Then, I compiled LLVM following the instructions on LLVM website:
$ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make -j 5 $ su # make install
Everything fine so far, so I continued with YouCompleteMe installation by compiling the YouCompleteMe support libraries following YouCompleteMe install instructions:
$ mkdir ~/ycm_build $ cd ~/ycm_build $ cmake -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=/usr/local/lib/libclang.so . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp $ make ycm_support_libs
Then I ran Vim and I noticed that YouCompleteMe still does not seem to work. When I enter edit mode in Vim in some C++ file (for example), YouCompleteMe prints error: The ycmd server SHUT DOWN (restart with :YcmRestartServer). Stderr (last 30 lines):
, and after that :YcmRestartServer
prints Restarting ycmd server...
, then ('Connection aborted.', error(111, 'Connection refused'))
).
:YcmDebugInfo
prints the following:
Printing YouCompleteMe debug information... -- Server crashed, no debug info from server -- Server running at: http://127.0.0.1:37730 -- Server process ID: 22358 -- Server logfiles: -- /tmp/ycm_temp/server_37730_stdout.log -- /tmp/ycm_temp/server_37730_stderr.log
/tmp/ycm_temp/server_37730_stdout.log
is empty, but /tmp/ycm_temp/server_37730_stderr.log
contains the following lines:
2015-05-20 17:06:46,126 - DEBUG - No global extra conf, not calling method YcmCorePreload Traceback (most recent call last): File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main "__main__", fname, loader, pkg_name) File "/usr/lib/python2.7/runpy.py", line 72, in _run_code exec code in run_globals File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/__main__.py", line 164, in Main() File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/__main__.py", line 150, in Main from ycmd import handlers File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/../ycmd/handlers.py", line 30, in str( e ) ) ) RuntimeError: Error importing ycm_core. Are you sure you have placed a version 3.2+ libclang.[so|dll|dylib] in folder "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd"? See the Installation Guide in the docs. Full error: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/../libclang.so)
So I ran the tests of YouCompleteMe and got this error when running ./vim/bundle/YouCompleteMe/third_party/ycmd/run_tests.sh
:
[ 98%] Building CXX object ycm/tests/CMakeFiles/ycm_core_tests.dir/main.cpp.o [100%] Building CXX object ycm/tests/CMakeFiles/ycm_core_tests.dir/TestUtils.cpp.o Linking CXX executable ycm_core_tests ../../clang+llvm-3.6.0-x86_64-linux-gnu/lib/libclang.so: undefined reference to `posix_spawn@GLIBC_2.15' ../../clang+llvm-3.6.0-x86_64-linux-gnu/lib/libclang.so: undefined reference to `memcpy@GLIBC_2.14' collect2: error: ld returned 1 exit status make[3]: *** [ycm/tests/ycm_core_tests] Error 1 make[2]: *** [ycm/tests/CMakeFiles/ycm_core_tests.dir/all] Error 2 make[1]: *** [ycm/tests/CMakeFiles/ycm_core_tests.dir/rule] Error 2 make: *** [ycm_core_tests] Error 2 Traceback (most recent call last): File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/build.py", line 196, in Main() File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/build.py", line 189, in Main BuildYcmdLibs( GetCmakeArgs( args ) ) File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/build.py", line 152, in BuildYcmdLibs _err = sys.stderr ) File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 1021, in __call__ return RunningCommand(cmd, call_args, stdin, stdout, stderr) File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 486, in __init__ self.wait() File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 500, in wait self.handle_command_exit_code(exit_code) File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 516, in handle_command_exit_code raise exc(self.ran, self.process.stdout, self.process.stderr) sh.ErrorReturnCode_2: RAN: '/usr/bin/make -j 8 ycm_core_tests' STDOUT: STDERR:
So it seems that Clang 3.6.0 may require glibc 2.15 or newer. Debian Wheezy ships with glibc 2.13. So decided to install the latest stable version of glibc (currently 2.21). I had already earlier compiled binutils and installed it to /usr/local/bin/
, so I didn't need to do that now.
So I downloaded http://ftp.gnu.org/gnu/glibc/glibc-2.21.tar.bz2 and then unpacked it and compiled the source and installed it:
$ cd ~/code $ mkdir ~/code/glibc $ cd ~/code/glibc $ mv -iv ~/downloads/glibc-2.21.tar.bz2 . $ tar xjvf glibc-2.21.tar.bz2 $ cd glibc-2.21 $ mkdir build $ cd build $ ../configure --with-binutils=/usr/local/bin --prefix=/usr/local/glibc/glibc-2.21 $ make -j 5 $ su # make install
Then I recompiled LLVM. I passed in CMAKE_CXX_FLAGS
environment variable the g++ linker flags to cmake
following Employed Russian's answer to SO question Multiple glibc libraries on a single host:
$ export CMAKE_CXX_FLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/ld-linux.so.2' $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make -j 5
And then I recompiled the YouCompleteMe support libs, again passing g++ linker flags to cmake
in CMAKE_CXX_FLAGS
:
$ export CMAKE_CXX_FLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/ld-linux.so.2' $ cmake -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=/usr/local/lib/libclang.so . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
But the problem with YouCompleteMe persists and tests still fail in the same way. Maybe CMAKE_CXX_FLAGS
is not a sufficient way to pass g++ linker flags to cmake
? I also tried using LD_LIBRARY_PATH
when compiling LLVM against glibc 2.21:
$ cd ~/code/llvm_source_tree $ mkdir build2 $ cd build2 $ export LD_LIBRARY_PATH="/usr/local/glibc/glibc-2.21/lib:$LD_LIBRARY_PATH" $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/
And got this error:
cmake: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
Then I also tried LD_PRELOAD
:
$ export LD_PRELOAD='/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2 /usr/local/glibc/glibc-2.21/lib/libc.so.6' $ export LD_LIBRARY_PATH="/usr/local/glibc/glibc-2.21/lib:$LD_LIBRARY_PATH" $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/
And got these errors:
-- The C compiler identification is unknown -- The CXX compiler identification is unknown Inconsistency detected by ld.so: dl-minimal.c: 136: realloc: Assertion `ptr == alloc_last_block' failed!
Then I also tried adding /usr/local/glibc/glibc-2.21/lib/ld-2.21.so
to export LD_PRELOAD
, but it didn't change the error message in any way.
I'm quite sure that Clang does not require glibc 2.15 (exact) even if the other missing symbol (posix_spawn@GLIBC_2.15
) is originally from glibc 2.15, as glibc according to its documentation attempts to maintain backward compatibility and anyway the other missing symbol (memcpy@GLIBC_2.14
) is from glibc 2.14. So I didn't try this all with glibc 2.15. But now I'm out of ideas and any advice would be appreciated.
I followed Employed Russian's answer (below), but my problem did not change in any way. So I concluded that export CMAKE_CXX_FLAGS
is not the right way to pass g++ linker flags to cmake
. CMAKE_CXX_FLAGS
is the name of an variable internal to cmake
, but cmake
does not care at all about an environment variable with the same name (CMAKE_CXX_FLAGS
). CMAKE_CXX_FLAGS
can be defined directly in CMakeLists.txt
, but in LLVM compiling instructions no master CMakeLists.txt
is used and I don't want to recreate LLVM compiling script from scratch if there's some more practical option. But there are still 3 other options available which I could find:
cmake
initializes CMAKE_CXX_FLAGS
from an environment variable named CXXFLAGS
. See sakra's answer to SO question Adding include directories to cmake when calling it from command line.$ export CXXFLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/ld-linux-x86-64.so.2' $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make
CMAKE_CXX_FLAGS
can also be initialized from the command line using -DCMAKE_CXX_FLAGS
:$ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' -DCMAKE_CXX_FLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/ld-linux-x86-64.so.2' ~/code/llvm_source_tree/llvm/ $ make
CMAKE_CXX_FLAGS
can also be initialized from the command line using -DCMAKE_CXX_FLAGS:STRING
(see Building mpllibs):$ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' -DCMAKE_CXX_FLAGS:STRING='-Wl,--rpath=/usr/local/glibc/glibc-2.21 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/ld-linux-x86-64.so.2' ~/code/llvm_source_tree/llvm/ $ make
All of these 3 options produces the exactly same result: compiling LLVM ends with the same error that is related to targets llvm-tblgen
and intrinsics_gen
(the only differences between the 3 Makefile
's produced above by cmake
commands are in directory names, caused by the fact that each build was done in different directory). It seems that the target llvm-tblgen
gets compiled and linked appropriately, but after that the target llvm-tblgen
seems to be a dependency of the target intrinsics_gen
, and somehow llvm-tblgen
cannot be found. These are the last lines of the output of make
(these are identical for each of the 3 builds above):
Linking CXX executable ../../bin/llvm-tblgen [ 4%] Built target llvm-tblgen Scanning dependencies of target intrinsics_gen [ 4%] Building Intrinsics.gen... /bin/sh: 1: ../../../bin/llvm-tblgen: not found make[2]: *** [include/llvm/IR/Intrinsics.gen.tmp] Error 127 make[1]: *** [include/llvm/IR/CMakeFiles/intrinsics_gen.dir/all] Error 2 make: *** [all] Error 2
I wonder if this if this is a bug in LLVM or is setting cmake
variable CMAKE_CXX_FLAGS
the way I did (in the 3 builds above) sufficient or is this caused by something else. Any ideas how to continue would be greatly appreciated.
As suggested by Employed Russian in his comment (below his answer):
$ export CXXFLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2' $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make
This also caused a compiling error related to targets llvm-tblgen
and intrinsics_gen
, but the error was different compared to the prior error. These are the last lines of make
output:
Linking CXX executable ../../bin/llvm-tblgen [ 4%] Built target llvm-tblgen Scanning dependencies of target intrinsics_gen [ 4%] Building Intrinsics.gen... ../../../bin/llvm-tblgen: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory make[2]: *** [include/llvm/IR/Intrinsics.gen.tmp] Error 127 make[1]: *** [include/llvm/IR/CMakeFiles/intrinsics_gen.dir/all] Error 2 make: *** [all] Error 2
So it seems that llvm-tblgen
is now found, but there's an error loading shared library libtinfo.so.5
. So I changed --rpath=/usr/local/glibc/glibc-2.21
to --rpath=/usr/local/glibc/glibc-2.21/lib
and tried again:
$ export CXXFLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21/lib -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2' $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make
However, this change of --rpath
did not change the error message produced by make
at all. I wonder where this shared library libtinfo.so.5
should be located.
Then I encountered Building the Clang + LLVM compilers website and tried adding -std=c++11
to CXXFLAGS
:
$ export CXXFLAGS='-std=c++11 -Wl,--rpath=/usr/local/glibc/glibc-2.21 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2' $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make
But it didn't help, the error message is identical, that is, shared library libtinfo.so.5
still cannot be found. Maybe my g++
version is too old, it's g++
4.7.2 that is shipped with Debian Wheezy (g++ --version
prints g++ (Debian 4.7.2-5) 4.7.2
). The author of Building the Clang + LLVM compilers website writes that his attempt to build LLVM on Fedora 15 using only g++
4.7.1 failed, whereas compiling it with several restarts with different g++
versions (4.8, 4.8.0, 4.7.1) finally succeeded (described on the website). Any ideas?
As suggested by Employed Russian, I recompiled glibc 2.21 with -Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu
:
$ cd ~/code/glibc/glibc-2.21 $ mv -iv build old_build $ mkdir build $ cd build $ export LD_FLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu' $ ../configure --with-binutils=/usr/local/bin --prefix=/usr/local/glibc/glibc-2.21 $ make -j 5
make check
produced some errors:
Summary of test results: 112 FAIL 2073 PASS 199 XFAIL 3 XPASS make[1]: *** [tests] Error 1 make[1]: Leaving directory `/home/user/code/glibc/glibc-2.21' make: *** [check] Error 2
Anyway, I installed the newly compiled glibc 2.21:
$ su # make install
make install
produced this warning:
/home/user/code/glibc/glibc-2.21/build/elf/ldconfig: Warning: ignoring configuration file that cannot be opened: /usr/local/glibc/glibc-2.21/etc/ld.so.conf: No such file or directory make[1]: Leaving directory `/home/user/code/glibc/glibc-2.21'
Then I recompiled LLVM again with: -Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu
:
$ export CXXFLAGS='-std=c++11 -Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2' $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make
But libstdc++.so.6
was missing:
Linking CXX executable ../../bin/llvm-tblgen [ 4%] Built target llvm-tblgen Scanning dependencies of target intrinsics_gen [ 4%] Building Intrinsics.gen... ../../../bin/llvm-tblgen: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory make[2]: *** [include/llvm/IR/Intrinsics.gen.tmp] Error 127 make[1]: *** [include/llvm/IR/CMakeFiles/intrinsics_gen.dir/all] Error 2 make: *** [all] Error 2
So I concluded that there must be still some other library directory that is needed for --rpath
.
$ cd /usr $ sudo find . -name 'libstdc++.so.6' ./lib32/debug/libstdc++.so.6 ./lib32/libstdc++.so.6 ./lib/x86_64-linux-gnu/debug/libstdc++.so.6 ./lib/x86_64-linux-gnu/libstdc++.so.6 ./lib/git-annex.linux/usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./lib/i386-linux-gnu/libstdc++.so.6
Of these, ./lib/x86_64-linux-gnu/libstdc++.so.6
looks most suitable to me. So I added /usr/lib/x86_64-linux-gnu
to --rpath
, and recompiled glibc 2.21 once again:
$ cd ~/code/glibc/glibc-2.21 $ mv -iv build old_build2 $ mkdir build $ cd build $ export LD_FLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu' $ ../configure --with-binutils=/usr/local/bin --prefix=/usr/local/glibc/glibc-2.21 $ make -j 5
I didn't bother to make check
this time but rather continued directly with the installation:
$ su # make install
And got the same seemingly harmless warning:
/home/user/code/glibc/glibc-2.21/build/elf/ldconfig: Warning: ignoring configuration file that cannot be opened: /usr/local/glibc/glibc-2.21/etc/ld.so.conf: No such file or directory make[1]: Leaving directory `/home/user/code/glibc/glibc-2.21'
So I added /usr/lib/x86_64-linux-gnu
to --rpath
for LLVM, and recompiled LLVM:
$ export CXXFLAGS='-std=c++11 -Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2' $ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/ $ make
The build was successful, so I installed LLVM:
$ su # make install
Then I recompiled YouCompleteMe support libs with the same CXXFLAGS
I used for compiling LLVM:
$ export CXXFLAGS='-std=c++11 -Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2' $ cmake -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=/usr/local/lib/libclang.so . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp $ make ycm_support_libs
This build was successful, too. Then I reinstalled YouCompleteMe:
$ cd $ .vim/bundle/YouCompleteMe/install.sh
Completion seems to work. Then I ran the tests of YouCompleteMe:
$ .vim/bundle/YouCompleteMe/run_tests.sh
OK, completion still works.
$ .vim/bundle/YouCompleteMe/third_party/ycmd/run_tests.sh
This caused a problem. It seems that this .vim/bundle/YouCompleteMe/third_party/ycmd/run_tests.sh
recompiles support libs - without using my Makefile
- and therefore breaks the support libs. Solution is not to run .vim/bundle/YouCompleteMe/third_party/ycmd/run_tests.sh
.
[100%] Building CXX object ycm/tests/CMakeFiles/ycm_core_tests.dir/TestUtils.cpp.o Linking CXX executable ycm_core_tests ../../clang+llvm-3.6.0-x86_64-linux-gnu/lib/libclang.so: undefined reference to `posix_spawn@GLIBC_2.15' ../../clang+llvm-3.6.0-x86_64-linux-gnu/lib/libclang.so: undefined reference to `memcpy@GLIBC_2.14' collect2: error: ld returned 1 exit status make[3]: *** [ycm/tests/ycm_core_tests] Error 1 make[2]: *** [ycm/tests/CMakeFiles/ycm_core_tests.dir/all] Error 2 make[1]: *** [ycm/tests/CMakeFiles/ycm_core_tests.dir/rule] Error 2 make: *** [ycm_core_tests] Error 2
So I recompiled the support libs the same way I recently did and after that and reinstalled YouCompleteMe once more:
$ export CXXFLAGS='-std=c++11 -Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib:/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2' $ cmake -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=/usr/local/lib/libclang.so . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp $ make ycm_support_libs
$ cd $ .vim/bundle/YouCompleteMe/install.sh
And finally, YouCompleteMe works again!
Then I also tried LD_PRELOAD
As explained here, in order to use custom glibc, you need to set correct --dynamic-linker
.
I see that you are using --dynamic-linker=/usr/local/glibc/glibc-2.21/ld-linux.so.2
, but that doesn't look right: you need ld-linux-x86-64.so.2
.
export LD_PRELOAD='/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2 ...
That (preloading of ld-linux
) can never work: it's the ld-linux
that interprets LD_PRELOAD
in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With