Skip to content

Instantly share code, notes, and snippets.

@micjabbour
Last active March 25, 2024 05:18
Show Gist options
  • Save micjabbour/ef6181f9a2cf17f90a5744fcf909438a to your computer and use it in GitHub Desktop.
Save micjabbour/ef6181f9a2cf17f90a5744fcf909438a to your computer and use it in GitHub Desktop.
How to install YouCompleteMe on Termux

How to install YouCompleteMe on Termux

Problem

As of March 2021, YouCompleteMe compiles fine on Termux, but it crashes once the plugin is loaded. The following error can be noticed in the logs:

ImportError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14__fs10filesystem18__weakly_canonicalERKNS1_4pathEPNS_10error_codeE" referenced by "/data/data/com.termux/files/home/.vim/bundle/YouCompleteMe/third_party/ycmd/ycm_core.so"...

The problem is caused by the lack of support for std::filesystem on ndk prior to r22. While there is an ongoing PR that aims to upgrade Termux to use ndk r22, the instructions below can be used to run YouCompleteMe on Termux before the linked PR gets merged.

Solution

  1. Install the prerequisite Termux packages.

    pkg install vim-python git python clang cmake
    
  2. Install Vundle by following the official instructions. This includes cloning the repository and editing your vimrc as necessary.

  3. Install YouCompleteMe by adding it to the list of plugins in your vimrc file, and then running the :PluginInstall command in vim.

    Plugin 'ycm-core/YouCompleteMe'
    
    :PluginInstall
    
  4. Apply the provided patch1 to use ghc::filesystem instead of std::filesystem in ycmd.

    cd ~/.vim/bundle/YouCompleteMe/third_party/ycmd
    curl https://gist.githubusercontent.com/micjabbour/ef6181f9a2cf17f90a5744fcf909438a/raw/ycmd_filesystem_patch.patch | git apply --3way -
    
  5. Build and install YouCompleteMe2, and configure it to use the clangd completer.3

    python install.py --clangd-completer
    
  6. Configure YouCompleteMe to use clangd from the libllvm Termux package.4 This can be done by adding the following line to the end of your vimrc file.

    let g:ycm_clangd_binary_path="/data/data/com.termux/files/usr/bin/clangd"
    

Next

If you are new to YouCompleteMe, it might be a bit tricky to configure it properly for your project. In this case, you can start by testing your installation on the example projects used for ycmd tests.

vim ~/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp

vim_ycm_cpp

vim ~/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/tests/python/testdata/basic.py

vim_ycm_py


  1. ^ The patch has been written for commit dbf67638 in the YouCompleteMe repository (the master branch at the time of this writing). If you are from the future, and the patch no longer applies, you might have to manually resolve the merge conflict. The patch simply modifies CMakeLists.txt to download ghc::filesystem header to the build directory, replaces all #include <filesystem> with #include <ghc_filesystem.hpp>, and changes all references to std::filesystem to use ghc::filesystem instead.

  2. ^ If you are on a device with limited RAM, try using export YCM_CORES=1 before running install.py. This controls the number of compilation jobs executed in parallel (a.k.a. -j), and overrides the default multiprocessing.cpu_count().

  3. ^ In my experiments, using --clang-completer (with --system-libclang) caused frequent crashes in ycmd. I couldn't identify the problem by looking at the logs, but I had a much better experience when using the --clangd-completer.

  4. ^ Neither libclang nor clangd binaries available in ycm_core's bintray (which are downloaded automatically when running install.py) are usable on android, because they use non-compatible ABIs.

