1

I am trying to write a program in c++ using botan but I don't know how to properly use it. Take for example the following code:

Botan::AutoSeeded_RNG rng;
Botan::UUID uuid = Botan::UUID(rng);
std::cout << uuid.to_string() << std::endl;

If I try to run this it throws an error which seems to be an issue with botan not being linked. But I'm not sure how I can link this using CMake. In CMakeList.txt I have

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
find_package(BOTAN REQUIRED)

based on this, and in modules, I have a file FindBOTAN.cmake.

But this throws the error Could NOT find Botan (missing: BOTAN_LIBRARIES BOTAN_INCLUDE_DIRS), the warning

The package name passed to `find_package_handle_standard_args` (PkgConfig)
does not match the name of the calling package (BOTAN).  This can lead to
problems in calling code that expects `find_package` result variables
(e.g., `_FOUND`) to follow a certain pattern.

and fails to find botan.

I have barely any experience using CMake hence I've based it on someone else's but now I've got the problem that I don't know what is going wrong.

Lenny
  • 27
  • 8
  • Have you installed Botan system wide? Do you intent for it to compile _with_ your project, or separately? – KamilCuk May 20 '22 at 17:53
  • Try `find_package(Botan REQUIRED)`. The error message is telling you that you capitalized wrong. – Alex Reinking May 20 '22 at 17:58
  • Ah, wait, that's thrown from the line in the find module, here: `include(FindPkgConfig)`. That's wrong. `include(Find*)` is _**always**_ wrong. That should be changed to `find_package(PkgConfig REQUIRED)`. – Alex Reinking May 20 '22 at 18:24
  • The warning is a bug in `FindBOTAN.cmake`, see this fix in `FindMPI.cmake` for example: https://github.com/Kitware/CMake/commit/56d949f05f37c65401825a30be0d39bd152cc33c. You should use `find_package(PkgConfig)` instead of `include(FindPkgConfig)` in this `FindBOTAN.cmake`. For the issue itself, you may have to append botan install folder to `CMAKE_PREFIX_PATH` during CMake configuration. – SpacePotatoes May 20 '22 at 18:25
  • @KamilCuk I've got botan through msys. – Lenny May 21 '22 at 11:04
  • @AlexReinking This does get rid of the error. – Lenny May 21 '22 at 11:05
  • @SpacePotatoes Same, it does get rid of the error, and setting CMAKE_PREFIX_PATH does allow it to be found. Now the CMake runs successfully but even after I link botan it still throws errors of undefined references, the ones that I linked in my original question. – Lenny May 21 '22 at 11:05

1 Answers1

2

That find module is totally wrong. You should point whoever wrote it to this answer. Here's something better (but could still be improved, e.g. by validating the version):

find_package(PkgConfig REQUIRED)

if (NOT TARGET Botan::Botan)
  pkg_check_modules(Botan QUIET IMPORTED_TARGET botan-2)
  if (TARGET PkgConfig::Botan)
    add_library(Botan::Botan ALIAS PkgConfig::Botan)
  endif ()
endif ()

if (NOT TARGET Botan::Botan)
  find_path(Botan_INCLUDE_DIRS NAMES botan/botan.h
            PATH_SUFFIXES botan-2
            DOC "The Botan include directory")

  find_library(Botan_LIBRARIES NAMES botan botan-2
               DOC "The Botan library")

  mark_as_advanced(Botan_INCLUDE_DIRS Botan_LIBRARIES)

  add_library(Botan::Botan IMPORTED UNKNOWN)
  set_target_properties(
    Botan::Botan
    PROPERTIES
    IMPORTED_LOCATION "${Botan_LIBRARIES}"
    INTERFACE_INCLUDE_DIRECTORIES "${Botan_INCLUDE_DIRS}"
  )
endif ()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
  Botan
  REQUIRED_VARS Botan_LIBRARIES Botan_INCLUDE_DIRS
)

Put this file in cmake/FindBotan.cmake and then you can use it from your top-level CMakeLists.txt like so:

cmake_minimum_required(VERSION 3.23)
project(botan_example)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(Botan REQUIRED)

add_executable(botan_example main.cpp)
target_link_libraries(botan_example PRIVATE Botan::Botan)

As always, you should endeavor to link to imported targets, like the Botan::Botan target that my revised find module defines. For main.cpp, I wrapped your code up like so:

#include <botan/botan.h>
#include <botan/uuid.h>
#include <iostream>

int main() {
  Botan::AutoSeeded_RNG rng;
  Botan::UUID uuid = Botan::UUID(rng);
  std::cout << uuid.to_string() << std::endl;
}

And I confirmed that it does indeed build:

alex@alex-ubuntu:~/test$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") 
-- Checking for module 'botan-2'
--   Found botan-2, version 2.12.1
-- Found Botan: botan-2  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
alex@alex-ubuntu:~/test$ cmake --build build/
[ 50%] Building CXX object CMakeFiles/botan_example.dir/main.cpp.o
[100%] Linking CXX executable botan_example
[100%] Built target botan_example
alex@alex-ubuntu:~/test$ ./build/botan_example 
6ACD38C7-3B70-4B57-A0F8-DEDCDCEF4D34
Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
  • I'm getting an error related to 'add_library(Botan::Botan ALIAS PkgConfig::Botan)' : add_library cannot create ALIAS target "Botan::Botan" because target "PkgConfig::Botan" does not already exist. – Lenny May 21 '22 at 11:06
  • @Lenny hmm, what version of CMake are you using? I tested it locally and it worked just fine. – Alex Reinking May 21 '22 at 16:07
  • I'm using version 3.22.3 in clion – Lenny May 21 '22 at 16:17
  • @Lenny - ahh, pkg-config failed to find Botan. I've updated my answer. But you might be missing the `-dev` package for Botan. – Alex Reinking May 21 '22 at 16:23
  • Now the CMake runs but the program still throws undefined reference errors. Also, how do I get the -dev package, I can only find a download for 2.19.1. – Lenny May 21 '22 at 16:34
  • 1
    Ok, I have no idea of how or why but it now works. CMake does print `-- Checking for module 'botan-2'` `-- No package 'botan-2' found` but it does not seem to have any problem with it as it links them anyway and now also compiles and runs the program. – Lenny May 21 '22 at 18:42
  • That sounds like `pkg-config` fails, but `find_path` and `find_library` succeed. – Alex Reinking May 21 '22 at 18:49