4

I want to create python module with C++ bindings of monero functions:

  • parse_and_validate_block_from_blob
  • get_block_hashing_blob
  • rx_slow_hash
  • and more...

I'm using ubuntu 18.04. For the simplicity of this question, I removed the code associated with creating of python module using pybind11.

I cloned the monero repository. I installed all dependencies following this instruction. Then, I run following commands to build static libs which I need:

$ cmake .
$ make cryptonote_basic

And I want to compile simple target pymonero.cpp (full):

#include <iostream>
#include "cryptonote_basic/cryptonote_format_utils.h"

using namespace cryptonote;
using namespace std;

int main() {
    blobdata b_blob = h2b("0c0ce185b0f2053941deed208d6449bb432fbce9778efb4cd9229cc79e4c04ef7b2a2f7c99df4a0000000002afdd1f01fff3dc1f018f918980888803025b08e22c6cb11c61b628de4217c3959627414d2d10579b780ca1e1fec0164bba210174b9819eb50c698d574bc408a0f7fedd608296647291551e98be4f7134bc26660000");
    blobdata hashing_blob;
    cout << "Input:\t" << string_to_hex(b_blob) << endl;

    block b = AUTO_VAL_INIT(b);
    if (!parse_and_validate_block_from_blob(b_blob, b)) {
        cout << "Not valid blob" << endl;
        return -1;
    }
    hashing_blob = get_block_hashing_blob(b);
    cout << "Output:\t" << string_to_hex(hashing_blob) << endl;
    return 0;
}

I'm trying to build this target with following commands:

echo "Building CXX object"
/usr/bin/c++  \
-I$MONERO_DIR/src \
-I$MONERO_DIR/contrib/epee/include \
-I$MONERO_DIR/external/easylogging++  \
-o _build/pymonero.cpp.o \
-c pymonero.cpp 

echo "Linking CXX executable pymonero"
/usr/bin/c++ _build/pymonero.cpp.o -o pymonero \
-L$MONERO_DIR/src -lversion \
-L$MONERO_DIR/src/cryptonote_basic -lcryptonote_basic \
-L$MONERO_DIR/src/device -ldevice \
-L$MONERO_DIR/src/ringct -lringct_basic \
-L$MONERO_DIR/src/common -lcommon \
-L$MONERO_DIR/src/crypto -lcncrypto \
-L$MONERO_DIR/contrib/epee/src -lepee \
-L$MONERO_DIR/external/easylogging++ -leasylogging \
-L$MONERO_DIR/external/randomx -lrandomx \
-L$MONERO_DIR/external/miniupnp \
/usr/lib/x86_64-linux-gnu/libboost_thread.so \
/usr/lib/x86_64-linux-gnu/libboost_chrono.so \
/usr/lib/x86_64-linux-gnu/libboost_system.so \
/usr/lib/x86_64-linux-gnu/libboost_filesystem.so \
/usr/lib/x86_64-linux-gnu/libboost_regex.so \
/usr/lib/x86_64-linux-gnu/libssl.so \
/usr/lib/x86_64-linux-gnu/libcrypto.so \
/usr/lib/x86_64-linux-gnu/libhidapi-libusb.so \
/usr/lib/x86_64-linux-gnu/libsodium.so \
/usr/lib/x86_64-linux-gnu/libunbound.so \
-lpthread -ldl 

$MONERO_DIR is path to the cloned monero repository. Output of last command give me following error:

Linking CXX executable pymonero
./monero//src/device/libdevice.a(device_ledger.cpp.o): In function `hw::ledger::device_ledger::reset()':
device_ledger.cpp:(.text+0x4a52): undefined reference to `MONERO_VERSION'
collect2: error: ld returned 1 exit status

I tried to build this target on ubuntu 16.04 and again got this error. I don’t know if I did it right that I came here with a question about compilation of C++ sources. But I am very tired and feel that here is some kind of simple inattentive mistake.

Andrei
  • 367
  • 1
  • 9

1 Answers1

4

This is not specific to Monero, rather a C/C++ linking question, nevertheless...

The order you add the libraries matters. In your example:

...
/usr/bin/c++ _build/pymonero.cpp.o -o pymonero \
-L$MONERO_DIR/src -lversion \
-L$MONERO_DIR/src/cryptonote_basic -lcryptonote_basic \
-L$MONERO_DIR/src/device -ldevice \
...

Linking CXX executable pymonero
./monero//src/device/libdevice.a(device_ledger.cpp.o): In function `hw::ledger::device_ledger::reset()':
device_ledger.cpp:(.text+0x4a52): undefined reference to `MONERO_VERSION'
collect2: error: ld returned 1 exit status

You have specified version before device, which is why you are getting a linking error. All your libraries need to be in the correct order based on their dependencies. Linking searches forwards for symbols, not backwards.

jtgrassie
  • 19,601
  • 4
  • 17
  • 54