What are *.a files found in /usr/lib/

I am trying to slim down my Poudriere Image build and I was running du to find largest files and directories and I ran across both *.o files and *.a files in /usr/lib/ which I wondered about.
Most of the actual library files have an *.so file extension with versioning number suffixed to them as well.

I am pretty sure 'o' files should not be in the directory. Object files might be a remnant of the build process. What are the 'a' files purpose? Also *_p.a files seem suspect.

I have already excluded /usr/lib/debug/ from my build but I am wondering about lib files actually needed.. I have stripped out the compilers so I can't see a need for object files.
This is a run only appliance build.
 
Another user confirmed my suspicions here in another post:

However, at the same time, the compiler also compiles other formats of my library, which I absolutely do not need. In particular, *..a and *_p.a.

Is this on track? These are other formats of the library?
 
Those are "ar archives". From the man 1 ar manual page:

The normal use of ar is for the creation and maintenance of libraries
suitable for use with the link editor ld(1), although it is not re-
stricted to this purpose. The ar utility can create and manage an
archive symbol table (see ar(5)) used to speed up link editing opera-
tions. If a symbol table is present in an archive, it will be kept up-
to-date by subsequent operations on the archive.
 
Using libarchive as an example:

Code:
/usr/lib # ls -ll libarchive*
-r--r--r--  1 root  wheel  5889036 Jan 28 00:21 libarchive.a
lrwxr-xr-x  1 root  wheel       15 Jan 28 00:21 libarchive.so -> libarchive.so.7
-r--r--r--  1 root  wheel        0 Jan 28 00:59 libarchive.so.7
-r--r--r--  1 root  wheel  5962494 Jan 28 00:21 libarchive_p.a
The "so" file is symbolic linked to versioned one. But versioned file has zero size? Is it linked to the 'a' file?
 
the versioned file having 0 size seems weird. on my system there's code there.
Code:
π file /usr/lib/libarchive.so.7
/usr/lib/libarchive.so.7: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 13.2, stripped

Also, the `.a` files are for static linking. As mentioned, they are ar-files that contain a sequence of .o files. if you're not compiling stuff on the machine, you should only need the .so files.

as for the _p versions, not sure. Those might be position-independent archives?
 
The .a files are static libraries in ar(5) format. Files with a .so extension are shared dynamic libraries in elf(5) format.

When you link your code with a static library, the actual code you linked is added to your executable at link time. This makes your binary executable larger, but there's no need to find anything at run time. This avoids "DLL hell" because you have the exact version you need already included in your code. However, if there's a bug in the library you'll have to re-compile and re-link to get a fix.

When you link to a shared library, it's loaded into your executable's address space at run time. Your binary is smaller, and many different binaries can share the same library file. There can be problems if the run time linker can't find the correct version of your library. However, bug fixes are as simple as dropping in a new version of the shared library and re-running your executable.

In my experience, linking is one of the hardest things to understand in the compilation process. I found this post on the Gold linker enlightening:
 
Thank You for pointing that out. This is on the actual MFS appliance machine...
That must have been a bad example because the other libraries have size.

Code:
-r--r--r--  1 root  wheel     31834 Jan 28 00:21 libgpio.a
lrwxr-xr-x  1 root  wheel        12 Jan 28 00:21 libgpio.so -> libgpio.so.0
-r--r--r--  1 root  wheel      9992 Jan 28 00:21 libgpio.so.0
-r--r--r--  1 root  wheel     32370 Jan 28 00:21 libgpio_p.a
 
Nice ldd manual example for finding what depends on the library:

find . -type f | xargs file -F ' ' | grep 'ELF.*dynamically' | cut -f1 -d' ' | xargs ldd -f '%A %o\n' | grep -F libgpio.so.0
./libgpio.so.0 libc.so.7

So libgpio.so is linked to libc.so.7 or libc is linked to libgpio?
 
right. so. the .a files are only necessary if you're building stuff on the box and doing static linking. you should be able to get away with removing the .a files if you're starved for space.
 
ldd uses the dynamic linker to load the binary and its dependencies into memory, and then relies on the dynamic linker itself to print details to the console
 
Thanks Everyone it appears there were no problems with them being removed from the build.

My mfsroot running memory disk is 835M with 428M used and 340M available. I have a 1000M budget but my pkglist is still small. Tying to make room for some programs and keep it small.
Board has 2G fixed RAM. Using half for mfsroot? Leaving 1G.. Just an experiment on MinnowboardMax.

I have some running SATADOM but I wanted to expose minimal usable system possible.microSD and MFS.
 
Here is a look at my Poudriere Image based MFS files. This is my image loaded with mdconfig on build box:

Code:
=>      3  2446253  md0  GPT  (1.2G)
        3    20480    1  efi  (10M)
    20483       45    2  freebsd-boot  (23K)
    20528  2425728    3  freebsd-ufs  (1.2G)

So a 10M EFI and freebsd-boot partition.

Mount the root partition and look at size:
df -h
/dev/md0p3 1.2G 1.0G 69M 94% /mnt

It would appear from this its almost out of space. The space is constrained by memory disk. It is RO and compressed and will not grow.

ls /mnt
boot mfsroot

ls -ll /mnt/mfsroot
-rw-r--r-- 1 root wheel 877592576 Dec 24 23:33 /mnt/mfsroot

So the memory disk within the structure is only 877 Megs. I believe it is gz format. Not sure. Not mountable.

I am going to try and remount my memory disk RW next time to alter settings. See if that works to modify.
 
Back
Top