Issue
I have a header only library, call it libA, in a subdirectory of my project called libs. I have a module in another subdirectory of my project, call it moduleA, that tries to include a header from libA. The files in moduleA try to #include "libA.h" but are apparently unable to find it. When attempting to build, the compiler details that there are undefined symbols.
Here is a rough diagram of my Project:
Project
|_libs
| |_libA
| | |_include
| | | |_libA.h
| | |_CMakeLists.txt
|
|_modules
| |_moduleA
| | |_include
| | | |_moduleA.h
| | |_src
| | | |_moduleA.cpp
| | |_CMakeLists.txt
Here is what I have in the CMakeLists.txt for libA:
add_library(libA INTERFACE)
target_include_directories(libA INTERFACE include)
Here is what I have in the CMakeLists.txt for moduleA:
add_library(moduleA
STATIC
src/moduleA.cpp
)
target_link_libraries(moduleA PUBLIC libA compile_flags)
target_include_directories(moduleA PUBLIC include)
I would think that linking libA would make libA.h available to other modules, but it doesn't seem to be the case.
Solution
As you've mentioned, CMake implements headers-only libraries as an interface library, which according to CMake's docs on add_library
is designed to not compile sources or produce any build artifact.
Basically when a target includes a interface library target, it just specifies the include path for its headers. Consequently, in your example you'll find out that adding `#include <libA.h>" to source files in your moduleA project will work as the build system is now able to find them.
Getting to your problem, if your project throws undefined symbols errors when building moduleA, this means it's compiling well but it's failing during the linking stage. With this in mind, odds are you're experiencing one of two problems:
- either your moduleA project is declaring symbols but not defining them, which results in missing symbols, or
- your libA project is actually not a headers-only library, or its missing symbol declarations in its include path.
To troubleshoot this issue, check the error message to get to the symbols that are missing, and check why they are missing to begin with. Either these symbols come from moduleA or from libA, and once you determine where they are coming from then it's just a matter of figuring out why your project is leaving them out.
Answered By - RAM Answer Checked By - David Goodson (WPSolving Volunteer)