2

Setup

I'm using clangd through neovim with nvim-lspconfig.

require('lspconfig').clangd.setup {
    -- on_attach = keybinds.on_attach,
    cmd = {
        "clangd",
        "--background-index",
        "--suggest-missing-includes",
        -- "--compile-commands-dir=/home/localuser/test/build",
    },
    filetypes = { "c", "cpp", "objc", "objcpp" },
}

Problem

clangd is not finding project specific includes.

What it should be doing

According to the documentation: (https://clangd.llvm.org/installation.html)

clangd will look in the parent directories of the files you edit looking for it, and also in subdirectories named build/. For example, if editing $SRC/gui/window.cpp, we search in $SRC/gui/, $SRC/gui/build/, $SRC/, $SRC/build/, …

I've built the project with cmake flag -DCMAKE_EXPORT_COMPILE_COMMANDS=1 and i have compile_commands.json in the build directory: ~/test/build/compile_commands.json

The source file I am editing is ~/test/src/main.cpp

As per the documentation, clangd should find the compilation database from the build folder, as the build folder is in a parent folder of the source file, but it does not.

What is happening

clangd gives errors on includes. I've included the full ~/.local/state/nvim/lsp.log at the end.

  • I can explicitly show clangd where the JSON is with the --compile-commands-dir flag (commented in first code block), and then it does work. However that is a system-wide configuration so I don't want to do that (and according to the documentation I shouldn't have to)
  • I can also symlink ./build/compile_commands.json to ./compile_commands.json, and then clangd works correctly.

Logs

I've created a small example. Its basically just a main() function which includes the opencv library (required in CMakeLists.txt) The project compiles just fine, but clangd complains that opencv2/opencv.hpp cannot be found.

Here's the test project directory layout:

localadmin@workstation:~/test$ tree
.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.16.3
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── progress.marks
│   │   ├── TargetDirectories.txt
│   │   └── test.dir
│   │       ├── build.make
│   │       ├── cmake_clean.cmake
│   │       ├── CXX.includecache
│   │       ├── DependInfo.cmake
│   │       ├── depend.internal
│   │       ├── depend.make
│   │       ├── flags.make
│   │       ├── link.txt
│   │       ├── progress.make
│   │       └── src
│   │           └── main.cpp.o
│   ├── cmake_install.cmake
│   ├── compile_commands.json
│   ├── Makefile
│   └── test
├── build.sh
├── CMakeLists.txt
└── src
    └── main.cpp

And here's the full lsp.log:

