How should I export the API of a shared library?

I use Eclipse CDT on a Fedora machine for developing C++ code. In the first project I programmed in C++, I wrote a client for Basex (Open Source XML database). So I am still a newbie in the C++ field.
To develop the code, I used 2 CMake projects. The test program was developed in the first project. The actual client was developed in the other project. The client now consists of 6 C++ files, each with its own header file. Each header file describes part of the complete API. And each header describes a class with both public and private methods.
My intention is to export the second project as a shared library. And as far as I understand it, I need to export the public API of a shared library through 1 single header file.

My question is how the content of that public API relates to the individual header files. Should I transfer all the public information to the public API?
Where can I find more information about the structure of a shared library?
as far as I understand it, I need to export the public API of a shared library through 1 single header file

I would say that is the standard practice, but not completely a requirement. You could provide each header and definition (*.h and *.cpp pair) as it's own shared library for instance; let's say your entire API spans 30MB or more and you want to give the user the ability to just include the bare-bones of your API as needed. I think QT does something like that where you could request exclusion and addition of certain chunks of the API to save build space.

Just make sure that you specify the correct compiler commands for creating a shared library "-shared -fPIC", and the output should follow a naming format like "-o libYourFramework.so" because Linux expects your shared libraries to start with the word lib.

My question is how the content of that public API relates to the individual header files. Should I transfer all the public information to the public API?

I find this question a bit confusing. Any header file containing functions that the user should be accessing should be made available. I'm actually not quite sure how you might hide your header files since your main header would tell them how to find the others.

But even if you could hide your headers, when documentation is lacking then the best way to find out how to use an API is by looking at the header files. Often the header files actually contain more complete documentation than accompanying pdf files because the comments are direct from you the developer.

Where can I find more information about the structure of a shared library

I found that compiling and installing SDL3 from source was very informative, their project layout is solid, figuring out where those headers and libSDL3.so files ended up, how pkg-config was set up, etc.

https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html <- Here's a short walk-through for creating and installing a shared lib, it's pretty good, though it fails to mention that step 1 should be run on all sub-files, and the resulting object files can all be linked together in step 2, or that step 1 and 2 could be combined into a single line.
I would also include -fPIC in step 2.

Mostly I recommend finding the source to a shared library that interests you and go through their build process, try to figure out what worked for them and what you could take away from that.
Last edited on
I,ve googled a bit and found these two links. My guess is that they match more or less my need.
1) https://stackoverflow.com/questions/29785378/common-or-multiple-header-files-for-shared-library
2) https://softwareengineering.stackexchange.com/questions/378122/c-is-it-a-good-idea-to-make-separate-headers-as-api

In Eclipse I,ve created 2 projects. libBasexTest and libBasexCpp,
- libBasexTest references LibBasexCpp
- libBasexCpp creates the following classes, each one has its own header file:
1
2
3
4
5
6
Base.cpp
  |- BasexClient.cpp
  |- QueryObject.cpp
BasexSocket.cpp
ResponseObj.cpp
ClientUtils.cpp


- The first link suggests that it is best to add namespaces to the existing header files and create a new header file (libBasexCpp.h ?) that contains copys of all the existing namespaces. Is this correct?
- The second link also suggests to create a separate header file but gives no details on how to do that. (Is implementing the PImpl pattern not overkill for a simple library?)
And as far as I understand it, I need to export the public API of a shared library through 1 single header file.

No, you don't have to. Many libraries, especially more complex ones, come with a large number of header files! Note: Wherever the user #include's your header file, everything in that header file gets "imported" into the user's namespace. Therefore you want to reduce the "public" header file(s) to the bare minimum! For example, don't define anything there that could be internal to your library. Also, at some point, you may want to split the header file into several header files, so that the user can decide to #include just what they really need...

