Using third-party libraries

I’d like to begin by acknowledging that there are many other posts discussing this topic. Nevertheless, after a thorough review, I’ve observed that none of them explicitly explain the specifics of my questions issues that I am encountering. I have several questions that I would greatly appreciate if someone could take the time to explaining how these elements function and their significance in more detail.

My first question involves the use of the 4 following commands:


Whenever I research the topic of “Adding third-party libraries”, I consistently come across one of the commands mentioned above. Each response typically addresses how to resolve issues by altering these commands or solving common small developer mistakes. However, none of them dive deeper into the actual functionality of these commands. While I did consult CMake’s documentation on them, I must admit that the documentation isn’t the most user-friendly resource I’ve encountered.

Here’s what I’ve managed to find about these commands. I start off with the ones I understand better (Or at least I hope I understand better):


# Specifies the directories that have header files in them. It will add those directories with their header files to the target.


# Links the library files to the final executable, so it can work after being exported.


# Find a package and load its package-specific details


# This command is used to find a library

Here are the questions that I have about the above:

  1. If “target_include_directories” locates the header files (.h files) and “target_link_libraries” identifies and links the necessary libraries to the final executable (.cpp and *.lib files), then the question arises: what purpose does “find_package” serve? (Aren’t header files and their corresponding implementation libraries all that’s required to utilize a library?)

  2. What sets apart “find_package” from “find_library”? (Both appear to serve the purpose of locating a library, yet one is labeled as a “package” and the other as a “library.” What advantages and disadvantages do they each bring to the table?)

In addition to the above commands, I’ve been wondering whether there exists a more direct and hands-on approach. Is there a way to explicitly specify the header and library files required for connection to one’s executable and project by giving the full path to each file, rather than depending on these commands? (I’ve noticed substantial variation between libraries – some, like the Boost library, seamlessly integrate with these commands, while others, like SFML, prove to be challenging to work with due to a lack of standardization and frequent architectural changes)

This looks fine.

This is correct, but not a complete picture. tll works by applying usage requirements of targets (the “right hand side”) to other targets (the “left hand side”). So target_link_libraries(tgt PRIVATE foo) says “give tgt the usage requirements of foo, but not those using tgt”. Usage requirements can be things like compile definitions, include directories, compile options, link options, libraries to link, and a few more.

Pretty much correct. Note that what it means to “find” a specific package can vary greatly.

If by “find” you mean “find where a library lives on the system”, yes. It has nothing to do with the linker finding said library though.

Here I see some confusion. target_include_directories(tgt) does not “locate” anything. It just says “tell the compiler when to add these directories to the include search path when compiling tgt”. This is basically a set of -I flags pretty much everywhere.

There are two parts:

  • finding where things are on the system
  • using them for specific things

So the find_* commands all handle the first part. But they do nothing about actually using this information. That belongs to the target_* family of commands.

A package is a logical collection of artifacts (headers, libraries, resources, executables, whatever). find_library is about finding a specific library.

1 Like