[2026] CMake Link Errors: LNK2019, undefined reference, and Fixes [#49-2]

[2026] CMake Link Errors: LNK2019, undefined reference, and Fixes [#49-2]

이 글의 핵심

Fix undefined reference and LNK2019: missing.cpp, missing libraries, extern C, vcpkg toolchain, and link order. CMake-focused troubleshooting for C++ builds.

Introduction: “undefined reference to ...” / LNK2019

undefined reference to ‘symbol’ (GCC/Clang) and LNK2019: unresolved external symbol (MSVC) mean the linker could not find a definition for a referenced symbol. Compile succeeds because declarations suffice; link fails when definitions are missing or wrong libraries are linked. This article covers:

  • Missing definitions, wrong translation units, .cpp not in target
  • Missing target_link_libraries
  • find_package / library not found (vcpkg toolchain, CMAKE_PREFIX_PATH)
  • C vs C++: extern “C”
  • Link order and multiple definition
  • CMake-centric debugging steps and CI hygiene See also: CMake intro, Compilation pipeline, Advanced CMake.

아래 코드는 mermaid를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

flowchart LR
    subgraph Compile[Compile]
        A[.cpp] --> B[Compiler]
        B --> C[.o / .obj]
    end
    subgraph Link[Link]
        C --> D[Linker]
        E[.a / .so / .lib] --> D
        D --> F[Executable / DLL]
    end
  • Compile: each .cpp is independent; declarations are enough.
  • Link: the linker resolves symbols across objects and libraries.

Scenarios

ScenarioFix
New library, unresolved Boost/Asio symbolsfind_package + target_link_libraries with correct components
multiple definitionNo non-inline function definitions in headers included by multiple TUs; use inline, one .cpp, or static
cannot find -lfoo / find_package failsCMAKE_TOOLCHAIN_FILE (vcpkg), CMAKE_PREFIX_PATH
C library from C++extern "C" + link the C library
Subproject static libadd_library + target_link_libraries(app PRIVATE mylib)

Debugging flow

아래 코드는 mermaid를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

flowchart TB
    A[Link error] --> B{Type?}
    B -->|undefined| C[Symbol name → own code or lib?]
    C -->|Own| D[Add .cpp / target_sources]
    C -->|External| E[target_link_libraries]
    B -->|multiple def| F[Header definitions / ODR]
    B -->|not found| G[Toolchain / prefix path]

1. Reading error messages

  • GCC/Clang: undefined reference to \Qualified::Name“
  • MSVC: mangled signature in LNK2019—match const, references, namespaces.

2. Missing definition / .cpp not built

  • find_package(Threads REQUIRED)target_link_libraries(…Threads::Threads)
  • Boost: link Boost::system, asio::asio, etc., not only include dirs.
  • Prefer imported targets over raw -l.

4. Library not found

vcpkg:

vcpkg install fmt:x64-linux
cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
find_package(fmt REQUIRED)
target_link_libraries(my_app PRIVATE fmt::fmt)

5. extern "C" for C libraries

C++ name mangling does not match C export names. Wrap C declarations in extern “C” (or use headers that already do).

  • Some linkers are sensitive to left-to-right resolution; CMake target dependencies usually propagate order.
  • ODR: one definition per symbol across the program; inline / single .cpp / static in TU.

Example fixes (sketches)

Missing utils.cpp:

add_executable(app main.cpp utils.cpp)

Boost Asio:

find_package(Boost REQUIRED COMPONENTS system)
target_link_libraries(app PRIVATE Boost::system asio::asio)

Multiple definition from header:

inline int add(int a, int b) { return a + b; }  // or move definition to .cpp

vcpkg fmt:

cmake -B build -DCMAKE_TOOLCHAIN_FILE=.../vcpkg.cmake

Debugging steps

  1. Extract symbol from the error.
  2. grep / IDE: declaration vs definition.
  3. Confirm .cpp in CMake target.
  4. For external libs: docs, nm, dumpbin.
  5. cmake —graphviz for dependency graph.
  6. CMAKE_EXE_LINKER_FLAGS=-Wl,—verbose (GCC) to see link line.

Quick fixes table

Error patternCheck
pthread_*Threads::Threads
dlopenCMAKE_DL_LIBS
_main / WinMainsubsystem and entry
vtable for ...virtuals implemented, .cpp linked
__atomic_*libatomic where needed
__gxx_personality_v0C++ linker / project(....LANGUAGES CXX)

Production patterns

  • IMPORTED / INTERFACE targets encapsulate paths.
  • FetchContent pins versions.
  • CI uses same vcpkg toolchain as dev.
  • PUBLIC/PRIVATE propagation for includes and libs.


FAQ

Summary

SymptomLikely causeFix
undefined referenceMissing definition or libAdd .cpp / target_link_libraries
cannot find -lfooPaths / toolchainvcpkg, find_library, PREFIX_PATH
C symbols missingManglingextern "C"
multiple definitionHeader definitionsinline / single .cpp
Next: Asio deadlock debugging (#49-3)
Previous: Segfault debugging (#49-1)

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3