A.1 — Static and dynamic libraries

A library is a package of code that is meant to be reused by many programs. Typically, a C++ library comes in two pieces:

1) A header file that defines the functionality the library is exposing (offering) to the programs using it.
2) A precompiled binary that contains the implementation of that functionality pre-compiled into machine language.

Some libraries may be split into multiple files and/or have multiple header files.

Libraries are precompiled for several reasons. First, since libraries rarely change, they do not need to be recompiled often. It would be a waste of time to recompile the library every time you wrote a program that used them. Second, because precompiled objects are in machine language, it prevents people from accessing or changing the source code, which is important to businesses or people who don’t want to make their source code available for intellectual property reasons.

There are two types of libraries: static libraries and dynamic libraries.

A static library (also known as an archive) consists of routines that are compiled and linked directly into your program. When you compile a program that uses a static library, all the functionality of the static library that your program uses becomes part of your executable. On Windows, static libraries typically have a .lib extension, whereas on linux, static libraries typically have an .a (archive) extension. One advantage of static libraries is that you only have to distribute the executable in order for users to run your program. Because the library becomes part of your program, this ensures that the right version of the library is always used with your program. Also, because static libraries become part of your program, you can use them just like functionality you’ve written for your own program. On the downside, because a copy of the library becomes part of every executable that uses it, this can cause a lot of wasted space. Static libraries also can not be upgraded easy -- to update the library, the entire executable needs to be replaced.

A dynamic library (also called a shared library) consists of routines that are loaded into your application at run time. When you compile a program that uses a dynamic library, the library does not become part of your executable -- it remains as a separate unit. On Windows, dynamic libraries typically have a .dll (dynamic link library) extension, whereas on Linux, dynamic libraries typically have a .so (shared object) extension. One advantage of dynamic libraries is that many programs can share one copy, which saves space. Perhaps a bigger advantage is that the dynamic library can be upgraded to a newer version without replacing all of the executables that use it.

Because dynamic libraries are not linked into your program, programs using dynamic libraries must explicitly load and interface with the dynamic library. This mechanism can be confusing, and makes interfacing with a dynamic library awkward. To make dynamic libraries easier to use, an import library can be used.

An import library is a library that automates the process of loading and using a dynamic library. On Windows, this is typically done via a small static library (.lib) of the same name as the dynamic library (.dll). The static library is linked into the program at compile time, and then the functionality of the dynamic library can effectively be used as if it were a static library. On Linux, the shared object (.so) file doubles as both a dynamic library and an import library. Most linkers can build an import library for a dynamic library when the dynamic library is created.

Installing and using libraries

Now that you know about the different kinds of libraries, let’s talk about how to actually use libraries in your program. Installing a library in C++ typically involves 4 steps:

1) Acquire the library. The best option is to download a precompiled package for your operating system (if it exists) so you do not have to compile the library yourself. If there is not one provided for your operating system, you will have to download a source-code-only package and compile it yourself (which is outside of the scope of this lesson). On Windows, libraries are typically distributed as .zip files. On Linux, libraries are typically distributed as packages (eg. .RPM). Your package manager may have some of the more popular libraries (eg. SDL) listed already for easy installation, so check there first.

2) Install the library. On Linux, this typically involves invoking the package manager and letting it do all the work. On Windows, this typically involves unzipping the library to a directory of your choice. We recommend keeping all your libraries in one location for easy access. For example, use a directory called C:\Libs, and put each library in it’s own subdirectory.

3) Make sure the compiler knows where to look for the header file(s) for the library. On Windows, typically this is the include subdirectory of the directory you installed the library files to (eg. if you installed your library to C:\libs\SDL-1.2.11, the header files are probably in C:\libs\SDL-1.2.11\include). On Linux, header files are typically installed to /usr/include, which should already be part of your include file search path. However, if the files are installed elsewhere, you will have to tell the compiler where to find them.

