Is there "includePath" option in clangd? - c++

I used to work with VSCode C/C++ extension. there was a feature in this extension(in a json file), called "includePath", which I could set the paths for my headers, so without execution of CMake or make, I would have the suggestion of my headers and code completion from those.
now I have switched to neovim and clangd as the language server for code completion. I searched a lot to find the corresponding feature in clangd options but I could not find anything more than this link.
since the clangd is a powerful language server, I am in wonder if there is not such a feature in it. so I want to know is there actually such a feature in clangd? and if YES how can I use that?
Note: I use a language client, called "coc-clangd". I don't know if it matters or not.

Clangd uses compile_commands.json database file which contains flags (such as include directories) for each file in project. But this file is auto-generated, so all modifications to it will be overwritten eventually. You can ask CMake to add any custom compile flags with -DCMAKE_CXX_FLAGS command line argument.
Example for system headers (#include <file.h>):
cmake -DCMAKE_CXX_FLAGS="-isystem /path/to/includes" /path/to/source
For project headers (#include "file.h"):
cmake -DCMAKE_CXX_FLAGS=-Ipath/to/includes /path/to/source
Additionally, you can set CXXFLAGS environment variable:
export CXXFLAGS="-isystem /path/to/includes"
cmake path/to/sources
After that new flags should appear in your compile_commands.json file.

Maybe this is useful: https://clangd.llvm.org/config
Create a file called '.clangd' in the top-level of the source directory.
Add those content.
CompileFlags: # Tweak the parse settings
Add:
- "-I=[folder]"
But I think this is not recommend, all include directories should be add in CMakeLists.txt file.

You can add includePath to clangd.fallbackFlags into vscode's settings.json like this:
"clangd.fallbackFlags": [
"-I${workspaceFolder}/include",
"-I/my/include"
]

To use code completion provided by Clangd, let Clangd retrieve include paths from compiler_commands.json with compiler calls used by CMake. Set the CMAKE_EXPORT_COMPILE_COMMANDS option in CMakeLists.txt, it will output compiler_commands.json to the build directory when CMake is run:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Copy the generated compiler_commands.json to the project source directory. Clangd will now source this file.

Related

Custom CMake target that uses only CMake functions [duplicate]

I have a project under CMake with some files generated with python generator from XML files. I cannot specify all files generated by this generator in CMakeLists.txt so I use file globbing for this.
The problem is that when I update my XML files or generator sources (which are in the same repository) I would like to have my build system reconfigured so changed files are taken into account when rebuilding the code (via make for example).
Is it possible to make CMake treat some files like it treats CMakeLists.txt files and to make it regenerate build system when those file are changed?
It doesn't require any kind of workarounds. The standard way is to use CMAKE_CONFIGURE_DEPENDS property:
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS <filename>)
Yes, you should be able to do that by (ab)using configure_file(). Configuring a file makes the source a dependency of the CMake run, so that any changes in it cause a reconfiguration. Simply like this:
configure_file(MyInputFile.xml DummyOutput.xml)
Since it has been a while I will add to #roolebo's answer.
There's actually a better command to add a dependency on a file:
set_directory_properties(PROPERTIES CMAKE_CONFIGURE_DEPENDS <relative_or_full_path_to_file>)
What might be confusing is that this command adds a property to the current directory. Well, it does not matter since you can set a full path to a file that resides outside of the current directory's scope, for instance: ../../config.json

How to set specific CMAKE_C_OUTPUT_EXTENSION for cross-compiling configurations with CMAKE?

I am trying to setup a toolchain file for cross compilation with CMake 3.12.0 version.
My object files have a different extensions than .obj on Windows and .o in UNIX.
Thus, I set my CMAKE_LANG_OUTPUT_EXTENSION to .src.
Unfortunately, this variable is overwritten by CMakeCInformation.cmake file in these lines:
# some compilers use different extensions (e.g. sdcc uses .rel)
# so set the extension here first so it can be overridden by the compiler specific file
if(UNIX)
set(CMAKE_C_OUTPUT_EXTENSION .o)
else()
set(CMAKE_C_OUTPUT_EXTENSION .obj)
endif()
If I comment these lines my configurations will work and the right object extension will be used.
I think my toolchain file is configured so that CMake will not execute its internal compiler checks.
This is how my toolchain file entry lines look:
SET(CMAKE_SYSTEM_NAME Generic)
INCLUDE(CMakeForceCompiler)
SET(CMAKE_C_COMPILER_FORCED TRUE)
SET(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
#other compiler configuration lines here
SET(CMAKE_C_OUTPUT_EXTENSION .src)
SET(CMAKE_ASM_OUTPUT_EXTENSION .o)
SET(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)
SET(CMAKE_ASM_OUTPUT_EXTENSION_REPLACE 1)
I know CMakeForceCompiler is depreciated and CMAKE_TRY_COMPILE_TARGET_TYPE should be used that is why both are there.
I am telling CMake about my toolchain file using -DCMAKE_TOOLCHAIN_FILE
Can you please help me figure out what I am doing wrong?
EDIT: I was also trying to CACHE the value of CMAKE_C_OUTPUT_EXTENSION. At least for me this didn't work.
Add SET(CMAKE_C_OUTPUT_EXTENSION .src) in the CMakeLists.txt file after the project command not in the toolchain file. This should get you the desired behavior (as it should override the values set by CMakeCInformation and any other module scripts).
The toolchain file is used for setting basic toolchain information on where the compiler is and some basic settings. Other variables need to be setup afterwards by custom compiler or platform files that can be included via CMAKE_USER_MAKE_RULES_OVERRIDE.
From CMake issue 18713: "This issue has been reported before and it was mentioned that the toolchain file isn't where these kinds of things should be set for more complicated toolchains."
CMake issue 398139 "Toolchain files should not be setting things like this. ... The output extension should be specified by compiler or platform information files that are loaded by CMakeCInformation after the defaults here are set."

How to make include directories added with AUTOUIC available to downstream targets?

I have a problem with CMake's AUTOUIC option in my qt project.
I have a target that has *.ui qt-form files and changed it to use the AUTOUIC option to automatically generate the corresponding ui_*.h files and add their location to the target's include directory.
The problem is, that I inlcude the generated "ui_*.h" file in a header of the target, which is then included in another test-target. The test-target however does not have the directory with the generated files set to its include directories and therefore will not find the ui_*.h file.
So is there any way to get the directory of the generated files so I can add it to the INTERFACE_INCLUDE_DIRECTORIES of my first target. When I do this using hardcoded names It solves my compile errors, but I would rather do this by getting that directory from some target property or so. I failed with that because the AUTOUIC include dirs seem to be added only after processing all the CMakeLists files.
Btw., I am currently using CMake 3.8.2, but updating to 3.9 is an option if the problem has been solved there.
From CMake version 3.9 onwards you can use the following snippet to add the autogenerated headers to a target's build interface include directories:
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig)
set(AUTOGEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_autogen/include_$<CONFIG>)
else()
set(AUTOGEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_autogen/include)
endif()
target_include_directories(${TARGET_NAME} INTERFACE
$<BUILD_INTERFACE:${AUTOGEN_INCLUDE_DIR}>
)
See:
Use GENERATOR_IS_MULTI_CONFIG to detect multi-config generators
AUTOUIC
GENERATOR_IS_MULTI_CONFIG
AUTOGEN_BUILD_DIR
I have the same issue - it looks like a bug in CMAKE (I'm using version 3.10 rc5)
and have opened a bug report to CMAKE here: https://gitlab.kitware.com/cmake/cmake/issues/17456
In the meantime you can copy the autgenerated header files to your project source directory by using the following commands after autouic has been run.
SET(AUTOGEN_BUILD_DIR "${CMAKE_BUILD_DIR}/<project>_autogen/include_${CONFIG}")
file(COPY "${AUTOGEN_BUILD_DIR}/ui_xxxx.h" DESTINATION "${CMAKE_SOURCE_DIR}/headers")
where ${CONFIG} is the type of build (Debug/Release)

Can I manually use CMake's cpp file dependency-scanner in my cmake code?

I am trying to add a custom target with CMake that executes one command for each given .cpp file. The command should only be re-executed when the source file itself or one of the included source files changes. AFAIK to achieve this I need a list of all the included files and add them to the DEPENDS option of the add_custom_command() calls that belong to my custom target.
So is there a built-in way to get that list of included files?
I know about the IMPLICIT_DEPENDS option of the add_custom_command() function but it only works for Makefile generators. I would like to make this work for all generators.
Thank you for your time
Edit:
As requested I will post some cmake code to show what I want to achieve.
I want to add a custom target, that runs clang-tidy on all the given .cpp files. When incrementally building the custom target the clang-tidy commands should be re-run whenever a .cpp file or one of its directly or indirectly included header files is changed. Just like re-runs of the compiler are handled.
# ----------------------------------------------------------------------------------------
# mainTargetName The name of the target that shall be analyzed
# files A list of all the main targets .cpp files
#
function( addStaticAnalysisTarget mainTargetName files )
set(targetName runStaticAnalysis_${mainTargetName})
set(command "clang-tidy-4.0 -checks=* -p ${CMAKE_BINARY_DIR}")
foreach( file ${files} )
get_filename_component( baseName ${file} NAME_WE)
set(stampFile ${CMAKE_CURRENT_BINARY_DIR}/analyze_${baseName}.stamp )
set(fullFile ${CMAKE_CURRENT_SOURCE_DIR}/${file})
set(commandWithFile "${command} ${fullFile}")
separate_arguments_for_platform( commandList ${commandWithFile})
add_custom_command(
OUTPUT ${stampFile}
DEPENDS "${fullFile}"
IMPLICIT_DEPENDS CXX "${fullFile}"
COMMAND ${commandList}
COMMAND cmake -E touch "${stampFile}" # without creating a file as a touch-stone the command will always be re-run.
WORKING_DIRECTORY ${CPPCODEBASE_ROOT_DIR}
COMMENT "${commandWithFile}"
VERBATIM
)
list(APPEND stampFiles ${stampFile})
endforeach()
set_source_files_properties(${stampFiles} PROPERTIES GENERATED TRUE) # make the stamp files known to cmake as generated files.
add_custom_target(
${targetName}
DEPENDS ${stampFiles}
)
endfunction()
The problem with that is, that it does not seem to work. When I change included files clang-tidy is not re-run for the affected files.
I used the "Unix Makefile" generator for this example so it should work at least with make. Any hints why it doesn't?
My hopes where that I could achieve the desired behavior for all generators by somehow getting the file-dependencies at cmake time and then adding them to the ''''DEPENDS'''' list. But the dependency scanning must be done each time the command is run, so it can not be done at cmake time. This means that the scanning must be implemented by cmake which it currently is not.
A guy with similar problems:
https://gitlab.kitware.com/cmake/cmake/issues/16830
Edit 2:
I think the problem that the IMPLICIT_DEPENDS option was not working was because I did not use correct filenames. I changed that in the code snipped, but I have not yet tested if it works in the project.
I think the answer to my question is ...
No, you can not use cmakes dependency scanner in the cmake code.
That makes sense, because this problem can not be solved at cmake time, because the dependencies of a .cpp file may change without cmake being re-run.
The problem must be solved within cmake itself at make time. This is done when using the IMPLICIT_DEPENDS option.
Also, I tried to solve a Problem that I did not really have, because at this point I can only run clang-tidy on linux anyways. However, clang-tidy may become available on windows as well and then I may have the problem again.
To sum the comments up:
Tambre stated that CMake is not a compiler and therefore can not do that.
I think this is wrong. According to this article, CMake can parse cpp include dependencies because make has no such dependency searcher itself. That was news to me, but I mostly live on Windows so I am not that familiar with make. It could also be possible that in the meantime make was extended to do its own dependency searching. Also this explains why the IMPLICIT_DEPENDS option is only available for make.
Florian pointed out that it is not necessary to create an own custom target for running clang-tidy. Instead, one can use the CXX_CLANG_TIDY target property to run clang-tidy for each file after compiling it. This means however, that static-analysis can not be separated from the build which could lead to inacceptable buildtimes.
There is the cmake -E cmake_depends command line, that could be used to retrieve dependencies at cmake time. But as stated above, I erroneously thought that I needed the dependencies at cmake time, while I needed them at runtime.
The IMPLICIT_DEPENDS options did not work because I had an error in my cmake code.

CMake with Xcode: configured header file (.h.in) not found

I'm working through the CMake tutorial and I'm up to the Adding a Version Number and Configured Header File section. Unfortunately Xcode isn't recognising the generated header file:
The error:
The header file was generated by CMake ok:
TutorialConfig.h.in
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR #Tutorial_VERSION_MAJOR#
#define Tutorial_VERSION_MINOR #Tutorial_VERSION_MINOR#
CMakeLists.txt
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}/src")
# add the executable
add_executable(Tutorial src/tutorial.cpp)
This is the tutorial I'm working from.
I don't use Xcode, but another IDE that's Linux based. But maybe I can help you a bit. I'm just wondering -- does your program compile? That's perhaps more important.
My IDE often complains about header files such as your's -- that is, configuration files that are generated by CMake. Such warnings (at least for me) can be ignored. I usually do because my build/ directory is sometimes empty. So when I've opened up the source file, there wouldn't be TutorialConfig.h yet.
In fact, the IDE can never know about such header files. That's because it doesn't know which build/ directory you're going to compile your program in.
If you are worried by the warning, then there is probably a place where you can specify to Xcode which build/ directory to search for header files. That will remove the warning, after you've run CMake once. However, removing such a warning is unreliable because you can always build in another directory that would have TutorialConfig.h missing.
Hope this helps!
Oh, haha. I changed #include "src/TutorialConfig.h" to #include "TutorialConfig.h" and all is well. I figured it out by checking out the project settings: