# Function for setting default options default values via env vars function(_trezor_default_val val_name val_default) if(NOT DEFINED ENV{${val_name}}) set(ENV{${val_name}} ${val_default}) endif() endfunction() # Define default options via env vars _trezor_default_val(USE_DEVICE_TREZOR ON) _trezor_default_val(USE_DEVICE_TREZOR_MANDATORY OFF) _trezor_default_val(USE_DEVICE_TREZOR_PROTOBUF_TEST ON) _trezor_default_val(USE_DEVICE_TREZOR_LIBUSB ON) _trezor_default_val(USE_DEVICE_TREZOR_UDP_RELEASE OFF) _trezor_default_val(USE_DEVICE_TREZOR_DEBUG OFF) _trezor_default_val(TREZOR_DEBUG OFF) # Main options OPTION(USE_DEVICE_TREZOR "Trezor support compilation" $ENV{USE_DEVICE_TREZOR}) OPTION(USE_DEVICE_TREZOR_MANDATORY "Trezor compilation is mandatory, fail build if Trezor support cannot be compiled" $ENV{USE_DEVICE_TREZOR_MANDATORY}) OPTION(USE_DEVICE_TREZOR_PROTOBUF_TEST "Trezor Protobuf test" $ENV{USE_DEVICE_TREZOR_PROTOBUF_TEST}) OPTION(USE_DEVICE_TREZOR_LIBUSB "Trezor LibUSB compilation" $ENV{USE_DEVICE_TREZOR_LIBUSB}) OPTION(USE_DEVICE_TREZOR_UDP_RELEASE "Trezor UdpTransport in release mode" $ENV{USE_DEVICE_TREZOR_UDP_RELEASE}) OPTION(USE_DEVICE_TREZOR_DEBUG "Trezor Debugging enabled" $ENV{USE_DEVICE_TREZOR_DEBUG}) OPTION(TREZOR_DEBUG "Main Trezor debugging switch" $ENV{TREZOR_DEBUG}) # Helper function to fix cmake < 3.6.0 FindProtobuf variables function(_trezor_protobuf_fix_vars) if(${CMAKE_VERSION} VERSION_LESS "3.6.0") foreach(UPPER PROTOBUF_SRC_ROOT_FOLDER PROTOBUF_IMPORT_DIRS PROTOBUF_DEBUG PROTOBUF_LIBRARY PROTOBUF_PROTOC_LIBRARY PROTOBUF_INCLUDE_DIR PROTOBUF_PROTOC_EXECUTABLE PROTOBUF_LIBRARY_DEBUG PROTOBUF_PROTOC_LIBRARY_DEBUG PROTOBUF_LITE_LIBRARY PROTOBUF_LITE_LIBRARY_DEBUG ) if (DEFINED ${UPPER}) string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER}) if (NOT DEFINED ${Camel}) set(${Camel} ${${UPPER}} PARENT_SCOPE) endif() endif() endforeach() endif() endfunction() macro(trezor_fatal_msg msg) if ($ENV{USE_DEVICE_TREZOR_MANDATORY}) message(FATAL_ERROR "${msg}\n" "==========================================================================\n" "[ERROR] To compile without Trezor support, set USE_DEVICE_TREZOR=OFF. " "It is possible both via cmake variable and environment variable, e.g., " "`USE_DEVICE_TREZOR=OFF make release`\n" "For more information, please check src/device_trezor/README.md\n" ) else() message(WARNING "${msg}\n" "==========================================================================\n" "[WARNING] Trezor support cannot be compiled! Skipping Trezor compilation. \n" "For more information, please check src/device_trezor/README.md\n") set(USE_DEVICE_TREZOR OFF) return() # finish this cmake file processing (as this is macro). endif() endmacro() # Use Trezor master switch if (USE_DEVICE_TREZOR) # Protobuf is required to build protobuf messages for Trezor include(FindProtobuf OPTIONAL) FIND_PACKAGE(Protobuf CONFIG) 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) trezor_fatal_msg("Trezor: Could not find Protobuf") elseif(NOT Protobuf_LIBRARY OR NOT EXISTS "${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}") trezor_fatal_msg("Trezor: Protobuf executable not found: ${Protobuf_PROTOC_EXECUTABLE}") unset(Protobuf_FOUND) elseif(NOT Protobuf_INCLUDE_DIR OR NOT EXISTS "${Protobuf_INCLUDE_DIR}") trezor_fatal_msg("Trezor: Protobuf include dir not found: ${Protobuf_INCLUDE_DIR}") unset(Protobuf_FOUND) else() message(STATUS "Trezor: Protobuf lib: ${Protobuf_LIBRARY}, inc: ${Protobuf_INCLUDE_DIR}, protoc: ${Protobuf_PROTOC_EXECUTABLE}") set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR}) set(Protobuf_FOUND 1) # override found if all required info was provided by variables endif() if(TREZOR_DEBUG) set(USE_DEVICE_TREZOR_DEBUG 1) message(STATUS "Trezor: debug build enabled") endif() # Compile debugging support (for tests) if (USE_DEVICE_TREZOR_DEBUG) add_definitions(-DWITH_TREZOR_DEBUGGING=1) endif() else() message(STATUS "Trezor: support disabled by USE_DEVICE_TREZOR") endif() if(Protobuf_FOUND AND USE_DEVICE_TREZOR) if (NOT "$ENV{TREZOR_PYTHON}" STREQUAL "") set(TREZOR_PYTHON "$ENV{TREZOR_PYTHON}" CACHE INTERNAL "Copied from environment variable TREZOR_PYTHON") else() find_package(Python QUIET COMPONENTS Interpreter) # cmake 3.12+ if(Python_Interpreter_FOUND) set(TREZOR_PYTHON "${Python_EXECUTABLE}") endif() endif() if(NOT TREZOR_PYTHON) find_package(PythonInterp) if(PYTHONINTERP_FOUND AND PYTHON_EXECUTABLE) set(TREZOR_PYTHON "${PYTHON_EXECUTABLE}") endif() endif() if(NOT TREZOR_PYTHON) trezor_fatal_msg("Trezor: Python not found") endif() endif() # Protobuf compilation test if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_CURRENT_LIST_DIR}" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR) if(RET) trezor_fatal_msg("Trezor: Protobuf test generation failed: ${OUT} ${ERR}") endif() if(ANDROID) set(CMAKE_TRY_COMPILE_LINKER_FLAGS "${CMAKE_TRY_COMPILE_LINKER_FLAGS} -llog") set(CMAKE_TRY_COMPILE_LINK_LIBRARIES "${CMAKE_TRY_COMPILE_LINK_LIBRARIES} log") 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.") endif() try_compile(Protobuf_COMPILE_TEST_PASSED "${CMAKE_BINARY_DIR}" SOURCES "${CMAKE_BINARY_DIR}/test-protobuf.pb.cc" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp" CMAKE_FLAGS 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} OUTPUT_VARIABLE OUTPUT ) if(NOT Protobuf_COMPILE_TEST_PASSED) trezor_fatal_msg("Trezor: Protobuf Compilation test failed: ${OUTPUT}.") endif() else () message(STATUS "Trezor: Protobuf Compilation test skipped, build may fail later") endif() endif() # Try to build protobuf messages if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}") set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}") set(TREZOR_PROTOBUF_PARAMS "") if (USE_DEVICE_TREZOR_DEBUG) set(TREZOR_PROTOBUF_PARAMS "--debug") endif() execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py ${TREZOR_PROTOBUF_PARAMS} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR) if(RET) trezor_fatal_msg("Trezor: protobuf messages could not be regenerated (err=${RET}, python ${PYTHON})." "OUT: ${OUT}, ERR: ${ERR}." "Please read src/device_trezor/trezor/tools/README.md") endif() message(STATUS "Trezor: protobuf messages regenerated out: \"${OUT}.\"") set(DEVICE_TREZOR_READY 1) add_definitions(-DDEVICE_TREZOR_READY=1) add_definitions(-DPROTOBUF_INLINE_NOT_IN_HEADERS=0) if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_definitions(-DTREZOR_DEBUG=1) endif() if(USE_DEVICE_TREZOR_UDP_RELEASE) message(STATUS "Trezor: UDP transport enabled (emulator)") add_definitions(-DUSE_DEVICE_TREZOR_UDP_RELEASE=1) endif() if (Protobuf_INCLUDE_DIR) include_directories(${Protobuf_INCLUDE_DIR}) endif() # LibUSB support, check for particular version # Include support only if compilation test passes if (USE_DEVICE_TREZOR_LIBUSB) find_package(LibUSB) endif() if (LibUSB_COMPILE_TEST_PASSED) add_definitions(-DHAVE_TREZOR_LIBUSB=1) if(LibUSB_INCLUDE_DIRS) include_directories(${LibUSB_INCLUDE_DIRS}) endif() endif() set(TREZOR_LIBUSB_LIBRARIES "") if(LibUSB_COMPILE_TEST_PASSED) list(APPEND TREZOR_LIBUSB_LIBRARIES ${LibUSB_LIBRARIES} ${LIBUSB_DEP_LINKER}) message(STATUS "Trezor: compatible LibUSB found at: ${LibUSB_INCLUDE_DIRS}") elseif(USE_DEVICE_TREZOR_LIBUSB AND NOT ANDROID) trezor_fatal_msg("Trezor: LibUSB not found or test failed, please install libusb-1.0.26") endif() if (BUILD_GUI_DEPS) set(TREZOR_DEP_LIBS "") set(TREZOR_DEP_LINKER "") if (Protobuf_LIBRARY) list(APPEND TREZOR_DEP_LIBS ${Protobuf_LIBRARY}) string(APPEND TREZOR_DEP_LINKER " -lprotobuf") endif() if (TREZOR_LIBUSB_LIBRARIES) list(APPEND TREZOR_DEP_LIBS ${TREZOR_LIBUSB_LIBRARIES}) string(APPEND TREZOR_DEP_LINKER " -lusb-1.0 ${LIBUSB_DEP_LINKER}") endif() endif() endif()