How to build a static XGboost library

I have built a static XGboost library libxgboost.a by editing CMakeLists.txt and changing the line option(BUILD_STATIC_LIB “Build static library” OFF) to option(BUILD_STATIC_LIB “Build static library” ON) and following the standard installation process from XGBoost source. ¿Is this the correct way to build a static library?

The problem is that when I link a C or C++ program with this library I get the following error message:

gcc -pthread -static -lxgboost -o “droditest” ./src/Drodi.o
/usr/bin/ld: ./src/Drodi.o: in function ‘main’:
/home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:148: undefined reference to ‘XGDMatrixCreateFromMat’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:160: undefined reference to ‘XGDMatrixSetFloatInfo’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:170: undefined reference to ‘XGBoosterCreate’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:179: undefined reference to ‘XGBoosterSetParam’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:198: undefined reference to ‘XGBoosterUpdateOneIter’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:203: undefined reference to ‘XGBoosterEvalOneIter’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:218: undefined reference to ‘XGBoosterPredict’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:229: undefined reference to ‘XGBoosterFree’
/usr/bin/ld: /home/oscar/workspace/droditest2_3.2/Debug/…/src/Drodi.c:233: undefined reference to ‘XGDMatrixFree’
collect2: error: ld returned 1 exit status

However when I link the same program with the shared library libxgboost.so it links and runs perfectly.

I need a static library version libxgboot.a because I need a self contained program that runs on computers without the library.

I am stuck here. Any ideas? Any help will be very appreciated.

Instead of using -lxgboost, try adding full path of libxgboost.a to the argument:

gcc -pthread -static -o "droditest" ./src/Drodi.o /path/to/libxgboost.a
1 Like

Thanks! That is the information I was looking for.’

It didn’t work exactly as you suggested but almost. I include the full information just in case there are some people still using plain C and requiring static libraries.

I had to use g++ instead of gcc, include -fopenmp option, include some libraries and add the full path of libdmlc.a to the argument. The link command that worked for me was:

g++ -pthread -fopenmp -static -lc -lstdc++ -o “droditest” ./src/Drodi.o /path/to/libxgboost.a /path/to/libdmlc.a

The libdmlc.a object was built together with the libxgboost.a object and it was located at xgboost/build/dmlc-core/libdmlc.a

Link command gave a couple of warnings, but I can live with that:

socket.cc:(.text+0x6e): warning: Using ‘getaddrinfo’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/12/libgomp.a(target.o): in function ‘gomp_target_init.part.0’:
(.text+0x386): warning: Using ‘dlopen’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

Thank you!

1 Like