diff --git a/cpp/ycm/CMakeLists.txt b/cpp/ycm/CMakeLists.txt
index 9542a152..1f65cfc2 100644
--- a/cpp/ycm/CMakeLists.txt
+++ b/cpp/ycm/CMakeLists.txt
@@ -25,6 +25,17 @@ option( USE_SYSTEM_LIBCLANG "Set to ON to use the system libclang library" OFF )
set( PATH_TO_LLVM_ROOT "" CACHE PATH "Path to the root of a LLVM+Clang binary distribution" )
set( EXTERNAL_LIBCLANG_PATH "" CACHE PATH "Path to the libclang library to use" )
+
+# download ghc filesystem dependency (a replacement for std::filesystem that works on termux)
+file(DOWNLOAD https://github.com/gulrak/filesystem/releases/download/v1.5.2/filesystem.hpp
+ ${CMAKE_CURRENT_BINARY_DIR}/ghc_fs/ghc_filesystem.hpp
+ )
+include_directories(
+ SYSTEM
+ ${CMAKE_CURRENT_BINARY_DIR}/ghc_fs
+ )
+
+
if ( USE_CLANG_COMPLETER AND
NOT USE_SYSTEM_LIBCLANG AND
NOT PATH_TO_LLVM_ROOT AND
diff --git a/cpp/ycm/ClangCompleter/TranslationUnit.cpp b/cpp/ycm/ClangCompleter/TranslationUnit.cpp
index 864adb87..82642820 100644
--- a/cpp/ycm/ClangCompleter/TranslationUnit.cpp
+++ b/cpp/ycm/ClangCompleter/TranslationUnit.cpp
@@ -23,7 +23,6 @@
#include <algorithm>
#include <cstdlib>
-#include <filesystem>
#include <memory>
using std::unique_lock;
diff --git a/cpp/ycm/IdentifierUtils.cpp b/cpp/ycm/IdentifierUtils.cpp
index 453bfa24..acddc7e2 100644
--- a/cpp/ycm/IdentifierUtils.cpp
+++ b/cpp/ycm/IdentifierUtils.cpp
@@ -18,13 +18,13 @@
#include "IdentifierUtils.h"
#include "Utils.h"
-#include <filesystem>
+#include <ghc_filesystem.hpp>
#include <string_view>
#include <unordered_map>
namespace YouCompleteMe {
-namespace fs = std::filesystem;
+namespace fs = ghc::filesystem;
namespace {
diff --git a/cpp/ycm/IdentifierUtils.h b/cpp/ycm/IdentifierUtils.h
index 641d11fa..b5305609 100644
--- a/cpp/ycm/IdentifierUtils.h
+++ b/cpp/ycm/IdentifierUtils.h
@@ -20,12 +20,12 @@
#include "IdentifierDatabase.h"
-#include <filesystem>
+#include <ghc_filesystem.hpp>
namespace YouCompleteMe {
YCM_EXPORT FiletypeIdentifierMap ExtractIdentifiersFromTagsFile(
- const std::filesystem::path &path_to_tag_file );
+ const ghc::filesystem::path &path_to_tag_file );
} // namespace YouCompleteMe
diff --git a/cpp/ycm/Utils.cpp b/cpp/ycm/Utils.cpp
index d4bafe7b..cc255426 100644
--- a/cpp/ycm/Utils.cpp
+++ b/cpp/ycm/Utils.cpp
@@ -18,13 +18,13 @@
#include "Utils.h"
#include <cmath>
-#include <filesystem>
+#include <ghc_filesystem.hpp>
#include <fstream>
#include <limits>
#include <string>
#include <vector>
-namespace fs = std::filesystem;
+namespace fs = ghc::filesystem;
namespace YouCompleteMe {
diff --git a/cpp/ycm/Utils.h b/cpp/ycm/Utils.h
index b5b18ed4..1ff426cb 100644
--- a/cpp/ycm/Utils.h
+++ b/cpp/ycm/Utils.h
@@ -20,14 +20,14 @@
#include <algorithm>
#include <cmath>
-#include <filesystem>
+#include <ghc_filesystem.hpp>
#include <limits>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
-namespace fs = std::filesystem;
+namespace fs = ghc::filesystem;
namespace YouCompleteMe {
@fedosacha02
Copy link

fedosacha02 commented Jun 15, 2022

(newenv) ~/.../bundle/YouCompleteMe $ python install.py --clangd-completer
1 error generated. make[3]: *** [ycm/CMakeFiles/ycm_core.dir/build.make:146: ycm/CMakeFiles/ycm_core.dir/IdentifierUtils.cpp.o] Error 1 make[2]: *** [CMakeFiles/Makefile2:2675: ycm/CMakeFiles/ycm_core.dir/all] Error 2 make[1]: *** [CMakeFiles/Makefile2:2682: ycm/CMakeFiles/ycm_core.dir/rule] Error 2 make: *** [Makefile:962: ycm_core] Error 2 FAILED ERROR: the build failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment