Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Managing a dependency for a C application

+4
−0

One of my applications has a dependency on a stb-library. Now I am publishing this application to Github. Should I:

  • Include the header that was used during development with the code? Have an install.sh script (for UNIX and UNIX-like operating systems) that would wget the header during installation?
  • A drawback I see with option 1 is that there may be bugs in the library, which might have been fixed later. However, a drawback with option 2 is that the library might have changed and could be incompatible with my code.

Which option should I choose, and why?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

1 comment thread

I am unaware which tags to use. Could a moderator help me with them? (2 comments)

2 answers

You are accessing this answer with a direct link, so it's being shown above all other answers regardless of its score. You can return to the normal view.

+2
−0

It depends on what you are distributing.

There are two types of distributions:

  • Binary (application is already compiled)
  • Source (users download raw source code and compile themselves)

Because you are using a header only library, anyone downloading a binary distribution does not need to download the header file(s) because the code they contain is statically compiled into your executable! If you did not using a header-only library and instead linked against a shared library, then your problem would be more complex...

As for the source distribution, yes, you will need to provide a method for developers to install the header file. Some languages (such as Go, Rust, Python, etc.) have package managers built into the core language utilities. Sadly, C/C++ does not. Instead, you must rely upon a smattering of unofficial C/C++ package management tools that the C/C++ community has widely adopted.

Popular solutions to managing C/C++ dependencies:

  1. Conan
  2. vcpkg
  3. CMake's FetchContent module
  4. pkg-config
  5. Git Submodules; I personally recommend you avoid them.
  6. Vendor your dependency (ie. copy + paste it into your app's repo)

This is by no means an exhaustive list, however this blog post seems to have some good information too.

If you already have a build system, such as CMake, Meson, Spack, etc., then I suggest that you go with whatever is conventional for that build system. If you don't have a build system, then I recommend you use one! I personally use CMake.

In the end, I think option #6 (vendoring the header file) is the best option. The stb-libraries are MIT licensed, so as long as you abide by the terms of the license, you can redistribute the header files in your own source code. By including the header file in your app's repo, you avoid all the extra work of setting up a dependency management solution.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

0 comment threads

+1
−0

I see 3 common ways to distribute such software:

  1. Statically linked binary
  2. Dynamically linked binary
  3. Source

1 means you compile everything into a standalone binary file. This bloats the file size, but you don't have to trust the user to have the dependencies (the libraries) installed correctly. This would be the easiest to create a package for, because it's "self contained". It's also popular for Windows, because Windows is bad at dealing with dependencies and libraries.

2 means you compile it such that the program will expect to find the library pre-installed on the user's computer and ready to go. This seems like a stretch, but it's actually common. Modern package managers (Linux, Mac Homebrew; Windows has Chocolatey but most don't use it) are pretty good at dealing with dependency chains and their repos are usually pretty good about having most libraries already packaged. Of course, your package would have to correctly indicate that it requires some other library, so that it gets automatically installed when people try to install your program.

2 will address your concern with the library update, whereas 1 requires you to release a new version just for the library update. However, library updates are not always drop-in, so you might have to be a bit more careful with specifying what version of the library you require. And yes, if the library does a breaking change, you'll have to release a new version of your program too. Keep in mind that not all OSes have the same versions of software. For example, Debian stable might have a very old version of your library, while Arch Linux will have the very latest, you might have to deal with that issue depending on how volatile your library is.

For 3, your build pipeline should be able to obtain a suitable version of the library from an appropriate source. Usually people have a Makefile that provides a build command, which will also ensure build dependencies are set up (not just libraries, but having the compiler installed).

3 is the easiest for developers. Some package repos make it even more convenient, for example Arch Linux has the AUR. Creating an AUR package is fairly straightforward, and you can easily indicate other packages (whether binary Arch repos or other AUR stuff) as dependencies. I think in Homebrew it's pretty easy as well. It also has the most potential for errors, because the build process will need to install a lot of build dependencies on the user's computer, and there's more things that can go wrong.

I'm not very familiar with distributing C programs, but getting the header with wget seems like an odd approach. Usually people will git-clone the upstream lib to a temp dir during the build, and checkout a specific commit or tag (to pin the version).

I would recommend that you start with step 0: Write a proper Makefile that follows the usual conventions like build and configure (you can look at other software for examples, or the manual of GNU Make, or distro packaging docs). Make sure it actually builds on a clean system (you can try a Docker container). Then distribute it as source if your target OS makes it easy like Arch or Homebrew. If you really want to distribute binaries, the easiest is probably to statically link everything and tell people to download the binary from Github Releases (or the equivalent in your host). If you want to create proper binary packages with dynamic linking, you will have to go to each OS'es packaging instructions, and maintain a separate package for each one (having a good Makefile will help here).

As an example, here's a page about how to do source distributions for Arch (AUR): https://wiki.archlinux.org/title/Creating_packages

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »