Clang-Tidy can't find my header files - c++

new to clang and clang-tidy here.
I have a project with this type of structure:
project/
- build/
- cmake/
- component1/
- src/
- someFile.cpp
- someFile2.cpp
- someFile.hpp
- someFile2.hpp
- component2/
- etc...
-
When I use clang-tidy to go through all the files in project/component1/ with this command: clang-tidy project/component1/src/* -checks=-*,clang-analyzer-*,-clang-analyzer-alpha*
It ends up throwing an error like this:
$HOME/project/component1/src/someFile.cpp:18:10: error: 'project/component1/someFile.hpp' file not found [clang-diagnostic-error]
\#include "component1/someFile.hpp"

This answer will only help you if you use CMake to manage your project.
CMake has an option to create a .json file that contains all the compiler calls with command line options. This file can be given to clang-tidy with the option:
-p <build-path> is used to read a compile command database.
For example, it can be a CMake build directory in which a file named
compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
CMake option to get this output). When no build path is specified,
a search for compile_commands.json will be attempted through all
parent paths of the first input file . See:
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an
example of setting up Clang Tooling on a source tree.
As the documentation states, you have to set the CMAKE_EXPORT_COMPILE_COMMANDS variable to generate the .json file with CMake and then pass the CMake output directory to clang-tidy.
Clang-tidy will then get the include paths from the commands in the .json file.

I tell clang-tidy to search for them using plain compiler includes, but they have to be introduced after a double dash (--). It also took me a while to discover it, since it is not included in the --help:
clang-tidy -checks='...' <source0> ... -- -Iblabla/ ...
Reading again the options, you coult try -extra-arg= parameter, but I use the double dash approax since it allows me to put all the options to give clang and clang-tidy in a single file, with no more processing than a $(cat $file) for both.
From: https://clang.llvm.org/extra/clang-tidy/#using-clang-tidy
clang-tidy is a LibTooling-based tool . You can also specify compilation options on the command line after --

Had the same problem in CMake. The problem in my case was that Clang-Tidy could not handle include directories via response files – at least in version 10.
Deactivating them solved it:
# Disable response files
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES Off)

Related

Is there "includePath" option in clangd?

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.

Compile a single file under CMake project?

I'm developing a C++ project which is going to be enclosed on a bigger one.
I've seen that on the bigger project (is a Qt application and it's being generated from qmake) I am able to compile a single file from the linux command line, just entering the relative path to the specific file as an argument to make.
On the other hand, I'm using CMake for my own project. When I modify some code for a compilation unit and I have to modify its header file, I have to wait a long time to compile its dependencies and then its own source file. But there are some situations in which I would prefer to check whether the source code in the *.cc file is compilable without errors.
Is there a way to generate a Makefile from CMake the way qmake does this? Switching to qmake is not an option anymore.
You do not have to add extra custom targets to your CMake scripts, as the Makefiles generated by CMake already contain .o targets for each .cc file. E.g. if you have a source file called mySourceFile.cc, there will be a Makefile in your build directory that defines a target called <Some Path>/mySourceFile.cc.o. If you cd into your build directory, you can use grep or ack-grep to locate the Makefile that defines this target, then cd into that Makefile's directory and build it.
E.g. suppose the command ack-grep mySourceFile.cc.o prints something like:
foo/bar/Makefile
119:x/y/z/mySourceFile.o: x/y/z/mySourceFile.cc.o
123:x/y/z/mySourceFile.cc.o:
124: # recipe for building target
Then you can build mySourceFile.cc.o by doing:
cd foo/bar && make x/y/z/mySourceFile.cc.o
CMake doesn't have a generic built-in way of doing this (it's an open issue), but if you're using the Ninja generator, you can can use a special Ninja syntax for building just the direct outputs of a given source file. For example, to compile just foo.o you would use:
ninja /path/to/foo.cpp^
Not out-of-the box. CMake does not expose those "internal" makefile rules in the main makefile.
You can do this only if you consider what kind of file structure CMake uses internally. You can e.g. for compiling a single .obj files using CMake generated makefiles call
make -f CMakeFiles/myProg.dir/build.make CMakeFiles/myProg.dir/main.cc.obj
when you have something like
cmake_minimum_required(VERSION 3.1)
project(myProg CXX)
file(WRITE "main.cc" "int main()\n{\nreturn 0;\n}")
add_executable(myProg main.cc)
To build src/foo.cpp alone:
cmake --build . --target src/foo.cpp.o
No, CMake does not offer built-in support to compile single files.
You have to add a target for each object file, maybe by a function iterating over all files of a directory.
Others have suggested ways to find the target name (ending in .cpp.o) from the .cpp filename, but if you already know the name of a target that will trigger compilation of the .cpp file and you're using ninja this suggestion should be easier.
First build the target:
ninja TriggersCppCompilationLib
Assuming your file was changed or was not yet built, ninja will print the full target name. When you see the name come up, hit enter so it is not overwritten. Then simply copy the name from the terminal (e.g. using tmux copy mode).

How to print/show included directories in CMakeList

I am trying to build a trivial proof of concept project using CMake, and I am rapidly getting tired of it - to the point that I think it may have been a better idea to handcraft my own damn Makefile.
I have a directory structure that looks something like this:
project:
/extproj
/src/file.cpp
/include/file1.h
My CMakeLists.txt file contains the following section, which I, having read the CMake documentation, rather naively believed, will be specifying the include directories for the project:
INCLUDE_DIRECTORIES (include/
extproj/sdk/math/linearalg/
extproj/sdk/math/nonlinearsolvers/
)
I am trying to build it using the following command
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} ${ALL_SOURCES}
Where ${ALL_SOURCES} is a list variable that contains all the C++ files I need to compile. I have verified that this variable contains the correct files.
I can't however, for the life of me, work out what on earth is being passed to the compiler as the include directories.
I searched online, and so a post that recommended using get_directory_properties. I tried that and of course CMake immediately failed to generate the Makefile and complained:
Unknown CMake command "get_directory_properties".
When I create a Makefile and run make on it, the compiler barfs immediately, with the error message:
/path/to/project/src/file1.cpp:1:10: fatal error: 'file1.h' file not
found
Is there ANY WAY, I can find out what on earth is being used as the include paths being passed to my compiler?
I believe the correct way to compile the source files is using
add_executable(executableName ${SRCS}. Then the directories added using include_directories(...) get passed to the compiler automatically.
If you are using a custom command to compile you need to change your CMakeLists.txt file.
set(MY_INCLUDE_DIRS_FLAGS "-Iinclude/ -Iextproj/sdk/math/linearalg/ -Iextproj/sdk/mat/nonlinearsolvers/")
set(MY_COMPILE_COMMAND ${CMAKE_CXX_COMPILER} ${MY_INCLUDE_DIRS_FLAGS} ${CMAKE_CXX_FLAGS} ${ALL_SOURCES}

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:

Use cmake to conditionally generate source input files

I'm using cmake with C++ project. I want to use precompiled headers in GCC.
I want to run cmake once and then, when running make, I want this actions to happen:
Run my custom tool (python script) on whole source tree. It generates precompiled.h headers in some subdirectories. It's purpose is to scan *.h and *.cpp for #include's and move them to common precompiled.h files.
generate GCC's precompiled headers (g++ -c precompiled.h -o precompiled.h.gch) ONLY when precompiled.h file has changed after step 1.
build outdated targets (after step 2. because I want to use .gch file)
I've managed to add dependencies, so whenever I build any target, my python script's target is executed (this is ugly, because now every target has to depend on single global_init target). Also I can modify my python script, so it doesn't modify precompiled.h when it is not necessary.
But I don't know what to do next. Is there any way to tell cmake that it should run my custom script and AFTER THAT determine if precompiled.h.gch must be created? Now it is always build (this file contains many #include's, so it takes some time). Basically:
Execute python script -> precompiled.h MAY BE updated
Examine precompiled.h timestamp and if it's newer -> build precompiled.h.gch
Standard compilation steps
I've looked in many places, but cmake's (and make's) way of calculating dependencies seems too weak to accomplish this task.
In this question:
lazy c++
compilation always happens after lazycpp is executed. This would not be optimal in my case.
The following CMake commands may serve as a starting point for your project:
add_custom_target(scanner COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scanner.py"
COMMENT "Scanning include files ..."
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
This command covers step 1. It invokes your python script which may update the existing precompiled.h files in CMAKE_CURRENT_SOURCE_DIR.
add_custom_command(OUTPUT precompiled.h.gch
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS}
-c "${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h" -o precompiled.h.gch
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h"
IMPLICIT_DEPENDS CXX "${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h")
add_custom_target(generate_precompiled DEPENDS
"${CMAKE_CURRENT_BINARY_DIR}/precompiled.h.gch")
add_dependencies(generate_precompiled scanner)
These commands cover step 2. The precompiled header is generated with a custom command which depends on precompiled.h and implicitly on other headers that precompiled.h includes.
precompiled.h.gch is generated in the CMAKE_CURRENT_BINARY_DIR directory.
Because the precompiled header generation requires precompiled.h to be updated by the python script, we add a target level dependency on the target scanner.
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
add_executable(main main.cpp)
set_target_properties(main PROPERTIES COMPILE_FLAGS "-include precompiled.h -H")
add_dependencies(main generate_precompiled)
These commands add standard compilation steps which generate an executable main. The precompiled header is included as a default header with gcc's -include switch. The CMAKE_CURRENT_BINARY_DIR which contains precompiled.h.gch is added as an include directory. gcc will pick up precompiled.h.gch from there when precompiled.h is included (see Using Precompiled Headers).
Finally the target dependency on generate_precompiled ensures that the precompiled header is updated if necessary.