From 1700841856464023fa622d0210e8a0bee583d505 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Fri, 7 Feb 2025 14:06:40 +0100 Subject: [PATCH] refactor(core): unify way how rust is added to build [no changelog] --- core/SConscript.bootloader | 49 +++++----------------- core/SConscript.bootloader_ci | 2 +- core/SConscript.bootloader_emu | 54 ++++++------------------- core/SConscript.firmware | 74 ++++++++-------------------------- core/SConscript.unix | 53 +++++++++--------------- core/site_scons/tools.py | 59 +++++++++++++++++++++++++++ 6 files changed, 119 insertions(+), 172 deletions(-) diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader index 95c9cffec5..ad3cf85776 100644 --- a/core/SConscript.bootloader +++ b/core/SConscript.bootloader @@ -155,7 +155,7 @@ env.Replace( '-fstack-protector-strong ' + env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD, CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', - LINKFLAGS='-T build/bootloader/memory.ld -Wl,--gc-sections -Wl,-Map=build/bootloader/bootloader.map -Wl,--warn-common -Wl,--print-memory-usage', + LINKFLAGS=['-Tbuild/bootloader/memory.ld', '-Wl,--gc-sections', '-Wl,-Map=build/bootloader/bootloader.map', '-Wl,--warn-common', '-Wl,--print-memory-usage'], CPPPATH=ALLPATHS, CPPDEFINES=[ 'BOOTLOADER', @@ -183,50 +183,19 @@ cmake_gen = env.Command( action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS', ) - # # Rust library # +features = ['bootloader',] + FEATURES_AVAILABLE + RUST_UI_FEATURES -RUST_PROFILE = 'release' -RUST_LIB = 'trezor_lib' -RUST_LIBDIR = f'build/bootloader/rust/{env.get("ENV")["RUST_TARGET"]}/{RUST_PROFILE}' -RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a' +rust = tools.add_rust_lib( + env, + 'bootloader', + 'release', + features, + ALLPATHS, + str(Dir('.').abspath)) -def cargo_build(): - # Determine the profile build flags. - if RUST_PROFILE == 'release': - profile = '--release' - else: - profile = '' - - features = [] - features.extend(RUST_UI_FEATURES) - features.append("ui") - features.append("bootloader") - features.extend(FEATURES_AVAILABLE) - - cargo_opts = [ - f'--target={env.get("ENV")["RUST_TARGET"]}', - f'--target-dir=../../build/bootloader/rust', - '--no-default-features', - '--features ' + ','.join(features), - '-Z build-std=core', - '-Z build-std-features=panic_immediate_abort', - ] - - bindgen_macros = tools.get_bindgen_defines(env.get("CPPDEFINES"), ALLPATHS) - build_dir = str(Dir('.').abspath) - - return f'export BINDGEN_MACROS={shlex.quote(bindgen_macros)}; export BUILD_DIR=\'{build_dir}\'; cd embed/rust; cargo build {profile} ' + ' '.join(cargo_opts) - -rust = env.Command( - target=RUST_LIBPATH, - source='', - action=cargo_build(), ) - -env.Append(LINKFLAGS=f' -L{RUST_LIBDIR}') -env.Append(LINKFLAGS=f' -l{RUST_LIB}') # # Program objects diff --git a/core/SConscript.bootloader_ci b/core/SConscript.bootloader_ci index cf0717ac7d..d171a762cc 100644 --- a/core/SConscript.bootloader_ci +++ b/core/SConscript.bootloader_ci @@ -131,7 +131,7 @@ env.Replace( '-fstack-protector-strong ' + env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD, CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', - LINKFLAGS=f'-T build/bootloader_ci/memory.ld -Wl,--gc-sections -Wl,-Map=build/bootloader_ci/bootloader.map -Wl,--warn-common', + LINKFLAGS=['-Tbuild/bootloader_ci/memory.ld', '-Wl,--gc-sections', '-Wl,-Map=build/bootloader_ci/bootloader.map', '-Wl,--warn-common', '-Wl,--print-memory-usage'], CPPPATH=[ 'embed/projects/bootloader_ci', 'embed/projects/bootloader_ci/nanopb', diff --git a/core/SConscript.bootloader_emu b/core/SConscript.bootloader_emu index 80669a5d85..5aa2c04470 100644 --- a/core/SConscript.bootloader_emu +++ b/core/SConscript.bootloader_emu @@ -194,6 +194,7 @@ env.Replace( '-ffreestanding ' '-fstack-protector-all ' + CCFLAGS_MOD, + LINKFLAGS='', CPPPATH=ALLPATHS, CPPDEFINES=[ 'BOOTLOADER', @@ -221,53 +222,24 @@ cmake_gen = env.Command( action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS', ) - # # Rust library # - -RUST_TARGET = os.popen("rustc -vV | sed -n 's/host: //p'").read().strip() -RUST_LIB = 'trezor_lib' - +env.get("ENV")["RUST_TARGET"] = os.popen("rustc -vV | sed -n 's/host: //p'").read().strip() +features = ['bootloader',] + FEATURES_AVAILABLE + RUST_UI_FEATURES if ARGUMENTS.get('TREZOR_EMULATOR_DEBUGGABLE', '0') == '1': - RUST_PROFILE = 'dev' - RUST_LIBDIR = f'build/bootloader_emu/rust/{RUST_TARGET}/debug' + profile = 'dev' else: - RUST_PROFILE = 'release' - RUST_LIBDIR = f'build/bootloader_emu/rust/{RUST_TARGET}/release' + profile = 'release' -RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a' +rust = tools.add_rust_lib( + env, + 'bootloader_emu', + profile, + features, + ALLPATHS, + str(Dir('.').abspath)) -def cargo_build(): - features = [] - - features.extend(RUST_UI_FEATURES) - features.append("ui") - features.append("bootloader") - features.extend(FEATURES_AVAILABLE) - - - cargo_opts = [ - f'--target={RUST_TARGET}', - '--target-dir=../../build/bootloader_emu/rust', - '--no-default-features', - '--features ' + ','.join(features), - '-Z build-std=core', - '-Z build-std-features=panic_immediate_abort', - ] - - bindgen_macros = tools.get_bindgen_defines(env.get("CPPDEFINES"), ALLPATHS) - build_dir = str(Dir('.').abspath) - - return f'export BINDGEN_MACROS={shlex.quote(bindgen_macros)}; export BUILD_DIR=\'{build_dir}\'; cd embed/rust; cargo build --profile {RUST_PROFILE} ' + ' '.join(cargo_opts) - -rust = env.Command( - target=RUST_LIBPATH, - source='', - action=cargo_build(), ) - -env.Append(LINKFLAGS=f'-L{RUST_LIBDIR}') -env.Append(LINKFLAGS=f'-l{RUST_LIB}') env.Append(LINKFLAGS='-lm') env.Append(LINKFLAGS='-Wl,' + ('-dead_strip' if env['PLATFORM'] == 'darwin' else '--gc-sections')) @@ -287,7 +259,7 @@ program_elf = env.Command( target='bootloader.elf', source=obj_program, action= - '$CC -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $LINKFLAGS', ) + '$CC -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $LINKFLAGS') env.Depends(program_elf, rust) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 57aeb9b677..a3d2bd7a52 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -454,7 +454,7 @@ env.Replace( '-fstack-protector-all ' + env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD, CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', - LINKFLAGS='-T build/firmware/memory.ld -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-Map=build/firmware/firmware.map -Wl,--warn-common', + LINKFLAGS=['-Tbuild/firmware/memory.ld', '-Wl,--gc-sections', '-Wl,--print-memory-usage', '-Wl,-Map=build/firmware/firmware.map', '-Wl,--warn-common'], CPPPATH=ALLPATHS, CPPDEFINES=[ 'FIRMWARE', @@ -751,68 +751,28 @@ protobuf_blobs = env.Command( ) env.Depends(protobuf_blobs, qstr_generated) -RUST_PROFILE = 'release' -RUST_LIB = 'trezor_lib' -RUST_LIBDIR = f'build/firmware/rust/{env.get("ENV")["RUST_TARGET"]}/{RUST_PROFILE}' -RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a' +# +# Rust library +# +features = ['micropython', 'protobuf', 'ui', 'translations'] + FEATURES_AVAILABLE + RUST_UI_FEATURES +if PYOPT == '0': + features.append('debug') + features.append('ui_debug') +if EVERYTHING: + features.append('universal_fw') -def cargo_build(): - # Determine the profile build flags. - if RUST_PROFILE == 'release': - profile = '--release' - else: - profile = '' +rust = tools.add_rust_lib( + env, + 'firmware', + 'release', + features, + ALLPATHS, + str(Dir('.').abspath)) - features = ['micropython', 'protobuf'] - if EVERYTHING: - features.append('universal_fw') - features.extend(RUST_UI_FEATURES) - features.append('ui') - features.append('translations') - if PYOPT == '0': - features.append('debug') - features.append('ui_debug') - - features.extend(FEATURES_AVAILABLE) - - cargo_opts = [ - f'--target={env.get("ENV")["RUST_TARGET"]}', - f'--target-dir=../../build/firmware/rust', - '--no-default-features', - '--features ' + ','.join(features), - '-Z build-std=core', - '-Z build-std-features=panic_immediate_abort', - ] - - env.get('ENV')['TREZOR_MODEL'] = TREZOR_MODEL - - if ARGUMENTS.get('RUST_PRINT_TYPES_SIZES', '0') == '1': - # see https://nnethercote.github.io/perf-book/type-sizes.html#measuring-type-sizes for more details - env.Append(ENV={'RUSTFLAGS': '-Z print-type-sizes'}) - - # Adds an ELF section with Rust functions' stack sizes. See the following links for more details: - # - https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/emit-stack-sizes.html - # - https://blog.japaric.io/stack-analysis/ - # - https://github.com/japaric/stack-sizes/ - env.Append(ENV={'RUSTFLAGS': '-Z emit-stack-sizes'}) - - bindgen_macros = tools.get_bindgen_defines(env.get("CPPDEFINES"), ALLPATHS) - build_dir = str(Dir('.').abspath) - - return f'export BINDGEN_MACROS={shlex.quote(bindgen_macros)}; export BUILD_DIR=\'{build_dir}\'; cd embed/rust; cargo build {profile} ' + ' '.join(cargo_opts) - -rust = env.Command( - target=RUST_LIBPATH, - source='', - action=cargo_build(), ) env.Depends(rust, protobuf_blobs) env.Depends(rust, TRANSLATION_DATA) -env.Append(LINKFLAGS=f' -L{RUST_LIBDIR}') -env.Append(LINKFLAGS=f' -l{RUST_LIB}') - - BOOTLOADER_SUFFIX = TREZOR_MODEL if BOOTLOADER_QA or BOOTLOADER_DEVEL: BOOTLOADER_SUFFIX += '_qa' diff --git a/core/SConscript.unix b/core/SConscript.unix index 6b0fd17ff8..913615861b 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -810,48 +810,35 @@ protobuf_blobs = env.Command( ) env.Depends(protobuf_blobs, qstr_generated) -TARGET = os.popen("rustc -vV | sed -n 's/host: //p'").read().strip() + +# +# Rust library +# +env.get("ENV")["RUST_TARGET"] = os.popen("rustc -vV | sed -n 's/host: //p'").read().strip() if ARGUMENTS.get('TREZOR_EMULATOR_DEBUGGABLE', '0') == '1': - RUST_PROFILE = 'dev' - RUST_LIBDIR = f'build/unix/rust/{TARGET}/debug' + profile = 'dev' else: - RUST_PROFILE = 'release' - RUST_LIBDIR = f'build/unix/rust/{TARGET}/release' -RUST_LIB = 'trezor_lib' -RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a' + profile = 'release' -def cargo_build(): - features = ['micropython', 'protobuf'] - if EVERYTHING: - features.append('universal_fw') - features.extend(RUST_UI_FEATURES) - features.append('ui') - features.append('translations') +features = ['micropython', 'protobuf', 'ui', 'translations'] + FEATURES_AVAILABLE + RUST_UI_FEATURES +if PYOPT == '0': + features.append('debug') + features.append('ui_debug') +if EVERYTHING: + features.append('universal_fw') - if PYOPT == '0': - features.append('debug') +rust = tools.add_rust_lib( + env, + 'firmware', + profile, + features, + ALLPATHS, + str(Dir('.').abspath)) - features.extend(FEATURES_AVAILABLE) - env.get('ENV')['TREZOR_MODEL'] = TREZOR_MODEL - - bindgen_macros = tools.get_bindgen_defines(env.get("CPPDEFINES"), ALLPATHS) - build_dir = str(Dir('.').abspath) - - return f'export BINDGEN_MACROS={shlex.quote(bindgen_macros)}; export BUILD_DIR=\'{build_dir}\'; cd embed/rust; cargo build --profile {RUST_PROFILE} --target-dir=../../build/unix/rust --no-default-features --features "{" ".join(features)}" --target {TARGET}' - -rust = env.Command( - target=RUST_LIBPATH, - source='', - action=cargo_build(), ) env.Depends(rust, protobuf_blobs) env.Depends(rust, TRANSLATION_DATA) - - -env.Append(LINKFLAGS=f'-L{RUST_LIBDIR}') -env.Append(LINKFLAGS=f'-l{RUST_LIB}') - env.Depends(obj_program, qstr_generated) program = env.Command( diff --git a/core/site_scons/tools.py b/core/site_scons/tools.py index ad4e25c7d2..26b58ff6d3 100644 --- a/core/site_scons/tools.py +++ b/core/site_scons/tools.py @@ -1,5 +1,6 @@ from __future__ import annotations +import shlex import subprocess import zlib from pathlib import Path @@ -125,3 +126,61 @@ def embed_raw_binary(obj_program, env, section, target_, file): f" --rename-section .data=.{section}" + " $SOURCE $TARGET", ) ) + + +def add_rust_lib( + env, build, profile, features, all_paths, build_dir, print_types_sizes=False +): + RUST_LIB = "trezor_lib" + RUST_TARGET = env.get("ENV")["RUST_TARGET"] + + # Determine the profile build flags. + if profile == "release": + profile = "--release" + RUST_LIBDIR = f"build/{build}/rust/{RUST_TARGET}/release" + else: + profile = "" + RUST_LIBDIR = f"build/{build}/rust/{RUST_TARGET}/debug" + RUST_LIBPATH = f"{RUST_LIBDIR}/lib{RUST_LIB}.a" + + def cargo_build(): + lib_features = [] + lib_features.extend(features) + lib_features.append("ui") + + cargo_opts = [ + f"--target={RUST_TARGET}", + f"--target-dir=../../build/{build}/rust", + "--no-default-features", + "--features " + ",".join(lib_features), + "-Z build-std=core", + "-Z build-std-features=panic_immediate_abort", + ] + + if print_types_sizes: + # see https://nnethercote.github.io/perf-book/type-sizes.html#measuring-type-sizes for more details + env.Append(ENV={"RUSTFLAGS": "-Z print-type-sizes"}) + + # Adds an ELF section with Rust functions' stack sizes. See the following links for more details: + # - https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/emit-stack-sizes.html + # - https://blog.japaric.io/stack-analysis/ + # - https://github.com/japaric/stack-sizes/ + env.Append(ENV={"RUSTFLAGS": "-Z emit-stack-sizes"}) + + bindgen_macros = get_bindgen_defines(env.get("CPPDEFINES"), all_paths) + + return ( + f"export BINDGEN_MACROS={shlex.quote(bindgen_macros)}; export BUILD_DIR='{build_dir}'; cd embed/rust; cargo build {profile} " + + " ".join(cargo_opts) + ) + + rust = env.Command( + target=RUST_LIBPATH, + source="", + action=cargo_build(), + ) + + env.Append(LINKFLAGS=f"-L{RUST_LIBDIR}") + env.Append(LINKFLAGS=f"-l{RUST_LIB}") + + return rust