1

I got the following cmake file:

cmake_minimum_required(VERSION 3.17)
project(blsbench2)

set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES main.cpp)

INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/src)
LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/src)
LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/object_blstmp)



INCLUDE_DIRECTORIES(/usr/local/include/relic/)
LINK_DIRECTORIES(/usr/local/lib/)

add_executable(blsbench2 ${SOURCE_FILES})

TARGET_LINK_LIBRARIES(blsbench2 bls relic)

And the following program

#include <iostream>
#include <bls.hpp>

using namespace bls;
using namespace std;

int main()
{
    std::cout << "Hello, World!" << std::endl;


    uint8_t seed[] = {0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192,
                      19, 18, 12, 89, 6, 220, 18, 102, 58, 209,
                      82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22};

    PrivateKey sk = PrivateKey::FromSeed(seed, sizeof(seed));
    PublicKey pk = sk.GetPublicKey();

    uint8_t msg[] = {100, 2, 254, 88, 90, 45, 23};

    Signature sig = sk.Sign(msg, sizeof(msg));


    return 0;
}

I'm working with CLion and the setup above allows me to include the library and use function auto completion.

The problem arises when I try to start running the program.

/usr/bin/ld: CMakeFiles/blsbench2.dir/main.cpp.o: in function `main':
/home/ray/CLionProjects/blsbench2/main.cpp:16: undefined reference to `bls::PrivateKey::FromSeed(unsigned char const*, unsigned long)'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:17: undefined reference to `bls::PrivateKey::GetPublicKey() const'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:21: undefined reference to `bls::PrivateKey::Sign(unsigned char const*, unsigned long) const'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:16: undefined reference to `bls::PrivateKey::~PrivateKey()'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:16: undefined reference to `bls::PrivateKey::~PrivateKey()'
/usr/bin/ld: CMakeFiles/blsbench2.dir/main.cpp.o: in function `bls::Signature::~Signature()':
/home/ray/CLionProjects/blsbench2/../../Documents/projects/bls-signatures/src/signature.hpp:101: undefined reference to `bls::AggregationInfo::~AggregationInfo()'
collect2: error: ld returned 1 exit status

I searched a bit on the internet and it said at a few places that this is due to the lack of .so files (might be mistaken here). However, the library builds a .a file which should be enough.

raycons
  • 735
  • 12
  • 26
  • Looks like the `bls` library **actually** does **not define** given symbols(constructors, destructors, methods). You may get the list of symbols defined in the static library with `nm --demangle` (the method is taken from here: https://stackoverflow.com/a/2714330/3440745). The `bls-signatures` project *manually* creates the `bls` library: [src/CMakeLists.txt](https://github.com/Chia-Network/bls-signatures/blob/master/src/CMakeLists.txt), and something could be wrong with this approach. – Tsyvarev May 29 '20 at 09:46

2 Answers2

3

This is due to how bls library is built. bls::PrivateKey class is implemented in a file that is part of a blstmp static library.

You can link directly to the blstmp library instead of bls. This works : your program runs fine. But it's a bit hacky.

This is due to an issue with CMake : when you build a library A that depends on a static library B, the objects files of library B are not copied into library A. So your program that links to A should also link to B. There is a discussion about that on CMake's mailing list.

But this is an issue with bls library, it could be useful to report it to maintainer.

antoine
  • 1,653
  • 11
  • 23
  • Okay, that seemed to have brought me one step further, now I get the following error: "bls.cpp:(.text+0x1a1): undefined reference to `core_set_thread_initializer'" For around three methods: core_set_thread_initializer, ep2_sub_projc, fp_inv_exgcd_bn Those do seem strongly tied to relic. – raycons May 29 '20 at 10:22
  • when I build your code, I have to link to `relic_s` instead of `relic`. It's worth a try. Another thing you could try is to build `bls` with your project directly with CMake's [`ExternalProject`](https://cmake.org/cmake/help/latest/module/ExternalProject.html) or `add_subdirectory` (I tried the second without success). – antoine May 29 '20 at 10:30
  • Only adding relic_s threw another batch of issues, adding both relic_s and relic only throws the 4 I mentioned. – raycons May 29 '20 at 11:03
0

As another user in the answers pointed out I went after the library maintainers.

The main problem was that they were a) Running a heavily modified version of relic. b) Spread it over 2 folders.

The solution:

a) As antoine pointed out including blstmp instead of bls b) Including relic_s instead of relic c) Including relic from the correct directories.

INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/src)
LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/src)

LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/contrib/relic/lib)
INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/build/contrib/relic/include)
INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/contrib/relic/include)

add_executable(blsbench2 ${SOURCE_FILES})

TARGET_LINK_LIBRARIES(blsbench2 blstmp relic_s)
raycons
  • 735
  • 12
  • 26