When Is #Include <New> Library Required in C++

When is #include new library required in C++?

Nothing in C++ prevents standard headers from including other standard headers. So if you include any standard header you might conceivably indirectly include all of them. However, this behaviour is totally implementation dependent, and if you need the features of a specific header you should always explicitly include it yourself.

Include an external library in C

First, as a beginner, you should always ask GCC to compile with all warnings and debugging information enabled, i.e. gcc -Wall -g. But at some time read How to invoke gcc. Use a good source code editor (such as GNU emacs or vim or gedit, etc...) to edit your C source code, but be able to compile your program on the command line (so don't always use a sophisticated IDE hiding important compilation details from you).

Then you are probably missing some Harvard specific library, some options like -L followed by a library directory, then -l glued to the library name. So you might need gcc -Wall -g -lcs50 (replace cs50 by the appropriate name) and you might need some -Lsome-dir

Notice that the order of program arguments to gcc is significant. As a general rule, if a depends upon b you should put a before b; more specifically I suggest

  1. Start with the gcc program name; add the C standard level eg -std=c99 if wanted
  2. Put compiler warning, debugging (or optimizing) options, eg -Wall -g (you may even want to add -Wextra to get even more warnings).
  3. Put the preprocessor's defines and include directory e.g. -DONE=1 and -Imy-include-dir/
  4. Put your C source file hello.c
  5. Put any object files with which you are linking i.e. bar.o
  6. Put the library directories -Lmy-lib-dir/ if relevant
  7. Pur the library names -laa and -lbb (when the libaa.so depends upon libbb.so, in that order)
  8. End with -o your-program-name to give the name of the produced binary. Don't use the default name a.out

Directory giving options -I (for preprocessor includes) and -L for libraries can be given several times, order is significant (search order).

Very quickly you'll want to use build automation tools like GNU make (perhaps with the help of remake on Linux)

Learn also to use the debugger gdb.

Get the habit to always ask for warnings from the compiler, and always improve your program till you get no warnings: the compiler is your friend, it is helping you!

Read also How to debug small programs and the famous SICP (which teaches very important concepts; you might want to use guile on Linux while reading it, see http://norvig.com/21-days.html for more). Be also aware of tools like valgrind

Have fun.

C library include

how to make some functions invisible ?

  1. do not declare the function in the header file of your library
  2. define the function as static in the source file of your library

Example:

your-lib.h

#ifndef YOUR_LIB_H
#define YOUR_LIB_H

void do_public_stuff(void);

#endif YOUR_LIB_H

your-lib.c

#include "your-lib.h"

// this functions is invisible
static void do_private_stuff(void)
{
// ...
}

// this functions is visible
void do_public_stuff(void)
{
// ...
}

user-code.c

#include "your-lib.h"

int main(void)
{
do_public_stuff();
return 0;
}

How can I include a needed C library using GCC?

If you used apt-get, Synaptic Package Manager, etc. to get the appindicator library (vs. building it from source), did you only install the libappindicator1 package or did you also install libappindicator-dev to get the libappindicator header files? Linux packages very often have split the runtime libraries from the compile-time headers. That way people who only need the libraries to satisfy a dynamic link don't have to install unneeded headers. But since you're doing development you need those headers and therefore need the libappindicator-dev package as well.

Do I need a main to create a static library?

your static library is a set of services, so it comes with a header file containing the protoype of the functions you want to expose to the outside. If you don't put a main symbol here, well, noone will put one for you fortunately.

(note that the filename isn't relevant, it's the symbol name which is relevant: main)

It's technically possible to put a main in it (some building tools create a .a file and link with the runtime to create an executable), but as a library of services, that would conflict with any application trying to link with it, that application also having a main.

So leave out the main function as we know it (the famous int main(int argc, char**argv)) out of your library (you can add a selftest entrypoint if you want). Creating a static library doesn't involve any linking, and creating a dynamic library doesn't require a main, just full symbol resolution and entrypoints.

Static Library Include Issue in C

As Michael Burr said, the #include of the .h file, and the linking with the library file, are two different (but related) things.

When you build a C program that consists of several parts, such as several .c source files, or libraries, the process is done in two steps. First the individual source .c files are compiled, that is, translated from the C source to modules of executable machine instructions. Then all the modules and libraries needed for the program are linked together, building the executable file.

The difference between static and dynamic linking is just when the linking is done. Conceptually they are the same thing, but static linking (with a static library) is done in advance, forming an executable file that can be run at a later time, and dynamic linking is done immediately before execution.

The type of linking (static or dynamic) doesn't at all affect the compilation step.

During compilation of an individual source file, the compiler needs to generate code for the calls to the library functions. For example, if a library contains a function f that takes a double as argument, and the source file contains the code f(7), the compiler needs to know that there is a function called f, and that it expects a double as argument, so the compiler can generate code that converts the integer 7 to a double, before actually calling the function f.

This is done by putting function declarations in a .h file, which is then included in your .c source file. For example, that declaration might look like this:

void f(double);

This makes the compiler able to generate the correct code, and also to give the correct warnings and error messages if there is something wrong.

The library, on the other hand, contains the compiled function definition, which is the actual code for the function that does something.

Note that the compilation step has very little to do with the library file, and nothing to do with the difference between static or dynamic linking. To be able to #include the .h file, the compiler needs to know where to find the .h file. That may be in a completely different place from the actual library file. The library file doesn't even have to be present on the same computer, or even exist at all. When the #include is performed, the actual functions in the library might not have been written yet.

One source of confusion could be that the gcc command,

gcc -lpthreads main.c -o server -L thread-pool -lthreadpool

looks like it performs both compilation and linking. It does, but that is just for convenience, and behind the scenes it is still done in two separate steps.

What is the usual way to add static libraries to a C or C++ project?

I am assuming that you want to use the third-party library as-is, without any custom modifications on your side. My answer will also be specific to GNU/Linux but since you're writing your own Makefiles, I assume that this is the relevant platform for you.

While dumping the library into your repository might seem a convenient quick-fix, it is not good practice. Ideally, your repository should only contain hand-written files that your project is responsible for. This keeps a clean separation of concerns.

If your project needs libfoo, another project I'm interested in might need it too so I might decide to install libfoo on my system and use it for all projects that require it. I can do this by downloading, building and installing libfoo manually or, if I'm lucky, I can install it via my package manager. When building and installing manually, there are at least two options. I can install it system-wide or locally for my user only. On the other hand, if I think that I won't ever need libfoo again or your project requires a specific version of libfoo that is not the version I usually want to use, I might prefer to build libfoo in a local directory and not install it at all.

So to summarize, the options for your users are.

  1. Install the library system-wide (eg in /usr/lib/) using the system's package manager.
  2. Manually download, build and install the library system-wide (eg /usr/local/lib/).
  3. Manually download, build and install the library for my local user only (eg ~/lib/).
  4. Manually download and build the library but don't install it (eg ~/src/foo-1.42/).

The decision what option to choose should be left to your users. But while you shouldn't impose anything on them, you should do everything you can to help them.

The first thing to do with external dependencies is to document them. In your README file, list all dependencies of your project with the URLS to the download-pages of the respective projects. If you know that a relevant operating system has already packaged the library, also mention the name of the package people have to install for that system. All GNU/Linux distributions I know have a web-site where you can search their package index so you might want to do it for the more popular ones. If your project needs a specific version of a library, don't forget to mention this prominently.

If your users decide to go with option (1), there is nothing more to do. They will use the package manager to install the library and your Makefile will reference it from the LIBS variable (eg -lfoo).

If your users decide to (or have to, because the library is not packaged for their system) go with option (2) or (3), the situation isn't much different. They will download, build and install the library and once this is done, your Makefile will again pick it up. However, if they install the library in a non-standard location, the linker might not find it directly. Therefore, it is important that your Makefile uses the LDFLAGS variable so users can add the respective option (eg -L${HOME}/lib/) to it. The same goes for the include path (eg -I${HOME}/include/) if your code is referencing headers from the package. These options belong into the CPPFLAGS variable.

If your users go with option (4), they will certainly have to use a linker flag to make the library be found. For example, if libfoo is downloaded to and built in a sub-directory foo, they would add -L./foo/ to LDFLAGS. In this case, however, you can make your user's life a little easier. Place a little shell script in your project's top-level directory that downloads and optionally configures and builds all external dependencies. Please document cleanly what actions will download stuff from the internet and make sure the user will have the last word what they want to download. Also, please have your script verify the checksums of downloaded packages before doing anything with them. Failure to do so is a potential entry point for attackers and you don't want your users to be exploited by using your software. In this case, your Makefile (or better, your configure script) should detect that the package was built locally and use that (ie add the respective -I… and -L… flags). You can also add the flags unconditionally because the pre-processor and linker will silently ignore non-existing directories.

Writing the helper script is not difficult. A simplistic version could look like this.

#! /bin/bash -eu

packages=(foo bar)
declare -A urls
urls['foo']='https://download.foo.org/foo-1.42.tar.gz'
urls['bar']='https://download.bar.org/bar-2.50.tar.gz'

cat <<'EOF' > dependency-checksums.sha1
0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 foo-1.42.tar.gz
62cdb7020ff920e5aa642c3d4066950dd1f01f4d bar-2.50.tar.gz
EOF

for pkg in "${packages[@]}"
do
wget "${urls[${pkg}]}" || exit
done

sha1sum --check dependency-checksums.sha1 || {
echo "ALERT: Verification of package integrity failed. Stop." >&2
exit 1
}

for pkg in "${packages[@]}"
do
ar="${urls[${pkg}]##*/}"
dir="${ar%.tar*}"
tar -xf "${ar}"
ln -s "${dir}/" "${pkg}"
( cd "${dir}" && ./configure && make )
done

You may consider polishing it a little. For example, make it understand the --help option and offer only downloading but not building the packages. Of course, you don't have to write a shell script. You can provide a Perl or Python script or even a Make script. In fact, it is a bad idea to use fancy Bash features as I did in the above example because many people don't use modern Bash shells.

If you're releasing your software as a source archive, there is nothing wrong with providing an alternative tarball that already contains all the external dependencies so your users don't have to download them individually. But you should only offer this as an alternative, not as the only option. That's for tarballs, the repository – as mentioned before – should be kept free of third-party stuff as much as possible.

While writing a decent “download my dependencies” script is easily doable, writing flexible configure scripts and Makefiles is tedious and you'll likely get it wrong. You should seriously consider using an automated framework for this. GNU packages usually use the GNU Autotools, namely Autoconf and Automake. If you want to learn more about these tools, I can recommend John Calcote's book “Autotools – A Practioner's Guide to GNU Autoconf, Automake, and Libtool”.

Build a library in C++ which does not require class instantiation

Supposed you have this:

#include "myLibrary.h"

// Some GUI code here

MyLibrary *mLib;
mLib = new MyLibrary;

// Using the library methods
mLib->startProcess();

Your library can hide the MyLibrary object like this:

startProcess() {
static MyLibrary* myLib = new MyLibrary;
myLib->startProcess();
}

Such that the user code looks like this:

#include "myLibrary.h"

MyLibrary::startProcess();

The function local static myLib will be initialized on first call of the method.

However, you probably want to use the MyLib instance also from other places in your code and wrapping it inside startProcess is not really an option. You'd rather use the much frowned upon Singleton Pattern. Here is a Q&A abuot the Meyers Singleton: Is Meyers' implementation of the Singleton pattern thread safe?.

I am not going into details, because the Singleton Pattern is well documented across the web. Only to outline the rough idea, this would allow you to get the desired user code (not tested):

struct MyLibrary {
static void startProcess() {
instance().doStartProcess();
}
private:

MyLibrary() = default; // private constructor
MyLibrary(MyLibrary&) = delete; // no copies
static MyLibrary& instance() {
static MyLibrary myLib; // the actual instance
return myLib;
}
void doStartProcess(){
// actual implementation
}
}

Note that the actual instance myLib is lazily initialized, ie only the first time instance() is called the function local static myLib is initialized.

C Installed Library - What is this?

In order to include the header files your project needs to know where those header files are. You could tell your pre-processor where they are, usually with -I, but for convenience your system has a set of directories it will search by default. This is called an "include path". Places like /usr/include, /usr/local/include and the like are typical.

Installing a library usually means putting it in an include path. sndfile.h will probably go into /usr/local/include/sndfile.h.

The code in the library is a little different. The install process will compile the code into a shared library that all processes can use. By using the shared library, rather than compiling it into every program, this reduces code size and memory usage system wide. Like the header file, shared libraries are found in a library path. /usr/lib and /usr/local/lib are common examples.

Shared libraries also have the advantage that one it's upgraded, every program that's using it also gets upgraded. This is very good for fixing bugs and plugging security holes. The downside is if a shared library introduces a bug or security hole, or changes its interface, it effect every program using it.


The install process should be documented in the README or INSTALL file of the project source. Typically it's...

./configure
make
make check
make install

But usually you can do this safer and easier with your package manager. For example, Debian has a libsndfile package as does Ubuntu. That way it will be kept up to date.


If you want to distribute a program which relies on another library, you have three choices.

First is to make the users manually install that library. This is a pain for most users.

Next is to use a packaging system, like that which comes with Ubuntu, and turn your software into a package. Then it can declare a dependency on the library's package. This is good, but it requires making a package for every major distribution.

You can distribute the library along with your source code. When your source code is built, build the library as well. If you distribute your program as a binary, you can distribute the compiled library as well. This is what a lot of applications are these days: directories full of compiled code and all their necessary support libraries and frameworks. An example is the OS X .app bundle.



Related Topics



Leave a reply



Submit