Let's say I have 10 *.hpp and *.cpp files that I need to compile a code. I know that I will need those same files for many different codes. Can I create a "package" with those files that would allow me to simply write:
#include <mypackage>
instead of:
#include "file1.hpp"
#include "file2.hpp"
...
#include "file10.hpp"
I wouldn't then need to write a makefile every time I need this "package".
To be more precise, I use Linux.
A collection of CPP sources (H files and CPP files) can be compiled together in to a "library," which can then be used in other programs and libraries. The specifics of how to do this are platform- and toolchain-specific, so I leave it to you to discover the details. However, I'll provide a couple links that you can have a read of:
Creating a shared and static library with the gnu compiler [gcc]
Walkthrough: Creating and Using a Dynamic Link Library (C++)
Libraries can be seperated in to two types: source code libraries, and binary libraries. There can also be hybrids of these two types -- a library can be both a source and binary library. Source code libraries are simply that: a collection of code distributed as just source code; typically header files. Most of the Boost libraries are of this type. Binary libraries are compiled in to a package that is runtime-loadable by a client program.
Even in the case of binary libraries (and obviously in the case of source libraries), a header file (or multiple header files) must be provided to the user of the library. This tells the compiler of the client program what functions etc to look for in the library. What is often done by library writers is a single, master header file is composed with declarations of everything that is exported by the library, and the client will #include that header. Later, in the case of binary libraries, the client program will "link" to the library, and this resolves all the names mentioned in the header to executable addresses.
When composing the client-side header file, keep complexity in mind. There may be many cases where some of your clients only want to use some few parts of your library. If you compose one master header file that includes everything from your library, your clients compilation times will be needlessly increased.
A common way of dealing with this problem is to provide individual header files for correlated parts of your library. If you think of all of Boost a single library, then Boost is an example of this. Boost is an enormous library, but if all you want is the regex functionality, you can only #include the regex-related header(s) to get that functionality. You don't have to include all of Boost if all you want is the regex stuff.
Under both Windows and Linux, binary libraries can be further subdivided in to two types: dynamic and static. In the case of static libraries, the code of the library is actually "imported" (for lack of a better term) in to the executable of the client program. A static library is distributed by you, but this is only needed by the client during the compilation step. This is handy when you do not want to force your client to have to distribute additional files with their program. It also helps to avoid Dependancy Hell. A Dynamic library, on the other hand, is not "imported" in to the client program directly, buy dynamically loaded by the client program when it executes. This both reduces the size of the client program and potentially the disc footprint in cases where multiple programs use the same dynamic library, but the library binary must be distributed & installed with the client program.
On Linux:
g++ FLAGS -shared -Wl,-soname,libLIBNAME.so.1 -o libLIBNAME.VERSION OBJECT_FILES
where
FLAGS: typical flags (e.g., -g, -Wall, -Wextra, etc.)
LIBNAME: name of your library
OBJECT_FILES: objects files resulting from compiling cpp files
VERSION: version of your library
Assuming your "file1.hpp" and "file2.hpp" etc are closely related and (nearly) always used together, then making one "mypacakge.h" that contains the includes of the other components is a good idea (it doesn't in and of itself make it into a library - that is a different process altogether).
If they are NOT closely related and/or used together, then you shouldn't have such a "mega include", because it just drags in a bunch of things that aren't needed.
To make a library involves building your code once, and either generating a .lib file or a shared librar (.dll or .so file). The exact steps to do this depends on what system you are using, and it's a little too complicated for me to explain here.
Edit: To explain further: All of the C++ library is actually one library file or shared library file [along with a number of header files that contain some of the code and the declarations needed to use the code in the library]. But you include <iostream> and <vector> separately - it would become pretty awful to include EVERYTHING from all the different C++ library headers in one <allcpplibrary>, even if it was a lot less typing involved. It is split into sections that do one thing per headerfile. So you get a "complete" set from one header file, but not a too much other things you don't actually need.
Yes and no.
You can write an include-all header so that #include "myLib.h" is sufficient, because you include all those headers through the single header. However, that does not mean that the single include is enough to have the content of the 10 '.cpp' files linked to your project automagically. You will have to compile them into a library and link that single library (instead of all the object files) to the projects that use "myLib.h". Library binaries come as static and dynamic libraries, the files are typically named .lib and .dll (windows) and .a and .so (linux) for static and dynamic libraries, respectively.
How to build and link such libraries depends on your build system, you might want to loke those terms up on the net.
One alternative is to get rid of the .cpp files by defininig all the functions in the headers. That way you won't have to link the additional library, but it comes at the cost of increased build times, because the compiler will have to process all those functions every time you include the header directly or indirectly into one of your translation units.
If a client needs all ten headers to actually make use of your "package" (library), that's pretty bad interface design.
If a client needs only some headers, depending on which parts of your library are being used, let the client include the appropriate headers, so only a minimal set of identifiers are introduced. This helps scope, modularization, and compilation times.
If all else fails, you can make an "interface header" for external use, which is different from the ones you use internally for actually compiling your library. This would be the one that gets installed, and consists of the necessary contents from the other headers. (I still don't think you would need everything from every header in your lib.)
I would discourage Salgar's solution. You either have individual headers, or a monolithic one. Providing individual headers plus a central one that simply includes the others strikes me as pretty poor layout.
What I do not understand is inhowfar Makefiles play into this. Header dependencies should be resolved automatically by your Makefile / build system, i.e. it shouldn't matter here how your header files are layed out.
simply all you'd have to do is create a .h or .hpp file that has
#ifndef MAIN_LIB_H
#define MAIN_LIB_H
#include "file1.hpp"
#include "file2.hpp"
#include "file3.hpp"
...
#include "file10.hpp"
#endif
make the file called whatever I would choose main_lib.h because of the ifndef, and just
#include "DIRECTORY PATH IF THERE IS ONE/main_lib.h"
in the main file. No need for anything else if you were using visual studios. Just build then press CTRL + F5.
Related
I coded a program importing and making use of many headers from the boost library. After that the compilation time went from 1-2 seconds to 30s+. Since I am always importing the same library I was wondering if there was a way to compile them once and for all to speed up the following compilations.
I am very unfamiliar with shared/static libraries and could not find a tutorial answering my question.
I do not mind have a much larger executable in case this is the price to pay.
If you include boost headers in one of your program's headers, and all / many of your program's .cpp files include that header, then the boost headers end up getting included in all of your .cpp files, and get compiled once for each one of them.
To avoid this, you can try to only include boost headers in (one) or a few .cpp files in your project.
You can also use PIMPL idiom, also known as "compilation firewall". The idea is that you expose only an interface in the header that your program uses, and if the implementation requires boost things, then that appears in the .cpp file only so you dont end up including boost everywhere.
Note that header-only libraries don't really have to do with shared vs. static. With shared / static libraries, you have object code of some kind which was obtained by compiling the libraries in advance. With header-only libraries, what you are importing is just template definitions into your code, and your compiler makes use of them. It's closer in spirit to static than to shared linking, but it's not really either.
I couldn't really find anything on Google or SO about this. I don't know if it's because it's uncommon, or because I am using the wrong terms to search. I read this question here, but it didn't really answer my question.
So what I am doing is trying to build a library on top of SDL for C++. Now what I can't seem to figure out is how to make projects that use my library be totally independent from SDLs files except the dll.
When I make my library, I link with SDL2.lib, and SDL2main.lib. I include all of SDLs header files into my libraries files. When I build, it generates my library file; GGL.lib.
But when I want to test my library in another project, I have to include all of SDLs header files, because in my project's Window.h, it includes SDL.h. I am wondering if there is any way for me to make my libraries header files independent from SDL except for the dll.
You obviously need to avoid including SDL header files in header files of your library. Include them only in source files, where possible. This removes redundant dependencies and speeds up compilation process. But you want complete independence, so if you can't remove one #include directive, you failed.
If you need to declare a pointer of an SDL type in your header (like one usually does with SDL), forward declare it. That type will however remain incomplete to the users of your library. In case your library is object-oriented, there's Pimpl Idiom, which is based on the same principle - this hides everything.
We can include < iostream > and we do not care about its cpp file, but why can't we do the same for our own classes ?
So if my project uses 50 custom classes, not only do I have to have 50 includes, but also have to compile/link 50 cpp files along with them (and clutter the project tree).
Q: Is there any way to use custom headers the same way we use standard libraries ?
In other words is there a kosher way so that we do not have to add all those cpp files in the project. I want to only include ClassSnake.hpp which in turn knows where to find ClassSnake.cpp which links to ClassVector.hpp which knows how to find ClassVector.cpp ... all in an automatic daisy chain without me having to explicitly add those cpp files in my project tree.
Edit: I am not worried so much about the cpp files recompiling. My issue is with having to remember which class internally links to which other class, so that I can properly include all those hidden cpp files in the project tree ... and clutter the tree.
Not really.
What you're missing is that your compiler toolchain has already compiled the bits <iostream> needs that aren't in the header.
Your compiler (linker really) just implicitly links this code in without you having to specify it.
If you want to clean up your project tree a bit, you could create other projects that are libraries of code for one main project to use.
Headers do not (normally) provide implementations of things (functions, classes), they must be implemented somewhere if you are going to use them.
When you include your own header, you include your own sources in order to provide the implementation. Straight forward enough there.
When you include a standard header (such as iostream), the implementation is in the libraries you include (either implicitly because the compiler just does it, or explicitly through compiler/linker options).
As an extention to Collin's answer, you could always offload "shared" code to a shared library, and then reference the header files and lib files in your other projects. The lib files will only come in to play at the linker stage, as all those other pesky .cpp files have already been compiled.
If this is is just a self-enclosed project with no other commonality, you're just going to have to suck up the fact you have to provide an implementation :)
First of all if you use a system such as make then it will identify that the .cpp file has not changed and therefore the compiler does not have to reconstruct the object file.
You can also create your own static/shared library. The method to do this depends on the platform. If you go down this avenue then all you need is the header file along with the library.
Please Google on how to construct how to make a library for you particular platform.
Actually, if you have a decent build process cpp files that have not changed will not be compiled again. They only have to be linked. If you don't want that either you need to create your own libraries. It can be done, is just a bit more involved.
Edit: This question might help you if you want to create your own library.
So answer to edited question: Yes, you can avoid having all those cpp files in the project but only if you don't want to change them. In this case you can just create a static or dynamic library and you will only need the symbols for linking. In that case you would create another project to compile everything into such a library.
STL code like "iostream" is made of templates no code is actually generated until instances of the templates are created.
When working with a large codebase, I've seen when certain object is being used, that object's header file is included. At other times that object's library is linked in the make file.
What is the reason for doing one or the other. If they have access to the source code, why not include all files whose object you are using instead of linking into their lib *.a files?
edit: made it clear based on first comment. It was a confusing statement
Normally, you need to do both. Header files tell the compiler what
functions are available, and what they look like. They have to be
present when you compile. Libraries contain the implementation, and
must be linked with the application in order for the compiler generated
calls to work.
In a few rare cases, the "library" may consist of just header files; C++
still requires the implementation of a template to be present in the
header, and not in a library, so a library which consists of nothing but
templates may be header-only. In such cases, it is sufficient to
include the headers; there's nothing more to link. (Of course, such
libraries drive compile times through the roof.)
There isn't necessarily a one-to-one relationship between header files and binaries. In fact, there quite commonly isn't. For example, just because you see foo.h being included doesn't necessarily mean there's going to be a foo.obj or foo.lib. The reverse is also true; ie, you might see foo.lib being linked but there is no foo.h.
Using Windows as an example, you need quite a few header files to use anything found in kernel32.lib, but there is no kernel32.h.
One good argument for use of libraries it's that can be used more easily: to compile large codebases, all the right dependencies must be available, and there could be specific steps required, not relevant for the task at hand. And of course, the compile time it's cut away.
Hey so i'm a little confused on why, in msVS++ 2010 you have to have include directories when all the headers and cpp files are inside the static libray or static library project in my case.
I made the static library project with cmake, and the source file i was told to set it to is the same i'm now told to make the include directory... it seems like I have 2 of the same cpp and header files.. except ones included statically in my sollution... WHY?
Because VS++ while abstracting the underlying implementation does not hide it completely.
Include directories and libraries are targeted at different phase of the process, which are traditionally handled by different programs. Include directories by the preprocessor, libraries by the linker. Those programs are now called (or part of?) VC++, but its interface still shows the underlying structure.
There are systems which allows to mark the needed libraries in the source code (and thus in the header) by the use of pragmas. Those have several disadvantages:
non standard
you can't as easily substitute libraries by another (say debug/instrumented/release, single thread/multi thread, ...)
Header files tell you about the functions you're calling.
Static libraries include the code of the function you're calling, but not information about how to call them.