Include external libraries using CMake

2,018 views
Skip to first unread message

Garet2k

unread,
Dec 23, 2021, 7:29:07 AM12/23/21
to ns-3-users
Now that ns-3 wants to switch to CMake, I wonder how to include external libraries in a script using CMake. There are some guides for waf but I can't wrap my head around what's the best way to include external libraries using CMake.

Gabriel

unread,
Dec 23, 2021, 9:47:13 AM12/23/21
to ns-3-users
Hi, I'm still working on the docs (MR831).
There are a few different ways to find the external library you want. 


The easy ways: 

1) Find libraries with CMake's FindPackage()

>find_package(SomeExternalLibrary QUIET) 
>if(${SomeExternalLibrary_FOUND}) 
>include_directories(${SomeExternalLibrary_INCLUDE_DIRS})
>set(external_libraries ${SomeExternalLibrary_LIBRARIES})
>endif()
>...
>set(libraries_to_link
>${libcore}
>${external_libraries}
>)

2) Find libraries with PkgConfig

>include(FindPkgConfig)
>if(PKG_CONFIG_FOUND)
>pkg_check_modules(EXTERNAL_LIBRARY libexternallibrary)
>endif()
>
>if(PKG_CONFIG_FOUND AND EXTERNAL_LIBRARY_FOUND)
>include_directories(${EXTERNAL_LIBRARY_INCLUDE_DIRS})
>set(external_libraries ${EXTERNAL_LIBRARY_LIBRARIES})
>endif()
>...
>set(libraries_to_link
>${libcore}
>${external_libraries}
>)

3) Find libraries from VcPkg with FindPackage()

>include(${VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
>find_package(SomeExternalLibrary QUIET) 
>if(${SomeExternalLibrary_FOUND}) 
>include_directories(${SomeExternalLibrary_INCLUDE_DIRS})
>set(external_libraries ${SomeExternalLibrary_LIBRARIES})
>endif()
>...
>set(libraries_to_link
>${libcore}
>${external_libraries}
>)



The hard way: if you want to find a library in a directory provided by you, try

find_library(
external_library_dependency 
external_library_name
PATHS /path/to/the/library/top/directory # you can manually provide a path to search for your library if it's not in the PATH
PATH_SUFFIXES /build /build/lib /lib # possible subfolders inside the top directory of your library
 )

${external_library_dependency} will have either the path to the external_library_name or will be set to ${external_library_name-NOTFOUND}.


Example: if you put the following block inside your cmake file and reconfigure, it will print the last two messages 
>find_library(pthread_dependency pthread)
>message(STATUS "Path to pthread = ${pthread_dependency}")

>find_library(nonsense_dependency nonsense)
>message(STATUS "Path to non-existing library = ${nonsense_dependency}")

Path to pthread = /usr/lib/x86_64-linux-gnu/libpthread.a
Path to non-existing library = nonsense_dependency-NOTFOUND


After you found the library you want, you can link it by adding ${external_library_dependency} to the libraries_to_link list.

>set(libraries_to_link
>           ${libcore}
>           ${external_library_dependency}
>)

However, this won't help you find the necessary include directories to include their headers, so you need to search for the headers too.

>find_file(external_library_header library_header.h 
>HINTS /path/to/the/library/top/directory
>PATH_SUFFIXES /build /build/include /include 
>)

For pthread.h, it would print

Path to pthread = /usr/include/pthread.h

Then you can get the folder containing it
>get_filename_component(external_library_include_directory ${external_library_header} DIRECTORY)
>include_directories(${external_library_include_directory})

Now everything should work.

Garet2k

unread,
Dec 23, 2021, 12:20:23 PM12/23/21
to ns-3-users
Thanks, this works really well and after some reading of the CMake docs this doesn't seem too complicated, too. Glad that you'll finally get rid of waf, the CMake approach appears to be so much simpler!
Reply all
Reply to author
Forward
0 new messages