# Undefined symbols when linking application to library

**URL:** <https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977>\
**Category:** Code\
**Tags:** os:macos\
**Created:** [July 2, 2022, 9:41am UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977 "2022-07-02T09:41:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mitchcurtis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mitchcurtis/32/2559_2.png) [@mitchcurtis](https://discourse.cmake.org/u/mitchcurtis)\
**Post date:** [July 2, 2022, 9:41am UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977/1 "2022-07-02T09:41:49Z")

</div>

When building [this](https://github.com/mitchcurtis/cmake-test) project, I get linker errors:

```auto
17:28:00: Running steps for project root...
17:28:00: Starting: "/opt/homebrew/Cellar/cmake/3.23.1/bin/cmake" --build /Users/mitch/dev/cmake-test-qt_dev_debug_non_fw-Debug --target all
[1/5 1.9/sec] Building CXX object app/CMakeFiles/app.dir/main.cpp.o
[2/5 3.5/sec] Building CXX object libs/libfoo/CMakeFiles/libfoo.dir/AbstractApplication.cpp.o
[3/5 5.3/sec] Building CXX object app/CMakeFiles/app.dir/Application.cpp.o
[4/5 6.6/sec] Linking CXX static library libs/libfoo/libfoo.a
[5/5 7.8/sec] Linking CXX executable app/app
FAILED: app/app 
: && /usr/bin/clang++ -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names app/CMakeFiles/app.dir/main.cpp.o app/CMakeFiles/app.dir/Application.cpp.o -o app/app -Wl,-rpath,/Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib libs/libfoo/libfoo.a /Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib/libQt6Core_debug.6.5.0.dylib /Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib/libQt6Core_debug.6.5.0.dylib -framework DiskArbitration -framework IOKit && :
Undefined symbols for architecture arm64:
  "vtable for Application", referenced from:
      Application::Application() in main.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for AbstractApplication", referenced from:
      AbstractApplication::AbstractApplication() in main.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
17:28:01: The process "/opt/homebrew/Cellar/cmake/3.23.1/bin/cmake" exited with code 1.
Error while building/deploying project root (kit: qt-dev-debug-non-fw)
When executing step "Build"
17:28:01: Elapsed time: 00:01.

```

The classes in libfoo are exported correctly from what I can see, and I’d prefer to not use `generate_export_header` as I’ll be supporting two build systems for this project.

The only thing that I can see that looks odd is that is that the linker uses a relative path to libfoo:

```auto
libs/libfoo/libfoo.a

```

From searching around I’ve read that CMake [should already be aware of the library if it’s created by the same project](https://stackoverflow.com/questions/66262324/qt6-desktop-app-and-shared-library-with-cmake#comment117150266_66262324). However, the answer on that same page says that the libraries need to be copied to the executable directory so that the application can find them, but if that were the case, I would think that I’d get a different error (about the linker being unable to find `libfoo.a`).

So what am I missing? What is the standard way to do this?

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [July 3, 2022, 1:36pm UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977/2 "2022-07-03T13:36:04Z")

</div>

You need a virtual destructor which is not defined anywhere. Add `~Application() override = default;` to your `Application` class. `AbstractApplication` likely needs the same thing.

---

<div class="post-metadata">

**Author:** ![mitchcurtis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mitchcurtis/32/2559_2.png) [@mitchcurtis](https://discourse.cmake.org/u/mitchcurtis)\
**Post date:** [July 3, 2022, 2:16pm UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977/3 "2022-07-03T14:16:08Z")

</div>

Thanks for the reply.

That was a mistake when making a minimal example from the original project. I’ve updated the example to fix that (and added Qbs build files to demonstrate that it works with Qbs):

> **[GitHub - mitchcurtis/build-test](https://github.com/mitchcurtis/build-test)**
>
> Contribute to mitchcurtis/build-test development by creating an account on GitHub.

However, I’m still getting the error:

```auto
22:13:27: Running steps for project build-test...
22:13:27: Starting: "/opt/homebrew/Cellar/cmake/3.23.1/bin/cmake" --build /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-cmake --target all
[1/1 21.6/sec] Linking CXX executable app/app
FAILED: app/app 
: && /usr/bin/clang++ -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names app/CMakeFiles/app.dir/main.cpp.o app/CMakeFiles/app.dir/Application.cpp.o -o app/app -Wl,-rpath,/Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib libs/libfoo/libfoo.a /Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib/libQt6Core_debug.6.5.0.dylib /Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib/libQt6Core_debug.6.5.0.dylib -framework DiskArbitration -framework IOKit && :
Undefined symbols for architecture arm64:
  "vtable for Application", referenced from:
      Application::Application() in Application.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for AbstractApplication", referenced from:
      AbstractApplication::AbstractApplication() in libfoo.a(AbstractApplication.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
22:13:27: The process "/opt/homebrew/Cellar/cmake/3.23.1/bin/cmake" exited with code 1.
Error while building/deploying project build-test (kit: qt-dev-debug-non-fw)
When executing step "Build"
22:13:27: Elapsed time: 00:00.

```

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [July 3, 2022, 3:08pm UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977/4 "2022-07-03T15:08:26Z")

</div>

> [@mitchcurtis](#):
>
> `-fsanitize=address`

Where is this coming from? The sanitizers tend to want to instrument things that might be implicit in normal builds. Does qbs have the same problem if you enable sanitizers there?

---

<div class="post-metadata">

**Author:** ![mitchcurtis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mitchcurtis/32/2559_2.png) [@mitchcurtis](https://discourse.cmake.org/u/mitchcurtis)\
**Post date:** [July 3, 2022, 4:31pm UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977/5 "2022-07-03T16:31:14Z")

</div>

[duplicate]

---

<div class="post-metadata">

**Author:** ![mitchcurtis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mitchcurtis/32/2559_2.png) [@mitchcurtis](https://discourse.cmake.org/u/mitchcurtis)\
**Post date:** [July 3, 2022, 4:35pm UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977/6 "2022-07-03T16:35:24Z")

</div>

That comes from the Qt build I built the project with. It was configured with `-DFEATURE_sanitize_address=ON`. The Qbs project is built with the same Qt build. Here’s the output from building `app` with Qbs in case it’s useful:

```auto
00:27:22: Running steps for project build-test...
/usr/bin/clang++ -g -O0 -Wall -Wextra -fsanitize=address -target arm64-apple-macosx10.13-macho -pipe -fexceptions -fvisibility=default -fPIC -DQT_DEPRECATED_WARNINGS -DQT_GUI_LIB -DQT_CORE_LIB -I/Users/mitch/dev/build-test/libs/libfoo -I/Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/qt.headers -isystem/Users/mitch/dev/qt-dev-debug-non-fw/qtbase/include -isystem/Users/mitch/dev/qt-dev-debug-non-fw/qtbase/include/QtGui -isystem/Users/mitch/dev/qt-dev-debug-non-fw/qtbase/include/QtCore -isystem/Users/mitch/dev/qt-dev-debug-non-fw/qtbase/mkspecs/macx-clang -std=c++17 -stdlib=libc++ -o /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/3a52ce780950d4d9/main.cpp.o -c /Users/mitch/dev/build-test/app/main.cpp
/usr/bin/clang++ -Wl,-arch,arm64,-rpath,@loader_path/../../../Library/Frameworks -stdlib=libc++ -L/Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib -fsanitize=address -target arm64-apple-macosx10.13-macho -o /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/.tmp/app /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/3a52ce780950d4d9/Application.cpp.o /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/3a52ce780950d4d9/main.cpp.o /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/73489b871e127538/moc_Application.cpp.o -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL -framework AppKit -framework ImageIO -framework Metal -framework DiskArbitration -framework IOKit /Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib/libQt6Gui_debug.dylib /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/libfoo.d09145fd/libfoo.dylib /Users/mitch/dev/qt-dev-debug-non-fw/qtbase/lib/libQt6Core_debug.dylib -framework OpenGL -framework AGL -framework AppKit -framework ImageIO -framework Metal -framework DiskArbitration -framework IOKit
/usr/bin/dsymutil -o /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/app.app.dSYM /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/.tmp/app
/usr/bin/strip -S /Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/app.7d104347/.tmp/app
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -f app.app
00:27:23: Elapsed time: 00:01.

```

Qbs installs everything to `install-root`:

```auto
mitch@Mitchs-MacBook-Pro install-root % pwd 
/Users/mitch/dev/build-test-qt_dev_debug_non_fw-Debug-qbs/Debug_qt_dev_d_3883db5c1278cc67/install-root
mitch@Mitchs-MacBook-Pro install-root % tree
.
└── usr
    └── local
        ├── Library
        │ └── Frameworks
        │ └── libfoo.dylib
        └── app.app
            └── Contents
                ├── Info.plist
                ├── MacOS
                │ └── app
                └── PkgInfo

7 directories, 4 files

```

---

<div class="post-metadata">

**Author:** ![mitchcurtis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mitchcurtis/32/2559_2.png) [@mitchcurtis](https://discourse.cmake.org/u/mitchcurtis)\
**Post date:** [July 5, 2022, 1:16pm UTC](https://discourse.cmake.org/t/undefined-symbols-when-linking-application-to-library/5977/7 "2022-07-05T13:16:01Z")

</div>

I was told that this is because

```auto
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

```

needs to be before `add_library` and `add_executable`.
