Коротко — clangd ориентируется не на «проектную структуру», а на команды компиляции (include‑директории, макросы и т.д.). Чтобы он перестал требовать относительных путей в #include, нужно дать ему правильные -I/-isystem флаги (или компилировать через CMake с экспортом базы компиляции). Что сделать — пошагово.
1) Самый надёжный способ — сгенерировать compile_commands.json
- Если проект на CMake:
- Включите экспорт команд: при конфигурации cmake укажите -DCMAKE_EXPORT_COMPILE_COMMANDS=ON, например:
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- Файл build/compile_commands.json появится автоматически. Поместите (или сделайте symlink) его в корень проекта, либо укажите clangd папку с ним (см. дальше).
- Если не CMake: используйте bear (https://github.com/rizsotto/Bear) или подобный инструмент:
- bear -- make
- в результате появится compile_commands.json.
Почему это важно: в compile_commands.json для каждого .cpp/.c файла перечислены реальные флаги компиляции (-I, -D, -std и т.д.). clangd использует их, чтобы резолвить include‑файлы.
2) Если по какой‑то причине compile_commands.json получить нельзя
- Создайте в корне файла compile_flags.txt с перечислением флагов по одному в строку, например:
-std=c++17
-Iinclude
-Isrc
-DDEBUG
clangd будет читать этот файл как «fallback» для всех TU, но это простой глобальный вариант (не даёт per‑file флагов).
3) Ещё один вариант — .clangd конфиг (YAML)
- в корне проекта создайте файл .clangd с содержимым, например:
CompileFlags:
Add: [-Iinclude, -Isrc, -std=c++17]
Это добавит указанные пути к тем флагам, что уже есть в compile_commands.json, или станет использоваться как доп. флаги.
4) Настройка в Sublime Text + LSP (clangd)
- Убедитесь, что LSP использует тот clangd, который вы настроили (и что он видит compile_commands.json).
- Пример настройки клиента clangd в настройках LSP (User или в .sublime-project):
{
"clients": {
"clangd": {
"command": ["clangd", "--compile-commands-dir=build"]
}
}
}
Либо поместите compile_commands.json в корень проекта и не указывайте опцию.
- Если у вас пакет LSP-clangd, настройка похожа — просто добавьте аргументы командной строки через поле command.
5) Дополнительные советы и отладка
- Проверьте содержимое compile_commands.json — в командной строке для каждого .cpp должны присутствовать нужные -I. Если их нет, инструменты сборки не были настроены правильно.
- Если у вас заголовки, которые не включены ни в один .cpp (чисто «library headers»), clangd всё равно сможет их находить, если соответствующие -I присутствуют в compile_commands или compile_flags. Если header нигде не виден, можно добавить «фиктивный» .cpp, который включает его, чтобы попасть в базу.
- Можно быстро создать символьную ссылку, если clangd ожидает compile_commands.json в корне:
ln -s build/compile_commands.json compile_commands.json
- Посмотрите логи LSP/clangd: включите verbose‑лог или запустите clangd вручную для отладки.
- Если используете Apple SDK / Xcode, убедитесь, что compile_commands содержит правильный -isysroot и флаги SDK (иначе system include не найдутся).
Пример минимального рабочего набора
- CMake: cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- ln -s build/compile_commands.json ./compile_commands.json
- В Sublime LSP: ничего больше не трогать — перезапустите clangd/редактор. После этого в #include <mylib/header.hpp> clangd должен найти header, если include папка указана через -I в compile_commands.json.
Если пришлёте:
- пример строки из compile_commands.json (команда компиляции) или
- структуру каталогов и пример #include,
я покажу точную строку -I или пример .clangd/compile_flags.txt для вашего случая.