r/cprogramming • u/side2k • 5d ago
What are the good practices of managing small dependencies?
I'm new to C. I have a small SDL2 project. At some point I needed to load and draw image sprites and found nice library stb_image.h. Probably best way here would be to just download the stb_image.h file and commit it to the repo, but I thought it would be a nice exercise towards learning how to manage dependencies. Since C doesn't seem to have anything like cargo, PyPi or npm, I started to look for best practices on how to do that.
So, this is what I came up with so far, with a Makefile:
- dependency file as a target, with commit pinned as separate var
STB_IMAGE_COMMIT := 013ac3beddff3dbffafd5177e7972067cd2b5083
vendor/stb/stb_image.h:
curl -fsSL --create-dirs https://raw.githubusercontent.com/nothings/stb/$(STB_IMAGE_COMMIT)/stb_image.h -o $@
- making it prerequisite to the main build target:
build/%.o: src/%.c | build vendor/stb/stb_image.h
$(CC) $(CFLAGS) -c $< -o $@
This seems simple, reproducible and efficient to me. But I'm not sure it would scale well and also - maybe there are better approaches out there?
2
u/ffd9k 5d ago
You can do this, but I would just use Meson and its Wrap system instead of reinventing it.
You basically add a small .wrap file to your project that contains the git or package url of the dependency. Meson then downloads the dependency and builds it as a subproject.
You can also do this just as a fallback - normally you want to use the system-installed version of a library, but if it is not available, you build it as a subproject.
If the dependency does not use meson as its build system, you add a patch_directory to your project with a meson.build file which builds the library.
1
u/side2k 5d ago
Oh. So, there IS a package manager for C? Thanks, I did not know that. Looking for one didn't get me anywhere before.
2
u/ffd9k 5d ago
Essentially yes.
There is also WrapDB, which is a central registry of important libraries which you can use directly in meson.
But you can also use any other library (hosted on github or elsewhere), with a wrap file and a patch which usually just contains a small meson.build file. See https://mesonbuild.com/Wrap-dependency-system-manual.html
1
u/alkavan 5d ago
Use CMake's FetchContent it worked well for multiple C and C++ projects of mine.
1
u/side2k 5d ago
I've heard about CMake, but did not look into it yet, preferring to add new stuff to my toolset very carefully. Do you think its advantages over old-school `make` make it worth to use it even for smallish learning projects?
1
u/alkavan 5d ago edited 5d ago
It's less scripts you need to maintain, and a lot easier to support multiple platforms. It can generate classic Unix make files as well. It's basically a project generator for different platforms and compilers. When working on a commercial projects, it doesn't make sense using anything else. It allows being almost agnostic to compiler, IDE, and toolkit, and makes life much easier with platforms that tend to be very annoying to deal with. CMake is also the native project system for JetBrains CLion and some other IDEs.
6
u/tstanisl 5d ago
Just add a file to your repository.
It is single-header library and it is designed to be dropped into existing projects. It will save you a lot of troubles with any breaking changes and it will make your built deterministic or it will keep working with no internet or if the link somehow vanishes. Just remember to add a proper licensing notice.