[START][2022-10-24 14:16:22] LSP logging initiated
[INFO][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:662 "Starting RPC client"   { args = { "--background-index", "--suggest-missing-includes" }, cmd = "clangd", extra = { cwd = "/home/localadmin/test" }}
[TRACE][2022-10-24 14:16:22] .../lua/vim/lsp.lua:1283   "LSP[clangd]"   "initialize_params" { capabilities = { callHierarchy = { dynamicRegistration = false }, offsetEncoding = { "utf-8", "utf-16" }, textDocument = { codeAction = { codeActionLiteralSupport = { codeActionKind = { valueSet = { "", "Empty", "QuickFix", "Refactor", "RefactorExtract", "RefactorInline", "RefactorRewrite", "Source", "SourceOrganizeImports", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" } } }, dataSupport = true, dynamicRegistration = false, isPreferredSupport = true, resolveSupport = { properties = { "edit" } } }, completion = { completionItem = { commitCharactersSupport = false, deprecatedSupport = false, documentationFormat = { "markdown", "plaintext" }, preselectSupport = false, snippetSupport = false }, completionItemKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 } }, contextSupport = false, dynamicRegistration = false, editsNearCursor = true }, declaration = { linkSupport = true }, definition = { linkSupport = true }, documentHighlight = { dynamicRegistration = false }, documentSymbol = { dynamicRegistration = false, hierarchicalDocumentSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, hover = { contentFormat = { "markdown", "plaintext" }, dynamicRegistration = false }, implementation = { linkSupport = true }, publishDiagnostics = { relatedInformation = true, tagSupport = { valueSet = { 1, 2 } } }, references = { dynamicRegistration = false }, rename = { dynamicRegistration = false, prepareSupport = true }, signatureHelp = { dynamicRegistration = false, signatureInformation = { activeParameterSupport = true, documentationFormat = { "markdown", "plaintext" }, parameterInformation = { labelOffsetSupport = true } } }, synchronization = { didSave = true, dynamicRegistration = false, willSave = false, willSaveWaitUntil = false }, typeDefinition = { linkSupport = true } }, window = { showDocument = { support = false }, showMessage = { messageActionItem = { additionalPropertiesSupport = false } }, workDoneProgress = true }, workspace = { applyEdit = true, configuration = true, symbol = { dynamicRegistration = false, hierarchicalWorkspaceSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, workspaceEdit = { resourceOperations = { "rename", "create", "delete" } }, workspaceFolders = true } }, clientInfo = { name = "Neovim", version = "0.8.0" }, initializationOptions = vim.empty_dict(), processId = 377762, rootPath = "/home/localadmin/test", rootUri = "file:///home/localadmin/test", trace = "off", workspaceFolders = { { name = "/home/localadmin/test", uri = "file:///home/localadmin/test" } }}
[DEBUG][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:285    "rpc.send"  { id = 1, jsonrpc = "2.0", method = "initialize", params = { capabilities = { callHierarchy = { dynamicRegistration = false }, offsetEncoding = { "utf-8", "utf-16" }, textDocument = { codeAction = { codeActionLiteralSupport = { codeActionKind = { valueSet = { "", "Empty", "QuickFix", "Refactor", "RefactorExtract", "RefactorInline", "RefactorRewrite", "Source", "SourceOrganizeImports", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" } } }, dataSupport = true, dynamicRegistration = false, isPreferredSupport = true, resolveSupport = { properties = { "edit" } } }, completion = { completionItem = { commitCharactersSupport = false, deprecatedSupport = false, documentationFormat = { "markdown", "plaintext" }, preselectSupport = false, snippetSupport = false }, completionItemKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 } }, contextSupport = false, dynamicRegistration = false, editsNearCursor = true }, declaration = { linkSupport = true }, definition = { linkSupport = true }, documentHighlight = { dynamicRegistration = false }, documentSymbol = { dynamicRegistration = false, hierarchicalDocumentSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, hover = { contentFormat = { "markdown", "plaintext" }, dynamicRegistration = false }, implementation = { linkSupport = true }, publishDiagnostics = { relatedInformation = true, tagSupport = { valueSet = { 1, 2 } } }, references = { dynamicRegistration = false }, rename = { dynamicRegistration = false, prepareSupport = true }, signatureHelp = { dynamicRegistration = false, signatureInformation = { activeParameterSupport = true, documentationFormat = { "markdown", "plaintext" }, parameterInformation = { labelOffsetSupport = true } } }, synchronization = { didSave = true, dynamicRegistration = false, willSave = false, willSaveWaitUntil = false }, typeDefinition = { linkSupport = true } }, window = { showDocument = { support = false }, showMessage = { messageActionItem = { additionalPropertiesSupport = false } }, workDoneProgress = true }, workspace = { applyEdit = true, configuration = true, symbol = { dynamicRegistration = false, hierarchicalWorkspaceSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, workspaceEdit = { resourceOperations = { "rename", "create", "delete" } }, workspaceFolders = true } }, clientInfo = { name = "Neovim", version = "0.8.0" }, initializationOptions = vim.empty_dict(), processId = 377762, rootPath = "/home/localadmin/test", rootUri = "file:///home/localadmin/test", trace = "off", workspaceFolders = { { name = "/home/localadmin/test", uri = "file:///home/localadmin/test" } } }}
[ERROR][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:734    "rpc"   "clangd"    "stderr"    "I[14:16:22.583] clangd version 10.0.0-4ubuntu1 
I[14:16:22.583] PID: 377766
I[14:16:22.583] Working directory: /home/localadmin/test
I[14:16:22.583] argv[0]: clangd
I[14:16:22.583] argv[1]: --background-index
I[14:16:22.583] argv[2]: --suggest-missing-includes
I[14:16:22.583] Starting LSP over stdin/stdout
I[14:16:22.584] <-- initialize(1)
I[14:16:22.584] --> reply:initialize(1) 0 ms
"
[DEBUG][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:388    "rpc.receive"   { id = 1, jsonrpc = "2.0", result = { capabilities = { codeActionProvider = { codeActionKinds = { "quickfix", "refactor", "info" } }, completionProvider = { resolveProvider = false, triggerCharacters = { ".", ">", ":" } }, declarationProvider = true, definitionProvider = true, documentFormattingProvider = true, documentHighlightProvider = true, documentLinkProvider = { resolveProvider = false }, documentOnTypeFormattingProvider = { firstTriggerCharacter = "
", moreTriggerCharacter = {} }, documentRangeFormattingProvider = true, documentSymbolProvider = true, executeCommandProvider = { commands = { "clangd.applyFix", "clangd.applyTweak" } }, hoverProvider = true, referencesProvider = true, renameProvider = { prepareProvider = true }, selectionRangeProvider = true, signatureHelpProvider = { triggerCharacters = { "(", "," } }, textDocumentSync = 2, typeHierarchyProvider = true, workspaceSymbolProvider = true }, offsetEncoding = "utf-8" }}
[DEBUG][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:285    "rpc.send"  { jsonrpc = "2.0", method = "initialized", params = vim.empty_dict()}
[INFO][2022-10-24 14:16:22] .../lua/vim/lsp.lua:1343    "LSP[clangd]"   "server_capabilities"   { server_capabilities = { codeActionProvider = { codeActionKinds = { "quickfix", "refactor", "info" } }, completionProvider = { resolveProvider = false, triggerCharacters = { ".", ">", ":" } }, declarationProvider = true, definitionProvider = true, documentFormattingProvider = true, documentHighlightProvider = true, documentLinkProvider = { resolveProvider = false }, documentOnTypeFormattingProvider = { firstTriggerCharacter = "
", moreTriggerCharacter = {} }, documentRangeFormattingProvider = true, documentSymbolProvider = true, executeCommandProvider = { commands = { "clangd.applyFix", "clangd.applyTweak" } }, hoverProvider = true, referencesProvider = true, renameProvider = { prepareProvider = true }, selectionRangeProvider = true, signatureHelpProvider = { triggerCharacters = { "(", "," } }, textDocumentSync = { change = 2, openClose = true, save = { includeText = false }, willSave = false, willSaveWaitUntil = false }, typeHierarchyProvider = true, workspaceSymbolProvider = true }}
[DEBUG][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:285    "rpc.send"  { jsonrpc = "2.0", method = "textDocument/didOpen", params = { textDocument = { languageId = "cpp", text = '#include <iostream>
#include "opencv2/opencv.hpp"

int main(int argc, char** argv ) {

 if(argc != 2)
 {
 std::cerr << std::endl << "Usage: ./datacollector";
 std::cerr << " dataset_save_path" << std::endl;
 // std::cerr << " path_to_settings"; 
 // std::cerr << " path_to_ros2bag_1";
 // std::cerr << " (path_to_ros2bag_2 ... path_to_ros2bag_N) " << std::endl;
 return 1;
 }
}
', uri = "file:///home/localadmin/test/src/main.cpp", version = 0 } }}
[ERROR][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:734    "rpc"   "clangd"    "stderr"    "I[14:16:22.723] <-- initialized
I[14:16:22.723] unhandled notification initialized
I[14:16:22.723] <-- textDocument/didOpen
"
[ERROR][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:734    "rpc"   "clangd"    "stderr"    "I[14:16:22.724] Failed to find compilation database for /home/localadmin/test/src/main.cpp
I[14:16:22.724] Updating file /home/localadmin/test/src/main.cpp with command clangd fallback
[/home/localadmin/test/src]
/usr/lib/llvm-10/bin/clang /home/localadmin/test/src/main.cpp -fsyntax-only -resource-dir=/usr/lib/llvm-10/lib/clang/10.0.0
"
[ERROR][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:734    "rpc"   "clangd"    "stderr"    "I[14:16:22.994] --> textDocument/publishDiagnostics
"
[DEBUG][2022-10-24 14:16:22] .../vim/lsp/rpc.lua:388    "rpc.receive"   { jsonrpc = "2.0", method = "textDocument/publishDiagnostics", params = { diagnostics = { { code = "pp_file_not_found", message = "'opencv2/opencv.hpp' file not found", range = { ["end"] = { character = 29, line = 1 }, start = { character = 9, line = 1 } }, relatedInformation = {}, severity = 1, source = "clang" } }, uri = "file:///home/localadmin/test/src/main.cpp" }}
[TRACE][2022-10-24 14:16:22] .../lua/vim/lsp.lua:1052   "notification"  "textDocument/publishDiagnostics"   { diagnostics = { { code = "pp_file_not_found", message = "'opencv2/opencv.hpp' file not found", range = { ["end"] = { character = 29, line = 1 }, start = { character = 9, line = 1 } }, relatedInformation = {}, severity = 1, source = "clang" } }, uri = "file:///home/localadmin/test/src/main.cpp"}
[TRACE][2022-10-24 14:16:22] ...lsp/handlers.lua:519    "default_handler"   "textDocument/publishDiagnostics"   { ctx = '{
 client_id = 1,
 method = "textDocument/publishDiagnostics"
}', result = { diagnostics = { { code = "pp_file_not_found", message = "'opencv2/opencv.hpp' file not found", range = { ["end"] = { character = 29, line = 1 }, start = { character = 9, line = 1 } }, relatedInformation = {}, severity = 1, source = "clang" } }, uri = "file:///home/localadmin/test/src/main.cpp" }}
[INFO][2022-10-24 14:16:29] .../lua/vim/lsp.lua:1814    "exit_handler"  { { _on_attach = <function 1>, attached_buffers = { true }, cancel_request = <function 2>, commands = {}, config = { _on_attach = <function 3>, autostart = true, capabilities = { callHierarchy = { dynamicRegistration = false }, offsetEncoding = { "utf-8", "utf-16" }, textDocument = { codeAction = { codeActionLiteralSupport = { codeActionKind = { valueSet = { "", "Empty", "QuickFix", "Refactor", "RefactorExtract", "RefactorInline", "RefactorRewrite", "Source", "SourceOrganizeImports", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" } } }, dataSupport = true, dynamicRegistration = false, isPreferredSupport = true, resolveSupport = { properties = { "edit" } } }, completion = { completionItem = { commitCharactersSupport = false, deprecatedSupport = false, documentationFormat = { "markdown", "plaintext" }, preselectSupport = false, snippetSupport = false }, completionItemKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 } }, contextSupport = false, dynamicRegistration = false, editsNearCursor = true }, declaration = { linkSupport = true }, definition = { linkSupport = true }, documentHighlight = { dynamicRegistration = false }, documentSymbol = { dynamicRegistration = false, hierarchicalDocumentSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, hover = { contentFormat = { "markdown", "plaintext" }, dynamicRegistration = false }, implementation = { linkSupport = true }, publishDiagnostics = { relatedInformation = true, tagSupport = { valueSet = { 1, 2 } } }, references = { dynamicRegistration = false }, rename = { dynamicRegistration = false, prepareSupport = true }, signatureHelp = { dynamicRegistration = false, signatureInformation = { activeParameterSupport = true, documentationFormat = { "markdown", "plaintext" }, parameterInformation = { labelOffsetSupport = true } } }, synchronization = { didSave = true, dynamicRegistration = false, willSave = false, willSaveWaitUntil = false }, typeDefinition = { linkSupport = true } }, window = { showDocument = { support = false }, showMessage = { messageActionItem = { additionalPropertiesSupport = false } }, workDoneProgress = true }, workspace = { applyEdit = true, configuration = true, symbol = { dynamicRegistration = false, hierarchicalWorkspaceSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, workspaceEdit = { resourceOperations = { "rename", "create", "delete" } }, workspaceFolders = true } }, cmd = { "clangd", "--background-index", "--suggest-missing-includes" }, cmd_cwd = "/home/localadmin/test", filetypes = { "c", "cpp", "objc", "objcpp" }, flags = {}, get_language_id = <function 4>, handlers = <1>{}, init_options = vim.empty_dict(), log_level = 2, message_level = 2, name = "clangd", on_attach = <function 5>, on_exit = <function 6>, on_init = <function 7>, root_dir = "/home/localadmin/test", settings = vim.empty_dict(), single_file_support = true, workspace_folders = <2>{ { name = "/home/localadmin/test", uri = "file:///home/localadmin/test" } }, <metatable> = <3>{ __tostring = <function 8> } }, handlers = <table 1>, id = 1, initialized = true, is_stopped = <function 9>, messages = { messages = {}, name = "clangd", progress = {}, status = {} }, name = "clangd", notify = <function 10>, offset_encoding = "utf-8", request = <function 11>, request_sync = <function 12>, requests = {}, rpc = { is_closing = <function 13>, notify = <function 14>, request = <function 15>, terminate = <function 16> }, server_capabilities = { codeActionProvider = { codeActionKinds = { "quickfix", "refactor", "info" } }, completionProvider = { resolveProvider = false, triggerCharacters = { ".", ">", ":" } }, declarationProvider = true, definitionProvider = true, documentFormattingProvider = true, documentHighlightProvider = true, documentLinkProvider = { resolveProvider = false }, documentOnTypeFormattingProvider = { firstTriggerCharacter = "
", moreTriggerCharacter = {} }, documentRangeFormattingProvider = true, documentSymbolProvider = true, executeCommandProvider = { commands = { "clangd.applyFix", "clangd.applyTweak" } }, hoverProvider = true, referencesProvider = true, renameProvider = { prepareProvider = true }, selectionRangeProvider = true, signatureHelpProvider = { triggerCharacters = { "(", "," } }, textDocumentSync = { change = 2, openClose = true, save = { includeText = false }, willSave = false, willSaveWaitUntil = false }, typeHierarchyProvider = true, workspaceSymbolProvider = true }, stop = <function 17>, supports_method = <function 18>, workspaceFolders = <table 2>, workspace_did_change_configuration = <function 19>, workspace_folders = <table 2>, <metatable> = { __index = <function 20> } } }
[DEBUG][2022-10-24 14:16:29] .../vim/lsp/rpc.lua:285    "rpc.send"  { id = 2, jsonrpc = "2.0", method = "shutdown"}
[ERROR][2022-10-24 14:16:30] .../vim/lsp/rpc.lua:734    "rpc"   "clangd"    "stderr"    "I[14:16:30.000] <-- shutdown(2)
I[14:16:30.000] --> reply:shutdown(2) 0 ms
"
[DEBUG][2022-10-24 14:16:30] .../vim/lsp/rpc.lua:388    "rpc.receive"   { id = 2, jsonrpc = "2.0"}
[DEBUG][2022-10-24 14:16:30] .../vim/lsp/rpc.lua:285    "rpc.send"  { jsonrpc = "2.0", method = "exit"}
[START][2022-10-24 14:18:47] LSP logging initiated
[INFO][2022-10-24 14:18:47] .../lua/vim/lsp.lua:1814    "exit_handler"  {} 

1
  • I'm voting to close this question as "not reproducible" because the behaviour which you find unexpected is functioning as intended according to the very documentation you quote. You seem to be misunderstanding that documentation. Your source file is test/src/main.cpp. your compile commands db file is test/build/compile_commands.json, which is NOT in the same or anestor directory of main.cpp. Commented Oct 25, 2023 at 9:37

1 Answer 1

0

Given the file /home/localuser/Projects/SLAM3/Examples/Stereo-Inertial/stereo_inertial_bag.cc, the places clangd will look are:

/home/localuser/Projects/SLAM3/Examples/Stereo-Inertial/compile_commands.json
/home/localuser/Projects/SLAM3/Examples/Stereo-Inertial/build/compile_commands.json
/home/localuser/Projects/SLAM3/Examples/compile_commands.json
/home/localuser/Projects/SLAM3/Examples/build/compile_commands.json
/home/localuser/Projects/SLAM3/compile_commands.json
/home/localuser/Projects/SLAM3/build/compile_commands.json
/home/localuser/Projects/compile_commands.json
/home/localuser/Projects/build/compile_commands.json
etc.

It does not look at /home/localuser/SLAM3/MyProject/build because your source file is not in MyProject.

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry, there was a typo in that first code block (fixed). There is no "MyProject" folder. compile_commands is in /home/localuser/Projects/SLAM3/build/compile_commands.json
@Olli Ok, in that case, I would expect clangd to find it. To try to diagnose the issue further, can you attach complete logs?
Hi, I've attached the full lsp logs to my original question, along with a simplified small one-file project to reproduce the issue.
@Olli: Here is the issue: clangd version 10.0.0-4ubuntu1. This is a very old clangd version (latest version is 15.0.3). The logic to look in build subdirectories was added in version 11 or 12 I believe. Newer versions can be obtained from github.com/clangd/clangd/releases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.