libc unit

From Free Pascal wiki
Jump to navigationJump to search

The libc unit (not to be confused with the libc library (.so)) is a header to the libc library created for Kylix.

FAQ: The libc unit is deprecated, and frozen in time for Kylix compatibility, and won't be ported to other architectures or operating systems.

The problem with unit libc

There is a lot of confusion about why unit libc has been deprecated. With this faq I hope to end this discussion. There is a lot of confusion because FPC has different policies on library libc and unit libc. An often heard argument is that (library) libc use is strictly forbidden, which is simply not related to the problem of the libc unit.

The libc library policy is way simpler and unrelated: the core bootstrap and some other base libraries is kept free from libc for bootstrapping and long term compatibility reasons. Functionality that needs the libc library is plugged in. (cthreads,clocale,cmem,cwstrings)

The actual problem with the UNIT libc is that Borland followed the same model with Kylix as they did on Windows. While doing Kylix, they simply stuffed anything platform dependant they could find into unit libc without any discrimination. This resulted the unit being stuffed top till bottom with types,consts and calls from various origins, and with various portability concerns:

  • linuxisms ( stuff that only works on Linux)
  • glibcisms (stuff that only works with glibc, but not e.g. with uclibc)
  • Libraries that are in fact external, but linked into the glibc library on stock linux (but not part of the actualy glibc distribution). Here I mean stuff like iconv.
  • kernel version dependant stuff
  • x86 specific issues
  • other system libraries like libdl.
  • All records and structures are visible without any discrimination, even if they are kernel version dependant. No attempt was made to clean up, and limit visibility of internal fields.
  • Temporary stuff like -32 and -64 versions of calls. (mostly x86 specific because that architecture has the largest legacy)

Note that this clearly makes this more than a "Linux vs the rest" situation. Other architectures (64-bit), embedded uclibc and long term compatility (what if libc no longer exports fstat64 because the grace period is over and off_t is always 64-bit?) are things that a lot of Linux developers will have to face sooner or later too.

For Borland this never was a problem, since they simply make you pay for the next "cleaned up" version, if Kylix hadn't been iced.

So what to replace it with?

That's not easily answered, since that is the exact problem with unit libc. It is a mix of stuff with a lot of different tradeoffs. Below are some options in decreasing preference.

  1. For basic Unix calls use existing units like baseunix,unix, termio (terminal), sockets (base networking), x86 (32-bit x86 cpu specific stuff like portio)
  2. For less basic, but common functionality use the units that already abstract these as much as possible:
    • dynlibs (dynamic loading of libraries). Also works on windows.
    • users (2.2.2+ Unix users, groups and passwords) or
    • iconvenc (2.2.3+, iconv unicode support)
    • netdb (DNS, though this is an independant implementation of a resolver lib, not a libc header) A good multiplatform resolver unit that uses libc would be a good thing.
  3. If the functionality you desire is not yet abstracted, create and submit a package where the functionality you desire is abstracted in a relative platform independant way. (e.g. an unit that provides an abstract notification mechanism, using inotify on Linux and Kpoll on FreeBSD and OS X). In first order, limit yourself to the base functionality. This will require some compromises, but rule of thumb is that 90% of the people only use the base functionality.
  4. If it is linux only, maintain your own headers, and put them on the contributed units page.
  5. If it is a single Linux system call that can't be abstracted add it to unit linux.

If you don't like either of these options, dig up as much information as you can about portability, and about what you want to achieve, and post it to the "fpc-devel" list.

But I only want....

If we first commit raw Linux/x86 headers (and thus often linux/x86-glibc specific ones), and only then start worrying about portability, we may as well fork the RTL immediately, and forget aboutcross-unix portability.

All people wanting to contribute must invest some time in learning to expose functionality in a portable way. Note that for it to be of any use for other projects like Lazarus, the database engines etc, it must be portable anyway, so better start with it.

While it is easy to just throw a barely tested basic header into SVN, without any research into portability, this will only cause frustration for users that have to change their code, because lateron the interfaces change again.

Also keep in mind that there are various portability concerns. Not just say "Mac OS X" vs Linux, but also more subtle problems like revealing kernel details, endianess, 32 vs 64-bit issues, using glibcisms (embedded Linuxes, also x86 use different libcs) etc.

It is unfair to drop all portability concerns onto the unix users that don't only mainstream linux/x86 (FreeBSD, OS X, non x86 Linux and Linux uclibc programmers). Specially because quite a lot of Linux/x86 users tend to develop for OS X too at some point.

Resources

Nobody expects that you prepare such a perfect unit at once, and without help. Here are some sources that can give assistance:

  • the fpc-devel maillist
  • the fpc-pascal maillist
  • FPC irc. (irc.freenode.net #fpc)
  • The Open Group site has a lot of information about what unix functionality is standarized. If you have troubles with interpretation, ask on IRC or the maillist.
  • Several *nix vendors have their manpages online, which can be used as a quick check to see if a certain call is supported. Don't take this as absolute truths though, there are exceptions.FreeBSD man page
  • And in all other cases, Google is a good resource. Searching for "freebsd name_of_call or " freebsd name_of_call porting" can yield good results.