I'm working on a library that links another library to use its static functions.
Everything was working perfectly until I switched from including all my code in the header file to sharing it between the .h and .cpp file.
I tried to use ./configure --prefix="<same path as before>" and then make install but ended up with a "/usr/bin/install: cannot stat .libs/<library name>.so.0.0.0': No such file or directory" error. (also, I did change my makefile to accommodate for the inclusion of the .cpp file)
Then, trying to compile my old library (which should've still worked since the linked library didn't make install correctly and was still technically using the older version) I get a pile of errors that seem to have to do with c++ itself. For example:
.../gcc/4.9.1/linux64/include/c++/4.9.1/bits/stl_bvector.h:354:13: error: expected ';' at end of member declaration
There are an absolute ton of errors similar to the one above, all having to do with issues in the path .../gcc/4.9.1/linux64/include/c++/4.9.1/
Has anyone run into this error before? Let me know if I need to provide any more information, it's just that I've never had this happen so I'm at a loss as to where to proceed. It's likely something simple I'm missing but the longer I stare at it the less it makes sense.
Thanks!
Update: I ended up solving the issue I was having. Basically, the .so file was not being accessed, so I used make clean and then the linked library compiled properly. Next, the issues with the base library was just an extra character within a header file that was causing the compiler to blow up with over 1500 lines of errors. After fixing that, it was able to link up properly and is working fine now.
I'm writing a set of unit tests, and creating stubs for classes that the unit test needs to compile and link. I would like to know whether the real header is being included, or the fake(stub) header is being included for these headers that I'm tying to stub out.
Any ideas on how to test this?
Nevermind, I found a solution. You can simply put the following in the fake header:
#pragma message ("Mock is being included")
and that will be printed when compiling, so you know which header is being #include'd.
If you have access to GCC/G++, use the -M option.
If you use Visual Studio: Go to Project Settings, then Configuration Properties, then C/C++, then Advanced, then Show Includes. It activates the compiler switch /showIncludes.
Both will output the dependency list at compile time.
Better than having to modify header files....
Note: I am new to c++. I had an existing solution with multiple projects that I was able to create a new project/.cpp file and include the .h file successfully(ie, compile and run the executable as expected) in one of the application's lower level files/projects. However, when I include the header for my file at the top level .cpp file/entry point for the application, several syntax errors are returned regarding log4cpp/category.hh.
After some searching I it seems it might be caused by a conflict between log4cpp and boost (I have 1.55) based on some SO questions. The existing solution has the log4cpp includes, and my .h/.cpp has the boost\filesystem.hpp include.
When I open category.hh, the errors point to 2 lines, each with 'Priority::ERROR'. The errors include "'constant': illegal token on right side of ::" and "function does not take 0 arguments".
Looking at Priority.hh, they have a typedef enum {} for various levels of priority. When I hover the cursor over each enum, all of them have an associated integer value except for ERROR.
What is strange to me is that the file I originally included my header in also has the log4cpp #includes, and does not throw any errors. The two locations are in different projects however.
With my knowledge of c++ I'm just not sure of how to go about resolving/debugging this. Is there a certain project property/setting I need to look for that would cause it to fail in one project but not the other? Any help is greatly appreciated.
while programming in c++,
Most of the times i get 'some symbol' has already been defined
see previous definition of 'some symbol'
I think this happens because improper order of headers file included.
How can i find out all the definitions of 'some symbol'
Thanks in advance,
Uday
EDIT:
I am using visual studio
I remember some command some thing like dumpbin /exports (I dont remember exactly) to get all the definition
That usually happens due to a couple of common problems:
you are redefining the same symbol
you are including a header file many times and it does not have include guards
you are incorrectly forward declaring with an incompatible type and then including
I would start trying to fix the second. Make sure that all headers have include guards so that if you include them from different places it won't try to redefine the symbols:
#ifndef HEADER_FILE_NAME_GUARD // or something alike
#define HEADER_FILE_NAME_GUARD
// rest of file
#endif
If you need to order your includes then you will run into troubles later, make sure that you can and do include all your dependencies at all places. (Or forward declare if you can)
Full-text search is the most cross-platform cross-environment and efficient technique for that.
Translating C++ into an executbale has two steps. In step one, the compiler works linearly through the inputs (typically .cpp files and the headers they include). In step 2, the linker combines the results from step 1.
From your description of "symbol defined before", I conclude the problem must occur within a .cpp file, as those are processed linearly. dumpbin /exports works on the output of step 1, which you probably won't have. Header inclusion could be the culprit, as that's an early phase of compilation. You want the preprocessed input. IIRC, you can get that with the /EP switch.
If you're using Visual Studio with Visual Assist installed, alt-G will pop up a list of all places where something is defined.
If you're using Visual Studio with Visual Assist installed, you'd better press Alt+X then D to see all the references to the symbol
If you need to order includes, it is an indication of 'Code Smell' in the first place. Most probably, your code is not designed well enough. All your common code should be part of a separate package/dll/lib(whatever) and should be included/linked from there.
If you are in C++/VC++, this normally happens when you include cpp & h files directly from other projects instead of linking to a utility library of some sort.
As somebody already pointed out, if you have to live with it, text search is the best option but try re-designing the code in a better way (if you can).
Generally I just grep the header files.
I am working on a large C++ project in Visual Studio 2008, and there are a lot of files with unnecessary #include directives. Sometimes the #includes are just artifacts and everything will compile fine with them removed, and in other cases classes could be forward declared and the #include could be moved to the .cpp file. Are there any good tools for detecting both of these cases?
While it won't reveal unneeded include files, Visual studio has a setting /showIncludes (right click on a .cpp file, Properties->C/C++->Advanced) that will output a tree of all included files at compile time. This can help in identifying files that shouldn't need to be included.
You can also take a look at the pimpl idiom to let you get away with fewer header file dependencies to make it easier to see the cruft that you can remove.
PC Lint works quite well for this, and it finds all sorts of other goofy problems for you too. It has command line options that can be used to create External Tools in Visual Studio, but I've found that the Visual Lint addin is easier to work with. Even the free version of Visual Lint helps. But give PC-Lint a shot. Configuring it so it doesn't give you too many warnings takes a bit of time, but you'll be amazed at what it turns up.
There's a new Clang-based tool, include-what-you-use, that aims to do this.
!!DISCLAIMER!! I work on a commercial static analysis tool (not PC Lint). !!DISCLAIMER!!
There are several issues with a simple non parsing approach:
1) Overload Sets:
It's possible that an overloaded function has declarations that come from different files. It might be that removing one header file results in a different overload being chosen rather than a compile error! The result will be a silent change in semantics that may be very difficult to track down afterwards.
2) Template specializations:
Similar to the overload example, if you have partial or explicit specializations for a template you want them all to be visible when the template is used. It might be that specializations for the primary template are in different header files. Removing the header with the specialization will not cause a compile error, but may result in undefined behaviour if that specialization would have been selected. (See: Visibility of template specialization of C++ function)
As pointed out by 'msalters', performing a full analysis of the code also allows for analysis of class usage. By checking how a class is used though a specific path of files, it is possible that the definition of the class (and therefore all of its dependnecies) can be removed completely or at least moved to a level closer to the main source in the include tree.
I don't know of any such tools, and I have thought about writing one in the past, but it turns out that this is a difficult problem to solve.
Say your source file includes a.h and b.h; a.h contains #define USE_FEATURE_X and b.h uses #ifdef USE_FEATURE_X. If #include "a.h" is commented out, your file may still compile, but may not do what you expect. Detecting this programatically is non-trivial.
Whatever tool does this would need to know your build environment as well. If a.h looks like:
#if defined( WINNT )
#define USE_FEATURE_X
#endif
Then USE_FEATURE_X is only defined if WINNT is defined, so the tool would need to know what directives are generated by the compiler itself as well as which ones are specified in the compile command rather than in a header file.
Like Timmermans, I'm not familiar with any tools for this. But I have known programmers who wrote a Perl (or Python) script to try commenting out each include line one at a time and then compile each file.
It appears that now Eric Raymond has a tool for this.
Google's cpplint.py has an "include what you use" rule (among many others), but as far as I can tell, no "include only what you use." Even so, it can be useful.
If you're interested in this topic in general, you might want to check out Lakos' Large Scale C++ Software Design. It's a bit dated, but goes into lots of "physical design" issues like finding the absolute minimum of headers that need to be included. I haven't really seen this sort of thing discussed anywhere else.
Give Include Manager a try. It integrates easily in Visual Studio and visualizes your include paths which helps you to find unnecessary stuff.
Internally it uses Graphviz but there are many more cool features. And although it is a commercial product it has a very low price.
You can build an include graph using C/C++ Include File Dependencies Watcher, and find unneeded includes visually.
If your header files generally start with
#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#endif
(as opposed to using #pragma once) you could change that to:
#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#else
#pragma message("Someheader.h superfluously included")
#endif
And since the compiler outputs the name of the cpp file being compiled, that would let you know at least which cpp file is causing the header to be brought in multiple times.
PC-Lint can indeed do this. One easy way to do this is to configure it to detect just unused include files and ignore all other issues. This is pretty straightforward - to enable just message 766 ("Header file not used in module"), just include the options -w0 +e766 on the command line.
The same approach can also be used with related messages such as 964 ("Header file not directly used in module") and 966 ("Indirectly included header file not used in module").
FWIW I wrote about this in more detail in a blog post last week at http://www.riverblade.co.uk/blog.php?archive=2008_09_01_archive.xml#3575027665614976318.
Adding one or both of the following #defines
will exclude often unnecessary header files and
may substantially improve
compile times especially if the code that is not using Windows API functions.
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
See http://support.microsoft.com/kb/166474
If you are looking to remove unnecessary #include files in order to decrease build times, your time and money might be better spent parallelizing your build process using cl.exe /MP, make -j, Xoreax IncrediBuild, distcc/icecream, etc.
Of course, if you already have a parallel build process and you're still trying to speed it up, then by all means clean up your #include directives and remove those unnecessary dependencies.
Start with each include file, and ensure that each include file only includes what is necessary to compile itself. Any include files that are then missing for the C++ files, can be added to the C++ files themselves.
For each include and source file, comment out each include file one at a time and see if it compiles.
It is also a good idea to sort the include files alphabetically, and where this is not possible, add a comment.
If you aren't already, using a precompiled header to include everything that you're not going to change (platform headers, external SDK headers, or static already completed pieces of your project) will make a huge difference in build times.
http://msdn.microsoft.com/en-us/library/szfdksca(VS.71).aspx
Also, although it may be too late for your project, organizing your project into sections and not lumping all local headers to one big main header is a good practice, although it takes a little extra work.
If you would work with Eclipse CDT you could try out http://includator.com to optimize your include structure. However, Includator might not know enough about VC++'s predefined includes and setting up CDT to use VC++ with correct includes is not built into CDT yet.
The latest Jetbrains IDE, CLion, automatically shows (in gray) the includes that are not used in the current file.
It is also possible to have the list of all the unused includes (and also functions, methods, etc...) from the IDE.
Some of the existing answers state that it's hard. That's indeed true, because you need a full compiler to detect the cases in which a forward declaration would be appropriate. You cant parse C++ without knowing what the symbols mean; the grammar is simply too ambiguous for that. You must know whether a certain name names a class (could be forward-declared) or a variable (can't). Also, you need to be namespace-aware.
Maybe a little late, but I once found a WebKit perl script that did just what you wanted. It'll need some adapting I believe (I'm not well versed in perl), but it should do the trick:
http://trac.webkit.org/browser/branches/old/safari-3-2-branch/WebKitTools/Scripts/find-extra-includes
(this is an old branch because trunk doesn't have the file anymore)
If there's a particular header that you think isn't needed anymore (say
string.h), you can comment out that include then put this below all the
includes:
#ifdef _STRING_H_
# error string.h is included indirectly
#endif
Of course your interface headers might use a different #define convention
to record their inclusion in CPP memory. Or no convention, in which case
this approach won't work.
Then rebuild. There are three possibilities:
It builds ok. string.h wasn't compile-critical, and the include for it
can be removed.
The #error trips. string.g was included indirectly somehow
You still don't know if string.h is required. If it is required, you
should directly #include it (see below).
You get some other compilation error. string.h was needed and isn't being
included indirectly, so the include was correct to begin with.
Note that depending on indirect inclusion when your .h or .c directly uses
another .h is almost certainly a bug: you are in effect promising that your
code will only require that header as long as some other header you're using
requires it, which probably isn't what you meant.
The caveats mentioned in other answers about headers that modify behavior
rather that declaring things which cause build failures apply here as well.