Eliminating the libnsl.so dependency from cmake-re
tipi release v0.0.67 is out π cmake-re & tipi no longer depends on libsnl.so on Linux
written by @lambourl & @pysco68 // March 24, 2025A bit of background
The tipi
and cmake-re
binaries for Linux linked against libnsl.so.1
for several versions because of an incidental chain of dependencies. This requirement became an issue as widely used Linux distributions (Ubuntu 24.04 or CentOS) stopped shipping that legacy shared object which in turn prevented our command line tools from functionning as intended.
What is libnsl.so.1
one might ask? It is a legacy Network Services Library that implementes SunRPC and NIS (Yellow Pages) support. It enabled remote procedure calls and centralized user authentication in and against older Unix systems. Many legacy applications still depend on it for RPC-based communication.
Explanation of the problem
After a while of digging we came to the conclusion that libnsl
was linked against by c-ares
which in turn is a dependency of libcurl
in our case.
In c-ares
's build system the mechanism is quite simple:
check_library_exists (nsl gethostbyname "" HAVE_LIBNSL)
...
if (HAVE_LIBNSL)
list (APPEND CARES_DEPENDENT_LIBS nsl)
endif ()
...
target_link_libraries (${PROJECT_NAME} PUBLIC ${CARES_DEPENDENT_LIBS})
...
list (APPEND CMAKE_REQUIRED_LIBRARIES ${CARES_DEPENDENT_LIBS})
Note how
list (APPEND CMAKE_REQUIRED_LIBRARIES ${CARES_DEPENDENT_LIBS})
would pollute CMake's global state in the case of aFetchContent
/add_subdirectory()
-ed usage ofc-ares
. We built Hermetic FetchContent to avoid these transitive pollutions by dependencies.
Basically, the build system checks for the symbol gethostbyname
in (lib)nsl
and links the library if it can be found.
The catch however is that none of our application code uses the facilities provided by libnsl
but it rather is a consequence of the mere presence of libnsl
on the system that is used to build our applications.
Sadly the c-ares
build system doesn't offer us a non-intrusive option to disable the inclusion of nsl
into the build.
Looking further up the dependency tree we see that c-ares
can be substituted by another DNS resolver in libcurl
to eliminate the dependency alltogether - in our case this has us rely on the libc
's gethostbyname()
instead which has been available approximatively forever by now (circa mid 2001 which is vintage all things considered).
Simply setting ENABLE_ARES
to OFF
in the libcurl
build and removing c-ares
from the build did the trick for us as libcurl
will rely on the libc
provided facilities by default:
check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL)
if(NOT NOT_NEED_LIBNSL)
check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL)
endif()
Results
On the bottom line, the visible improvement is that our single Linux binary release is now running on even more Linux distributions (from the Ubuntu 16.04 vintage to today) with our almost fully statically linked binary.
In addition to the above our latest and greatest tipi
& cmake-re
release contains the following:
v0.0.67 - Dashing Duck π¦
Features
- Windows on ARM with Visual Studio build support and CMake Visual Studio Toolset Arch argument specification
Bug Fixes
- Fix unconditional test execution in cmake-re containerized and remote build
- Removed dependency on libnsl.so on Linux to improve compatibility
- Fix local containerized build failing on docker runtime search errors for some projects
Give it a go and tell us if you like it!
As per usual the release can be found here: tipi & cmake-re v0.0.67 at github.com/tipi-build/cli.


Lambour Luc and Yannic Staudt
@lambourl & @pysco68
software engineer at tipi & co-founder of tipi