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().