I am new to linux system programming and I came across API and ABI while reading Linux System Programming.

Definition of API :

An API defines the interfaces by which one piece of software communicates with another at the source level.

Definition of ABI :

Whereas an API defines a source interface, an ABI defines the low-level binary interface between two or more pieces of software on a particular architecture. It defines how an application interacts with itself, how an application interacts with the kernel, and how an application interacts with libraries.

How can a program communicate at a source level ? What is a source level ? Is it related to source code in anyway? Or the source of the library gets included in the main program ?

The only difference I know is API is mostly used by programmers and ABI is mostly used by compiler.

up vote 36 down vote accepted

The API is what humans use. We write source code. When we write a program and want to use some library function we write code like:

 long howManyDecibels = 123L;
 int ok = livenMyHills( howManyDecibels);

and we needed to know that there is a method livenMyHills(), which takes a long integer parameter. So as a Programming Interface it's all expressed in source code. The compiler turns this into executable instructions which conform to the implementation of this language on this particular operating system. And in this case result in some low level operations on an Audio unit. So particular bits and bytes are squirted at some hardware. So at runtime there's lots of Binary level action going on which we don't usually see.

API: Application Program Interface

This is the set of public types/variables/functions that you expose from your application/library.

In C/C++ this is what you expose in the header files that you ship with the application.

ABI: Application Binary Interface

This is how the compiler builds an application.
It defines things (but is not limited to):

  • How parameters are passed to functions (registers/stack).
  • Who cleans parameters from the stack (caller/callee).
  • Where the return value is placed for return.
  • How exceptions propagate.

I mostly come across these terms in the sense of an API-incompatible change, or an ABI-incompatible change.

An API change is essentially where code that would have compiled with the previous version won't work anymore. This can happen because you added an argument to a function, or changed the name of something accessible outside of your local code. Any time you change a header, and it forces you to change something in a .c/.cpp file, you've made an API-change.

An ABI change is where code that has already been compiled against version 1 will no longer work with version 2 of a codebase (usually a library). This is generally trickier to keep track of than API-incompatible change since something as simple as adding a virtual method to a class can be ABI incompatible.

I've found two extremely useful resources for figuring out what ABI compatibility is and how to preserve it:

this is my layman explanations:

  • api - think include files. they provide programming interface
  • abi - think kernel module. when you run it on some kernel, they has to agree how to communicate without include files, ie as low-level binary interface

(Application Binary Interface) A specification for a specific hardware platform combined with the operating system. It is one step beyond the API (Application Program Interface), which defines the calls from the application to the operating system. The ABI defines the API plus the machine language for a particular CPU family. An API does not ensure runtime compatibility, but an ABI does, because it defines the machine language, or runtime, format.

enter image description here

Courtesy

Let me give a specific example how ABI and API differ in Java.

An ABI incompatible change is if I change a method A#m() from taking a String as an argument to String... argument. This is not ABI compatible because you have to recompile code that is calling that, but it is API compatible as you can resolve it by recompiling without any code changes in the caller.

Here is the example spelled out. I have my Java library with class A

// Version 1.0.0
public class A {
    public void m(String string) {
        System.out.println(string);
    }
}

And I have a class that uses this library

public class Main {
    public static void main(String[] args) {
        (new A()).m("string");
    }
}

Now, the library author compiled their class A, I compiled my class Main and it is all working nicely. Imagine a new version of A comes

// Version 2.0.0
public class A {
    public void m(String... string) {
        System.out.println(string[0]);
    }
}

If I just take the new compiled class A and drop it together with the previously compiled class Main, I get an exception on attempt to invoke the method

Exception in thread "main" java.lang.NoSuchMethodError: A.m(Ljava/lang/String;)V
        at Main.main(Main.java:5)

If I recompile Main, this is fixed and all is working again.

Your program (source code) can be compiled with modules who provide proper API.

Your program (binary) can run on platforms who provide proper ABI.

API restricts type definitions, function definitions, macros, sometimes global variables a library should expose.

ABI restricts what a "platform" should provide for you program to run on. I like to consider it in 3 levels:

  • processor level - the instruction set, the calling convention

  • kernel level - the system call convention, the special file path convention (e.g. the /proc and /sys files in Linux), etc.

  • OS level - the object format, the runtime libraries, etc.

Consider a cross-compiler named arm-linux-gnueabi-gcc. "arm" indicates the processor architecture, "linux" indicates the kernel, "gnu" indicates its target programs use GNU's libc as runtime library, different from arm-linux-androideabi-gcc which use Android's libc implementation.

  • this is a very succint explanation of difference between them, and in a very unique perspective. – Sajuuk May 2 at 10:26

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.