add_executable is for creating an executable program - you know: my_program.exe. add_library is for creating a library, either static or dynamic, e.g.: my_library.lib or my_library.dll. A library is a bundle of compiled source code that can be used by other projects. For example: PhotoShop is a program and Qt is a library. However, when you make a project which is an executable program you may sometimes choose to split it into several internal libraries, i.e. libraries that are not supposed to be shared and used by other projects. The most common reason it that the project has unit tests which are run as a separate executable program. If you just do this: add_executable(my_program src/main.cpp src/src1.cpp src/src2.cpp ...) add_executable(my_program_tests test/main.cpp src/src1.cpp, src/src2.cpp ...) Then you end up compiling the files src1.cpp, src2.cpp, ..., two times, wasting time. You only need to compile them once and link the generated object code into the main executable and the test executable. This can be accomplished by putting the source code (except the one with the main function`) into a static library: add_library(my_program_code STATIC src/src1.cpp src/src2.cpp ...) add_executable(my_program src/main.cpp) # link the 'my_program_code' library into the main executable target_link_libraries(my_program my_program_code ) add_executable(my_program_tests test/main.cpp) # link the 'my_program_code' library into the test executable target_link_libraries(my_program_tests my_program_code) Now you project compiles faster! Header files are not normally added as source files to a target as they are not compiled. For an executable you should normally put the header files in the same directory as the .cpp files - there is no benefit of splitting them up and putting them in a separate include directory. If you make a standalone library that is supposed to be used by others it is a good idea to put the public header files in a separate include directory. The reason is that the end user only needs the compiled library code (.lib, .dll) and the public headers. As part of the installation process the compiled library files and the public headers are copied to the installation directory - you don't want to copy the .cpp files as well! When you put your header files in a different directory than where the .cpp files are the compiler can's find them. You need to tell it in which directories to search. That is what ´target_include_directories` does. I found out they include the headers by target_link_directories I highly doubt so. They should use target_include_directories for the reason mentioned above. I highly recommend spending a few hours (it will turn into days! trust me) on studying the CMake basics. Here are some resources: https://cmake.org/cmake/help/latest/guide/tutorial/index.html https://cliutils.gitlab.io/modern-cmake/ https://github.com/friendlyanon/cmake-init Answer from the_poope on reddit.com
🌐
CMake
cmake.org › cmake › help › latest › command › add_library.html
add_library — CMake 4.3.0 Documentation
Added in version 3.11: The source files can be omitted if they are added later using target_sources(). For SHARED and MODULE libraries the POSITION_INDEPENDENT_CODE target property is set to ON automatically. A SHARED library may be marked with the FRAMEWORK target property to create an macOS Framework.
🌐
Reddit
reddit.com › r/cmake › how do i add my library, include and other files needed for statictic linking in vscode with c++ and cmake?
r/cmake on Reddit: How do i add my library, include and other files needed for statictic linking in vscode with c++ and cmake?
May 31, 2024 -

So i understand that i need to link my header files which are located in the include folder i also understand that i need to link the lib files in the lib folder.

But i am stuck.

For example if i want to include sfml and use it in my project do i just need to do the following add_library(root/lib) and include_directories(root/include/SFML).

This is my hieracy:

🌐
Android Developers
developer.android.com › devices › compatibility › support 16 kb page sizes
Support 16 KB page sizes | Compatibility | Android Developers
To support compiling 16 KB-aligned shared libraries with Android NDK version r26 or lower, you need to update your ndk-build or cmake configuration as follows: Update your Android.mk to enable 16 KB ELF alignment: ... Always update your NDK. This should only be used as a last resort, and no support is guaranteed. In addition ...
🌐
CMake
cmake.org › cmake › help › v3.8 › command › add_library.html
add_library — CMake 3.8.2 Documentation
See the cmake-buildsystem(7) manual for more on defining buildsystem properties. add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED [GLOBAL])
🌐
Reddit
reddit.com › r/cpp_questions › cmakelist.txt, add_executable vs. add_library vs. target_link_libraries vs. target_link_directories
r/cpp_questions on Reddit: CMakeList.txt, add_executable vs. add_library vs. target_link_libraries vs. target_link_directories
May 24, 2023 -

