CLI11 icon indicating copy to clipboard operation
CLI11 copied to clipboard

linker error when CLI.hpp not included

Open cconverse711 opened this issue 1 year ago • 3 comments

Using version 2.4.2, I get a linker error when trying to build the following code:

#include <CLI/App.hpp>

int main(int argc, char **argv) {
    CLI::App app("");
    return 0;
}

Error:

/usr/bin/ld: CMakeFiles/app.dir/app.cpp.o: warning: relocation against `_ZTVN3CLI10ConfigBaseE' in read-only section `.text._ZN3CLI3AppC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_PS0_[_ZN3CLI3AppC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_PS0_]'
/usr/bin/ld: CMakeFiles/app.dir/app.cpp.o: in function `CLI::ConfigBase::~ConfigBase()':
app.cpp:(.text._ZN3CLI10ConfigBaseD2Ev[_ZN3CLI10ConfigBaseD5Ev]+0x7): undefined reference to `vtable for CLI::ConfigBase'
/usr/bin/ld: CMakeFiles/app.dir/app.cpp.o: in function `CLI::ConfigBase::~ConfigBase()':
app.cpp:(.text._ZN3CLI10ConfigBaseD0Ev[_ZN3CLI10ConfigBaseD5Ev]+0x7): undefined reference to `vtable for CLI::ConfigBase'
/usr/bin/ld: CMakeFiles/app.dir/app.cpp.o: in function `CLI::App::App(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, CLI::App*)':
app.cpp:(.text._ZN3CLI3AppC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_PS0_[_ZN3CLI3AppC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_PS0_]+0x227): undefined reference to `vtable for CLI::Formatter'
/usr/bin/ld: app.cpp:(.text._ZN3CLI3AppC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_PS0_[_ZN3CLI3AppC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_PS0_]+0x461): undefined reference to `vtable for CLI::ConfigBase'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/app.dir/build.make:97: app] Error 1
make[1]: *** [CMakeFiles/Makefile2:139: CMakeFiles/app.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

This seems similar to #316 , as the error can be resolved by adding #include <CLI/CLI.hpp>, however the linking failure is still somewhat unexpected. Generally I try to follow the "include what you use" rule, so that's why I was including App.hpp directly -- is CLI.hpp the only official include "entrypoint" of the library?

cconverse711 avatar Aug 08 '24 02:08 cconverse711

For this to work you would need to be linking with the static library, which is not built by default. Just including that header would be missing many of the definitions as seen from the linker errors.

A majority of time, I use the single header version to keep things very simple and contained, but either CLI/CLI.hpp or building the static library (usually through CMake, but other means are also possible), also should work fine.

phlptp avatar Aug 08 '24 11:08 phlptp

Got it, that makes sense. I recently switched form using the static library version to the conan package which is header only. It still seems somewhat problematic that including a public header that's not named as a forward header would cause such linker errors. Is it possible to easily prevent the linker errors by adjusting the includes in that file, or some way to provide an compiler error message that suggests the workaround?

cconverse711 avatar Aug 12 '24 14:08 cconverse711

The file that includes the necessary includes is CLI/CLI.hpp. All the files in the library would need to be included as App_inl.hpp needs definitions for them all to function. So if you want to use the static library then just including App.hpp is fine, but if you want to use the header only then you need to use CLI.hpp as you then need all the definitions available in your compilation unit.

phlptp avatar Aug 16 '24 11:08 phlptp