Table of Contents

CMake Executables and Libraries

add_executable(name source1.cpp source2.cpp) builds an executable from source files. add_library(name source1.cpp ...) builds a library — either static (.a, .lib) or shared (.so, .dll) depending on the type specified.

Building an executable:

add_executable(myapp main.cpp)
add_executable(myapp main.cpp util.cpp helper.cpp)

The first creates an executable from one source file. The second lists multiple sources. You can also use glob patterns to find sources:

file(GLOB SOURCES "src/*.cpp")
add_executable(myapp ${SOURCES})

Building libraries:

add_library(mylib STATIC source.cpp)   # static library (.a or .lib)
add_library(mylib SHARED source.cpp)   # shared library (.so or .dll)
add_library(mylib source.cpp)          # default: STATIC on most systems
add_library(mylib INTERFACE)           # header-only: no compilation

Static libraries are linked into the final executable (no runtime dependency). Shared libraries are loaded at runtime (smaller executable, but library must be available).

Modern practice: use target_sources() instead of listing files in add_executable() or add_library():

add_executable(myapp)
target_sources(myapp PRIVATE main.cpp util.cpp)

This is clearer when building complex targets with conditional sources or generated files.

Specifying sources:

add_executable(myapp
  src/main.cpp
  src/utils.cpp
  include/utils.h
)

Header files can be included (for IDE project generation and dependency tracking), but only .cpp files are actually compiled.

Use add_library() for anything reusable: core logic, utilities, third-party wrappers. Use add_executable() for entry points and tools. Both can link to other targets via target_link_libraries().