CMAKE difference between PUBLIC PRIVATE and INTERFACE link

target_link_libraries(target [PUBLIC|INTERFACE|PRIVATE] libs...)

Taken from https://cmake.org/pipermail/cmake/2016-May/063400.html

Nicest explanation I’ve seen regarding this topic.

1. PRIVATE

Target A needs library B for it’s implementation but a library C that uses A would not need to know/use library B.

For example, a wrapper library A that links to a low level networking library. User C only talks with A by passing a uint8_t array, and B underlying does all the magic. The user C never needs to learn how to use, or how the structures of B look like.

int A(int input) {
    B::datatype foo;
    foo.dotask(input);
}

2. INTERFACE

Target A needs library B. User C of library A only has to know about B it’s API. For example a library A that takes a structure of library B and casts it to uint8_t array to store it into a file. A never uses/calls B code, only uses it’s API, for example, relaying the calls to another library.

int A(B::datatype foo) {
    memcpy(... (uint8_t *)foo ...);
}

3. PUBLIC

PRIVATE + INTERFACE

int A(B::datatype foo) {
    foo.bar();
}