Search code examples
cmakefilestatic-libraries

Best practice regarding static library linking and project directory structure in C


I have a project in C, and due to the nature of the application I'm making I've decided to statically link libconfig into my final binary to minimize the external dependencies needed to use it. Before, I've only ever dynamically linked libraries by doing the standard method of just using flags pointing to /usr/lib and /usr/include, leaving my personal project directory structure untouched.

This time around however I've compiled the static libconfig.a and included it in my directory structure, and have the Makefile use that for linking, as well as the required header file for the library, placed in my include/ directory which contains header files for my projects source .c files. See:

project/
├── LICENSE
├── Makefile
├── README.md
├── bin/
├── include/
│   ├── headerfile1.h
│   ├── headerfile2.h
│   └── libs
│       └── libconfig.h
├── lib/
│   └── libconfig.a
├── obj/
└── src
    ├── srcfile1.c
    └── srcfile2.c

I am worried that this is bad practice, and I'm wondering if there exists a more standard and elegant way to deal with what I'm trying to do, especially if in the future someone will try to compile this from source.


Solution

  • I have a project in C, and due to the nature of the application I'm making I've decided to statically link libconfig into my final binary to minimize the external dependencies needed to use it.

    This is a thing that is sometimes done, most often in the form of statically linking all dependencies.

    Another thing that seems more common is for a binary software distribution to be dynamically linked against private versions of shared libraries that it provides itself (including third-party libraries). I don't like this much, personally, but it does have some advantages.

    However, those are completely separate questions from how the project source is organized and what is included in it.

    I'm wondering if there exists a more standard and elegant way to deal with what I'm trying to do, especially if in the future someone will try to compile this from source.

    There are no standards for project and build system organization. There are loose conventions at best.

    One of the ways that some projects deal with third-party dependencies that they suspect others might have difficulty obtaining is to bundle source for those dependencies. They will then set up their build system to build the dependency as well. Sometimes they will have (and IMO, they always should have) an easy means for people to build against libraries provided by the system instead of using the bundled copy. This is largely orthogonal to linking -- you can do either static or dynamic linking in conjunction with this.

    Another way that projects deal with third-party dependencies, especially those that are readily available, is simply to document their dependencies, along with instructions for how to obtain them at need.


    BUT if libconfig is the only dependency you're concerned about, then I think you're making much ado about nothing. It is a widely distributed open source library, with a long history and still maintained, with curated versions available from all the most popular Linux distributions, and easy to build from source if needed.