mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-09 08:08:09 +00:00

WIP - refactor and extend font generation for non-ascii characters WIP - add czech characters mapping between UTF8 value and index WIP - regenerate font files with czech characters WIP - shorten czech button text, it was causing SHUTDOWN for some reason WIP - support UTF8 characters in fonts.c WIP - account for translation in tests WIP - small fixes WIP - fix last test WIP - support UTF8 also in Rust font operations WIP - add a script to find non-translated english strings in micropython code WIP - add a validator script for checking missing micropython translations WIP - translate remaining altcoins and other apps in core (fido, sdcard, TT layouts, ...) WIP - generate czech glyphs for TT fonts WIP - modify gen_font.py to account for negative bearing czech characters WIP - extend translation validation scripts, move them into core/tools WIP - translate TT layouts in Rust WIP - fix tests WIP - fix inverse coloring of nonprintable glyph WIP - add build and test pipelines for Czech language WIP - merge both JSON files together WIP - run new isort WIP - unify all the translation in Rust, expose to micropython TEMP - leave en_merged.json file, so it is accessible by translators with old link WIP - fixes WIP - add french characters and translation via Google Translator WIP - skip rustfmt in mako-created files WIP - revert all the font height changes causing false-positive UI diff WIP - fixes after rebase WIP - fix broken translations WIP - revert some wording changes causing UI diff WIP - improve validation and translate scripts, translate missing strings WIP - sort all keys alphabetically WIP - remove any usage of translation in bootloader WIP - add newline at the end of JSON file WIP - fix bitcoin-only strings check WIP - fix python support check WIP - add some missing translations WIP - fix SD card device test WIP - fix pystyle WIP - fix rust unittests WIP - fix click tests WIP - flag errors in french translations WIP - add script transferring translations data into a byte blob WIP - regenerate fr.rs WIP - store and read language translations from flash WIP - storing language name in storage WIP - sending language_data in apply_settings protobuf message WIP - separate protobuf message for translations, fixes WIP - set up translations area for TT as well WIP - get rid of TREZOR_LANG env variable during build WIP - make the firmware buildable for TT WIP - add basic device tests WIP - set language for tests WIP - counting with language when writing fixtures WIP - add todos WIP - fix CI WIP - unify translations, make titles CAPITAL WIP - translate missing english WIP - skip translations messages for T1 WIP - not changing tests names for english WIP - fix flake8 WIP - no test language setting for T1 WIP - clippy lint about complex data type WIP - fix some english UI diff for TR WIP - fix cstyle WIP - minimize the usage of #[cfg(feature = "micropython")] outside translations module WIP - minimize TT's UI diff WIP - fix ruststyle WIP - fix TR build WIP - advanced Shamir text change WIP - storing the language name as the first item in the translation data WIP - modify and extend tests after storing language name WIP - modify checklist sentence WIP - add TEST_LANG into Makefile for all the emu tests WIP - default arguments WIP - reimplement default arguments remove unneeded pub from get_info function WIP - Rust handling of object attributes lookups from upy - thanks Matejcik! WIP - generate mock interface for attribute-based translations lookups WIP - change function calls to object attributes WIP - symbolic link for unix/translations.c WIP - fix and improve the reading of translations - thanks Matejcik! WIP - add support for multiple languages in removing missing tests WIP - fix multiple-accounts warning in tests WIP - fix encoding of newlines in translations WIP - fix czech tutorial text WIP - fix czech click tests WIP - do not translate wire error messages WIP - add language options to click tests as well WIP - setup czech device tests in CI WIP - setup czech click tests in CI WIP - record czech device tests for TR WIP - record czech click tests for TR WIP - record czech device tests for TT WIP - record czech click tests for TT WIP - pystyle WIP - cstyle WIP - fix Rust micropython import dependency WIP - fix czech recordings WIP - support french translations in tests WIP - shorten some french words to fix the tests WIP - fix micropython cfg compilation WIP - record french click tests for TR WIP - record french device tests for TR WIP - record french device tests for TT WIP - record french click tests for TT WIP - fix french translations - shorten them WIP - translate missing french words WIP - fix click tests WIP - add french tests into CI WIP - pystyle WIP - allow for czech/french tests in update script WIP - update czech fixtures WIP - update french fixtures WIP - ruststyle WIP - disallow MPU to run it on hardware WIP - cstyle WIP - change translations delimiter from * to \x00 WIP - change translations protobufs WIP - remove language handling from storage WIP - add header into JSON files WIP - count with header in translations blob WIP - yml style fixes WIP - fix proto gen WIP - verify version and data hash WIP - fix loading test translations feat(core): allow access to translations area in firmware [no changelog] WIP - fixes after rebase WIP - increase the TT's translations area to 3 sectors WIP - dynamically read the maximum translations size WIP - record non-english tests from CI WIP - loading font data from translations blob WIP - bump translations version WIP - include czech and french glyph data WIP - whitelist another negative-bearing glyph WIP - remove czech/french glyphs from common font files WIP - fix language tests WIP - specific fonts for specific models WIP - revert the non-ascii font hardcoding WIP - include missing BIG font into nonprintable logic WIP - minor Rust code improvements WIP - include newlines at the end of json files WIP - move glyph Rust function to librust_fonts.h WIP - add all fonts into translations file WIP - move fonts into its own dir WIP - reflect separate dir for fonts WIP - not putting translations trezorhal into bootloader WIP - write and read multiple fonts into translations data WIP - silence pyright issue/notissue WIP - delete no more used translations/*.py imports WIP - fix bootloader builds by introducing translations feature and TRANSLATIONS flag WIP - fix TT's bootloader Rust build WIP - fix tests in non-english languages WIP - not search for UTF-8 when there are no translations data WIP - add colons to strings where missing WIP - fix language loading in tests WIP - fix signmessage input flow to work in all languages WIP - create offset table for translation strings WIP - code improvements WIP - record foreign language fixtures + sync with main in english WIP - do alignment check before reading u16 data WIP - allocate blob in RAM for translations data WIP - add TODO for blob generation WIP - record non-english device tests WIP - use bytes.align_to instead of messing with pointers WIP - fixtures WIP - remove unused import WIP - add order.py WIP - add order.json WIP - take order.json into account in creating general.rs WIP - take order.json into account in generating the blob WIP - style WIP - sort the language files WIP - remove unused file WIP - code improvements WIP - add TODO for homescreen notification WIP - translate plural forms WIP - translate time intervals WIP - sign translations with dev keys, validate signatures, improve robustness WIP - improve tests for translations WIP - add `trezorctl utils sign-translations` for production signing of the blob WIP - pyright fix WIP - changing TR progress loader offset - it was colliding with title WIP - show indeterminate loader when loading translations data WIP - record new and updated language tests WIP - show the change language title/prompt in the target language WIP - sort keys WIP - add crowdin-cli into shell.nix WIP - add crowdin sync script
430 lines
15 KiB
Rust
430 lines
15 KiB
Rust
#[cfg(feature = "test")]
|
|
use std::ffi::OsStr;
|
|
use std::{env, path::PathBuf, process::Command};
|
|
|
|
fn main() {
|
|
#[cfg(feature = "micropython")]
|
|
generate_qstr_bindings();
|
|
#[cfg(feature = "micropython")]
|
|
generate_micropython_bindings();
|
|
generate_trezorhal_bindings();
|
|
#[cfg(feature = "test")]
|
|
link_core_objects();
|
|
}
|
|
|
|
fn mcu_type() -> String {
|
|
match env::var("MCU_TYPE") {
|
|
Ok(mcu) => mcu,
|
|
Err(_) => String::from("STM32F427xx"),
|
|
}
|
|
}
|
|
|
|
fn model() -> String {
|
|
match env::var("TREZOR_MODEL") {
|
|
Ok(model) => model,
|
|
Err(_) => String::from("T"),
|
|
}
|
|
}
|
|
|
|
fn board() -> String {
|
|
if !is_firmware() {
|
|
return String::from("boards/board-unix.h");
|
|
}
|
|
|
|
match env::var("TREZOR_BOARD") {
|
|
Ok(board) => {
|
|
format!("boards/{}", board)
|
|
}
|
|
Err(_) => String::from("boards/trezor_t.h"),
|
|
}
|
|
}
|
|
|
|
/// Generates Rust module that exports QSTR constants used in firmware.
|
|
#[cfg(feature = "micropython")]
|
|
fn generate_qstr_bindings() {
|
|
let out_path = env::var("OUT_DIR").unwrap();
|
|
|
|
// Tell cargo to invalidate the built crate whenever the header changes.
|
|
println!("cargo:rerun-if-changed=qstr.h");
|
|
|
|
bindgen::Builder::default()
|
|
.header("qstr.h")
|
|
// Build the Qstr enum as a newtype so we can define method on it.
|
|
.default_enum_style(bindgen::EnumVariation::NewType { is_bitfield: false })
|
|
// Pass in correct include paths.
|
|
.clang_args(&[
|
|
"-I",
|
|
if is_firmware() {
|
|
"../../build/firmware"
|
|
} else {
|
|
"../../build/unix"
|
|
},
|
|
])
|
|
// Customize the standard types.
|
|
.use_core()
|
|
.ctypes_prefix("cty")
|
|
.size_t_is_usize(true)
|
|
// Tell cargo to invalidate the built crate whenever any of the
|
|
// included header files change.
|
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
|
.generate()
|
|
.expect("Unable to generate Rust QSTR bindings")
|
|
.write_to_file(PathBuf::from(out_path).join("qstr.rs"))
|
|
.unwrap();
|
|
}
|
|
|
|
fn prepare_bindings() -> bindgen::Builder {
|
|
let mut bindings = bindgen::Builder::default();
|
|
|
|
// Common include paths and defines
|
|
bindings = bindings.clang_args([
|
|
"-I../../../crypto",
|
|
"-I../../../storage",
|
|
"-I../../vendor/micropython",
|
|
"-I../../vendor/micropython/lib/uzlib",
|
|
"-I../lib",
|
|
"-I../trezorhal",
|
|
"-I../models",
|
|
format!("-D{}", mcu_type()).as_str(),
|
|
format!("-DTREZOR_MODEL_{}", model()).as_str(),
|
|
format!("-DTREZOR_BOARD=\"{}\"", board()).as_str(),
|
|
]);
|
|
|
|
// Pass in correct include paths and defines.
|
|
if is_firmware() {
|
|
let mut clang_args: Vec<&str> = Vec::new();
|
|
|
|
let includes = env::var("RUST_INCLUDES").unwrap();
|
|
let args = includes.split(';');
|
|
|
|
for arg in args {
|
|
clang_args.push(arg);
|
|
}
|
|
clang_args.push("-nostdinc");
|
|
clang_args.push("-I../firmware");
|
|
clang_args.push("-I../../build/firmware");
|
|
clang_args.push("-I../../vendor/micropython/lib/cmsis/inc");
|
|
clang_args.push("-DUSE_HAL_DRIVER");
|
|
bindings = bindings.clang_args(&clang_args);
|
|
|
|
// Append gcc-arm-none-eabi's include paths.
|
|
let cc_output = Command::new("arm-none-eabi-gcc")
|
|
.arg("-E")
|
|
.arg("-Wp,-v")
|
|
.arg("-")
|
|
.output()
|
|
.expect("arm-none-eabi-gcc failed to execute");
|
|
if !cc_output.status.success() {
|
|
panic!("arm-none-eabi-gcc failed");
|
|
}
|
|
let include_paths =
|
|
String::from_utf8(cc_output.stderr).expect("arm-none-eabi-gcc returned invalid output");
|
|
let include_args = include_paths
|
|
.lines()
|
|
.skip_while(|s| !s.contains("search starts here:"))
|
|
.take_while(|s| !s.contains("End of search list."))
|
|
.filter(|s| s.starts_with(' '))
|
|
.map(|s| format!("-I{}", s.trim()));
|
|
|
|
bindings = bindings.clang_args(include_args);
|
|
} else {
|
|
bindings = bindings.clang_args(&[
|
|
"-I../unix",
|
|
"-I../trezorhal/unix",
|
|
"-I../../build/unix",
|
|
"-I../../vendor/micropython/ports/unix",
|
|
"-DTREZOR_EMULATOR",
|
|
]);
|
|
}
|
|
|
|
bindings
|
|
// Customize the standard types.
|
|
.use_core()
|
|
.ctypes_prefix("cty")
|
|
.size_t_is_usize(true)
|
|
// Disable the layout tests. They spew out a lot of code-style bindings, and are not too
|
|
// relevant for our use-case.
|
|
.layout_tests(false)
|
|
// Tell cargo to invalidate the built crate whenever any of the
|
|
// included header files change.
|
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
|
}
|
|
|
|
#[cfg(feature = "micropython")]
|
|
fn generate_micropython_bindings() {
|
|
let out_path = env::var("OUT_DIR").unwrap();
|
|
|
|
// Tell cargo to invalidate the built crate whenever the header changes.
|
|
println!("cargo:rerun-if-changed=micropython.h");
|
|
|
|
let bindings = prepare_bindings()
|
|
.header("micropython.h")
|
|
// obj
|
|
.new_type_alias("mp_obj_t")
|
|
.allowlist_type("mp_obj_type_t")
|
|
.allowlist_type("mp_obj_base_t")
|
|
.allowlist_function("mp_obj_new_int")
|
|
.allowlist_function("mp_obj_new_int_from_ll")
|
|
.allowlist_function("mp_obj_new_int_from_ull")
|
|
.allowlist_function("mp_obj_new_int_from_uint")
|
|
.allowlist_function("mp_obj_new_bytes")
|
|
.allowlist_function("mp_obj_new_str")
|
|
.allowlist_function("mp_obj_new_tuple")
|
|
.allowlist_function("mp_obj_get_int_maybe")
|
|
.allowlist_function("mp_obj_is_true")
|
|
.allowlist_function("mp_call_function_n_kw")
|
|
.allowlist_function("trezor_obj_get_ll_checked")
|
|
.allowlist_function("trezor_obj_str_from_rom_text")
|
|
// buffer
|
|
.allowlist_function("mp_get_buffer")
|
|
.allowlist_var("MP_BUFFER_READ")
|
|
.allowlist_var("MP_BUFFER_WRITE")
|
|
.allowlist_var("mp_type_str")
|
|
.allowlist_var("mp_type_bytes")
|
|
.allowlist_var("mp_type_bytearray")
|
|
.allowlist_var("mp_type_memoryview")
|
|
// dict
|
|
.allowlist_type("mp_obj_dict_t")
|
|
.allowlist_function("mp_obj_new_dict")
|
|
.allowlist_var("mp_type_dict")
|
|
// fun
|
|
.allowlist_type("mp_obj_fun_builtin_fixed_t")
|
|
.allowlist_var("mp_type_fun_builtin_0")
|
|
.allowlist_var("mp_type_fun_builtin_1")
|
|
.allowlist_var("mp_type_fun_builtin_2")
|
|
.allowlist_var("mp_type_fun_builtin_3")
|
|
.allowlist_type("mp_obj_fun_builtin_var_t")
|
|
.allowlist_var("mp_type_fun_builtin_var")
|
|
// gc
|
|
.allowlist_function("gc_alloc")
|
|
// iter
|
|
.allowlist_type("mp_obj_iter_buf_t")
|
|
.allowlist_function("mp_getiter")
|
|
.allowlist_function("mp_iternext")
|
|
// list
|
|
.allowlist_type("mp_obj_list_t")
|
|
.allowlist_function("mp_obj_new_list")
|
|
.allowlist_function("mp_obj_list_append")
|
|
.allowlist_function("mp_obj_list_get")
|
|
.allowlist_function("mp_obj_list_set_len")
|
|
.allowlist_var("mp_type_list")
|
|
// map
|
|
.allowlist_type("mp_map_elem_t")
|
|
.allowlist_function("mp_map_init")
|
|
.allowlist_function("mp_map_init_fixed_table")
|
|
.allowlist_function("mp_map_lookup")
|
|
// exceptions
|
|
.allowlist_function("nlr_jump")
|
|
.allowlist_function("mp_obj_new_exception")
|
|
.allowlist_function("mp_obj_new_exception_args")
|
|
.allowlist_function("trezor_obj_call_protected")
|
|
.allowlist_var("mp_type_AttributeError")
|
|
.allowlist_var("mp_type_IndexError")
|
|
.allowlist_var("mp_type_KeyError")
|
|
.allowlist_var("mp_type_MemoryError")
|
|
.allowlist_var("mp_type_OverflowError")
|
|
.allowlist_var("mp_type_ValueError")
|
|
.allowlist_var("mp_type_TypeError")
|
|
// time
|
|
.allowlist_function("mp_hal_ticks_ms")
|
|
.allowlist_function("mp_hal_delay_ms")
|
|
// debug
|
|
.allowlist_function("mp_print_strn")
|
|
.allowlist_var("mp_plat_print")
|
|
// typ
|
|
.allowlist_var("mp_type_type")
|
|
// module
|
|
.allowlist_type("mp_obj_module_t")
|
|
.allowlist_var("mp_type_module")
|
|
// qstr
|
|
.allowlist_function("qstr_data")
|
|
// `ffi::mp_map_t` type is not allowed to be `Clone` or `Copy` because we tie it
|
|
// to the data lifetimes with the `MapRef` type, see `src/micropython/map.rs`.
|
|
// TODO: We should disable `Clone` and `Copy` for all types and only allow-list
|
|
// the specific cases we require.
|
|
.no_copy("_mp_map_t");
|
|
|
|
// Write the bindings to a file in the OUR_DIR.
|
|
bindings
|
|
.generate()
|
|
.expect("Unable to generate bindings")
|
|
.write_to_file(PathBuf::from(out_path).join("micropython.rs"))
|
|
.unwrap();
|
|
}
|
|
|
|
fn generate_trezorhal_bindings() {
|
|
let out_path = env::var("OUT_DIR").unwrap();
|
|
|
|
// Tell cargo to invalidate the built crate whenever the header changes.
|
|
println!("cargo:rerun-if-changed=trezorhal.h");
|
|
|
|
let bindings = prepare_bindings()
|
|
.header("trezorhal.h")
|
|
// model
|
|
.allowlist_var("MODEL_INTERNAL_NAME")
|
|
.allowlist_var("MODEL_FULL_NAME")
|
|
// common
|
|
.allowlist_var("HW_ENTROPY_DATA")
|
|
// secbool
|
|
.allowlist_type("secbool")
|
|
.must_use_type("secbool")
|
|
.allowlist_var("sectrue")
|
|
.allowlist_var("secfalse")
|
|
// flash
|
|
.allowlist_function("flash_init")
|
|
// storage
|
|
.allowlist_var("EXTERNAL_SALT_SIZE")
|
|
.allowlist_function("storage_init")
|
|
.allowlist_function("storage_wipe")
|
|
.allowlist_function("storage_is_unlocked")
|
|
.allowlist_function("storage_lock")
|
|
.allowlist_function("storage_unlock")
|
|
.allowlist_function("storage_has_pin")
|
|
.allowlist_function("storage_get_pin_rem")
|
|
.allowlist_function("storage_change_pin")
|
|
.allowlist_function("storage_ensure_not_wipe_code")
|
|
.allowlist_function("storage_has")
|
|
.allowlist_function("storage_get")
|
|
.allowlist_function("storage_set")
|
|
.allowlist_function("storage_delete")
|
|
.allowlist_function("storage_set_counter")
|
|
.allowlist_function("storage_next_counter")
|
|
.allowlist_function("translations_read")
|
|
// display
|
|
.allowlist_function("display_clear")
|
|
.allowlist_function("display_offset")
|
|
.allowlist_function("display_refresh")
|
|
.allowlist_function("display_backlight")
|
|
.allowlist_function("display_text")
|
|
.allowlist_function("display_text_render_buffer")
|
|
.allowlist_function("display_text_width")
|
|
.allowlist_function("display_pixeldata")
|
|
.allowlist_function("display_pixeldata_dirty")
|
|
.allowlist_function("display_set_window")
|
|
.allowlist_function("display_sync")
|
|
.allowlist_function("display_get_fb_addr")
|
|
.allowlist_function("display_get_wr_addr")
|
|
.allowlist_var("DISPLAY_DATA_ADDRESS")
|
|
.allowlist_var("DISPLAY_FRAMEBUFFER_WIDTH")
|
|
.allowlist_var("DISPLAY_FRAMEBUFFER_HEIGHT")
|
|
.allowlist_var("DISPLAY_FRAMEBUFFER_OFFSET_X")
|
|
.allowlist_var("DISPLAY_FRAMEBUFFER_OFFSET_Y")
|
|
.allowlist_var("DISPLAY_RESX")
|
|
.allowlist_var("DISPLAY_RESY")
|
|
.allowlist_type("toif_format_t")
|
|
// fonts
|
|
.allowlist_function("font_height")
|
|
.allowlist_function("font_max_height")
|
|
.allowlist_function("font_baseline")
|
|
.allowlist_function("font_get_glyph")
|
|
// uzlib
|
|
.allowlist_function("uzlib_uncompress_init")
|
|
.allowlist_function("uzlib_uncompress")
|
|
// bip39
|
|
.allowlist_function("mnemonic_word_completion_mask")
|
|
.allowlist_var("BIP39_WORDLIST_ENGLISH")
|
|
.allowlist_var("BIP39_WORD_COUNT")
|
|
// slip39
|
|
.allowlist_function("slip39_word_completion_mask")
|
|
.allowlist_function("button_sequence_to_word")
|
|
.allowlist_var("SLIP39_WORDLIST")
|
|
.allowlist_var("SLIP39_WORD_COUNT")
|
|
// random
|
|
.allowlist_function("random_uniform")
|
|
// rgb led
|
|
.allowlist_function("rgb_led_set_color")
|
|
// time
|
|
.allowlist_function("hal_delay")
|
|
.allowlist_function("hal_ticks_ms")
|
|
// dma2d
|
|
.allowlist_function("dma2d_setup_const")
|
|
.allowlist_function("dma2d_setup_4bpp")
|
|
.allowlist_function("dma2d_setup_16bpp")
|
|
.allowlist_function("dma2d_setup_4bpp_over_4bpp")
|
|
.allowlist_function("dma2d_setup_4bpp_over_16bpp")
|
|
.allowlist_function("dma2d_start")
|
|
.allowlist_function("dma2d_start_blend")
|
|
.allowlist_function("dma2d_start_const")
|
|
.allowlist_function("dma2d_start_const_multiline")
|
|
.allowlist_function("dma2d_wait_for_transfer")
|
|
//buffers
|
|
.allowlist_function("buffers_get_line_16bpp")
|
|
.allowlist_function("buffers_free_line_16bpp")
|
|
.allowlist_function("buffers_get_line_4bpp")
|
|
.allowlist_function("buffers_free_line_4bpp")
|
|
.allowlist_function("buffers_get_text")
|
|
.allowlist_function("buffers_free_text")
|
|
.allowlist_function("buffers_get_jpeg")
|
|
.allowlist_function("buffers_free_jpeg")
|
|
.allowlist_function("buffers_get_jpeg_work")
|
|
.allowlist_function("buffers_free_jpeg_work")
|
|
.allowlist_function("buffers_get_blurring")
|
|
.allowlist_function("buffers_free_blurring")
|
|
.allowlist_function("buffers_get_blurring_totals")
|
|
.allowlist_function("buffers_free_blurring_totals")
|
|
.allowlist_var("TEXT_BUFFER_HEIGHT")
|
|
.no_copy("buffer_line_16bpp_t")
|
|
.no_copy("buffer_line_4bpp_t")
|
|
.no_copy("buffer_text_t")
|
|
.no_copy("buffer_jpeg_t")
|
|
.no_copy("buffer_jpeg_work_t")
|
|
.no_copy("buffer_blurring_t")
|
|
.no_copy("buffer_blurring_totals_t")
|
|
//usb
|
|
.allowlist_function("usb_configured")
|
|
// touch
|
|
.allowlist_function("touch_read")
|
|
// button
|
|
.allowlist_function("button_read");
|
|
|
|
// Write the bindings to a file in the OUR_DIR.
|
|
bindings
|
|
.generate()
|
|
.expect("Unable to generate bindings")
|
|
.write_to_file(PathBuf::from(out_path).join("trezorhal.rs"))
|
|
.unwrap();
|
|
}
|
|
|
|
fn is_firmware() -> bool {
|
|
let target = env::var("TARGET").unwrap();
|
|
target.starts_with("thumbv7")
|
|
}
|
|
|
|
#[cfg(feature = "test")]
|
|
fn link_core_objects() {
|
|
let crate_path = env::var("CARGO_MANIFEST_DIR").unwrap();
|
|
let build_path = format!("{}/../../build/unix", crate_path);
|
|
|
|
// List of object filenames to ignore in the `embed` directory
|
|
let embed_blocklist = [OsStr::new("main_main.o")];
|
|
|
|
// Collect all objects that the `core` library uses, and link it in. We have to
|
|
// make sure to avoid the object with the `_main` symbol, so we don't get any
|
|
// duplicates.
|
|
let mut cc = cc::Build::new();
|
|
for obj in glob::glob(&format!("{}/embed/**/*.o", build_path)).unwrap() {
|
|
let obj = obj.unwrap();
|
|
if embed_blocklist.contains(&obj.file_name().unwrap()) {
|
|
// Ignore.
|
|
} else {
|
|
cc.object(obj);
|
|
}
|
|
}
|
|
|
|
for obj in glob::glob(&format!("{}/vendor/**/*.o", build_path)).unwrap() {
|
|
let obj = obj.unwrap();
|
|
cc.object(obj);
|
|
}
|
|
|
|
// Add frozen modules, if present.
|
|
for obj in glob::glob(&format!("{}/*.o", build_path)).unwrap() {
|
|
cc.object(obj.unwrap());
|
|
}
|
|
|
|
// Compile all the objects into a static library and link it in automatically.
|
|
cc.compile("core_lib");
|
|
|
|
println!("cargo:rustc-link-lib=SDL2");
|
|
println!("cargo:rustc-link-lib=SDL2_image");
|
|
}
|