uuid library linking

Hello,
I’m learning how to use cmake for future projects. So far, i built a sample executable, library and linked them together. Wrote a ctest test case, ran code coverage, memcheck and generated a html report, all good up to this point. Next, I wanted to link to an existing library on my ubuntu machine like UUID, I found the uuid.h file and the libuuid.so.

I tried everything recommended by google AI search and nothing seem to work, when compiling, my include <uuid/uuid> is never found. I checked the generated Makefile and it has no mention of uuid. Tried to locate a simple compile/linking example with cmake.

Thanks!

Once you start consuming third-party libraries is where things get a little “interesting”, shall we say.

IMO, the easiest thing to do is to start using a package manager like vcpkg to get access to third party libraries like uuid.

Also, I note that the library you’re using is only available on linux through vcpkg, whereas there are other uuid libraries that are supported by linux, macOS and Windows, such as stduuid.

I gave a presentation on vcpkg a few years ago and there is plenty of documentation on how to get started with vcpkg.

If you’re not willing to use vcpkg, then your next step would be to write a CMake find module that locates uuid and sets up an imported target that you can link against with target_link_libraries. This isn’t much more complicated than the CMake you’ve already been writing, but there’s lots of little things that can go wrong and you’re more likely to gain more by learning a package manager like vcpkg than by learning how to write find modules.

There’s no need to do any of that and there’s nothing complex about this use case.

If they want to build with libuuid, installed from their standard upstream distro repositories, it will be as trivial as target_link_libraries(<tgt> PRIVATE uuid)

If they want to get very fancy with it, uuid ships a pkg-config file, so one can use the various pkg-config support mechanism in CMake to construct an imported target from that.

Here’s an example of building, linking, and testing against libuuid on Ubuntu. Check the Github CI workflow for details on how CMake is being invoked:

@vito.gamberini - Thank you for taking the time to put this example together.

I cloned and tried to build on my system but i’m on an older cmake version 3.22. I updated accordingly, and got a successful build. 3.22 doesn’t support FILE_SET.

➜ build git:(main) ✗ ldd example-test
linux-vdso.so.1 (0x00007fff27f77000)
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x000079a12d158000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000079a12ce00000)
/lib64/ld-linux-x86-64.so.2 (0x000079a12d182000)

cmake_minimum_required(VERSION 3.22.1)

project(cmake-uuid-example)

add_library(example)

target_sources(example
PRIVATE
src/lib.cpp
)

target_link_libraries(example
PUBLIC
uuid
)

target_include_directories(example PUBLIC
src
)

add_executable(example-test)
target_sources(example-test
PRIVATE
test/test.cpp
)
target_link_libraries(example-test
PRIVATE
example
)

enable_testing()
add_test(NAME example-test COMMAND example-test)

Yes and no.

Just slapping it onto the link libraries may or may not work because it makes assumptions about the host environment.

yup.

I tried repeating the step in my example and it doesn’t work (given I’m on cmake 3.22).

i see vcpkg does make it easy. reminds me of NuGet, let me play with this a bit.

A quick test based on the directions here

example built/ran just fine…will spend time to see how this can be good.

One note: you assume libuuid is installed on your system and your compiler use -std=C++17 as default?

cmake_minimum_required(VERSION 3.28...4.1)

project(cmake-uuid-example LANGUAGES CXX)

add_library(example)
target_sources(example
  PRIVATE
    src/lib.cpp

  INTERFACE
    FILE_SET HEADERS
    BASE_DIRS
      src
    FILES
      src/lib.hpp
)
target_compile_features(example PUBLIC cxx_std_17)
find_library(UUID_LIB uuid REQUIRED NAMES libuuid)
target_link_libraries(example
  PUBLIC
    ${UUID_LIB}
)

add_executable(example-test)
target_sources(example-test
  PRIVATE
    test/test.cpp
)
target_link_libraries(example-test
  PRIVATE
    example
)

enable_testing()
add_test(NAME example-test COMMAND example-test)

They didn’t specify a C++ version, relying on the compiler default is fine. And yes they explicitly stated they wanted to use their system libuuid from Ubuntu.

I’m on c++ version (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

target_link_libraries and target_include_directories on latest cmake version support full paths, but 3.22 cmake does not mention such usage.

cmake latest says:

If an imported library has the IMPORTED_NO_SONAME target property set, CMake may ask the linker to search for the library instead of using the full path (e.g. /usr/lib/libfoo.so becomes -lfoo).

The full path to the target’s artifact will be quoted/escaped for the shell automatically.