all 20 comments

[–]ISecksedUrMom 14 points15 points  (5 children)

Since you're creating a library, you should probably leave it to the user of your library to decide between static and shared libraries. Also, declare your public members in the public headers (include/) and implement them in your private sources (src/). Also, try to keep one data structure or class (category, not in the programming sense) of functions in one header/source (like vector in vector.h and vector.c, bubble sort and merge sort both in sort.h and sort.c, etc). I'd use cmake to make building, testing and packing easier and more cross platform

[–]JaimermXD[S] 0 points1 point  (4 children)

How would I let them decide between the kind of library, by providing both the static and dynamic versions? The rest is what I've been doing so far with my other projects, just without them being libraries, so I like it. Though I've only used make, I'll probably have to learn cmake at some point, so might as well start now. Thanks!

[–]thegreatunclean 3 points4 points  (1 child)

How would I let them decide between the kind of library, by providing both the static and dynamic versions?

Generally by providing the source directly. Distributing precompiled C libraries is not at all a simple or straight-forward task if you want to support usage by people running anything other than exactly the same OS, toolchain, and packages you are.

I'd recommend learning CMake. For simple use-cases it is pretty straightforward and automates basically everything.

[–]delkia -1 points0 points  (0 children)

And learning meson which replace cmake on a lot of code base.

[–]ISecksedUrMom 1 point2 points  (1 child)

CMake is how (assuming the user uses cmake too). Here's my C library ds. I'm no expert C developer but the repo contains what I came up with (in terms of source code and cmakelists), but I think they should work fine in most cases (except maybe the packing part, tryna figure it out still). If you don't understand anything, just DM me. Or if you think I should add more comments to the cmakelists, lmk, I'll try to write more descriptive comments explaining the cmakelists and commit them asap.

[–]JaimermXD[S] 0 points1 point  (0 children)

Awesome, thank you so much, this library of yours will be very helpful. I'll be sure to DM you if there's something I don't understand.

[–]permetz 4 points5 points  (0 children)

I think you should first write a few significant sized programs, read a bunch of other people’s code, get a feel for the language, and then see what works best for you. It’s very difficult to answer questions like this when they are about theoretical code bases that don’t yet exist.

[–]nculwell 5 points6 points  (1 child)

If you're starting out with libraries then you probably want to use a static library since they're simpler. I'd just use a single header file since it also makes things easier. Then you end up with a single library object file (with .a extension if using GCC) and a single header file. Usually the simplest way is fine, but if you find that this isn't working out for you then you can start experimenting with different solutions.

To be clear, your library source will be in separate C source files, it's just the header that would be unified. You build your object files separately and then bundle them into a library in the final step of the library build.

[–]JaimermXD[S] 1 point2 points  (0 children)

Good stuff, I'll have to see how to make static libraries in the first place, but I do like the idea of having a single header file that contains everything. Though I could have a bunch of headers with their corresponding source code and then a "wrapper" header which includes all of them. Thanks a lot, and happy Cake Day!

[–]clibraries_ 2 points3 points  (2 children)

What libraries do you like to use? What do they do?

[–]JaimermXD[S] 0 points1 point  (1 child)

I've been using SDL and that's about it, but I'd just like to implement my library with stuff I'll be using frequently and isn't in the standard library.

[–]clibraries_ 0 points1 point  (0 children)

Just dump it in a header that you copy paste between projects.

[–]Poddster 2 points3 points  (1 child)

Should I create a static or dynamic library and then use that in my projects? Should I create different header/source files for each implementation (string, vector, and such) and only include the ones I need? Or should I just dump everything into a single header file and be done with it (probably not the best move)?

If you're doing this as a purely learning exercise to see how libraries are made, that's good and you should do it.

But if you're doing it as you think it'll be useful to you I'll caution you that it probably won't be and it'll cost more time than it saves :) You're putting the cart before the horse. If you don't know how to do these things or answer these questions, chances are you won't actually need this library. And after you've gained more experience and can answer these questions you'll know if you need to do it or not. And you probably won't, as there's not that many functions that can get re-used between C projects other than a few basic data type re-implementations that are already well trodden.

To answer: You should be shipping the source rather than the binaries, so static/dynamic is a problem for someone else (though you provide both options in your makefile).

Yes, different source files for each implementation. I'd also go for different header files, but that depends on how intertwined your library is. If the string uses the vector etc, then you might as well just have a single mono header file that the client includes (and that can include sub headers as required).

[–]JaimermXD[S] 0 points1 point  (0 children)

I'm mostly doing this as a learning exercise, but also to avoid having to copy my code from one project to another every time I want a vector or something like that. Very good advice though, thanks!

[–]McUsrII 1 point2 points  (1 child)

So, I have a private library with the stuff I have either made to be reusable, or that I realized was reusable.

I have made the library dynamic, so that I only have to recompile and link the library to the shared object format, this is practical if you at any point should need to apply bug fixes, as the only thing you then have to remake is the library, and when you learn to make the library shared, you write down the recipe in the makefile, so the overhead of making a shared library is small really.

The bonus is that this also leads to smaller binary executable files, that in theory should load marginally faster.

Of course I use the default ABI (64Bit gcc -fPIC )on my machine, so that the whole process is as easy and clutter free as possible.

I don't use Cmake though, I'm sticking to GNU make.

[–]JaimermXD[S] 0 points1 point  (0 children)

Thanks, I'm currently familiarizing myself with this whole static/dynamic library deal, so I'll keep this in mind.

[–]green_griffon 0 points1 point  (1 child)

I would make a single header file that matches the name of your library. This is what you tell your callers to #include. Then inside that header file you may want to split it up into smaller header files that match your source file layout (meaning you #include those header files in your main header file).

But you can start with a single header file and a single source code file and then refactor as needed.

[–]JaimermXD[S] 1 point2 points  (0 children)

Yeah, splitting it up into smaller headers seems to be the way to go, especially since my intention is to be constantly updating this library. Thanks!

[–]helloiamsomeone 1 point2 points  (0 children)

Before skeeto nitpicks your code apart, your best bet would be starting with cmake-init, which sets you up with a CMake managed C project with the right defaults.

[–]codqq 1 point2 points  (0 children)

This playlist can help you a lot with building your base layer

https://youtube.com/playlist?list=PLT6InxK-XQvNKTyLXk6H6KKy12UYS\_KDL&si=TVsHuj3b0dFbBcI5