I have a C program which uses a small part of the Gandalf C Machine Vision Library. There are thousands of source files. Some are includes (both .h and .c) and some are dependent in the linker stage.
I don't want to have a monolithic library. I would like to include in my source tree only the include and source files that are required. My test project is in VS2010, but I'm open to all options.
Is there a tool that I can use to detect both the include and source file dependencies?
This question is the closest I could find, but it's asking only to find all header file dependencies:
Automatically discovering C dependencies
Klocwork has an On-the-Fly source code analysis product which can figure out redundant and unused header file. Have a look to see if it fulfills your requirements.
I have used checkheaders to find redundant #include's in the past and it's free.
As for source (object) file dependencies, this is a hard problem to solve. I have trolled the corners of the internet to find such a tool but to no avail. This question summarises one way you could do it by writing your own tool.
Related
I am building a small library of my own *.c & *.h files and am not sure how I should manage them, especially when including them into a project. I'm using Codeblocks on Ubuntu in case that matters. For each .c/.h file pair, I have a Codeblocks project that is a playground where I can modify & test out any changes or newfound bugs.
I'm thinking I should compile the .c into libraries (.a/.so), put them into respective custom 'XXX/bin' and 'XXX/include' folders, and include/link from those locations (add to the PATH).
The other option (which I've been doing for right or wrong) is to add the .c file directly to my project and #include the full path of the .h file (I know this is wrong, but it works).
How do you all manage your .c and .h files?
Actually, both ways (prepare object files and use headers with them when compile program, and add source code and headers to each project with full or relative path) are quite normal. You should choose a way that is convenient for you. I do not know how Codeblocks works, but I suppose that as most IDE it can support dependencies, optimize build time and rebuild libraries (components of complex project) if some files were updated.
My suggestion is to consider some project build tools (project makers) like cmake. You will be able to configure building process for any project and to use different compilers, as well as different compiling options for different projects, while source files (*.c and *.h) storage is unchanged.
Start from cmake tutorial and other documentation
Of course, at first it will be not easy to deal with the makefile syntax, but when you get used to it you will realize how much it's convenient.
I think it is possible to include headers from their exact source, on a linux platform at least.
assume that you put your *.h in /usr/include you can just use
#include "/usr/include/*.h"
w/o moving your source files you can add the same chunk of code to every new sources you write, but VolAnd's above mentioned suggestions are probably more standard ways of managing.
Recently I have been working with the TIVA C series launchpad board which has a Cortex-M4 chip on it. I use the Code Composer Studio as my IDE.
There is a lot of confusion going on right now because through trial and error I see that in order to use certain functions that the chip manufacturer provides, I will need to include the .c file instead of including the .h file.
This caught me off guard and I admit that I am not an expert programmer or an expert when it comes to compiler design. But does anyone know why a compiler would need the .c file instead of needing the .h file?
The .h file is still being used since it has definitions in it that the .c file requires.
Perhaps a better question may be this:
When there is a .h file and a .c file, do you include the .c file in your code or do you include the .h file?
My trial and error exercise is telling me that you must include the .c file but I am totally in the blind on what the actual rules are.
Sorry if any part of this is too vague. I would be totally fine with sharing my main.c file so you can see how I included the files but I felt that my question is more of a question regarding what the general rules are for including files when there is both a .h and a .c file.
Thank you for any time you can give me in helping me understand this issue.
EDIT: Why the down votes? I thought coming here for help was what this place was about?
It is important to understand that substantially all C programs are built from multiple source files. Under some circumstances many of those sources are pre-compiled into one or more libraries, but it is quite common that building a C program will involve also building multiple C source files and linking those to each other and to appropriate libraries to produce the final result.
It is also important to understand that although C permits multiple compatible declarations of functions and file-scope variables, it permits only one definition of each distinct function or variable anywhere in an entire program. This is the primary reason for the convention of placing declarations into header files (ordinarily named with a .h extension). Any number of source files that contribute to a given program may #include the same header file, but at most one of them could #include the source file that contains the corresponding definitions, and then only if that file were not included directly in the build.
It may be possible to write your main source file so that it #includes the .c files containing all the needed definitions directly, in which case it is not necessary to include the headers, but you cannot have two separate source files doing that contribute to the same program if that produces duplicate function definitions. Ultimately, too, this approach may fail, for there can be limits on how large and complex a source file a given compiler can manage.
If there are header files accompanying the chip manufacturer's C source files, then your own source files should include only those headers. You should be able to build object files from such sources just fine. To build executable programs, however, you must also build the chip manufacturer's C sources, and link them to your own. It would be sensible to create a library containing the chip manufacturer's sources and to link that, but it would also work to build the needed source files directly for every program. Your IDE should have support for both options.
I came onto a project that employs the method of using a header file MyProject.h that has all the headers of each .c file. Each .c file has their own header file that has #include "MyProject.h", whatever libraries are needed, and any other declarations necessary for the file.
To me it seems redundant and somewhat unnatural, but it compiles and subsequently runs as expected. My thought is that the compiler would be doing way more work than necessary and is possibly over-bloating the .exe. What are the disadvantages, if any, to doing this?
A subsequent question I have is, say I included a library like Time.h in one file using the above example. Will the compiler only build Time.h once into the binary or for every file now because of MyProject.h? What about with structs, enums, etc...?
To have such a header file is poor practice and bad design. The problem is that it will create a tight coupling dependency between every single file of your project, even if they are completely unrelated.
Good program design is to create autonomous modules that only include the resources they are using. They should do this from their own h files, to document exactly which dependencies a particular module has.
The main downside is increased build times. Every source file includes every header of the project, whether it needs it or not.
It's also conceptually unclean. A source file should include the headers it needs. It should be possible to search for a header's name to find the parts of the source code that uses these facilities. Minimizing unnecessary includes is evidence of a loosely coupled system. However, include-what-you-use is hard to enforce, because you cannot prevent transitive availability of facilities through headers in C.
It should not lead to increased executable size. Even if the headers contain code (which is rare in C, but common in C++), the linker should eliminate duplicates and remove unused code.
All previous answers were clear enough, but.
The main disadvantage of "one big header file" is the problem with code reusability. For example, you've created some module as a part of your application. Let's say, this module implements API for some hardware. And then you want to make another application, which should use this module.
In this case you have to remember which header files you have to include to compile this module, or, if you just copy your previous "big header file", it requires a lot of unnecessary third party libraries and header files.
Nobody wants to spend a lot of time to make some module working. It's much better if you can use it right out-of-the-box, isn't it?
Most of my libraries have one precompiled header containing external includes and one "main" header for each library that contains the precompiled header items + all the .h files for the library in question. All of my .cpp files first include the precompiled header and then the main header.
That's it. None of my other .h files have any includes in at all. My .cpp files only include these two headers. Other libraries that need to use the library will #include that same main header.
Doing this has greatly simplified header file headache/complexity issue for me though I would add that most of my libraries are relatively small in the grand scheme of things. I don't know if this would work for a very large (monster) project. Perhaps not.
The way this works is actually quite nice. Others above, concerned about "coupling" want to minimise it, but if you don't include any headers at all you're 100% uncoupled, even from your dependencies. If you want to reuse the class, use the library that contains it.
Simple.
I am learning C programming language. To understand clearly how big projects are written in C. I browsed few Trending C projects on Github. This is project written in C: Here. One thing i don't understand is why there are so many folder in the project directory: bin, conf, contrib, docs, images, m4, man, notes, etc. The only folders i understand is src folder, which has all the header files and c files. But there is still one more doubt related to source folder. Every header file has a C file with same name. I can compile main file but how are main.c file linked to other C files. I guess the other C files has all the function defintions & main file is calling them. main.c has called header file which has all the fucntion prototypes. I am now little bit confused b/w these big projects management. Please help me to understand. Also where to read about it so i can learn this stuff.
What actually i want to ask is: If I have 5 files
main.c , header.h , function1.c, function2.c, fuction3.c. How can i use 3 functions written in these 3 function1,2,3.c files.
I want to learn how to built a big project and manage that in different files and the way files are arranged on GIT. Even if i create a project i'll write 1000 lines in same .c file which is a total mess. I want to learn how to manage this clearity and arrangement of projects. Where to learn all this?
One thing i don't understand is why there are so many folder in the project directory: bin, conf, contrib, docs, images, m4, man, notes, etc.
Because a piece of software does not only consist of source code. A lot of supplementary stuff is required:
the documentation (in /man and docs);
build scripts (usually for the de facto standard Unix configuration tools "autoconf", "automake", "M4" and "make", located in the conf and/or m4 folder);
resources that are used by the GUI if the program has one (/images);
etc.
I can compile main file but how are main.c file linked to other C files
Using a piece of software called the linker. A lot of compilers (including the popular GCC and Clang toolchains) invoke the system linker by default (unless you tell them that they should only compile but not link) which in turn resolves the references between the source files and creates the final executable. Read more about the C compilation process here.
I want to learn how to built a big project and manage that in different files and the way files are arranged on GIT. Where to learn all this?
Unfortunately, there's no single place you can gather all the wisdom from. You will need to use Google a lot, read the documentation and manuals and tutorials for build systems like make and version control systems like Git, etc.
However, I've found for you a relevant Stack Overflow question that should help get you started: How to split a C program into multiple files?
I will put my two cents here.
About this source files:
As You probably already know there are header files (.h) which contains function declarations, you need to #include such file to be able to use functions from within, BUT if you take a peek inside one of such header files you'll notice that there are ONLY declarations, without definitions.
The .c files solves this mystery:
If you have file function.c with some functions inside and want use this functions in, say, main.c file you need to create header file for that: function.h which will contain declaration (prototypes) of that functions from function.c file. You also need to #include this header in function.c file if i recall correctly.
Then you can #include such header to your main.c file and use this functions.
About code organization:
There are some best practices and methods for organization of code and project managements. Also sometimes IDE used by developer has some particular way of organizing projects.
Just for clarification: git itself doesn't enforce any particular organization
A friend at work told me today that
It is a known convention to not add header files to the project file in C project.
I was shocked and couldn't find any logical reason for this(because I felt that this convention would just make it difficult to reach the file I need).
He explained it as that the H file doesn't really contain compilable C code, so it is not "part of the project", but just meta data.
FYI - we work currently on an embedded project.
For example - project file could be - eww file with IAR workbench, or vcxproj in visual studio, or cproject file with eclipse
Does any one ever encountered this kind of convention, and could say how popular is it and what is the practical advantage/logic of it?
I don't believe this is a convention. Header files describe the interfaces between parts of your program, which I would argue is more important than the specific bits of code for many projects. If you move into C++, you may also find significant portions of the project's code implemented in headers to support templates in older C++ versions.
Your IDE is meant to keep the code you're using front and center, so you can access the source that you need and edit any code while minimizing context switching.
My advice: Add the headers to your project, but categorize them in a separate folder, filter group, or other mechanism to make them easy to access. Make sure they're visible to the compiler, set their build targets to not compile (since they're just being included) and you should be set.
There are no disadvantages of adding a header file to the project.
Some advantages I find:
If I create 'Source Files' , 'Header Files' etc folders and and add the respective files to the folder,it looks neat when you open the project in your IDE as I can directly see what are the header files being used in my project (which most of the times are created by you)
In some IDEs (eg MSVC) , I can search the header file directly using the search window if that header file has been added to the project.Otherwise I need to open one of the C/C++ files which includes this header and has to open the file from the line where #include is defined for that file.
So it is upto you , whether you need everything organized . depending your IDE etc , you can add/exclude header files to the project.
Hope this helps.
The only reason I can think of to not include .h files in your project file is if they aren't a part of your project. For example stdio.h. I have seen people do this before and it can cause problems. The main issue is that is can make your project non-portable. It can also lead to people accidentally modifying files that they shouldn't.
Is it possible that's what your friend was talking about?
Based on your comments, looks like one counter-example is enough to show that .h files are sometimes included in project files. Here's an example of a Qt qmake .pro file for a project, which lists header files:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.c \
module.c
HEADERS += \
module.h
To get that, I used Qt Creator first to create the project as "plain C project", then generated the module.h and the module.c stubs with Qt Creator, which added both to the .pro file. Now having the .h files in the .pro is optional: project would compile without it, but it would be harder to navigate the project etc, and I'd have to manually remove each .h from .pro after generating them.
As a complete opposite, I think there are build systems (with their project files) also for C projects, where you don't actually need to list any files. You just list directories, or even have standard directory layout, and the build system will scan the directories and compile the project according to it's rules. I think this is possible with cmake at least. And of course for many project file types (like plain Makefiles) you can use wildcards to find all .c files in a directory.
As to reasons why .h files would not be listed:
Compiler will find the .h files based on #includes, they are not given in command line (only include directories are given).
A modern IDE will scan the sources anyway and find all the used include files without them being listed.
If .h file lists are maintained manually, but per above two points nothing will actually fail if one is forgotten, then the list in project file may get out of date, when someone just forgets either to add or remove one when there are changes.
Listing build dependencies for each .c file is actually a bit different than just listing the .h files in project files, and is best handled automatically.
Using a version control should remove any ambiguity between files which are really part of the project even if they are not used (because they are in version control), and which are just some clutter which should be removed/ignored.
So, if having .h files listed in a project file is any extra work, and if it does not offer any concrete advantage (for example with some IDE), then a convention of just not having them seems sensible.