Search code examples
c++cmakedependencies

CMake manage dependency (libsodium)


I am writing a C++ command-line tool. For the build system, I use CMake.

My application needs libsodium. It should compile under Windows and Linux. Especially for CI/ CD it needs a good way of managing dependencies on its own.

First approach

In previous projects, I always added the needed dependencies through CMake like this link (Getting CMake to do all the work instead).

I also tried that with libsodium but it is a little bit more complicated since sodium does not officially support CMake. (I am getting a linker error)

second approach

So I tried another approach. While searching for different ways to handle dependencies in CMake I found Hunter. I think this is another neat way to add the dependencies. So I tried this:

cmake_minimum_required(VERSION 3.15.2)

include("cmake/HunterGate.cmake")
HunterGate(
    URL "https://github.com/cpp-pm/hunter/archive/v0.23.244.tar.gz"
    SHA1 "2c0f491fd0b80f7b09e3d21adb97237161ef9835"
)

project(someProject)


hunter_add_package(libsodium)
find_package(libsodium CONFIG REQUIRED)

...

target_link_libraries(someProject
    libsodium::libsodium
    )

The error I get while using Hunter:

[hunter] Calculating Toolchain-SHA1
[hunter] Calculating Config-SHA1
[hunter] HUNTER_ROOT: C:/.hunter
[hunter] [ Hunter-ID: 2c0f491 | Toolchain-ID: 9e19749 | Config-ID: 711bb51 ]
[hunter] LIBSODIUM_ROOT: C:/.hunter/_Base/2c0f491/9e19749/711bb51/Install (ver.: 1.0.16-p0)
[hunter] Building libsodium
[hunter ** FATAL ERROR **] Build step failed (dir: C:/.hunter/_Base/2c0f491/9e19749/711bb51/Build/libsodium
[hunter ** FATAL ERROR **] [Directory:C:/.hunter/_Base/Download/Hunter/0.23.244/2c0f491/Unpacked/cmake/projects/libsodium]
------------------------------ ERROR -----------------------------
    https://hunter.readthedocs.io/en/latest/reference/errors/error.external.build.failed.html
------------------------------------------------------------------
CMake Error at C:/.hunter/_Base/Download/Hunter/0.23.244/2c0f491/Unpacked/cmake/modules/hunter_error_page.cmake:12 (message):
Call Stack (most recent call first):
  C:/.hunter/_Base/Download/Hunter/0.23.244/2c0f491/Unpacked/cmake/modules/hunter_fatal_error.cmake:20 (hunter_error_page)
  C:/.hunter/_Base/Download/Hunter/0.23.244/2c0f491/Unpacked/cmake/modules/hunter_download.cmake:623 (hunter_fatal_error)
  C:/.hunter/_Base/Download/Hunter/0.23.244/2c0f491/Unpacked/cmake/projects/libsodium/hunter.cmake:59 (hunter_download)
  C:/.hunter/_Base/Download/Hunter/0.23.244/2c0f491/Unpacked/cmake/modules/hunter_add_package.cmake:62 (include)
  CMakeLists.txt:13 (hunter_add_package)


Configuring incomplete, errors occurred!

Is the package in Hunter broken or do I need to do something different?

Does anybody have another idea how to manage such dependencies neatly and easily? I would be happy with any answer. Even if it is a complete other approach... Thanks

Edit 1: build error

C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s: Assembler messages:
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:30: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:32: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:34: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:36: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:38: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:40: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:42: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:44: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:46: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:48: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:50: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:544: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:546: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:548: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:550: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:552: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:554: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:556: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:558: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:560: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:562: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:564: Error: invalid register for .seh_savexmm
C:\Users\SORKAL~1\AppData\Local\Temp\cclEnZwH.s:566: Error: invalid register for .seh_savexmm

Solution

  • Long ago but here is what I finally did:

    1. Conan

    @R2RT suggested I tried conan.io, but sadly there was/ is no prebuild binary for Windows MinGW. Since I didn't had the time to deal with the conan.io ecosystem I scrapped that plan.

    2. Hunter

    Nearly got that working... But at the end my companies has a stupid proxy... Therefore Hunter does not know the injected SSL Certificate from my company and I could not do this either.

    3. Back to the first plan

    Finally I decided to give CMake with External_Progject another shot. That finally worked.

    For that I wrote a very crude CMake script for libsodium that looks like this:

    cmake_minimum_required(VERSION 3.5.0)
    project(libsodium VERSION 1.0.32 LANGUAGES C CXX ASM)
    
    INCLUDE(CheckCCompilerFlag)
    
    #----------------------------------------------------------
    ######################### OPTIONS #########################
    #----------------------------------------------------------
    
    OPTION(LIBSODIUM_BUILD_SHARED_LIBRARIES "Build the library dynamically (ON/TRUE) or statically (OFF/FALSE).")
    OPTION(ENABLE_BLOCKING_RANDOM           "Enable this switch only if /dev/urandom is totally broken on the target platform.")
    OPTION(ENABLE_MINIMAL_BUILD             "Only compile the minimum set of functions required for the high-level API.")
    OPTION(ENABLE_TESTS                     "Enable testing.")
    OPTION(DISABLE_ASM                      "Disable AMD64 assembly implementations.")
    OPTION(DISABLE_PIE                      "Do not produce position independent executables.")
    OPTION(DISABLE_SSP                      "Do not compile with -fstack-protector.")
    
    #----------------------------------------------------------
    ######################### VERSION #########################
    #----------------------------------------------------------
    
    SET(VERSION 1.0.3)
    SET(SODIUM_LIBRARY_VERSION_MAJOR 7)
    SET(SODIUM_LIBRARY_VERSION_MINOR 5)
    SET(DLL_VERSION 6)
    
    SET(SODIUM_LIBRARY_VERSION "15:0:2")
    #                            | | |
    #                     +------+ | +---+
    #                     |        |     |
    #                  current:revision:age
    #                     |        |     |
    #                     |        |     +- increment if interfaces have been added
    #                     |        |        set to zero if interfaces have been removed
    #                     |        |        or changed
    #                     |        +- increment if source code has changed
    #                     |           set to zero if current is incremented
    #                     +- increment if interfaces have been added, removed or changed
    
    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include/sodium/version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include/sodium/version.h)
    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include/sodium/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/libsodium/include/sodium/version.h)
    
    
    #----------------------------------------------------------
    ##################### SOURCE / HEADERS ####################
    #----------------------------------------------------------
    
    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium)
    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include)
    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include/sodium)
    #For version.h.in to version.h
    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/src/libsodium/include/sodium)
    
    file(GLOB_RECURSE libsodium_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/*.h)
    
    file(GLOB_RECURSE libsodium_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/*.c)
    
    #----------------------------------------------------------
    ######################### LIBRARY #########################
    #----------------------------------------------------------
    
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/build")
    
    
    IF(ENABLE_BLOCKING_RANDOM)
        ADD_DEFINITIONS("-DUSE_BLOCKING_RANDOM")
    ENDIF(ENABLE_BLOCKING_RANDOM)
    
    IF(LIBSODIUM_BUILD_SHARED_LIBRARIES)
        ADD_LIBRARY(libsodium SHARED ${libsodium_HEADERS} ${libsodium_SOURCE})
    ELSE(LIBSODIUM_BUILD_SHARED_LIBRARIES)
        ADD_DEFINITIONS("-DSODIUM_STATIC")
        ADD_LIBRARY(libsodium STATIC ${libsodium_HEADERS} ${libsodium_SOURCE})
    ENDIF(LIBSODIUM_BUILD_SHARED_LIBRARIES)
    
    SET_TARGET_PROPERTIES(libsodium PROPERTIES
        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib
        ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib
        PROJECT_LABEL "libsodium"
    )
    

    This was inspired by some CMakeLists I found while searching for a solution. I am not completly happy with this solution but I decided that my future me should care about this.