4) Tell the linker where to look for the library file(s). As with step 3, this typically involves adding a directory to the list of places the linker looks for libraries. On Windows, this is typically the /lib subdirectory of the directory you installed the library files to. On Linux, libraries are typically installed to /usr/lib, which should already be a part of your library search path.

Once the library is installed and the IDE knows where to look for it, the following 3 steps typically need to be performed for each project that wants to use the library:

5) If using static libraries or import libraries, tell the linker which library files to link.

6) #include the library’s header file(s) in your program. This tells the compiler about all of the functionality the library is offering so that your program will compile properly.

7) If using dynamic libraries, make sure the program knows where to find them. Under Linux, libraries are typically installed to /usr/lib, which is in the default search path after the paths in the LD_LIBRARY_PATH environment variable. On Windows, the default search path includes the directory the program is run from, directories set by calling SetDllDirectory(), the Windows, System, and System32 directories, and directories in the PATH environment variable. The easiest way to use a .dll is to copy the .dll to the location of the executable. Since you’ll typically distribute the .dll with your executable, it makes sense to keep them together anyway.

Steps 3-5 involve configuring your IDE -- fortunately, almost all IDEs work the same way when it comes to doing these things. Unfortunately, because each IDE has a different interface, the most difficult part of this process is simply locating where the proper place to perform each of these steps is. Consequently, in the next few lessons in this section, we’ll cover how to do all of these steps for both Visual Studio Express 2005 and Code::Blocks. If you are using another IDE, read both -- by the time you’re done, you should have enough information to do the same with your own IDE with a little searching.

A.2 -- Using libraries with Visual Studio
23.7 -- Random file I/O