For example, if you have several classes that are closely related and that are almost always used together, then it could make sense to merge the declarations of those classes in a single header file. In the general case, however, I would tend to create a separate header file for each class, in order to have a clean separation and to not clutter the user's namespace with (probably) unneeded declarations.

The C standard library actually is a good example of this, as its public API is split into various header files for different purposes:
https://en.wikipedia.org/wiki/C_standard_library#Application_programming_interface_(API)

Should I transfer all the public information to the public API?

Yeah, you should think of the "public" header file(s), i.e. the .h file(s) that are usually provided in an include directory, alongside with the actual library, as the public interface (API) of your library. It is supposed to contain everything that the user needs to call into your library. It also means that anything which is not considered to be part of the public API of your library should not be in the "public" header files.

Keep in mind: Everything you put into the "public" header files becomes a contract between the application and your library. You won't be able to change those things afterwards (without breaking existing applications), so be very careful what you decide to put in the "public" header files! Meanwhile, anything that remains "internal" to your library can usually be changed quite easily...

How exactly you organize your "public" header files (e.g. whether you use one or several header files), that is totally up to you 😉
Last edited on
The answer so far has been: "Yes. Kind of."

If you would like to share the code with us in some form (like through github) we might be able to test it, use it, share it, and help figure out what configuration would be best for your users.

But without seeing the code or the API, there is not much that we can offer.

Without seeing the code, the best we can say is, "yes, those are options that you might take. They might make sense for certain situations, possibly that option could be useful". There has been no absolutes made yet because there are pros and cons that must be weighed based on what you are trying to do.
Last edited on
I hardly ever use git and have never used Eclipse before to export an existing project to a local git-repository.
My first attempt to use Eclipse egit to a fresh created local repository resulted in a f***kedup project ;-(.
I'll do my best to publish all code - still including the remnants of try-outs - via git.

EDIT
I created a local Repo and remote repo on Github (so I know that I am able to login to Github). I have enabled 2FA and regenerated security keys but everytime that I try to push changes to Github, I get a 403 error.
Any idea how I might configure git on my Fedora installation?
Last edited on
Oomph.
Eclipse is a beast. It took me a bit to get used to everything. I'm used to just using command line tools while programming (g++, git and vim)
OK, To your issue:
I created a local Repo and remote repo on Github (so I know that I am able to login to Github). I have enabled 2FA and regenerated security keys but everytime that I try to push changes to Github, I get a 403 error.
Any idea how I might configure git on my Fedora installation?

You're going to want to create a personal access token (in github) then plug that into Eclipse: https://stackoverflow.com/questions/32527522/how-to-github-two-factor-authentication-with-eclipse

After copying your files over and pushing the project changes to git, just share a link to the github page to anyone you want.
Here's a "How to" to push your changes to github: https://www.numpyninja.com/post/how-to-export-eclipse-projects-to-github

About the shared library, are you getting an error message about -fPIC?
If yes, then go to "Project" in the side view there will be a drop-down for "C/C++ Build", and in that drop-down is the "Settings" menu.
In the Settings menu options, there are two drop-downs both labeled "GCC C++ Compiler" go to "Miscellaneous" in both of those drop-downs, and click the selector for "Position Independent Code (-fPIC)"

Last edited on
I've been trying for nearly a week to create submodules for libBasexCpp and libBasexTest.
They are created but in Github I can't open them (see also: https://stackoverflow.com/questions/76324845/how-can-i-push-a-local-submodule-to-a-remote-repository-on-github). And yesterday, after accidentally deleting the local files, I could restore them with Git fetch.
I haven't yet figured out how to properly configure git, but for now I've published all source code in the sources directory.
I have also copied the CMakeLists.txt files

See https://github.com/BenEngbers/BasexCpp/tree/master

Hope this helps.

EDIT

I finally managed to create a submodule for libBasexCpp. Since libBasexTest is not meant to be a shared object but is only a testprogram, I
didn't create a separate submodule.

END EDIT
Last edited on
Topic archived. No new replies allowed.