Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trezor: support c++17 and protobuf v25, libusb fix #smol #9064

Merged
merged 1 commit into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions cmake/CheckTrezor.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,25 @@ if (USE_DEVICE_TREZOR)
# Protobuf is required to build protobuf messages for Trezor
include(FindProtobuf OPTIONAL)

FIND_PACKAGE(Protobuf CONFIG)
# PkgConfig works better with new Protobuf
find_package(PkgConfig QUIET)
pkg_check_modules(PROTOBUF protobuf)

if (NOT Protobuf_FOUND)
FIND_PACKAGE(Protobuf CONFIG)
endif()
if (NOT Protobuf_FOUND)
FIND_PACKAGE(Protobuf)
endif()

_trezor_protobuf_fix_vars()

# Early fail for optional Trezor support
if(${Protobuf_VERSION} GREATER 21)
trezor_fatal_msg("Trezor: Unsupported Protobuf version ${Protobuf_VERSION}. Please, use Protobuf v21.")
elseif(NOT Protobuf_FOUND AND NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR)
if(NOT Protobuf_FOUND AND NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR)
trezor_fatal_msg("Trezor: Could not find Protobuf")
elseif(NOT Protobuf_LIBRARY OR NOT EXISTS "${Protobuf_LIBRARY}")
elseif(${CMAKE_CXX_STANDARD} LESS 17 AND ${Protobuf_VERSION} GREATER 21)
trezor_fatal_msg("Trezor: Unsupported Protobuf version ${Protobuf_VERSION} with C++ ${CMAKE_CXX_STANDARD}. Please, use Protobuf v21.")
elseif(NOT Protobuf_LIBRARY)
trezor_fatal_msg("Trezor: Protobuf library not found: ${Protobuf_LIBRARY}")
unset(Protobuf_FOUND)
elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
Expand Down Expand Up @@ -150,9 +156,10 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
endif()

if(USE_DEVICE_TREZOR_PROTOBUF_TEST)
# For now, Protobuf v21 is the maximum supported version as v23 requires C++17. TODO: Remove once we move to C++17
if(${Protobuf_VERSION} GREATER 21)
trezor_fatal_msg("Trezor: Unsupported Protobuf version ${Protobuf_VERSION}. Please, use Protobuf v21.")
if(PROTOBUF_LDFLAGS)
set(PROTOBUF_TRYCOMPILE_LINKER "${PROTOBUF_LDFLAGS}")
else()
set(PROTOBUF_TRYCOMPILE_LINKER "${Protobuf_LIBRARY}")
endif()

try_compile(Protobuf_COMPILE_TEST_PASSED
Expand All @@ -164,7 +171,7 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
CMAKE_EXE_LINKER_FLAGS ${CMAKE_TRY_COMPILE_LINKER_FLAGS}
"-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
LINK_LIBRARIES ${Protobuf_LIBRARY} ${CMAKE_TRY_COMPILE_LINK_LIBRARIES}
LINK_LIBRARIES "${PROTOBUF_TRYCOMPILE_LINKER}" ${CMAKE_TRY_COMPILE_LINK_LIBRARIES}
OUTPUT_VARIABLE OUTPUT
)
if(NOT Protobuf_COMPILE_TEST_PASSED)
Expand Down
10 changes: 5 additions & 5 deletions cmake/FindLibUSB.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,6 @@ if ( LibUSB_FOUND )
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${LibUSB_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${TEST_COMPILE_EXTRA_LIBRARIES})

check_library_exists ( "${LibUSB_LIBRARIES}" usb_open "" LibUSB_FOUND )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_device_list "" LibUSB_VERSION_1.0 )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_port_numbers "" LibUSB_VERSION_1.0.16 )

if((STATIC AND UNIX AND NOT APPLE AND NOT FREEBSD) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux") OR ANDROID)
find_library(LIBUDEV_LIBRARY udev)
if(LIBUDEV_LIBRARY)
Expand All @@ -132,6 +128,10 @@ if ( LibUSB_FOUND )
endif()
endif()

check_library_exists ( "${LibUSB_LIBRARIES}" usb_open "" LibUSB_FOUND )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_device_list "" LibUSB_VERSION_1.0 )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_port_numbers "" LibUSB_VERSION_1.0.16 )