Recently I'm cleaning up the cmakelist.txt file of my project. I found out when using CLion, it automatically adds both my header and source files to add_executable command in cmake. But when I read some open sourced projects on GitHub. I found out they include the headers by target_link_directories, or create a library from the directory including both headers and sources. May I ask about the rationale behind those choices? thanks

Top answer
1 of 2
10
add_executable is for creating an executable program - you know: my_program.exe. add_library is for creating a library, either static or dynamic, e.g.: my_library.lib or my_library.dll. A library is a bundle of compiled source code that can be used by other projects. For example: PhotoShop is a program and Qt is a library. However, when you make a project which is an executable program you may sometimes choose to split it into several internal libraries, i.e. libraries that are not supposed to be shared and used by other projects. The most common reason it that the project has unit tests which are run as a separate executable program. If you just do this: add_executable(my_program src/main.cpp src/src1.cpp src/src2.cpp ...) add_executable(my_program_tests test/main.cpp src/src1.cpp, src/src2.cpp ...) Then you end up compiling the files src1.cpp, src2.cpp, ..., two times, wasting time. You only need to compile them once and link the generated object code into the main executable and the test executable. This can be accomplished by putting the source code (except the one with the main function`) into a static library: add_library(my_program_code STATIC src/src1.cpp src/src2.cpp ...) add_executable(my_program src/main.cpp) # link the 'my_program_code' library into the main executable target_link_libraries(my_program my_program_code ) add_executable(my_program_tests test/main.cpp) # link the 'my_program_code' library into the test executable target_link_libraries(my_program_tests my_program_code) Now you project compiles faster! Header files are not normally added as source files to a target as they are not compiled. For an executable you should normally put the header files in the same directory as the .cpp files - there is no benefit of splitting them up and putting them in a separate include directory. If you make a standalone library that is supposed to be used by others it is a good idea to put the public header files in a separate include directory. The reason is that the end user only needs the compiled library code (.lib, .dll) and the public headers. As part of the installation process the compiled library files and the public headers are copied to the installation directory - you don't want to copy the .cpp files as well! When you put your header files in a different directory than where the .cpp files are the compiler can's find them. You need to tell it in which directories to search. That is what ´target_include_directories` does. I found out they include the headers by target_link_directories I highly doubt so. They should use target_include_directories for the reason mentioned above. I highly recommend spending a few hours (it will turn into days! trust me) on studying the CMake basics. Here are some resources: https://cmake.org/cmake/help/latest/guide/tutorial/index.html https://cliutils.gitlab.io/modern-cmake/ https://github.com/friendlyanon/cmake-init
2 of 2
3
Not an expert. I think the headers are only added so the IDE can recognize the structure, I think Qt creator didn't show the project properly if the headers weren't listed. I usually do target_include_directories, rather than list the headers together with the sources. An executable needs one main. You can't do unit tests on an executable, without some ugly workarounds. That's why you create libraries, which you the link to your simple executable, and to the unit tests.
🌐
NVIDIA
docs.nvidia.com › cuda › cuda-installation-guide-linux
CUDA Installation Guide for Linux — Installation Guide for Linux 13.2 documentation
January 28, 2026 - For older versions of CMake, the ExternalProject_Add module is an alternative method.
Find elsewhere
🌐
ICS
ics.com › blog › find-and-link-libraries-cmake
Find and Link Libraries with CMake | ICS
June 21, 2023 - Using the same library as before, let's look at what we can do to make “numbers” its own library. The first thing to do is start to clean up the main CMakeLists.txt. We can accomplish this by removing the numbers source files from our target and instead use add_subdirectory to add the numbers ...
🌐
CMake
cmake.org › cmake › help › latest › guide › tutorial › In-Depth CMake Library Concepts.html
Step 5: In-Depth CMake Library Concepts — CMake 4.3.0 Documentation
Verify a shared library is produced for MathFunctions then reset BUILD_SHARED_LIBS, either by reconfiguring with -DBUILD_SHARED_LIBS=OFF or deleting the CMakeCache.txt. There are no changes to the project for this exercise. Interface libraries are those which only communicate usage requirements for other targets, they do not build or produce any artifacts of their own. As such all the properties of an interface library must themselves be interface properties, specified with the INTERFACE scope keywords. add_library(MyInterface INTERFACE) target_compile_definitions(MyInterface INTERFACE MYINTERFACE_COMPILE_DEF)
🌐
Reddit
reddit.com › r/cmake › difference between add_library, add_subdirectory and target_link_libraries
r/cmake on Reddit: Difference between add_library, add_subdirectory and target_link_libraries
August 31, 2023 -

I am following the official cmake tutorial and am currently at Step 2:

Step 2: Adding a Library — CMake 3.27.4 Documentation

Here, a library is created in a child directory. Then, in the parent directory, it is added as a subdirectory. Then, the library is linked to.

Why is there a need to do this in 3 separate steps? I come from a Visual Studio IDE background where if my co-programmer has written a specialized code he is incharge of. All I need to do to incorporate it in my code is to add his header and implementation file to VSIDE and build the entire project. This will create .obj files for my own .cpp files as well as his new .cpp implementation files and linking happens at the linker stage without the need to specify any special library.

The only linking that I have had to do are those cases where I do not have the .cpp implementation file. The author of the library provides header files that define various objects. Then, I have to specify the .lib file in the linker section of the IDE and the project successfully builds.

So, what is the need of 3 separate stages in CMake, when one already has the .cpp files from the library author?

🌐
CMake
cmake.org › cmake › help › latest › guide › tutorial › Adding a Library.html
Step 2: Adding a Library — CMake 4.3.0 Documentation
Step 3: Adding Usage Requirements for a Library · Show Source · index · next | previous | CMake 4.3.0 » · Documentation » · CMake Tutorial » · Step 2: Adding a Library · © Copyright 2000-2026 Kitware, Inc. and Contributors.
🌐
CMake
cmake.org › cmake › help › v3.21 › guide › tutorial › Adding a Library.html
Step 2: Adding a Library — CMake 3.21.7 Documentation
To make use of the new library we will add an add_subdirectory() call in the top-level CMakeLists.txt file so that the library will get built. We add the new library to the executable, and add MathFunctions as an include directory so that the mysqrt.h header file can be found.
🌐
CMake
cmake.org › cmake › help › latest › variable › BUILD_SHARED_LIBS.html
BUILD_SHARED_LIBS — CMake 4.3.0 Documentation
if(BUILD_SHARED_LIBS) add_library(example SHARED ${sources}) else() add_library(example STATIC ${sources}) endif() CMake does not define BUILD_SHARED_LIBS by default, but projects often create a cache entry for it using the option() command:
🌐
Gitlab
cliutils.gitlab.io › modern-cmake › chapters › basics.html
Introduction to the basics — Modern CMake
target_link_libraries is probably the most useful and confusing command in CMake. It takes a target (another) and adds a dependency if a target is given. If no target of that name (one) exists, then it adds a link to a library called one on your path (hence the name of the command).
🌐
Visual Studio Code
code.visualstudio.com › docs › cpp › config-mingw
Using GCC with MinGW
November 3, 2021 - This change impacts how wildcards like "*.cpp" are processed in build commands. To build multiple C++ files in your tasks.json, you must explicitly list the files, use a build system like make or cmake or implement the following workarounds: https://www.msys2.org/docs/c/#expanding-wildcard-arguments.
🌐
Coderwall
coderwall.com › p › gtcfva › disable-cmake-auto-add-lib-prefix-when-using-add_library
Disable CMake auto add `lib` prefix when using `add_library` (Example)
February 25, 2016 - #cmake · Just set this: SET_TARGET_PROPERTIES(name PROPERTIES PREFIX "") This is a Hello Coderwall Tip ;) #cmake · Say Thanks · Respond · 32.25K · 3 · 13K · 5 · 12.06K · 5 · Post · Post a tip · Best #Cmake Authors · daniperez · 57.3K · #cmake · #C++ #Shell ·
🌐
CMake
cmake.org › cmake › help › v3.0 › command › add_library.html
add_library — CMake 3.0.2 Documentation
Adds a library target called <name> to be built from the source files listed in the command invocation. The <name> corresponds to the logical target name and must be globally unique within a project.
🌐
GitHub
github.com › ttroy50 › cmake-examples › issues › 70
What's the meaning of add_library (*** ALIAS ***) · Issue #70 · ttroy50/cmake-examples
September 12, 2021 - add_library(hello::library ALIAS hello_library) why must to use alias name for hello_library? Can I not use the alias name?
Author   kuazhangxiaoai