6

In the comments of a recent answer, I equated a static library with an archive of compiled object files.

The response was that they are not the same, so what is the difference?

To clarify - gcc accepts an archive of object files as a library, as per Ar_(Unix) #Example_usage. How does this differ from other forms of static library (if any), and what benefits or negatives are there from using these different library types?

The specific claim was that compiling the source files directly instead of linking with a static library

will result in faster and better code, especially if you turn on Link Time Optimisation.

and

You can make an archive of .o files that have been compiled with -flto but those aren't really a static library

however if there are other differences, then I welcome answers addressing those.

Baldrickk
  • 714
  • 5
  • 12
  • 1
    Since "object archive" is a term I think you made up, this question is unanswerable. – whatsisname Mar 28 '19 at 16:41
  • 3
    @whatsisname as per [ibm page on ar](https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxa500/libarc.htm) _"ar maintains archive libraries. The archive library is a collection of files, typically object files."_ – Baldrickk Mar 28 '19 at 16:45
  • I looked at the link you posted, which led me [here](https://en.wikipedia.org/wiki/Ar_(Unix)), which led me [here](https://en.wikipedia.org/wiki/Archive_file) which describes an "archive" as something akin to a [Zip file](https://en.wikipedia.org/wiki/Zip_(file_format)). – Robert Harvey Mar 28 '19 at 16:51
  • 1
    A zip of object files is an archive, but isn't useable as a static library AFAIK. Any .a static library is one type of archive, though. Unless the respondee expected a different platform, since you haven't specified one. – Useless Mar 28 '19 at 16:56
  • @Useless: Clearly, they're two different things. – Robert Harvey Mar 28 '19 at 16:57
  • Each apple is different then the next apple. Doesn't make any of them oranges. Yet this is all fruit. I can't say who is right. Can you provide the context this dispute happened in? – candied_orange Mar 28 '19 at 17:03
  • 2
    No, one is a superset of the other. A static library is (at least in POSIX-ish environments) one possible type of archive. But there are lots of other archives thar are not at all static libraries. – Useless Mar 28 '19 at 17:05
  • @candied_orange see the linked question – Baldrickk Mar 28 '19 at 17:07
  • What linked question? Do you just want to know how the file formats of different archives differ? Or how gcc differs in treating archives as static libraries? Or something else? – Useless Mar 28 '19 at 17:08
  • @Useless to clear up any confusion on behalf of _any_ party, I'm interested only in what can be used as a static library when compiling/linking, and not any other type of archive – Baldrickk Mar 28 '19 at 17:08
  • @Useless specifically, [this answer](https://softwareengineering.stackexchange.com/a/369128/149608) (question linked in the panel on the right) and how the use of different (static) libraries can affect the compilation/linking process – Baldrickk Mar 28 '19 at 17:09
  • So are you really asking about the LTO behaviour, and whether there are similar issues? That's a compiler-specific link-time optimization quality-of-implementation question, and nothing really to do with the archives themselves except that they don't typically contain the original source code. – Useless Mar 28 '19 at 17:17
  • Just curious, why the static limitation? Have something against dynamic libraries? – candied_orange Mar 28 '19 at 18:06
  • 1
    @RobertHarvey A static library is literally an archive of object files in ar format (which is a different but equally valid format to zip or tar). – user253751 Mar 29 '19 at 02:49

2 Answers2

5

A static library is just an ar archive (like zip but ancient) of object files. An object file is the source code that has been compiled to machine code, but hasn't been linked yet. You can make a static library like this (on Linux/OSX):

# Create a source file containing the single function in our library.
echo "int answer() { return 42; }" > answer.cpp
# Compile it to machine code.
c++ -c answer.cpp -o answer.o
# Compress it into an ar archive.
ar -r libanswer.a answer.o

That's it. The ar format isn't specific to static libraries at all. You can use it like Zip if you want (but nobody does because it is old and rubbish). There is also one slight improvement you can make which is to add an index to all the symbols in the library which can give a performance improvement when linking. Like this:

ar -rs libanswer.a answer.o

That's all ranlib does if you've ever wondered.

Anyway - the point about Link Time Optimisation is that it doesn't create a "real" object file, in the sense that it doesn't compile to machine code. Take a look:

$ c++ -c answer.cpp -o answer.o
$ c++ -c answer.cpp -flto -o answer_lto.o
$ file answer.o
answer.o: Mach-O 64-bit object x86_64
$ file answer_lto.o
answer_lto.o: LLVM bitcode, wrapper x86_64

answer.o is a native Mach-O object file (because I am on Mac; on Linux it will be ELF). But answer_lto.o is not! It's LLVM bitcode. That hasn't been compiled to machine code.

You can put this in an ar archive if you want:

ar -r libanswer_lto.a answer_lto.o

But this isn't a real static library, and no tools (except Clang) will be able to link with it. GCC could link with libanswer.a but not with libanswer_lto.a.

I guess you could call libanswer_lto.a a "static library" if you wanted (definitions can change etc.) but if you said "here is a static library" and gave them libanswer_lto.a most people would say "what, no it isn't".

I would call it an LLVM bitcode library or something like that.

Timmmm
  • 226
  • 1
  • 6
  • You can't use a zip file for linking. It won't work unless you unpack it and manually link the object files. –  Apr 01 '19 at 12:22
  • No of course not. I didn't say that you could. – Timmmm Apr 01 '19 at 12:51
  • Then why mention `zip` files? They were only asked about in the comments, not the question itself. –  Apr 01 '19 at 21:11
  • 4
    I was explaining what an `ar` archive is. It's like a `zip` file (but a much older format, and without any compression). – Timmmm Apr 02 '19 at 11:58
1

They're both the same, and they're both made by ar.

An archive of object files (made by ar rc $object_files or something similar) is equivalent to other forms of a static library (of which, as far as I know, there are none).

The claim

that compiling the source files directly instead of linking with a static library will result in faster and better code

is not true. There is no overall effect of linking from a static archive vs. linking against the source/object files directly. In fact, linking object files directly may significantly increase executable size.

The claim

You can make an archive of .o files that have been compiled with -flto but those aren't really a static library

is not necessarily true. Those object files should work when linked into any program or shared library, and the difference is not obvious as to whether they are regular object files or LTO objects.

  • GCC also [does not produce standard object files when using `-flto`](https://gcc.gnu.org/onlinedocs/gccint/LTO-object-file-layout.html#LTO-object-file-layout). They *are* in ELF format, but they just have sections containing GCC IR, exactly like LLVM does. You couldn't link them with Clang. – Timmmm Apr 02 '19 at 12:03
  • You cannot link with a static library (i.e. an archive of fully-compiled object files) if you want to use LTO. LTO needs access to the GCC IR, or LLVM bitcode. – Timmmm Apr 02 '19 at 12:05