100 comments to A.1 — Static and dynamic libraries

  • yeokaiwei

    Hi Alex,
    What happens when someone deletes their library from the Internet ie deleting the wheel?

    How should we go about librarie disappearing or changing licenses?

    • Alex

      Web libraries work differently than C++ libraries. On the web, if you reference code that lives on another site, you'd better hope that site remains reachable.

      C++ libraries are distributed as files and either compiled into the executable (if a static library) or bundled into the program installer (if a dynamic library). If the library author changes the license, that should only apply to new distributions of the library, not current versions. And if the library author pulls the library altogether, that shouldn't impact the use or inclusion of current versions, unless they have some network-based capabilities that no longer work.

  • yeokaiwei

    Hi Alex,
    Could you cover library licenses?

    I just read an article that affects developers.

    There seems to be an issue with licenses in the library.

    For certain licenses, if you use the library, you must make your code open-source.

    "By adding the GPL-licensed editor module code to its own application, Wix essentially placed its whole mobile application under the scope of the GPL license."

    • Alex

      Library licenses aren't really in-scope for this tutorial series, as that topic lives more in the legal realm than the C++ realm.

      As you note, some software is distributed with a license that states that if you use that software, you have to open-source your own software. If you are developing a commercial application, this can be prohibitive. Some open-source software can be dual licensed, where you can use it for free if you're an open source program, or you can buy a commercial license if you're not.

  • yeokaiwei

    Hi Alex,
    What is the difference between precompiled headers, libraries, parallel builds and bytecode?

    From the quote, "Libraries are precompiled for several reasons.", do libraries = precompiled headers?

    • Alex

      Normally when you compile a program, the compiler compiles each code file individually. Every header that is #included is copied into the code file at the point of inclusion, and then the whole thing is compiled. In a code base with lots of headers, this means lots of redundant compiling.

      Precompiled headers compiles headers into an intermediate form, so that if that header file is encountered again in the same codebase, the precompiled version can be used rather than compiling that code again. This speeds up compilation of large code bases.

      Libraries are basically compiled code that are packaged up for distribution. This allows others to use your code without having access to the source code (useful so they can use your product without having to compile it first, and so they can't steal it).

      Parallel builds (I presume you mean parallel compilation) involves using multiple threads (or in some cases, multiple machines) to compile several files simultaneously. This also speeds up compilation of large code bases.

      Bytecode is a portable, partially compiled file that is meant to then be efficiently intepreted by an interpreter. Since C++ is typically fully compiled, we normally don't see bytecode in C++. Java uses this.

      • yeokaiwei

        Thanks Alex,

        Just a silly question for clarification purposes.

        Are libraries precompiled headers (PCH)?

        The reason I'm asking is because libraries seem to fit the description of PCH. Libraries are .h (header files) and they are precompiled. We use #include <library name> and configure the include file path.

        However, when you look at the IDE options, precompiled headers seem to describe a separate entity as there is a separate checkbox for precompiled headers.

        Lastly, on a side note, could you cover software licenses?

        The reason I'm asking is because there is some contention over Lesser GNU Public License v3.


        • Alex

          Libraries and precompiled headers are different. Precompiled headers are an intermediate step to speed up compilation of a program. The compiler takes some header file foo.h, and compiles it into intermediate file foo.pch. Then the intermediate code for foo.pch can be included wherever foo.h would be recompiled.

          Libraries are code that has been compiled in .lib/.dll/.a/.so files for distribution. Typically uncompiled header files are also included with a library distribution to make it easy for the program integrating the library to import all the type and function declarations needed to use the library.

          Software licenses are a separable topic, and one that I'm not as familiar with. You're better off turning to other sources for information on the ins and out of these.

          • yeokaiwei

            Hi Alex,
            Could you touch on std::unordered_map?

            Setting up a proper hash table function seems to be something very important and I see it quite often.

            • Alex

              I'm intending to do some lessons on std::unordered_map and other useful containers, but realistically it'll be a while until I get to them.

              Until then, you can check out

              You might also do a google search on "unordered_map tutorial" and see what comes up.

              • yeokaiwei

                Hi Alex,
                I did.

                It's a bit confusing.

                Once I read up that it's best to use cryptographic hashes and SHA-3 hashing algorithms, I knew I was in over my head.

                Could you cover how to setup passwords and logins?

                • Alex

                  You're getting into advanced (security-related) topics here. That's a bit outside my core knowledge set.

                  As a general principle, you don't want to store passwords in a database in plain text -- if the DB gets hacked, the user's PW is exposed. So what you do is you hash the password using a one-way hash (e.g. SHA-3), and save the hashed password in the DB. When the user enters their PW, you hash it using the same algorithm, and then check if it matches the hash in the DB. That way you can still do password checks but in a way that doesn't expose the user's PW in case of a breach.

                  • yeokaiwei

                    Hi Alex,
                    If this is advanced, then how do we setup proper password logins?

                    What should we look at or read?

                    • Alex

                      Next step would be to learn how to use SQL and find a 3rd party library that allows your C++ code to interact with a database. Then you can create a user table and experiment with storing and retrieving data from the database.

  • yeokaiwei

    Hi Alex,
    Could you add a page to explain the Free Software Foundation, GNU Public License, Lesser Gnu Public License, BSD license, MIT License, Apache License and other licenses for the libraries?

    Thank you.

  • yeokaiwei

    Hi Alex,
    Thanks for all the tutorials.

    I hope to see become the first stop of C++ learners.

    Lastly, would you like to cover the #include <optional> library?

    It is a peculiar one.

  • sami


    I have questions:
    "...because precompiled objects are in machine language,.."
    1) As far as I remember, machine codes (binary) are not portable and source codes need to be recompiled on a different OS(s). So, here, we are having just machine codes of libraries and we don't have access to the source code to recompile them, then how come they do work?

    2) According to the definition of static library, it means that programmers can have access to the course codes of static libraries as they are not machine language, they are written to C++ (in this example), right?

    3) are dynamic libraries those pre-compiled ones that contain machine language (binary) which are linked by a linker?

    "4) Tell the linker where to look for the library file(s)".
    Do you mean "binary machine language" by talking about "library files"?

    • nascardriver

      They only work if they're binary compatible with your program. If the library wasn't compiled for your setup and you don't have the source, you can't use the library.

      Static libraries are compiled, they don't contain source code. You only have the full source code of a library if it's a header-only library.

      Static and dynamic libraries are pre-compiled and get linked by the linker.

      "Library files" are the compiled libraries (.dll, .dylib, .so, .a, .obj, etc.).

  • terapty

    I remember having had trouble making libraries for a project I was working on in C so I was wondering, is it simpler in C++? And if not, could there be an extension of this appendix providing the basics on how to make your own library, e.g. explain some of the options provided by compilers to do so?
    I realise that what I'm asking is not a simple question and requires a lot of time and effort, I'm mostly wondering if it's projected at least.

  • Dear Teacher,
    Please let me say you that most of today's libraries include both .lib and .dll files, and for program run with "all Configurations", both are needed. Does it mean that these libraries linking both static and dynamic?

  • Dear Teacher,
    Please let me say you regarding "Libraries are precompiled for several reasons" that at
    section "Building GLFW", 2nd §, it is said: "Compiling the library from the source code guarantees that the resulting library is perfectly tailored for your CPU/OS, a luxury pre-compiled binaries don't always provide (sometimes, pre-compiled binaries are not available for your system). The problem with providing source code to the open world however is that not everyone uses the same IDE or build system for developing their application, which means the project/solution files provided may not be compatible with other people's setup. So people then have to setup their own project/solution with the given .c/.cpp and .h/.hpp files, which is cumbersome. Exactly for those reasons there is a tool called CMake."
    By the way let me point out that owner of this site Mr. Joey De Vries in his "Introduction", section "Prerequisites", first paragraph,  recommends your tutorials.
    With regards and friendship
    Georges Theodosiou

  • Andis

    Point 3) talks about the location of the header files. For me, the part "On Linux, libraries are typically installed to /usr/include" is a bit misleading, as the location of the .so-files are described in the same manner: , e.g. under point 4) "On Linux, libraries are typically installed to /usr/lib".

  • To point 7) I would add a note that, for Linux, the dynamic loader looks for shared objects in the LD_LIBRARY_PATH environment variable, as opposed to Windows, which uses the same PATH env var as for executables.

  • masterOfNothing

    " The easiest way to use a .dll is to copy the .dll to the location of the executable. Since you’ll typically distribute the .dll with your executable, it makes sense to keep them together anyway."

    Where the project .exe file is located? does windows OS come with such library files that C++ would be capable to using?

    What about OpneGL?

    • Alex

      > Where the project .exe file is located?


      > does windows OS come with such library files that C++ would be capable to using?
      > What about OpneGL?


  • Dan

    I created a Folder named "Lib" in C:/
    But I didn't understand how exactly do I link the folder into my main.c file where I need to use the functions I created in the Lib file.
    Can you please be more specific?
    Thanks in advance :)

  • Nima

    Dear Alex and nascardriver Hello!
    I have a question about .lib and .dll file.
    Consider we have a very simple library with these files:
    power.h ----> header of simple power function
    power.lib ----> binary of power function for linking
    power.dll ----> binary used as dynamically linking
    But we don't have power.cpp!
    Now, I want to use this power function in my program hence I have to include power.h in my source code and also power.lib file in order to pass linking stage successfully!
    In this case how can I use power.dll? Because if I use power.lib, all of binaries are copied into final exe and we don't need to use power.dll anymore also if we use power.dll directly in linking stage, linker gives error about this!
    So the question is how can we use dynamically link libraries when we want to link against a library which source code isn't available at that moment?
    Thanks a lot!

    • nascardriver

      Hi Nima,

      your should still need the .dll file after you added the .lib to your project. MS has a nice documentation about how to link dynamically using VS

      • Nima

        Dear nascardriver thank you so much!
        I read the link that you sent.
        As far as I remember, I didn't see something like:

        In beginning of every header file in boost, opencv and many other libraries source code for generating proper dlls after building library but why it should be like this?
        Thanks in advance!

        • nascardriver

          Those macros allow you to selectively export/import things in the library and program in MSVC. boost, opencv and many other libraries are cross-platform compatible. __declspec would break them as it only works in MSVC.
          I suppose they simply export everything, but I rarely use libraries, so I'm not sure.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]