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.
Related
I have been reading up on make and looking at the Makefiles for popular C projects on GitHub to cement my understanding.
One thing I am struggling to understand is why none of the examples I've looked at (e.g. lz4, linux and FFmpeg) seem to account for header file dependencies.
For my own project, I have header files that contain:
Numeric and string constants
Macros
Short, inline functions
It would seem essential, therefore, to take any changes to these into account when determining whether to recompile.
I have discovered that gcc can automatically generate Makefile fragments from dependencies as in this SO answer but I haven't seen this used in any of the projects I've looked at.
Can you help me understand why these projects apparently ignore header file dependencies?
I'll attempt to answer.
The source distros of some projects include a configure script which creates a makefile from a template/whatever.
So the end user which needs to recompile the package for his/her target just has to do:
$ configure --try-options-until-it-works
$ make
Things can go wrong during the configure phase, but this has nothing to do with the makefile itself. User has to download stuff, adjust paths or configure switches and run again until makefile is successfully generated.
But once the makefile is generated, things should go pretty smooth from there for the user which only needs to build the product once to be able to use it.
A few portion of users will need to change some source code. In that case, they'll have to clean everything, because the makefile provided isn't the way the actual developpers manage their builds. They may use other systems (code::blocks, Ant, gprbuild...) , and just provide the makefile to automate production from scratch and avoid to depend on a complex production system. make is fairly standard even on Windows/MinGW.
Note that there are some filesystems which provide build audit (Clearcase) where the dependencies are automatically managed (clearmake).
If you see the makefile as a batch script to build all the sources, you don't need to bother adding a dependency system using
a template makefile
a gcc -MM command to append dependencies to it (which takes time)
Note that you can build it yourself with some extra work (adding a depend target to your makefile)
I recently installed openjtalk on a linux machine, and I want to be able to wrap it in Go. The source files for openjtalk have several subfolders with different sources, which I assume are found by the compiler because of the make files.
Should I copy each of those sub-folders into /usr/local/include? Is that a "correct" way of fixing include dependencies. From what I tested, Go seems to find the included files if I copy them, but I'm not sure if this is the correct, linux way of doing things.
It's usually not a good idea to change locations of external libraries. Some libraries automatically put themselves in include paths of compilers but for those that don't, adding their paths to the compilers' include paths is always a better idea.
For example, in gcc, you can gcc -I/your/header/directory to include your directory. Usually people put those info in the Makefile. This way, you can put external libraries' source code in your repository and just tell compiler to also look for the headers there. This way, when setting up a new working environment, all you have to do is pull from the repository.
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.
Related to using cmake to link object files into lib.xxxx.a file, but not quite the same thing, I have built several static libraries on Windows using CMake 2.8.x using VS2008 SP1. Is there a way via CMake alone to relink all of the .obj files inside all of those existing static libraries into one larger monolithic library, preferably via the add_library CMake function, or other similar construct?
I think the answer is "no", and so I have thought about rolling my own via a custom command via the usual add_custom_command + add_custom_target approach, that simply constructs the library manually, by supplying all of the other libraries .obj files when calling LINK.EXE. But I see some problems with that approach:
I could not find a CMake variable that indicates the fully-qualified path to the LINK.EXE executable. I would then have to somehow derive the path to LINK.EXE using a fragile heuristic: It is fragile in the sense that different Visual Studio versions may locate the LINK.EXE file in different directories, and I'm needing this to work for both 32-bit and 64-bit Windows compiler conditions, and be resilient against upgrades between VS2008 and future compiler revisions.
I would have to find a way to find all of the .obj files of the other static libraries, at build time versus at CMake time, since at CMake time the .obj files of course do not (always) exist. For reasons of build performance, I desire not to resort to extracting the .obj files from the .lib files for the sake of adding them to the LINK.EXE command line, so a FILE(GLOB...) construct would be my best second alternative in this case.
It may be possible to simply call LINK.EXE via: LINK.EXE /OUT:monolithic.lib lib1.lib lib2.lib ..., but maybe not all .obj's will be included (EDIT: I have confirmed that LINK.EXE omits some .obj files from lib1.lib lib2.lib ... without any diagnostic messages explaining why, so this approach is a non-starter); the online docs for LINK.EXE are unclear as to that point. Anyone have any experience with using LINK.EXE in that manner?
Thanks,
Brent
P.S., I know how to create a DLL using CMake, but I specifically do not want to resort to building a DLL at this point in time.
Create a static library "merged" with a dummy source file, and add libs to be merged to the STATIC_LIBRARY_FLAGS, so they will be additional input to lib.exe.
This would be something like:
ADD_LIBRARY(merged STATIC dummy.c)
SET_TARGET_PROPERTIES(merged PROPERTIES
STATIC_LIBRARY_FLAGS "full\path\to\lib1.lib full\path\to\lib2.lib")
This approach is used inside MySQL, there is a more general macro here to merge static libraries that works crosss-platform. It can be found here http://www.mail-archive.com/cmake#cmake.org/msg28670/libutils.cmake