I've set up CPPCheck (v1.6.1) for a large project containing a bunch of libraries.
When I check a library then I get some check failures which I'm interested in and all is well. However at this point I just have a text file list of all the *.cpp and *.h in that library which I'm passing by '--file-list=...'
Of course, I do get some errors about missing includes, because this library (say MyLibA) includes files from another one of my libraries (MyLibB).
So I now construct a text file that has all the include paths from MyLibB and pass it to cppcheck via '--includes-file=...'.
At this point I get some cpp failures about headers within MyLibB, which is not unexpected, however all the errors that were reported about MyLibA are no longer reported.
Is this a bug or am I doing something wrong?
If cppcheck runs into a #error then it aborts the check. So you can end up in the situation whereby including headers triggers a #error (if for example you haven't correctly set up your -D preprocessor defines for cppcheck on the command line).
This means that files that were checked previously will no longer get checked because the tests were aborted in the header, i.e. before the offending lines of code were reached
Related
I've been able to make a fair amount of progress in trying to add Bazel build files to enable the building of the gennorm2 tool in ICU. Here is my work-in-progress PR using the Bazel target //icu4c/source/tools/gennorm2.
I'm currently getting stuck when running bazelisk build //icu4c/source/tools/gennorm2 --verbose_failures --sandbox_debug with these errors.
They reference functions defined in urename.h. As I understand it, urename.h is also used to rename certain functions by appending a suffix with the version number (_68), but I defined a preprocessor constant U_DISABLE_RENAMING to disable that specific behavior. This only had the effect of changing the names of the undefined function names in the error output, but otherwise not changing it (ex: errors now complain of u_errorName instead of u_errorName_68).
The part that puzzles me is why the error output claims that these symbols are not found. As you can see, the target //icu4c/source/tools/gennorm2 depends on //icu4c/source/common:platform, which in turn depends on //icu4c/source/common:headers, which includes the field hdrs = glob(["unicode/*.h", "unicode/*.h",]), which should be matching
/icu4c/source/common/unicode/urename.h.
In case it helps, this is the verbose log output when running make VERBOSE=1 using the current autotools-based configure + make build on a fresh checkout of ICU.
A teammate was able to take a look and help me reason through the errors and ultimately fix them.
The first thing is to acknowledge that it is indeed a linker error, which can see by noticing the error message references the linker program ld.
This is important because we previously spent time in the wrong place by debugging the compile configs as if the problem happened during the compile phase before the linker phase. (But I learned about one way to debug compile problems is taking the raw GCC command given by --verbose_failures --sandbox_debug and replacing -c with -E and changing the argument of -o to a .txt file in /tmp to save the output what the compiler sees for that file after all the includes are recursively inlined). This means that my attempts to solve the problem by specifying preprocessor defines for the compile-phase were misguided.
The project's documentation on dependencies revealed that I had mis-specified a dependency on one of the targets to specify only the headers (//icu4c/source/common:headers) instead of the relevant definitions and headers (//icu4c/source/common:platform).
After doing that, we solved another problem that was small and interesting. The gennorm2 target depends on code to get the current year (ex: for printing out help messages that include the copyright statement with the year range). As an i18n library, ICU has code to get that, somewhere in //icu4c/source/i18n:icu4ci18n. This creates an excessive amount of code dependencies for an isolated use case (and will cause problems for follow-on work), so we replaced the block of code in gennorm2 calling those calendar year fns (ucal_open, ucal_getNow, ucal_setMillis, ucal_get, ucal_close) with the libc date library function to give us the year as a number, and added linkopts = ["-ldl"] to link in the dl date library.
I'm currently stuck on a compilation problem on Android for my app.
I get the following error during the compilation of my native library with ndk-build:
BackgroundDisplayConfiguration.h:12:23: fatal error: glm/glm.hpp:
No such file or directory
#include <glm/glm.hpp>
^
What puzzles me is that I have specified a path for this header only library in my Android.mk the following way:
LOCAL_CPPFLAGS += -I../../glm/include
and this path exists and is correct, but moreover if I mess up this path I get the same error in other files that include glm.hpp. When the path is correct, only this file yields an error, and I don't understand why. Any pointers?
EDIT: Okay, this is even more puzzling. The include option appear in every compiler command for each file, but not on the compiler command for the big wrapper generated by swig (that outputs my library_native_wrap.o), and that's where it yields an error... Well, it at least explains the observed behavior.
So I found a workaround for this, even though it doesn't feel quite right.
Indeed, I found out that when compiling every source of my library, the compiler command actually had the include option, but then, when compiling the output of swig (that big unique c++ wrapper file), the option wasn't there anymore.
I found a way to correct this by adding my include path to the LOCAL_EXPORT_C_INCLUDES.
For some reason, the LOCAL_CPPFLAGS aren't used when compiling the wrapper...
I'm trying to have Cmake check if the file cxxabi.h is available. This file is from the c++ standard library, at least with g++. My current cmake commands look like this:
include(CheckIncludeFiles)
...
check_include_files(cxxabi.h HAVE_CXXABI)
if(HAVE_CXXABI)
...
else(HAVE_CXXABI)
...
endif(HAVE_CXXABI)
When this is executed, I get:
-- Looking for include files HAVE_CXXABI
-- Looking for include files HAVE_CXXABI - not found.
Although the file is available in /usr/include/c++/4.6.4/ and can properly be found by g++ when I compile a c++ code.
I suspect the macro check_include_files uses the C compiler instead of the C++ one to compile a small program that includes the required file, which of course fails since cxxabi.h is a C++ file.
Any idea how to solve that? (i.e. making the macro use the C++ compiler instead of the C one)
As edited in my original question:
Problem solved. There is a different macro for C++ headers, check_include_file_cxx, located in CheckIncludeFileCXX.
There exists another problem with CHECK_INCLUDE_FILES that I recently discovered with MinGW. The file tested was "ddk/ntapi.h". In the CMakeErr.log for this header I got a multiply messages like "DWORD - does not name a type" and so on for all MS types used in this header. Because of this reason the compilation fails and a requested header appears as "not found", whereas it is not true.
This happens because CheckIncludeFile.cxx contains only the requested header, and some headers in MinGW (and probably in the other APIs) does not include in its body all the list of required headers to be compiled in a standalone program that CMake creates.
The solution for this problem is to add absent basic includes into the CMAKE_REQURED_FLAGS, or as a third variable of CHECK_INCLUDE_FILE_CXX:
CHECK_INCLUDE_FILE_CXX("ddk/ntapi.h" VAR "-include windows.h")
how to include certain header files by default so that i don't have to type them in every programs:
In dev c++ and code::blocks
Make a global header file that in turn includes whatever files you need in every project, and then you only have to include that single file.
However I would recommend against it, unless all your different project are very similar. Different projects have different needs and also need different header files.
You could issue a compiler directive in your project file or make script to do "per project" includes, but in general I would avoid that.
Source code should be as clear as possible to any reader just by its content. Whenever I have source code that dramatically changes its semantics, eg. by headers that are unknown to me, this can be quite confusing.
On top of that, if you "inject" those headers for certain compilation units that don't need them, that will negatively impact compile time.
As a substitution, what about introducing a common.h/hpp header that includes those certain header files? You can then include your common header in all files that need them and change this common set of headers for all depending files at once. It also opens the door to use precompiled header files, which may be worth a look for you.
From GCC documentation (AFAIK GCC is default compiler used by the development environment you are citing)
-include file
Process file as if #include "file" appeared as the first line of the primary source file. However, the first directory searched for
file is the preprocessor's working directory instead of the directory
containing the main source file. If not found there, it is searched
for in the remainder of the #include "..." search chain as normal.
If multiple -include options are given, the files are included in the order they appear on the command line.
-imacros file
Exactly like -include, except that any output produced by scanning file is thrown away. Macros it defines remain defined. This allows you
to acquire all the macros from a header without also processing its
declarations.
All files specified by -imacros are processed before all files specified by -include.
But it is usually a bad idea to use these.
Dev c++ works with MingW compiler, which is gcc compiler for Windows. Gcc supports precompiled headers, so you can try that. Precompiled headers are header files that you want compiled and added to every object file in a project. Try searching for that in Google for some information.
Code::blocks supports them too, when used with gcc, even better, so there it may even be easier.
If your editor of choice supports macros, make one that adds your preferred set of include files. Once made, all you have to do is invoke your macro to save yourself the repetitive typing and you're golden.
Hope this helps.
Suppose I have files a.cpp and b.cpp and I get warnings in a.cpp and an error in b.cpp. I fix the error in b.cpp and recompile -- since Visual Studio doesn't have to recompile a.cpp, it doesn't remind me of the warnings it found before.
I'd like to somehow have the warnings persist; however, I don't want it to treat warnings as errors (I'd like it to still compile/run even with warnings). Is this possible?
You could go into the project settings and set all warnings as errors in the C/C++ tab (category: General).
Essentially, you're out of luck. The C++ compilation will discard all of the errors and warnings. Because it only recompiles .CPP files that have a missing .OBJ file (i.e. the ones that had errors and failed last time), you'll only see the errors.
You have a few options. Off the top of my head:
Write a macro that responds to the build complete event. If it sees any warnings, it could delete the .OBJ file. The .CPP file would be compiled again next time. Unfortunately, this means that your program may not run without recompilation.
You could write a macro that works the other way: on build start, look to see if there are any warnings, and then delete the .OBJ file.
Write a VS addin that remembers warnings until the .CPP file is compiled again.
As Hernan already said, add a custom build step that makes a copy of the intermediate file that contains the build results (warnings). Not sure how to do naming for this, but you could create a bat file that gets called as a custom build step.
Why you would want to save warnings is beyond me. Treat them as errors, or ignore them or pragma/disable them.
Rebuild your project or recompile only the a.cpp file. Warnings are output by the compiler, so you won't get warnings for files not included in the current compilation.
You can save your current build output going to the Output pane and pressing Ctrl+S (defaults to output-build.txt if I don't remember bad.)
In your project settings I think build output messages can be saved on files. Check it and tell your results.
Cheers
Given that you don't want to recompile the files that cause the warning, one option you might have is to write a small utility that filters the output of the compiler for warnings and writes them to the .cpp file as a //TODO comment.
Then the IDE will place them in the todo list.
I'm not aware of anything that does this out of the box, but it probably wouldn't be too difficult to whip up.
If you don't want the utility mucking around with the actual source files (and I'm not sure I would), you might want to have it write the //TODO comments to a dummy 'todo.cpp' file and have that file in the project. Then they'll show up in the todo list and since the file is nothing but comments, it won't affect the build. Just make sure the utility is smart about not adding duplicates to the list. A macro could be written to take you from the todo.cpp line to the corresponding actual location of the warning.
I'd strongly recommend running with warnings as errors as much as possible, and certainly in all the code you're writing yourself. It is way eaiser to fix the warnings here and now, than wait until later and try to do them all in one pass.
There are several reasons why you want to run with warnings as errors:
The majority of warnings actually indicate that there is a problem with your code.
If you have a lot of warnings, you won't notice if a new one appears in the middle. I've seen this happen a lot.
If there is a warning which you think is bogus or you for some reason just can't fix it right away, you can switch it off. Use the /w option or suitable #pragma. Note that you can switch it of for only a particular file, or even in a particular place in your code. If you still want a notice when compiling, but a #pragma message there.
If there is code which is outside of your control, but you just have to compile it into your program, switch of warnings for that particular module or source file, or even run it without /WX. Chances are you aren't modifying the code anyway, so point 2 is probably not so relevant.
I really cannot see any valid reasons for not running with /WX (or -Werror).