# Library 1.0.16+ compilation test.
# The check_library_exists does not work well on Apple with shared libs.
if (APPLE OR LibUSB_VERSION_1.0.16 OR STATIC)
Expand All @@ -141,7 +141,7 @@ if ( LibUSB_FOUND )
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
LINK_LIBRARIES ${TEST_COMPILE_EXTRA_LIBRARIES}
LINK_LIBRARIES ${LibUSB_LIBRARIES} ${TEST_COMPILE_EXTRA_LIBRARIES}
OUTPUT_VARIABLE OUTPUT)
unset(TEST_COMPILE_EXTRA_LIBRARIES)
message(STATUS "LibUSB Compilation test: ${LibUSB_COMPILE_TEST_PASSED}")
Expand Down
22 changes: 16 additions & 6 deletions src/device_trezor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,29 @@ Please, refer to [monero readme](https://github.com/trezor/trezor-firmware/blob/

## Dependencies

Trezor uses [Protobuf](https://protobuf.dev/) library. As Monero is compiled with C++14, the newest Protobuf library version cannot be compiled because it requires C++17 (through its dependency Abseil library).
This can result in a compilation failure.
Trezor uses [Protobuf](https://protobuf.dev/) library. Monero is now compiled with C++ 17 by default.
Protobuf v21 is tested, older versions are not guaranteed to work. Note that Protobuf v23+ requires C++ 17.

Protobuf v21 is the latest compatible protobuf version.
If you are getting Trezor compilation errors, it may be caused by abseil (protobuf dependency) not being compiled with C++17.
To fix this try installing protobuf from sources:

If you want to compile Monero with Trezor support, please make sure the Protobuf v21 is installed.
```shell
git clone --recursive [email protected]:protocolbuffers/protobuf.git
cd protobuf
cmake -DABSL_PROPAGATE_CXX_STD=TRUE -DCMAKE_CXX_STANDARD=17 -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_BUILD_TESTS=OFF .
cmake --build .
sudo make install
```

If Monero is compiled with C++14, Protobuf v21 is the latest compatible protobuf version for C++ 14.
If you want to compile Monero with Trezor support with C++14, please make sure the Protobuf v21 is installed.

More about this limitation: [PR #8752](https://github.com/monero-project/monero/pull/8752),
[1](https://github.com/monero-project/monero/pull/8752#discussion_r1246174755), [2](https://github.com/monero-project/monero/pull/8752#discussion_r1246480393)

### OSX

To build with installed, but not linked protobuf:
To build with installed, but not linked Protobuf v21:

```bash
CMAKE_PREFIX_PATH=$(find /opt/homebrew/Cellar/protobuf@21 -maxdepth 1 -type d -name "21.*" -print -quit) \
Expand All @@ -53,7 +63,7 @@ pacman --noconfirm -U mingw-w64-x86_64-protobuf-c-1.4.1-1-any.pkg.tar.zst mingw-

### Other systems

- install protobufv21
- install Protobuf v21
- point `CMAKE_PREFIX_PATH` environment variable to Protobuf v21 installation.

## Troubleshooting
Expand Down
1 change: 1 addition & 0 deletions tests/core_tests/wallet_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class wallet_accessor_test
{
public:
static void set_account(tools::wallet2 * wallet, cryptonote::account_base& account);
static void set_password(tools::wallet2 * wallet, const epee::wipeable_string & password) { wallet->setup_keys(password); }
static tools::wallet2::transfer_container & get_transfers(tools::wallet2 * wallet) { return wallet->m_transfers; }
static subaddresses_t & get_subaddresses(tools::wallet2 * wallet) { return wallet->m_subaddresses; }
static void process_parsed_blocks(tools::wallet2 * wallet, uint64_t start_height, const std::vector<cryptonote::block_complete_entry> &blocks, const std::vector<tools::wallet2::parsed_block> &parsed_blocks, uint64_t& blocks_added);
Expand Down
1 change: 1 addition & 0 deletions tests/trezor/trezor_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,7 @@ bool gen_trezor_wallet_passphrase::generate(std::vector<test_event_entry>& event

const auto wallet_path = (m_wallet_dir / "alice2").string();
const epee::wipeable_string& password = epee::wipeable_string("test-pass");
wallet_accessor_test::set_password(m_wl_alice2.get(), password);
m_wl_alice2->store_to(wallet_path, password);

// Positive load
Expand Down