linking vtk library fail: undefined reference to `vtksys::SystemToolsManager::SystemToolsManager()

I have a file a.cpp consisting of the following lines:

#include <vtkVersion.h> 
int main(){}

I try to build it with vtk 9.3

g++ -L/usr/local/lib -I/usr/local/include/vtk-9.3   -lvtksys-9.3   -o a.out  a.cpp

but it reports:

/usr/bin/ld: /tmp/ccnbq1jH.o: in function `__static_initialization_and_destruction_0(int, int)':
a.cpp:(.text+0x61): undefined reference to `vtksys::SystemToolsManager::SystemToolsManager()'
/usr/bin/ld: a.cpp:(.text+0x76): undefined reference to `vtksys::SystemToolsManager::~SystemToolsManager()'
collect2: error: ld returned 1 exit status

I try to see if the symbols are there

nm --demangle --dynamic --defined-only --extern-only /usr/local/lib/libvtksys-9.3.so|grep vtksys::SystemToolsManager

and it shows:

0000000000054746 T vtksys::SystemToolsManager::SystemToolsManager()
0000000000054746 T vtksys::SystemToolsManager::SystemToolsManager()
000000000005477e T vtksys::SystemToolsManager::~SystemToolsManager()
000000000005477e T vtksys::SystemToolsManager::~SystemToolsManager()

That means the symbol is there. What is the problem? However, when I build my code using vtk-6.3, there is no problem.

g++ -L/usr/lib/x86_64-linux-gnu -I/usr/include/vtk-6.3   -lvtksys-6.3   -o a.out  a.cpp

Try changing your a.cpp as follows, and you will probably see the same link error with VTK 6.3:

#include <vtksys/SystemTools.hxx> 
int main(){}

As for the cause of the eror, if a.cpp needs to link to libvtksys-9.3, then it needs to come before it on the command line:

g++ -L/usr/local/lib -I/usr/local/include/vtk-9.3 a.cpp -lvtksys-9.3 -o a.out 

The reason that merely including SystemTools.hxx causes a link dependency is the following line in this header:

// This instance will show up in any translation unit that uses
// SystemTools. It will make sure SystemTools is initialized 
// before it is used and is the last static object destroyed.
static SystemToolsManager SystemToolsManagerInstance;

From the gcc man page:

  -l library

     It makes a difference where in the command you write this option; the
     linker searches and processes libraries and object files in the order
     they are specified.  Thus, foo.o -lz bar.o searches library z after
     file foo.o but before bar.o.  If bar.o refers to functions in z, those
     functions may not be loaded.

And, in general, the only supported way to build against VTK is to use CMake and the targets that VTK exports (in addition to any vtk_module_autoinit() calls that may be needed to use vtkObjectFactory-using classes).

Thank you very much everyone.

I forget that order of -l is important.

For those who might have this problem:

I have this problem because the library liggghts (GitHub - CFDEMproject/LIGGGHTS-PUBLIC: official release of the LIGGGHTS® DEM software by DCS Computing. For further info, forums, and bug reports, please visit http://www.cfdem.com. For the DEM software Aspherix® by DCS Computing that replaces LIGGGHTS, please visit https://www.aspherix-dem.com/) cannot be built against the latest VTK library using the legacy method make auto. By changing the order in the Makefile.auto,

        TMP := $(shell $(ECHO) '$Hinclude <vtkVersion.h> \n int main(){}' > $(TMPFILE) && $(CXX) $(EXTRA_LIB) $(VTK_LIB) $(VTK_INC) $(EXTRA_ADDLIBS)  -lvtksys$(VTK_APPENDIX) $(CCFLAGS) -xc++ -o /dev/null  $(TMPFILE) 2>> $(AUTO_LOG_FILE) && echo 0 || echo -1)

to

        TMP := $(shell $(ECHO) '$Hinclude <vtkVersion.h> \n int main(){}' > $(TMPFILE) && $(CXX) $(EXTRA_LIB) $(VTK_LIB) $(VTK_INC) $(EXTRA_ADDLIBS) $(TMPFILE) -lvtksys$(VTK_APPENDIX) $(CCFLAGS) -xc++ -o /dev/null  2>> $(AUTO_LOG_FILE) && echo 0 || echo -1)

everything works.