From 1c387aefa68f1001290367573c57cd7f50b6b628 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Tue, 3 Feb 2026 13:42:51 -0800 Subject: [PATCH] Centralize Rust build logic into RustBuild.cmake Each Rust crate now calls `bn_add_rust_crate` to configure its build, greatly reducing the amount of boilerplate. This CMake function discovers dependencies on other crates within the repository and generates the appropriate CMake dependencies. The build invocation for crates within the same workspace are combined where possible (i.e., no custom cargo flags are required) in order to allow dependencies to be reused and to improve scheduling efficiency. Static library variants of crates are generated when needed (static-only targets, or targets that are statically linked for demo builds), removing the need to maintain custom static variants of crates. Static libraries are merged into a static umbrella crate to avoid the duplicate symbol errors related to the Rust standard library that would otherwise occur when linking multiple static crates into the same binary. --- CMakeLists.txt | 21 +- Cargo.lock | 245 +----- Cargo.toml | 7 - arch/msp430/CMakeLists.txt | 133 +--- arch/riscv/CMakeLists.txt | 133 +--- cmake/FindBinaryNinjaCore.cmake | 17 + cmake/RustBuild.cmake | 822 +++++++++++++++++++++ cmake/rust/generate_static_crate.py | 229 ++++++ cmake/rust/generate_static_umbrella.py | 107 +++ cmake/rust/resolve_path_deps.py | 55 ++ plugins/bntl_utils/CMakeLists.txt | 182 +---- plugins/dwarf/dwarf_export/CMakeLists.txt | 114 +-- plugins/dwarf/dwarf_import/CMakeLists.txt | 191 +---- plugins/dwarf/dwarf_import/demo/Cargo.toml | 24 - plugins/dwarf/dwarf_import/demo/build.rs | 30 - plugins/idb_import/CMakeLists.txt | 191 +---- plugins/idb_import/demo/Cargo.toml | 23 - plugins/idb_import/demo/build.rs | 30 - plugins/pdb-ng/CMakeLists.txt | 176 +---- plugins/pdb-ng/demo/Cargo.toml | 21 - plugins/pdb-ng/demo/build.rs | 15 - plugins/svd/CMakeLists.txt | 183 +---- plugins/svd/build.rs | 14 +- plugins/svd/demo/Cargo.toml | 22 - plugins/svd/demo/build.rs | 34 - plugins/warp/CMakeLists.txt | 195 +---- plugins/warp/api/CMakeLists.txt | 6 +- plugins/warp/build.rs | 14 +- plugins/warp/demo/Cargo.toml | 37 - plugins/warp/demo/build.rs | 25 - plugins/workflow_objc/CMakeLists.txt | 185 +---- plugins/workflow_objc/demo/Cargo.toml | 21 - plugins/workflow_objc/demo/build.rs | 15 - plugins/workflow_swift/CMakeLists.txt | 220 +----- plugins/workflow_swift/demo/Cargo.toml | 20 - plugins/workflow_swift/demo/build.rs | 15 - 36 files changed, 1537 insertions(+), 2235 deletions(-) create mode 100644 cmake/RustBuild.cmake create mode 100644 cmake/rust/generate_static_crate.py create mode 100644 cmake/rust/generate_static_umbrella.py create mode 100644 cmake/rust/resolve_path_deps.py delete mode 100644 plugins/dwarf/dwarf_import/demo/Cargo.toml delete mode 100644 plugins/dwarf/dwarf_import/demo/build.rs delete mode 100644 plugins/idb_import/demo/Cargo.toml delete mode 100644 plugins/idb_import/demo/build.rs delete mode 100644 plugins/pdb-ng/demo/Cargo.toml delete mode 100644 plugins/pdb-ng/demo/build.rs delete mode 100644 plugins/svd/demo/Cargo.toml delete mode 100644 plugins/svd/demo/build.rs delete mode 100644 plugins/warp/demo/Cargo.toml delete mode 100644 plugins/warp/demo/build.rs delete mode 100644 plugins/workflow_objc/demo/Cargo.toml delete mode 100644 plugins/workflow_objc/demo/build.rs delete mode 100644 plugins/workflow_swift/demo/Cargo.toml delete mode 100644 plugins/workflow_swift/demo/build.rs diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fc08047cd..cb9face5fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,17 +41,6 @@ target_include_directories(binaryninjaapi target_link_libraries(binaryninjaapi PUBLIC binaryninjabase) -# Store path to user plugin dir -if(WIN32) - set(plugin_dir "$ENV{APPDATA}\\Binary Ninja\\plugins") -elseif(APPLE) - set(plugin_dir "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins") -else() - set(plugin_dir "$ENV{HOME}/.binaryninja/plugins") -endif() -set(BN_USER_PLUGINS_DIR "${plugin_dir}" CACHE PATH "Path to Binary Ninja user plugins") -message(STATUS "Binary Ninja User Plugins Dir: ${BN_USER_PLUGINS_DIR}") - find_package(BinaryNinjaCore) if(BinaryNinjaCore_FOUND) target_link_libraries(binaryninjaapi PUBLIC ${BinaryNinjaCore_LIBRARIES}) @@ -120,15 +109,7 @@ if(NOT HEADLESS) endif() function(bn_install_plugin target) - if(WIN32) - set(plugin_dir "$ENV{APPDATA}\\Binary Ninja\\plugins") - elseif(APPLE) - set(plugin_dir "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins") - else() - set(plugin_dir "$ENV{HOME}/.binaryninja/plugins") - endif() - set(BN_USER_PLUGINS_DIR "${plugin_dir}" CACHE PATH "Path to Binary Ninja user plugins") - + # BN_USER_PLUGINS_DIR is set by FindBinaryNinjaCore.cmake if(NOT BN_INTERNAL_BUILD) if(WIN32) install(TARGETS ${target} RUNTIME diff --git a/Cargo.lock b/Cargo.lock index e9aa136aff..09447d2979 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,16 +126,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55f533f8e0af236ffe5eb979b99381df3258853f00ba2e44b6e1955292c75227" dependencies = [ "clipboard-win", - "image", "log", "objc2", "objc2-app-kit", - "objc2-core-foundation", - "objc2-core-graphics", "objc2-foundation", "parking_lot", "percent-encoding", - "windows-sys 0.59.0", "x11rb", ] @@ -204,7 +200,7 @@ name = "binaryninja" version = "0.1.0" dependencies = [ "binaryninjacore-sys", - "bitflags 2.9.1", + "bitflags", "insta", "rayon", "rstest 0.24.0", @@ -243,7 +239,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.1", + "bitflags", "cexpr", "clang-sys", "itertools 0.13.0", @@ -257,12 +253,6 @@ dependencies = [ "syn", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.9.1" @@ -369,24 +359,12 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" -[[package]] -name = "bytemuck" -version = "1.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" - [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" -[[package]] -name = "byteorder-lite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" - [[package]] name = "bytes" version = "1.11.1" @@ -825,7 +803,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags 2.9.1", + "bitflags", "block2", "libc", "objc2", @@ -869,22 +847,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "dwarf_import-static" -version = "0.1.0" -dependencies = [ - "binaryninja", - "binaryninjacore-sys", - "cpp_demangle", - "dwarfreader", - "gimli", - "indexmap", - "iset", - "object 0.36.7", - "regex", - "tracing", -] - [[package]] name = "dwarfdump" version = "0.1.0" @@ -997,15 +959,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - [[package]] name = "fixedbitset" version = "0.5.7" @@ -1018,7 +971,7 @@ version = "25.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1045398c1bfd89168b5fd3f1fc11f6e70b34f6f66300c87d44d3de849463abf1" dependencies = [ - "bitflags 2.9.1", + "bitflags", "rustc_version", ] @@ -1369,20 +1322,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "idb_import-static" -version = "0.1.0" -dependencies = [ - "anyhow", - "binaryninja", - "binaryninjacore-sys", - "idb-rs", - "serde", - "serde_json", - "sha2", - "tracing", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -1410,19 +1349,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "image" -version = "0.25.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" -dependencies = [ - "bytemuck", - "byteorder-lite", - "num-traits", - "png", - "tiff", -] - [[package]] name = "indexmap" version = "2.10.0" @@ -1514,12 +1440,6 @@ dependencies = [ "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" - [[package]] name = "js-sys" version = "0.3.77" @@ -1558,7 +1478,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ - "bitflags 2.9.1", + "bitflags", "libc", ] @@ -1647,7 +1567,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e16d10087ae9e375bad7a40e8ef5504bc08e808ccc6019067ff9de42a84570f" dependencies = [ - "bitflags 2.9.1", + "bitflags", "debugid", "num-derive", "num-traits", @@ -1695,7 +1615,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", - "simd-adler32", ] [[package]] @@ -1710,7 +1629,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.1", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -1744,7 +1663,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30ab316ee07638762db759975a633e8971c17a346ff2bed93321c5cb2600f024" dependencies = [ - "bitflags 2.9.1", + "bitflags", "displaydoc", "nt-string", "pelite", @@ -1833,7 +1752,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" dependencies = [ - "bitflags 2.9.1", + "bitflags", "objc2", "objc2-core-graphics", "objc2-foundation", @@ -1845,7 +1764,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.9.1", + "bitflags", "dispatch2", "objc2", ] @@ -1856,7 +1775,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" dependencies = [ - "bitflags 2.9.1", + "bitflags", "dispatch2", "objc2", "objc2-core-foundation", @@ -1875,7 +1794,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" dependencies = [ - "bitflags 2.9.1", + "bitflags", "objc2", "objc2-core-foundation", ] @@ -1886,7 +1805,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" dependencies = [ - "bitflags 2.9.1", + "bitflags", "objc2", "objc2-core-foundation", ] @@ -1997,19 +1916,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "pdb-import-plugin-static" -version = "0.1.0" -dependencies = [ - "anyhow", - "binaryninja", - "binaryninjacore-sys", - "itertools 0.14.0", - "pdb", - "regex", - "tracing", -] - [[package]] name = "pelite" version = "0.10.0" @@ -2093,19 +1999,6 @@ dependencies = [ "plotters-backend", ] -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - [[package]] name = "portable-atomic" version = "1.11.1" @@ -2161,7 +2054,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.9.1", + "bitflags", "hex", ] @@ -2275,7 +2168,7 @@ version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ - "bitflags 2.9.1", + "bitflags", ] [[package]] @@ -2347,7 +2240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64", - "bitflags 2.9.1", + "bitflags", "serde", "serde_derive", "unicode-ident", @@ -2456,7 +2349,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags", "errno", "libc", "linux-raw-sys 0.4.15", @@ -2469,7 +2362,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.1", + "bitflags", "errno", "libc", "linux-raw-sys 0.9.4", @@ -2722,12 +2615,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "similar" version = "2.7.0" @@ -2810,18 +2697,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "svd_ninja-static" -version = "0.1.0" -dependencies = [ - "binaryninja", - "binaryninjacore-sys", - "insta", - "serde_json", - "svd-parser", - "tracing", -] - [[package]] name = "swift-demangler" version = "0.1.0" @@ -2924,17 +2799,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "tiff" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - [[package]] name = "time" version = "0.3.41" @@ -3197,18 +3061,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "warp" -version = "1.0.0" -source = "git+https://github.com/Vector35/warp/?tag=1.0.0#57dcb5abea59a611466be9550ba25b36c5399ce6" -dependencies = [ - "bon", - "flatbuffers", - "flate2", - "itertools 0.14.0", - "uuid", -] - [[package]] name = "warp" version = "1.0.1" @@ -3259,34 +3111,7 @@ dependencies = [ "tracing", "uuid", "walkdir", - "warp 1.0.1", -] - -[[package]] -name = "warp_ninja-static" -version = "0.1.0" -dependencies = [ - "ar", - "arboard", - "base64", - "binaryninja", - "binaryninjacore-sys", - "compact_str", - "criterion", - "dashmap", - "directories", - "insta", - "itertools 0.14.0", - "rayon", - "serde", - "serde_json", - "serde_qs", - "tempdir", - "thiserror 2.0.18", - "tracing", - "uuid", - "walkdir", - "warp 1.0.0", + "warp", ] [[package]] @@ -3382,12 +3207,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "weezl" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" - [[package]] name = "widestring" version = "1.2.1" @@ -3663,7 +3482,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.1", + "bitflags", ] [[package]] @@ -3679,19 +3498,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "workflow_objc-static" -version = "0.1.0" -dependencies = [ - "binaryninja", - "binaryninjacore-sys", - "bstr", - "dashmap", - "once_cell", - "thiserror 2.0.18", - "tracing", -] - [[package]] name = "workflow_swift" version = "0.1.0" @@ -3703,17 +3509,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "workflow_swift-static" -version = "0.1.0" -dependencies = [ - "binaryninja", - "binaryninjacore-sys", - "swift-demangler", - "thiserror 2.0.18", - "tracing", -] - [[package]] name = "writeable" version = "0.6.2" diff --git a/Cargo.toml b/Cargo.toml index 085c694187..8c48cad6d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,25 +12,18 @@ members = [ "rust/plugin_examples/flowgraph_layout", "view/minidump", "plugins/dwarf/dwarf_import", - "plugins/dwarf/dwarf_import/demo", "plugins/dwarf/dwarf_export", "plugins/dwarf/dwarfdump", "plugins/dwarf/shared", "plugins/idb_import", - "plugins/idb_import/demo", "plugins/pdb-ng", - "plugins/pdb-ng/demo", "plugins/svd", - "plugins/svd/demo", "plugins/warp", - "plugins/warp/demo", "plugins/warp/examples/headless", "plugins/workflow_objc", - "plugins/workflow_objc/demo", "plugins/bntl_utils", "plugins/bntl_utils/cli", "plugins/workflow_swift", - "plugins/workflow_swift/demo", ] [workspace.dependencies] diff --git a/arch/msp430/CMakeLists.txt b/arch/msp430/CMakeLists.txt index 4edac65625..eb2461c27c 100644 --- a/arch/msp430/CMakeLists.txt +++ b/arch/msp430/CMakeLists.txt @@ -2,114 +2,31 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(arch_msp430) -file(GLOB PLUGIN_SOURCES CONFIGURE_DEPENDS - ../../binaryninjacore.h - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs - ${PROJECT_SOURCE_DIR}/disasm/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) -else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) -endif() - -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() - -set(CARGO_FEATURES "") -set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}arch_msp430${CMAKE_SHARED_LIBRARY_SUFFIX}) -set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}arch_msp430.pdb) -set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) -set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - -set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) - -add_custom_target(arch_msp430 ALL DEPENDS ${OUTPUT_FILE_PATH}) -add_dependencies(arch_msp430 binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET arch_msp430 PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB_RECURSE API_SOURCES CONFIGURE_DEPENDS - ${BN_API_SOURCE_DIR}/rust/src/*.rs - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/src/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(LIB_PATH ${PROJECT_BINARY_DIR}/target/debug/${OUTPUT_FILE_NAME}) - else() - set(LIB_PATH ${PROJECT_BINARY_DIR}/target/release/${OUTPUT_FILE_NAME}) +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( + BN_API_PATH + NAMES binaryninjaapi.h + HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} + REQUIRED + ) endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${LIB_PATH} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() -elseif(WIN32) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake" - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() + +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE ${PROJECT_NAME} + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins +) + +add_dependencies(${PROJECT_NAME} binaryninjaapi) diff --git a/arch/riscv/CMakeLists.txt b/arch/riscv/CMakeLists.txt index a6f1239136..ff6e530145 100644 --- a/arch/riscv/CMakeLists.txt +++ b/arch/riscv/CMakeLists.txt @@ -2,114 +2,31 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(arch_riscv) -file(GLOB PLUGIN_SOURCES CONFIGURE_DEPENDS - ../../binaryninjacore.h - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs - ${PROJECT_SOURCE_DIR}/disasm/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) -else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) -endif() - -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() - -set(CARGO_FEATURES "") -set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}arch_riscv${CMAKE_SHARED_LIBRARY_SUFFIX}) -set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}arch_riscv.pdb) -set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) -set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - -set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) - -add_custom_target(arch_riscv ALL DEPENDS ${OUTPUT_FILE_PATH}) -add_dependencies(arch_riscv binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET arch_riscv PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB_RECURSE API_SOURCES CONFIGURE_DEPENDS - ${BN_API_SOURCE_DIR}/rust/src/*.rs - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/src/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(LIB_PATH ${PROJECT_BINARY_DIR}/target/debug/${OUTPUT_FILE_NAME}) - else() - set(LIB_PATH ${PROJECT_BINARY_DIR}/target/release/${OUTPUT_FILE_NAME}) +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( + BN_API_PATH + NAMES binaryninjaapi.h + HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} + REQUIRED + ) endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${LIB_PATH} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() -elseif(WIN32) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake" - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() + +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE ${PROJECT_NAME} + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins +) + +add_dependencies(${PROJECT_NAME} binaryninjaapi) diff --git a/cmake/FindBinaryNinjaCore.cmake b/cmake/FindBinaryNinjaCore.cmake index cc436dea7d..5ec14e9bc3 100644 --- a/cmake/FindBinaryNinjaCore.cmake +++ b/cmake/FindBinaryNinjaCore.cmake @@ -6,13 +6,30 @@ # BinaryNinjaCore_LIBRARIES - The libraries for linking core plugins # BinaryNinjaCore_LIBRARY_DIRS - The link paths required for core plugins # BinaryNinjaCore_DEFINITIONS - Compiler switches required for core plugins +# BN_USER_PLUGINS_DIR - User plugin directory (e.g. ~/.binaryninja/plugins) +# BN_PLUGIN_OUTPUT_DIR - Plugin output directory (internal: build tree, standalone: user plugins) # # According to Good CMake Hygiene, we should use BinaryNinjaCore_ named variables. # Existing plugins likely use BN_ names already, so both are provided. cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +# User plugin directory (always available, independent of build mode) +if(WIN32) + set(_BN_USER_PLUGINS_DEFAULT "$ENV{APPDATA}\\Binary Ninja\\plugins") +elseif(APPLE) + set(_BN_USER_PLUGINS_DEFAULT "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins") +else() + set(_BN_USER_PLUGINS_DEFAULT "$ENV{HOME}/.binaryninja/plugins") +endif() +set(BN_USER_PLUGINS_DIR "${_BN_USER_PLUGINS_DEFAULT}" CACHE PATH "Path to Binary Ninja user plugins") + if(NOT BN_INTERNAL_BUILD) + # For standalone builds, plugins go to the user plugins dir + if(NOT DEFINED BN_PLUGIN_OUTPUT_DIR) + set(BN_PLUGIN_OUTPUT_DIR "${BN_USER_PLUGINS_DIR}") + endif() + set(PATH_HINTS "$ENV{BN_INSTALL_DIR}" "${BN_INSTALL_DIR}") if(WIN32) # System-wide install diff --git a/cmake/RustBuild.cmake b/cmake/RustBuild.cmake new file mode 100644 index 0000000000..1a402799be --- /dev/null +++ b/cmake/RustBuild.cmake @@ -0,0 +1,822 @@ +# Centeralized Rust build functions +# +# This module provides functions to build Rust crates in both standalone (open source) +# and combined (internal) build modes. +# +# Standalone mode: +# Each crate invokes cargo directly. Used for open-source api/ builds. +# +# Combined mode (BN_INTERNAL_BUILD=ON): +# Crates register with build groups; cargo is invoked once per group to avoid +# lock contention. Each crate specifies a GROUP (e.g. "plugins", "internal"). +# +# Groups are created with bn_add_rust_crate_group() and build all SHARED crates +# registered to that group in a single cargo invocation. +# +# STATIC crates are not built by groups directly. Instead, they are collected +# and combined into a single staticlib via bn_add_rust_static_umbrella(). This +# avoids duplicate symbol errors related to Rust standard library symbols +# that occur when linking multiple Rust staticlibs into one binary. The umbrella +# generates a wrapper crate that re-exports all the static crates as dependencies. +# +# For STATIC crates, a static variant of the Cargo.toml is auto-generated +# at configure time (cdylib -> rlib, workspace deps resolved, features added). +# +# Public API: +# bn_add_rust_crate() - Register a Rust crate for building +# bn_add_rust_crate_group() - Create a group target (combined mode) +# bn_declare_rust_static_umbrella() - Forward-declare umbrella target before crates register +# bn_add_rust_static_umbrella() - Combine static crates into one staticlib +# +# Example: +# bn_add_rust_crate( +# TARGET pdb_import_plugin +# CRATE pdb-import-plugin +# WORKSPACE ${BN_API_SOURCE_DIR} +# OUTPUT_TYPE SHARED +# OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} +# GROUP plugins +# DEMO_STATIC # in DEMO builds, switch to static output +# ) +# # Later: +# bn_add_rust_crate_group(plugins WORKSPACE ${BN_API_SOURCE_DIR}) +# bn_add_rust_static_umbrella(rust_static GROUPS plugins +# OUTPUT_DIR ${CMAKE_BINARY_DIR}) + +cmake_minimum_required(VERSION 3.15) + +# Guard against multiple inclusion +if(DEFINED _BN_RUST_BUILD_CMAKE_INCLUDED) + return() +endif() +set(_BN_RUST_BUILD_CMAKE_INCLUDED TRUE) + +# Set default target directory if not already set +# Combined builds use BN_RUST_TARGET_DIR +# Standalone builds use per-target directories (rust-target-${TARGET}/) to avoid lock contention +if(NOT DEFINED BN_RUST_TARGET_DIR) + set(BN_RUST_TARGET_DIR ${CMAKE_BINARY_DIR}/rust-target) +endif() + +# Get the rust target directory for a given target name +# Combined builds (BN_INTERNAL_BUILD without CARGO_ARGS) share BN_RUST_TARGET_DIR +# Every other crate builds in a per-target directory to avoid lock contention +function(bn_get_rust_target_dir TARGET_NAME OUT_VAR) + cmake_parse_arguments(ARG "" "CARGO_ARGS" "" ${ARGN}) + if(BN_INTERNAL_BUILD AND NOT ARG_CARGO_ARGS) + set(${OUT_VAR} ${BN_RUST_TARGET_DIR} PARENT_SCOPE) + else() + set(${OUT_VAR} ${CMAKE_BINARY_DIR}/rust-target-${TARGET_NAME} PARENT_SCOPE) + endif() +endfunction() + +# Find rustup +find_program(BN_RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) + +# Use CARGO_STABLE_VERSION if set, otherwise default +if(NOT DEFINED CARGO_STABLE_VERSION) + set(CARGO_STABLE_VERSION 1.91.1) +endif() + +set(BN_CARGO_COMMAND ${BN_RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) + +# Derive api path from this file's location (api/cmake/RustBuild.cmake -> api/) +get_filename_component(_BN_RUST_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) +get_filename_component(_BN_API_PATH "${_BN_RUST_CMAKE_DIR}" DIRECTORY) +# Python scripts for Rust build support (run at configure time) +set(_BN_GENERATE_STATIC_CRATE_SCRIPT "${_BN_RUST_CMAKE_DIR}/rust/generate_static_crate.py") +set(_BN_GENERATE_STATIC_UMBRELLA_SCRIPT "${_BN_RUST_CMAKE_DIR}/rust/generate_static_umbrella.py") +set(_BN_RESOLVE_PATH_DEPS_SCRIPT "${_BN_RUST_CMAKE_DIR}/rust/resolve_path_deps.py") +find_package(Python3 REQUIRED COMPONENTS Interpreter) +# Reconfigure when the Python scripts change +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + ${_BN_GENERATE_STATIC_CRATE_SCRIPT} + ${_BN_GENERATE_STATIC_UMBRELLA_SCRIPT} + ${_BN_RESOLVE_PATH_DEPS_SCRIPT}) + + +# Get cargo profile info: the command-line argument and output directory name +# OUT_ARG: "" for debug, "--release" for release, "--profile=X" for custom +# OUT_DIR: "debug", "release", or the custom profile name +function(_bn_get_cargo_profile OUT_ARG OUT_DIR) + if(CMAKE_BUILD_TYPE MATCHES Debug) + if(DEMO) + set(${OUT_ARG} "--profile=dev-demo" PARENT_SCOPE) + set(${OUT_DIR} "dev-demo" PARENT_SCOPE) + else() + set(${OUT_ARG} "" PARENT_SCOPE) + set(${OUT_DIR} "debug" PARENT_SCOPE) + endif() + else() + if(DEMO) + set(${OUT_ARG} "--profile=release-demo" PARENT_SCOPE) + set(${OUT_DIR} "release-demo" PARENT_SCOPE) + else() + set(${OUT_ARG} "--release" PARENT_SCOPE) + set(${OUT_DIR} "release" PARENT_SCOPE) + endif() + endif() +endfunction() + +# Get the cargo options list +# Optional second argument specifies target directory (defaults to BN_RUST_TARGET_DIR) +function(_bn_get_cargo_opts OUT_VAR) + if(ARGC GREATER 1) + set(TARGET_DIR_ARG ${ARGV1}) + else() + set(TARGET_DIR_ARG ${BN_RUST_TARGET_DIR}) + endif() + _bn_get_cargo_profile(PROFILE_ARG _unused) + set(OPTS --target-dir=${TARGET_DIR_ARG}) + if(PROFILE_ARG) + list(APPEND OPTS ${PROFILE_ARG}) + endif() + if(FORCE_COLORED_OUTPUT) + list(APPEND OPTS --color always) + endif() + set(${OUT_VAR} ${OPTS} PARENT_SCOPE) +endfunction() + +# Get the cargo profile name as spelled in CARGO_PROFILE__* environment variables +function(_bn_get_cargo_profile_env_name OUT_VAR) + _bn_get_cargo_profile(_unused PROFILE_DIR) + if(PROFILE_DIR STREQUAL "debug") + set(PROFILE_NAME dev) + else() + set(PROFILE_NAME ${PROFILE_DIR}) + endif() + string(TOUPPER ${PROFILE_NAME} PROFILE_NAME) + string(REPLACE "-" "_" PROFILE_NAME ${PROFILE_NAME}) + set(${OUT_VAR} ${PROFILE_NAME} PARENT_SCOPE) +endfunction() + +# Gather source files for a plugin (for dependency tracking) +function(_bn_gather_plugin_sources OUT_VAR) + cmake_parse_arguments(ARG "" "SOURCE_DIR" "EXPLICIT_SOURCES" ${ARGN}) + + if(ARG_EXPLICIT_SOURCES) + set(${OUT_VAR} ${ARG_EXPLICIT_SOURCES} PARENT_SCOPE) + return() + endif() + + if(NOT ARG_SOURCE_DIR) + set(ARG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS + ${ARG_SOURCE_DIR}/Cargo.toml + ${ARG_SOURCE_DIR}/build.rs + ${ARG_SOURCE_DIR}/src/*.rs) + + if(TARGET binaryninjaapi) + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND SOURCES ${BN_API_SOURCE_DIR}/binaryninjacore.h) + endif() + + # Resolve path dependencies and track their sources + if(EXISTS "${ARG_SOURCE_DIR}/Cargo.toml") + # Reconfigure when Cargo.toml changes so path dependency resolution reruns + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + "${ARG_SOURCE_DIR}/Cargo.toml") + + execute_process( + COMMAND ${Python3_EXECUTABLE} "${_BN_RESOLVE_PATH_DEPS_SCRIPT}" + --manifest-path "${ARG_SOURCE_DIR}/Cargo.toml" + --cargo ${BN_CARGO_COMMAND} + OUTPUT_VARIABLE _PATH_DEPS_OUTPUT + ERROR_VARIABLE _PATH_DEPS_ERROR + RESULT_VARIABLE _PATH_DEPS_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if(_PATH_DEPS_RESULT EQUAL 0 AND _PATH_DEPS_OUTPUT) + string(REPLACE "\n" ";" _PATH_DEP_DIRS "${_PATH_DEPS_OUTPUT}") + foreach(_DEP_DIR ${_PATH_DEP_DIRS}) + file(TO_CMAKE_PATH "${_DEP_DIR}" _DEP_DIR) + file(GLOB_RECURSE _DEP_SOURCES CONFIGURE_DEPENDS + ${_DEP_DIR}/Cargo.toml + ${_DEP_DIR}/build.rs + ${_DEP_DIR}/src/*.rs) + list(APPEND SOURCES ${_DEP_SOURCES}) + # Reconfigure if a path dep's Cargo.toml changes (may gain new path deps) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + "${_DEP_DIR}/Cargo.toml") + endforeach() + endif() + endif() + + set(${OUT_VAR} ${SOURCES} PARENT_SCOPE) +endfunction() + +# Compute the library filename cargo will produce for a given crate name and output type. +# Cargo converts hyphens to underscores in output filenames. +# Sets OUT_FILE_NAME in parent scope. +function(_bn_cargo_output_name OUT_FILE_NAME CRATE_NAME OUTPUT_TYPE) + string(REPLACE "-" "_" LIB_NAME ${CRATE_NAME}) + if(OUTPUT_TYPE STREQUAL "SHARED") + set(${OUT_FILE_NAME} ${CMAKE_SHARED_LIBRARY_PREFIX}${LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX} PARENT_SCOPE) + else() + set(${OUT_FILE_NAME} ${CMAKE_STATIC_LIBRARY_PREFIX}${LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX} PARENT_SCOPE) + endif() +endfunction() + +# Compute cargo output paths based on platform +# Sets in parent scope: +# OUT_CARGO_DIR - directory containing output (non-universal only) +# OUT_CARGO_FILES - list of cargo output files +function(_bn_compute_cargo_paths TARGET_DIR PROFILE_DIR OUTPUT_FILE_NAME) + if(APPLE AND UNIVERSAL) + set(OUT_CARGO_DIR "" PARENT_SCOPE) + set(AARCH64_PATH ${TARGET_DIR}/aarch64-apple-darwin/${PROFILE_DIR}/${OUTPUT_FILE_NAME}) + set(X86_64_PATH ${TARGET_DIR}/x86_64-apple-darwin/${PROFILE_DIR}/${OUTPUT_FILE_NAME}) + set(OUT_CARGO_FILES ${AARCH64_PATH} ${X86_64_PATH} PARENT_SCOPE) + else() + set(OUT_CARGO_DIR ${TARGET_DIR}/${PROFILE_DIR} PARENT_SCOPE) + set(OUT_CARGO_FILES ${TARGET_DIR}/${PROFILE_DIR}/${OUTPUT_FILE_NAME} PARENT_SCOPE) + endif() +endfunction() + +# Create a custom command for cargo build and/or copy operations +# +# Modes (based on which parameters are provided): +# 1. Group build (CARGO_OPTS + OUTPUT_FILES): cargo build only, outputs are cargo files +# 2. Standalone build (CARGO_OPTS + COPY_TO): cargo build + copy/lipo to final destination +# 3. Copy only (COPY_TO + COPY_FROM_FILES): copy/lipo only, depends on cargo output files +# +function(_bn_create_build_command) + cmake_parse_arguments(ARG + "" + "COPY_TO;OUTPUT_FILE_NAME;OUTPUT_TYPE;TARGET_NAME;WORKSPACE;MANIFEST_PATH;TARGET_DIR;RPATH_KIND" + "CARGO_OPTS;PACKAGE_ARGS;DEPENDS;OUTPUT_FILES;COPY_FROM_FILES;BYPRODUCTS" + ${ARGN}) + + if(NOT ARG_RPATH_KIND) + set(ARG_RPATH_KIND plugin) + endif() + + set(ALL_COMMANDS "") + set(CMD_OUTPUT "") + set(CMD_DEPENDS ${ARG_DEPENDS}) + set(CMD_BYPRODUCTS ${ARG_BYPRODUCTS}) + + if(ARG_CARGO_OPTS) + set(CMD_COMMENT "Building ${ARG_TARGET_NAME}") + else() + set(CMD_COMMENT "Copying ${ARG_TARGET_NAME}") + endif() + + # Add manifest path to package args if specified + set(FULL_PACKAGE_ARGS ${ARG_PACKAGE_ARGS}) + if(ARG_MANIFEST_PATH) + list(APPEND FULL_PACKAGE_ARGS --manifest-path=${ARG_MANIFEST_PATH}) + endif() + + # Build cargo commands if CARGO_OPTS provided + if(ARG_CARGO_OPTS) + # Build env var list - BN_RUST_TARGET_DIR lets build.rs know where to write generated files + set(CARGO_ENV_VARS BINARYNINJADIR=${BN_INSTALL_BIN_DIR}) + if(ARG_TARGET_DIR) + list(APPEND CARGO_ENV_VARS BN_RUST_TARGET_DIR=${ARG_TARGET_DIR}) + endif() + # rustc links bundled native static libraries from temporary copies of their rlibs + # and deletes them afterwards, so a packaging-time dsymutil cannot find those objects. + # Packed split-debuginfo makes rustc produce the dSYM itself at link time. + if(APPLE AND ARG_OUTPUT_TYPE STREQUAL "SHARED") + _bn_get_cargo_profile_env_name(PROFILE_ENV_NAME) + list(APPEND CARGO_ENV_VARS CARGO_PROFILE_${PROFILE_ENV_NAME}_SPLIT_DEBUGINFO=packed) + endif() + + if(APPLE) + set(ENV_PREFIX ${CMAKE_COMMAND} -E env MACOSX_DEPLOYMENT_TARGET=10.14 ${CARGO_ENV_VARS}) + if(UNIVERSAL) + list(APPEND ALL_COMMANDS + COMMAND ${ENV_PREFIX} ${BN_CARGO_COMMAND} build --target=aarch64-apple-darwin ${ARG_CARGO_OPTS} ${FULL_PACKAGE_ARGS} + COMMAND ${ENV_PREFIX} ${BN_CARGO_COMMAND} build --target=x86_64-apple-darwin ${ARG_CARGO_OPTS} ${FULL_PACKAGE_ARGS}) + else() + list(APPEND ALL_COMMANDS + COMMAND ${ENV_PREFIX} ${BN_CARGO_COMMAND} build ${ARG_CARGO_OPTS} ${FULL_PACKAGE_ARGS}) + endif() + else() + list(APPEND ALL_COMMANDS + COMMAND ${CMAKE_COMMAND} -E env ${CARGO_ENV_VARS} + ${BN_CARGO_COMMAND} build ${ARG_CARGO_OPTS} ${FULL_PACKAGE_ARGS}) + endif() + endif() + + # Build copy/lipo commands if COPY_TO provided + if(ARG_COPY_TO) + # Get source files - either from COPY_FROM_FILES or OUTPUT_FILES + if(ARG_COPY_FROM_FILES) + set(SRC_FILES ${ARG_COPY_FROM_FILES}) + list(APPEND CMD_DEPENDS ${SRC_FILES}) + else() + set(SRC_FILES ${ARG_OUTPUT_FILES}) + endif() + + if(APPLE AND UNIVERSAL) + list(GET SRC_FILES 0 AARCH64_PATH) + list(GET SRC_FILES 1 X86_64_PATH) + list(APPEND ALL_COMMANDS + COMMAND lipo -create ${AARCH64_PATH} ${X86_64_PATH} -output ${ARG_COPY_TO}) + # Stage the dSYM next to the library, merging the per-architecture DWARF slices + if(ARG_OUTPUT_TYPE STREQUAL "SHARED") + set(_DSYM_DWARF Contents/Resources/DWARF/${ARG_OUTPUT_FILE_NAME}) + list(APPEND ALL_COMMANDS + COMMAND ${CMAKE_COMMAND} -E rm -rf ${ARG_COPY_TO}.dSYM + COMMAND ${CMAKE_COMMAND} -E copy_directory ${AARCH64_PATH}.dSYM ${ARG_COPY_TO}.dSYM + COMMAND lipo -create ${AARCH64_PATH}.dSYM/${_DSYM_DWARF} ${X86_64_PATH}.dSYM/${_DSYM_DWARF} + -output ${ARG_COPY_TO}.dSYM/${_DSYM_DWARF}) + list(APPEND CMD_BYPRODUCTS ${ARG_COPY_TO}.dSYM) + endif() + else() + list(GET SRC_FILES 0 SRC_PATH) + get_filename_component(SRC_DIR ${SRC_PATH} DIRECTORY) + list(APPEND ALL_COMMANDS + COMMAND ${CMAKE_COMMAND} -E copy ${SRC_PATH} ${ARG_COPY_TO}) + # Stage the dSYM next to the library + if(APPLE AND ARG_OUTPUT_TYPE STREQUAL "SHARED") + list(APPEND ALL_COMMANDS + COMMAND ${CMAKE_COMMAND} -E rm -rf ${ARG_COPY_TO}.dSYM + COMMAND ${CMAKE_COMMAND} -E copy_directory ${SRC_PATH}.dSYM ${ARG_COPY_TO}.dSYM) + list(APPEND CMD_BYPRODUCTS ${ARG_COPY_TO}.dSYM) + endif() + # Replace the build tree rpath with the relative one the installed plugin needs + if(UNIX AND NOT APPLE AND ARG_OUTPUT_TYPE STREQUAL "SHARED") + list(APPEND ALL_COMMANDS + COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=${ARG_RPATH_KIND} -DBINARY_PATH=${ARG_COPY_TO} + -P ${_BN_RUST_CMAKE_DIR}/SetElfRpath.cmake) + endif() + # Copy PDB on Windows for non-DEMO shared libraries + if(WIN32 AND ARG_OUTPUT_TYPE STREQUAL "SHARED" AND NOT DEMO) + get_filename_component(DST_DIR ${ARG_COPY_TO} DIRECTORY) + set(PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${ARG_TARGET_NAME}.pdb) + list(APPEND ALL_COMMANDS + COMMAND ${CMAKE_COMMAND} -E copy ${SRC_DIR}/${PDB_NAME} ${DST_DIR}/${PDB_NAME}) + endif() + # Copy import library on Windows for shared libraries + # Cargo produces .dll.lib; consumers expect .lib + if(WIN32 AND ARG_OUTPUT_TYPE STREQUAL "SHARED") + get_filename_component(_IMPLIB_DST_DIR ${ARG_COPY_TO} DIRECTORY) + get_filename_component(_IMPLIB_STEM ${ARG_OUTPUT_FILE_NAME} NAME_WE) + set(_IMPLIB_DST ${_IMPLIB_DST_DIR}/${_IMPLIB_STEM}.lib) + list(APPEND ALL_COMMANDS + COMMAND ${CMAKE_COMMAND} -E copy + ${SRC_DIR}/${ARG_OUTPUT_FILE_NAME}.lib ${_IMPLIB_DST}) + endif() + endif() + set(CMD_OUTPUT ${ARG_COPY_TO}) + if(_IMPLIB_DST) + list(APPEND CMD_OUTPUT ${_IMPLIB_DST}) + endif() + else() + set(CMD_OUTPUT ${ARG_OUTPUT_FILES}) + endif() + + if(ARG_WORKSPACE) + set(WORKING_DIR_ARG WORKING_DIRECTORY ${ARG_WORKSPACE}) + else() + set(WORKING_DIR_ARG "") + endif() + + if(CMD_BYPRODUCTS) + set(BYPRODUCTS_ARG BYPRODUCTS ${CMD_BYPRODUCTS}) + else() + set(BYPRODUCTS_ARG "") + endif() + + add_custom_command( + OUTPUT ${CMD_OUTPUT} + ${ALL_COMMANDS} + ${WORKING_DIR_ARG} + DEPENDS ${CMD_DEPENDS} + ${BYPRODUCTS_ARG} + COMMENT "${CMD_COMMENT}" + ) +endfunction() + +# Generate a static variant of a Cargo.toml +# Uses Python script for TOML manipulation +# Transforms: cdylib -> rlib, workspace deps -> path deps, adds features +function(_bn_generate_static_crate) + cmake_parse_arguments(ARG "" "SOURCE_CARGO_TOML;OUTPUT_DIR;CRATE_NAME;API_PATH;BN_FEATURE;CRATE_FEATURE" "" ${ARGN}) + + execute_process( + COMMAND ${Python3_EXECUTABLE} "${_BN_GENERATE_STATIC_CRATE_SCRIPT}" + --source "${ARG_SOURCE_CARGO_TOML}" + --output-dir "${ARG_OUTPUT_DIR}" + --crate-name "${ARG_CRATE_NAME}" + --api-path "${ARG_API_PATH}" + --bn-feature "${ARG_BN_FEATURE}" + --crate-feature "${ARG_CRATE_FEATURE}" + OUTPUT_VARIABLE _OUTPUT + ERROR_VARIABLE _ERROR + RESULT_VARIABLE _RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if(NOT _RESULT EQUAL 0) + message(FATAL_ERROR "Failed to generate static crate:\n${_ERROR}") + endif() + + # The script prints the generated crate path + set(GENERATED_CRATE_PATH ${_OUTPUT} PARENT_SCOPE) +endfunction() + +# Generate an umbrella crate that combines multiple static crates into one staticlib +# This avoids duplicate symbol errors when linking multiple Rust staticlibs into +# a single shared library or executable. +function(_bn_generate_static_umbrella UMBRELLA_NAME) + cmake_parse_arguments(ARG "" "OUTPUT_DIR" "CRATES" ${ARGN}) + + set(CRATE_ARGS "") + foreach(ENTRY ${ARG_CRATES}) + list(APPEND CRATE_ARGS --crate "${ENTRY}") + endforeach() + + execute_process( + COMMAND ${Python3_EXECUTABLE} "${_BN_GENERATE_STATIC_UMBRELLA_SCRIPT}" + --name "${UMBRELLA_NAME}" + --output-dir "${ARG_OUTPUT_DIR}" + ${CRATE_ARGS} + OUTPUT_VARIABLE _OUTPUT + ERROR_VARIABLE _ERROR + RESULT_VARIABLE _RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if(NOT _RESULT EQUAL 0) + message(FATAL_ERROR "Failed to generate static umbrella:\n${_ERROR}") + endif() + + # Return the umbrella directory + set(UMBRELLA_DIR ${_OUTPUT} PARENT_SCOPE) +endfunction() + +# Create a Rust build group target for shared libraries +function(bn_add_rust_crate_group GROUP_NAME) + cmake_parse_arguments(ARG "" "WORKSPACE;DEPENDS" "" ${ARGN}) + + if(NOT ARG_WORKSPACE) + message(FATAL_ERROR "bn_add_rust_crate_group: WORKSPACE is required") + endif() + + get_property(PACKAGES GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP_NAME}_PACKAGES) + if(NOT PACKAGES) + # No shared packages - check if we have only static crates + get_property(STATIC_CRATES GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP_NAME}_STATIC_CRATES) + if(NOT STATIC_CRATES) + message(WARNING "bn_add_rust_crate_group: no packages registered for group '${GROUP_NAME}'") + endif() + return() + endif() + + _bn_get_cargo_opts(CARGO_OPTS) + + get_property(OUTPUT_FILES GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP_NAME}_OUTPUT_FILES) + get_property(SOURCE_FILES GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP_NAME}_SOURCE_FILES) + + set(PACKAGE_ARGS "") + foreach(PKG ${PACKAGES}) + list(APPEND PACKAGE_ARGS -p ${PKG}) + endforeach() + + _bn_create_build_command( + TARGET_NAME ${GROUP_NAME} + OUTPUT_FILES ${OUTPUT_FILES} + OUTPUT_TYPE SHARED + WORKSPACE ${ARG_WORKSPACE} + CARGO_OPTS ${CARGO_OPTS} + PACKAGE_ARGS ${PACKAGE_ARGS} + DEPENDS ${SOURCE_FILES} + TARGET_DIR ${BN_RUST_TARGET_DIR} + ) + + add_custom_target(${GROUP_NAME} DEPENDS ${OUTPUT_FILES}) + + # Collect target dependencies from registered crates and function argument + get_property(TARGET_DEPS GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP_NAME}_TARGET_DEPENDS) + if(ARG_DEPENDS) + list(APPEND TARGET_DEPS ${ARG_DEPENDS}) + endif() + if(TARGET_DEPS) + add_dependencies(${GROUP_NAME} ${TARGET_DEPS}) + endif() + + # Connect wrapper targets to this group + get_property(WRAPPER_TARGETS GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP_NAME}_WRAPPER_TARGETS) + foreach(TARGET_NAME ${WRAPPER_TARGETS}) + add_dependencies(${TARGET_NAME} ${GROUP_NAME}) + endforeach() +endfunction() + +# Declare a static umbrella target so it can be referenced before crates have +# registered. Call bn_add_rust_static_umbrella() later to configure the build. +function(bn_declare_rust_static_umbrella UMBRELLA_TARGET OUTPUT_DIR) + _bn_cargo_output_name(_FILE_NAME ${UMBRELLA_TARGET} STATIC) + add_library(${UMBRELLA_TARGET} STATIC IMPORTED GLOBAL) + set_target_properties(${UMBRELLA_TARGET} PROPERTIES + IMPORTED_LOCATION ${OUTPUT_DIR}/${_FILE_NAME}) + # Create interface library to carry link dependencies (populated by bn_add_rust_static_umbrella) + add_library(${UMBRELLA_TARGET}_deps INTERFACE) +endfunction() + +# Build a static umbrella crate combining static crates from specified groups +# Creates a single staticlib that includes all static crates to avoid duplicate symbols +function(bn_add_rust_static_umbrella UMBRELLA_TARGET) + cmake_parse_arguments(ARG "" "OUTPUT_DIR" "GROUPS;DEPENDS" ${ARGN}) + + if(NOT ARG_GROUPS) + message(FATAL_ERROR "bn_add_rust_static_umbrella: GROUPS is required") + endif() + if(NOT ARG_OUTPUT_DIR) + message(FATAL_ERROR "bn_add_rust_static_umbrella: OUTPUT_DIR is required") + endif() + + set(ALL_CRATES "") + set(ALL_SOURCE_FILES "") + set(ALL_TARGET_DEPENDS "") + set(ALL_BYPRODUCTS "") + set(ALL_LINK_DEPS "") + + foreach(GROUP ${ARG_GROUPS}) + get_property(CRATES GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP}_STATIC_CRATES) + get_property(SOURCES GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP}_STATIC_SOURCE_FILES) + get_property(TARGET_DEPS GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP}_TARGET_DEPENDS) + get_property(BYPRODUCTS GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP}_BYPRODUCTS) + get_property(LINK_DEPS GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP}_LINK_DEPS) + + list(APPEND ALL_CRATES ${CRATES}) + list(APPEND ALL_SOURCE_FILES ${SOURCES}) + list(APPEND ALL_TARGET_DEPENDS ${TARGET_DEPS}) + list(APPEND ALL_BYPRODUCTS ${BYPRODUCTS}) + list(APPEND ALL_LINK_DEPS ${LINK_DEPS}) + endforeach() + + list(LENGTH ALL_CRATES CRATE_COUNT) + if(CRATE_COUNT EQUAL 0) + message(WARNING "bn_add_rust_static_umbrella: no static crates registered for groups: ${ARG_GROUPS}") + return() + endif() + + set(UMBRELLA_GEN_DIR ${CMAKE_BINARY_DIR}/generated-rust) + _bn_generate_static_umbrella(${UMBRELLA_TARGET} + OUTPUT_DIR ${UMBRELLA_GEN_DIR} + CRATES ${ALL_CRATES} + ) + + _bn_get_cargo_profile(_unused PROFILE_DIR) + _bn_cargo_output_name(CARGO_OUTPUT_NAME ${UMBRELLA_TARGET} STATIC) + set(OUTPUT_FILE_PATH ${ARG_OUTPUT_DIR}/${CARGO_OUTPUT_NAME}) + + _bn_get_cargo_opts(CARGO_OPTS) + _bn_compute_cargo_paths(${BN_RUST_TARGET_DIR} ${PROFILE_DIR} ${CARGO_OUTPUT_NAME}) + + set(UMBRELLA_DIR ${UMBRELLA_GEN_DIR}/${UMBRELLA_TARGET}) + _bn_create_build_command( + TARGET_NAME ${UMBRELLA_TARGET} + OUTPUT_FILES ${OUT_CARGO_FILES} + COPY_TO ${OUTPUT_FILE_PATH} + OUTPUT_FILE_NAME ${CARGO_OUTPUT_NAME} + OUTPUT_TYPE STATIC + WORKSPACE ${UMBRELLA_DIR} + CARGO_OPTS ${CARGO_OPTS} + DEPENDS ${ALL_SOURCE_FILES} + ${UMBRELLA_DIR}/Cargo.toml + ${UMBRELLA_DIR}/src/lib.rs + BYPRODUCTS ${ALL_BYPRODUCTS} + TARGET_DIR ${BN_RUST_TARGET_DIR} + ) + + add_custom_target(${UMBRELLA_TARGET}_build ALL DEPENDS ${OUTPUT_FILE_PATH}) + + if(ARG_DEPENDS) + list(APPEND ALL_TARGET_DEPENDS ${ARG_DEPENDS}) + endif() + if(ALL_TARGET_DEPENDS) + add_dependencies(${UMBRELLA_TARGET}_build ${ALL_TARGET_DEPENDS}) + endif() + + if(NOT TARGET ${UMBRELLA_TARGET}) + add_library(${UMBRELLA_TARGET} STATIC IMPORTED GLOBAL) + endif() + set_target_properties(${UMBRELLA_TARGET} PROPERTIES IMPORTED_LOCATION ${OUTPUT_FILE_PATH}) + add_dependencies(${UMBRELLA_TARGET} ${UMBRELLA_TARGET}_build) + + # Populate the _deps interface library with link dependencies that must come after rust_static. + # This is needed because GNU ld requires libraries to appear in dependency order. + if(ALL_LINK_DEPS) + target_link_libraries(${UMBRELLA_TARGET}_deps INTERFACE ${ALL_LINK_DEPS}) + endif() + + # Connect static wrapper targets to umbrella + foreach(GROUP ${ARG_GROUPS}) + get_property(WRAPPER_TARGETS GLOBAL PROPERTY _BN_RUST_GROUP_${GROUP}_WRAPPER_TARGETS) + foreach(TARGET_NAME ${WRAPPER_TARGETS}) + # Only add dependency for static targets + get_target_property(OUTPUT_PATH ${TARGET_NAME} OUTPUT_FILE_PATH) + if(OUTPUT_PATH MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") + add_dependencies(${TARGET_NAME} ${UMBRELLA_TARGET}_build) + endif() + endforeach() + endforeach() +endfunction() + +function(bn_add_rust_crate) + cmake_parse_arguments(ARG "DEMO_STATIC" "TARGET;CRATE;WORKSPACE;OUTPUT_TYPE;OUTPUT_DIR;GROUP;CARGO_ARGS;CRATE_PATH;BN_FEATURE;CRATE_FEATURE;RPATH_KIND" "SOURCES;EXTRA_SOURCES;DEPENDS;BYPRODUCTS" ${ARGN}) + + if(NOT ARG_TARGET) + message(FATAL_ERROR "bn_add_rust_crate: TARGET is required") + endif() + set(TARGET_NAME ${ARG_TARGET}) + + if(NOT ARG_CRATE) + message(FATAL_ERROR "bn_add_rust_crate: CRATE is required") + endif() + + if(NOT ARG_OUTPUT_TYPE) + message(FATAL_ERROR "bn_add_rust_crate: OUTPUT_TYPE (SHARED or STATIC) is required") + endif() + if(NOT ARG_OUTPUT_DIR) + message(FATAL_ERROR "bn_add_rust_crate: OUTPUT_DIR is required") + endif() + + if(NOT ARG_WORKSPACE) + set(ARG_WORKSPACE ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + if(NOT ARG_CRATE_PATH) + set(ARG_CRATE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + # DEMO_STATIC: For DEMO builds only, switch to static output with demo features + if(ARG_DEMO_STATIC) + if(DEMO) + set(ARG_OUTPUT_TYPE STATIC) + set(ARG_OUTPUT_DIR ${CMAKE_BINARY_DIR}) + if(NOT ARG_BN_FEATURE) + set(ARG_BN_FEATURE "demo") + endif() + if(NOT ARG_CRATE_FEATURE) + set(ARG_CRATE_FEATURE "demo") + endif() + endif() + endif() + + # OUTPUT_TYPE STATIC: Generate a static variant of the crate + if(ARG_OUTPUT_TYPE STREQUAL "STATIC") + if(NOT ARG_BN_FEATURE) + set(ARG_BN_FEATURE "no_exports") + endif() + if(NOT ARG_CRATE_FEATURE) + set(ARG_CRATE_FEATURE "static") + endif() + set(ARG_CRATE "${ARG_CRATE}-static") + _bn_generate_static_crate( + SOURCE_CARGO_TOML ${ARG_CRATE_PATH}/Cargo.toml + OUTPUT_DIR ${CMAKE_BINARY_DIR}/generated-rust + CRATE_NAME ${ARG_CRATE} + API_PATH ${_BN_API_PATH} + BN_FEATURE ${ARG_BN_FEATURE} + CRATE_FEATURE ${ARG_CRATE_FEATURE} + ) + set(ARG_CRATE_PATH ${GENERATED_CRATE_PATH}) + + set(_GENERATED_FILES ${GENERATED_CRATE_PATH}/Cargo.toml) + if(EXISTS ${GENERATED_CRATE_PATH}/build.rs) + list(APPEND _GENERATED_FILES ${GENERATED_CRATE_PATH}/build.rs) + endif() + endif() + + _bn_cargo_output_name(OUTPUT_FILE_NAME ${ARG_CRATE} ${ARG_OUTPUT_TYPE}) + set(OUTPUT_FILE_PATH ${ARG_OUTPUT_DIR}/${OUTPUT_FILE_NAME}) + + # Compute import library path on Windows for shared libraries + if(WIN32 AND ARG_OUTPUT_TYPE STREQUAL "SHARED") + get_filename_component(_OUTPUT_STEM ${OUTPUT_FILE_NAME} NAME_WE) + set(OUTPUT_LIB_PATH ${ARG_OUTPUT_DIR}/${_OUTPUT_STEM}.lib) + endif() + + _bn_get_cargo_profile(_unused PROFILE_DIR) + _bn_gather_plugin_sources(PLUGIN_SOURCES + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} + EXPLICIT_SOURCES ${ARG_SOURCES}) + + # Process EXTRA_SOURCES: expand directories into file lists + if(ARG_EXTRA_SOURCES) + foreach(_DEP IN LISTS ARG_EXTRA_SOURCES) + if(IS_DIRECTORY "${_DEP}") + file(GLOB_RECURSE _DEP_FILES CONFIGURE_DEPENDS "${_DEP}/*") + list(APPEND PLUGIN_SOURCES ${_DEP_FILES}) + else() + list(APPEND PLUGIN_SOURCES "${_DEP}") + endif() + endforeach() + endif() + + set(USE_COMBINED_BUILD FALSE) + if(BN_INTERNAL_BUILD AND NOT ARG_CARGO_ARGS) + set(USE_COMBINED_BUILD TRUE) + endif() + + if(USE_COMBINED_BUILD) + if(NOT ARG_GROUP) + message(FATAL_ERROR "bn_add_rust_crate: GROUP is required when BN_INTERNAL_BUILD is ON") + endif() + + if(ARG_OUTPUT_TYPE STREQUAL "STATIC") + # Static crates get combined into an umbrella crate + # Register crate info for umbrella generation (name=path or name=path:feature) + if(ARG_CRATE_FEATURE) + set(_CRATE_ENTRY "${ARG_CRATE}=${ARG_CRATE_PATH}:${ARG_CRATE_FEATURE}") + else() + set(_CRATE_ENTRY "${ARG_CRATE}=${ARG_CRATE_PATH}") + endif() + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_STATIC_CRATES "${_CRATE_ENTRY}") + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_STATIC_SOURCE_FILES ${PLUGIN_SOURCES} ${_GENERATED_FILES}) + if(ARG_DEPENDS) + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_TARGET_DEPENDS ${ARG_DEPENDS}) + # Convert target names to library paths for linking + foreach(_DEP ${ARG_DEPENDS}) + if(WIN32) + set(_LINK_EXPR "$") + else() + set(_LINK_EXPR "$") + endif() + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_LINK_DEPS "${_LINK_EXPR}") + endforeach() + endif() + if(ARG_BYPRODUCTS) + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_BYPRODUCTS ${ARG_BYPRODUCTS}) + endif() + + # Create a dummy target - the actual library comes from the umbrella + add_custom_target(${TARGET_NAME} ALL) + set_property(TARGET ${TARGET_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) + set_property(TARGET ${TARGET_NAME} PROPERTY RUST_TARGET_DIR ${BN_RUST_TARGET_DIR}) + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_WRAPPER_TARGETS ${TARGET_NAME}) + else() + # Shared libraries use the normal group build + _bn_compute_cargo_paths(${BN_RUST_TARGET_DIR} ${PROFILE_DIR} ${OUTPUT_FILE_NAME}) + + # Register with the group + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_PACKAGES ${ARG_CRATE}) + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_OUTPUT_FILES ${OUT_CARGO_FILES}) + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_SOURCE_FILES ${PLUGIN_SOURCES}) + if(ARG_DEPENDS) + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_TARGET_DEPENDS ${ARG_DEPENDS}) + endif() + + # Create copy-only command (depends on cargo output files from group) + _bn_create_build_command( + COPY_TO ${OUTPUT_FILE_PATH} + COPY_FROM_FILES ${OUT_CARGO_FILES} + OUTPUT_FILE_NAME ${OUTPUT_FILE_NAME} + OUTPUT_TYPE ${ARG_OUTPUT_TYPE} + TARGET_NAME ${TARGET_NAME} + RPATH_KIND ${ARG_RPATH_KIND} + ) + + add_custom_target(${TARGET_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) + set_property(TARGET ${TARGET_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) + set_property(TARGET ${TARGET_NAME} PROPERTY RUST_TARGET_DIR ${BN_RUST_TARGET_DIR}) + if(OUTPUT_LIB_PATH) + set_property(TARGET ${TARGET_NAME} PROPERTY OUTPUT_LIB_PATH ${OUTPUT_LIB_PATH}) + endif() + set_property(GLOBAL APPEND PROPERTY _BN_RUST_GROUP_${ARG_GROUP}_WRAPPER_TARGETS ${TARGET_NAME}) + endif() + + else() + bn_get_rust_target_dir(${TARGET_NAME} STANDALONE_TARGET_DIR CARGO_ARGS ${ARG_CARGO_ARGS}) + _bn_get_cargo_opts(CARGO_OPTS ${STANDALONE_TARGET_DIR}) + _bn_compute_cargo_paths(${STANDALONE_TARGET_DIR} ${PROFILE_DIR} ${OUTPUT_FILE_NAME}) + + if(ARG_CARGO_ARGS) + separate_arguments(FEATURES_LIST NATIVE_COMMAND ${ARG_CARGO_ARGS}) + list(APPEND CARGO_OPTS ${FEATURES_LIST}) + endif() + + _bn_create_build_command( + COPY_TO ${OUTPUT_FILE_PATH} + OUTPUT_FILES ${OUT_CARGO_FILES} + OUTPUT_FILE_NAME ${OUTPUT_FILE_NAME} + OUTPUT_TYPE ${ARG_OUTPUT_TYPE} + TARGET_NAME ${TARGET_NAME} + RPATH_KIND ${ARG_RPATH_KIND} + WORKSPACE ${ARG_WORKSPACE} + CARGO_OPTS ${CARGO_OPTS} + PACKAGE_ARGS -p ${ARG_CRATE} + DEPENDS ${PLUGIN_SOURCES} + BYPRODUCTS ${ARG_BYPRODUCTS} + TARGET_DIR ${STANDALONE_TARGET_DIR} + ) + + add_custom_target(${TARGET_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) + set_property(TARGET ${TARGET_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) + set_property(TARGET ${TARGET_NAME} PROPERTY RUST_TARGET_DIR ${STANDALONE_TARGET_DIR}) + if(OUTPUT_LIB_PATH) + set_property(TARGET ${TARGET_NAME} PROPERTY OUTPUT_LIB_PATH ${OUTPUT_LIB_PATH}) + endif() + if(ARG_DEPENDS) + add_dependencies(${TARGET_NAME} ${ARG_DEPENDS}) + endif() + endif() +endfunction() diff --git a/cmake/rust/generate_static_crate.py b/cmake/rust/generate_static_crate.py new file mode 100644 index 0000000000..7a0a8c2e2b --- /dev/null +++ b/cmake/rust/generate_static_crate.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python3 +""" +Generate a static crate from an original crate. + +This script transforms a Cargo.toml for static builds: +- Adds -static suffix to package name +- Changes crate-type from cdylib to rlib +- Adds path to lib.rs pointing to original source +- References original build.rs via absolute path +- Converts workspace dependencies to path dependencies +- Converts relative path dependencies to absolute paths +- Adds specified feature to binaryninja dependency +- Ensures specified feature exists in [features] section +""" + +import argparse +from pathlib import Path + +try: + import tomllib +except ModuleNotFoundError: + import pip._vendor.tomli as tomllib + +# Workspace dependencies and their paths relative to api_path +WORKSPACE_DEPS = { + 'binaryninja': 'rust', + 'binaryninjacore-sys': 'rust/binaryninjacore-sys', +} + +# Sections emitted in this order; anything else follows after. +_SECTION_ORDER = [ + "package", "lib", "features", + "dependencies", "build-dependencies", "dev-dependencies", +] + +# Top-level keys whose dict values represent sub-sections ([key.subkey]) +# rather than inline tables. +_SUBSECTION_KEYS = {"profile"} + + +def parse_toml(path): + with open(path, "rb") as f: + return tomllib.load(f) + + +def _format_value(value): + """Format a single TOML value for inline use.""" + if isinstance(value, bool): + return "true" if value else "false" + if isinstance(value, int): + return str(value) + if isinstance(value, float): + return str(value) + if isinstance(value, str): + return f'"{value}"' + if isinstance(value, list): + items = ", ".join(_format_value(v) for v in value) + return f"[{items}]" + if isinstance(value, dict): + items = ", ".join(f"{k} = {_format_value(v)}" for k, v in value.items()) + return f"{{ {items} }}" + raise ValueError(f"Unsupported TOML value type: {type(value)}") + + +def _write_table(lines, header, data): + """Append a [header] section with key = value lines.""" + if lines and lines[-1] != "": + lines.append("") + lines.append(f"[{header}]") + for key, value in data.items(): + lines.append(f"{key} = {_format_value(value)}") + + +def serialize_toml(data): + """Serialize a dict to TOML (Cargo.toml subset).""" + lines = [] + + ordered_keys = [k for k in _SECTION_ORDER if k in data] + ordered_keys += [k for k in data if k not in ordered_keys] + + for key in ordered_keys: + value = data[key] + + # Array of tables: [[key]] + if isinstance(value, list) and value and isinstance(value[0], dict): + for item in value: + if lines and lines[-1] != "": + lines.append("") + lines.append(f"[[{key}]]") + for k, v in item.items(): + lines.append(f"{k} = {_format_value(v)}") + continue + + if not isinstance(value, dict): + continue + + # Sub-sections: [key.subkey] + if key in _SUBSECTION_KEYS: + for subkey, subvalue in value.items(): + if isinstance(subvalue, dict): + _write_table(lines, f"{key}.{subkey}", subvalue) + else: + _write_table(lines, key, value) + + return "\n".join(lines) + "\n" + + +def _transform_deps(deps, source_dir, api_path, bn_feature): + """Transform a dependencies section: resolve workspace / relative paths.""" + result = {} + for name, spec in deps.items(): + # Simple version string – keep as-is + if isinstance(spec, str): + result[name] = spec + continue + + spec = dict(spec) + + # Resolve workspace dependencies to absolute path dependencies + if spec.pop("workspace", None): + if name in WORKSPACE_DEPS: + spec["path"] = (api_path / WORKSPACE_DEPS[name]).resolve().as_posix() + + # Make relative paths absolute (resolve relative to crate directory) + if "path" in spec: + p = Path(spec["path"]) + if not p.is_absolute(): + spec["path"] = (source_dir / p).resolve().as_posix() + + # Add feature to binaryninja dependency + if name == "binaryninja" and bn_feature: + features = list(spec.get("features", [])) + if bn_feature not in features: + features.append(bn_feature) + spec["features"] = features + + result[name] = spec + return result + + +def transform_cargo_data(data, source_dir, api_path, bn_feature, crate_feature): + """Return a new dict representing the static variant of *data*.""" + result = {} + + # Package – rename with -static suffix and point to original build.rs + package = dict(data.get("package", {})) + package["name"] = package["name"] + "-static" + build_rs_path = source_dir / "build.rs" + if build_rs_path.exists(): + package["build"] = build_rs_path.resolve().as_posix() + result["package"] = package + + # Lib – switch to rlib and point at the original source tree + lib = dict(data.get("lib", {})) + lib["crate-type"] = ["rlib"] + lib["path"] = (source_dir / "src" / "lib.rs").resolve().as_posix() + result["lib"] = lib + + # Features – ensure the requested crate feature exists + features = dict(data.get("features", {})) + if crate_feature and crate_feature not in features: + features[crate_feature] = [] + if features: + result["features"] = features + + # Dependencies + if "dependencies" in data: + result["dependencies"] = _transform_deps( + data["dependencies"], source_dir, api_path, bn_feature + ) + + # Build-dependencies (no bn_feature injection here) + if "build-dependencies" in data: + result["build-dependencies"] = _transform_deps( + data["build-dependencies"], source_dir, api_path, None + ) + + # Dev-dependencies (no bn_feature injection here) + if "dev-dependencies" in data: + result["dev-dependencies"] = _transform_deps( + data["dev-dependencies"], source_dir, api_path, None + ) + + # Carry over remaining sections (profiles, etc.) + for key in data: + if key not in result: + result[key] = data[key] + + return result + + +def main(): + parser = argparse.ArgumentParser(description='Generate static Cargo.toml') + parser.add_argument('--source', required=True, help='Path to original Cargo.toml') + parser.add_argument('--output-dir', required=True, help='Output directory for generated crate') + parser.add_argument('--crate-name', required=True, help='Name for the generated crate') + parser.add_argument('--api-path', required=True, help='Path to the api directory') + parser.add_argument('--bn-feature', default='demo', help='Feature to add to binaryninja (default: demo)') + parser.add_argument('--crate-feature', default='demo', help='Feature to add to crate (default: demo)') + args = parser.parse_args() + + source_path = Path(args.source) + output_dir = Path(args.output_dir) + api_path = Path(args.api_path) + source_dir = source_path.parent + + data = parse_toml(source_path) + + new_data = transform_cargo_data( + data, source_dir, api_path, + bn_feature=args.bn_feature, + crate_feature=args.crate_feature, + ) + + new_content = serialize_toml(new_data) + + crate_dir = output_dir / args.crate_name + crate_dir.mkdir(parents=True, exist_ok=True) + + (crate_dir / 'Cargo.toml').write_text(new_content) + + # Write source directory for build.rs to read at compile time + (crate_dir / 'source_dir.txt').write_text(source_dir.resolve().as_posix()) + + print(crate_dir) + + +if __name__ == '__main__': + main() diff --git a/cmake/rust/generate_static_umbrella.py b/cmake/rust/generate_static_umbrella.py new file mode 100644 index 0000000000..abd98f8e65 --- /dev/null +++ b/cmake/rust/generate_static_umbrella.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +""" +Generate a static umbrella crate that combines multiple static crates into one staticlib. + +This avoids duplicate symbol errors from Rust standard library symbols when linking +multiple Rust staticlibs into a single binary. +""" + +from __future__ import annotations + +import argparse +from pathlib import Path + + +def parse_crate_arg(value: str) -> tuple[str, str, str | None]: + """Parse a 'name=path' or 'name=path:feature' crate argument.""" + name, _, rest = value.partition('=') + if not rest: + raise argparse.ArgumentTypeError(f"Expected name=path, got: {value}") + # Split on the *last* colon to avoid matching the Windows drive letter (C:\...). + left, sep, right = rest.rpartition(':') + if sep and len(left) > 1: + path, feature = left, right + else: + path, feature = rest, None + return name, path, feature or None + + +def generate_cargo_toml(name: str, crates: list[tuple[str, str, str | None]]) -> str: + """Generate Cargo.toml content for the umbrella crate.""" + lines = [ + '[package]', + f'name = "{name}"', + 'version = "0.1.0"', + 'edition = "2021"', + '', + '[lib]', + 'crate-type = ["staticlib"]', + '', + '[dependencies]', + ] + + for crate_name, crate_path, feature in crates: + # Normalize to forward slashes for TOML basic strings (backslash is escape) + crate_path = crate_path.replace('\\', '/') + if feature: + lines.append(f'{crate_name} = {{ path = "{crate_path}", features = ["{feature}"] }}') + else: + lines.append(f'{crate_name} = {{ path = "{crate_path}" }}') + + lines.extend([ + '', + '[profile.release]', + 'panic = "abort"', + 'lto = false', + 'debug = 1', + '', + '[profile.release-demo]', + 'inherits = "release"', + 'lto = false', + '', + '[profile.dev-demo]', + 'inherits = "dev"', + ]) + + return '\n'.join(lines) + '\n' + + +def generate_lib_rs(crates: list[tuple[str, str, str | None]]) -> str: + """Generate lib.rs content for the umbrella crate.""" + lines = [ + '// Generated umbrella crate - do not edit', + '// Combines multiple static Rust crates into a single staticlib', + '', + ] + + for crate_name, _, _ in crates: + crate_ident = crate_name.replace('-', '_') + lines.append(f'pub use {crate_ident};') + + return '\n'.join(lines) + '\n' + + +def main(): + parser = argparse.ArgumentParser(description='Generate static umbrella crate') + parser.add_argument('--name', required=True, help='Name of the umbrella crate') + parser.add_argument('--output-dir', required=True, help='Output directory') + parser.add_argument('--crate', action='append', required=True, + type=parse_crate_arg, metavar='NAME=PATH', + help='Crate to include (may be repeated)') + args = parser.parse_args() + + output_dir = Path(args.output_dir) + crates = args.crate + + umbrella_dir = output_dir / args.name + src_dir = umbrella_dir / 'src' + src_dir.mkdir(parents=True, exist_ok=True) + + (umbrella_dir / 'Cargo.toml').write_text(generate_cargo_toml(args.name, crates)) + (src_dir / 'lib.rs').write_text(generate_lib_rs(crates)) + + print(umbrella_dir) + + +if __name__ == '__main__': + main() diff --git a/cmake/rust/resolve_path_deps.py b/cmake/rust/resolve_path_deps.py new file mode 100644 index 0000000000..aa1d935e26 --- /dev/null +++ b/cmake/rust/resolve_path_deps.py @@ -0,0 +1,55 @@ +"""Resolve path dependencies from a Cargo.toml for CMake rebuild tracking. + +Uses ``cargo metadata`` to find all local path dependencies for a crate. +Outputs one absolute directory path per line on stdout, suitable for +consumption by CMake's execute_process(). + +Usage: + python3 resolve_path_deps.py \ + --manifest-path \ + --cargo +""" + +import argparse +import json +import subprocess +import sys +from pathlib import Path + + +def main(): + parser = argparse.ArgumentParser( + description="Resolve path dependencies via cargo metadata" + ) + parser.add_argument( + "--manifest-path", required=True, help="Path to crate Cargo.toml" + ) + parser.add_argument( + "--cargo", nargs="+", default=["cargo"], help="Cargo command tokens" + ) + args = parser.parse_args() + + manifest = str(Path(args.manifest_path).resolve()) + + result = subprocess.run( + [*args.cargo, "metadata", "--no-deps", "--format-version", "1", + "--manifest-path", manifest], + capture_output=True, text=True, + ) + + if result.returncode != 0: + print(result.stderr, end="", file=sys.stderr) + sys.exit(result.returncode) + + metadata = json.loads(result.stdout) + + for pkg in metadata["packages"]: + if pkg["manifest_path"] == manifest: + for dep in pkg["dependencies"]: + if dep.get("path"): + print(dep["path"]) + break + + +if __name__ == "__main__": + main() diff --git a/plugins/bntl_utils/CMakeLists.txt b/plugins/bntl_utils/CMakeLists.txt index 7f2c504e48..68368d003c 100644 --- a/plugins/bntl_utils/CMakeLists.txt +++ b/plugins/bntl_utils/CMakeLists.txt @@ -2,173 +2,33 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(bntl_utils) -if(NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD) - if(NOT BN_API_PATH) - # If we have not already defined the API source directory try and find it. - find_path( +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( BN_API_PATH NAMES binaryninjaapi.h - # List of paths to search for the clone of the api HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} REQUIRED - ) - endif() - set(CARGO_STABLE_VERSION 1.91.1) - add_subdirectory(${BN_API_PATH} binaryninjaapi) -endif() - -file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() - -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) - - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - # NOTE: --no-default-features is set to disable building artifacts used for testing - # NOTE: the linker is looking in the target dir and linking on it apparently. - set(CARGO_FEATURES "--no-default-features") - - set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) -endif() - +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE bntl_utils + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins + EXTRA_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/templates +) -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) add_dependencies(${PROJECT_NAME} binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB API_SOURCES CONFIGURE_DEPENDS - ${BN_API_SOURCE_DIR}/binaryninjacore.h - ${BN_API_SOURCE_DIR}/rust/src/*.rs - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/src/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -endif() diff --git a/plugins/dwarf/dwarf_export/CMakeLists.txt b/plugins/dwarf/dwarf_export/CMakeLists.txt index 08b45c6411..6ae83beed6 100644 --- a/plugins/dwarf/dwarf_export/CMakeLists.txt +++ b/plugins/dwarf/dwarf_export/CMakeLists.txt @@ -2,95 +2,31 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(dwarf_export) -file(GLOB PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs - ${PROJECT_SOURCE_DIR}/../shared/Cargo.toml - ${PROJECT_SOURCE_DIR}/../shared/src/*.rs) - -file(GLOB API_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/../../../binaryninjacore.h - ${PROJECT_SOURCE_DIR}/../../../rust/binaryninjacore-sys/build.rs - ${PROJECT_SOURCE_DIR}/../../../rust/binaryninjacore-sys/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../../rust/binaryninjacore-sys/src/* - ${PROJECT_SOURCE_DIR}/../../../rust/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../../rust/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) -else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}dwarf_export.pdb) +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( + BN_API_PATH + NAMES binaryninjaapi.h + HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} + REQUIRED + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) + endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -set(OUTPUT_FILE ${CMAKE_STATIC_LIBRARY_PREFIX}dwarf_export${CMAKE_SHARED_LIBRARY_SUFFIX}) -set(PLUGIN_PATH ${TARGET_DIR}/${OUTPUT_FILE}) - -add_custom_target(dwarf_export ALL DEPENDS ${PLUGIN_PATH}) -add_dependencies(dwarf_export binaryninjaapi) +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE dwarf_export + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins +) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -if(CARGO_API_VERSION) - set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_API_VERSION} cargo build) -else() - set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo build) -endif() - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE}) - endif() - - add_custom_command( - OUTPUT ${PLUGIN_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_CORE_OUTPUT_DIR} - ${RUSTUP_COMMAND} --target=aarch64-apple-darwin ${CARGO_OPTS} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_CORE_OUTPUT_DIR} - ${RUSTUP_COMMAND} --target=x86_64-apple-darwin ${CARGO_OPTS} - COMMAND mkdir -p ${TARGET_DIR} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${PLUGIN_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${PLUGIN_PATH} ${BN_CORE_PLUGIN_DIR} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) - else() - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(LIB_PATH ${PROJECT_BINARY_DIR}/target/debug/${OUTPUT_FILE}) - else() - set(LIB_PATH ${PROJECT_BINARY_DIR}/target/release/${OUTPUT_FILE}) - endif() - - add_custom_command( - OUTPUT ${PLUGIN_PATH} - COMMAND ${CMAKE_COMMAND} -E env MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BN_CORE_OUTPUT_DIR} ${RUSTUP_COMMAND} ${CARGO_OPTS} - COMMAND ${CMAKE_COMMAND} -E copy ${PLUGIN_PATH} ${BN_CORE_PLUGIN_DIR} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) - endif() -elseif(WIN32) - add_custom_command( - OUTPUT ${PLUGIN_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BN_CORE_OUTPUT_DIR} ${RUSTUP_COMMAND} ${CARGO_OPTS} - COMMAND ${CMAKE_COMMAND} -E copy ${PLUGIN_PATH} ${BN_CORE_PLUGIN_DIR} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${BN_CORE_PLUGIN_DIR} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) -else() - add_custom_command( - OUTPUT ${PLUGIN_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BN_CORE_OUTPUT_DIR} ${RUSTUP_COMMAND} ${CARGO_OPTS} - COMMAND ${CMAKE_COMMAND} -E copy ${PLUGIN_PATH} ${BN_CORE_PLUGIN_DIR} - COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH="${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE}" -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake" - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) -endif() +add_dependencies(${PROJECT_NAME} binaryninjaapi) diff --git a/plugins/dwarf/dwarf_import/CMakeLists.txt b/plugins/dwarf/dwarf_import/CMakeLists.txt index dead11c030..023c18a24e 100644 --- a/plugins/dwarf/dwarf_import/CMakeLists.txt +++ b/plugins/dwarf/dwarf_import/CMakeLists.txt @@ -2,173 +2,32 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(dwarf_import) -if(NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD) - if(NOT BN_API_PATH) - # If we have not already defined the API source directory try and find it. - find_path( - BN_API_PATH - NAMES binaryninjaapi.h - # List of paths to search for the clone of the api - HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} - REQUIRED - ) - endif() - set(CARGO_STABLE_VERSION 1.91.1) - add_subdirectory(${BN_API_PATH} binaryninjaapi) +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( + BN_API_PATH + NAMES binaryninjaapi.h + HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} + REQUIRED + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) + endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE dwarf_import + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins + DEMO_STATIC +) -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) - endif() -endif() - -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() - -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) - - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - # NOTE: --no-default-features is set to disable building artifacts used for testing - # NOTE: the linker is looking in the target dir and linking on it apparently. - set(CARGO_FEATURES "--no-default-features") - - set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) -endif() - - -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) add_dependencies(${PROJECT_NAME} binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB API_SOURCES CONFIGURE_DEPENDS - ${BN_API_SOURCE_DIR}/binaryninjacore.h - ${BN_API_SOURCE_DIR}/rust/src/*.rs - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/src/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -endif() diff --git a/plugins/dwarf/dwarf_import/demo/Cargo.toml b/plugins/dwarf/dwarf_import/demo/Cargo.toml deleted file mode 100644 index d4418edd46..0000000000 --- a/plugins/dwarf/dwarf_import/demo/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "dwarf_import-static" -version = "0.1.0" -edition = "2021" -license = "Apache-2.0" - -[lib] -crate-type = ["staticlib"] -path = "../src/lib.rs" - -[features] -demo = [] - -[dependencies] -dwarfreader = { path = "../../shared/" } -binaryninja = { workspace = true, features = ["demo"]} -binaryninjacore-sys.workspace = true -gimli = "0.31" -iset = "0.2.2" -cpp_demangle = "0.4.3" -regex = "1" -indexmap = "2.5.0" -object = "0.36" -tracing = "0.1" \ No newline at end of file diff --git a/plugins/dwarf/dwarf_import/demo/build.rs b/plugins/dwarf/dwarf_import/demo/build.rs deleted file mode 100644 index 8cbaf2b1cc..0000000000 --- a/plugins/dwarf/dwarf_import/demo/build.rs +++ /dev/null @@ -1,30 +0,0 @@ -fn main() { - let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") - .expect("DEP_BINARYNINJACORE_PATH not specified"); - - println!("cargo::rustc-link-lib=dylib=binaryninjacore"); - println!( - "cargo::rustc-link-search={}", - link_path - .to_str() - .expect("Failed to convert link path to string") - ); - - #[cfg(target_os = "linux")] - { - println!( - "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}", - link_path.to_string_lossy() - ); - } - - #[cfg(target_os = "macos")] - { - let crate_name = std::env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME not set"); - let lib_name = crate_name.replace('-', "_"); - println!( - "cargo::rustc-link-arg=-Wl,-install_name,@rpath/lib{}.dylib", - lib_name - ); - } -} diff --git a/plugins/idb_import/CMakeLists.txt b/plugins/idb_import/CMakeLists.txt index 8f594097b3..2f9be25084 100644 --- a/plugins/idb_import/CMakeLists.txt +++ b/plugins/idb_import/CMakeLists.txt @@ -2,175 +2,32 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(idb_import) -file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) - -file(GLOB API_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/../../binaryninjacore.h - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/build.rs - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/src/* - ${PROJECT_SOURCE_DIR}/../../rust/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../rust/src/*.rs - ${PROJECT_SOURCE_DIR}/../../rust/src/*/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( + BN_API_PATH + NAMES binaryninjaapi.h + HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} + REQUIRED + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) - - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR ${BN_CORE_OUTPUT_DIR}) -endif() - +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE idb_import + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins + DEMO_STATIC +) -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) add_dependencies(${PROJECT_NAME} binaryninjaapi) - -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -if(CARGO_API_VERSION) - set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_API_VERSION} cargo) -else() - set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) -endif() - -if(APPLE) - set(CARGO_DSYM_ENV) - if(NOT DEMO) - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(CARGO_DSYM_ENV CARGO_PROFILE_DEV_SPLIT_DEBUGINFO=packed) - else() - set(CARGO_DSYM_ENV CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO=packed) - endif() - endif() - - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - set(DSYM_BYPRODUCTS) - set(DSYM_COMMANDS) - if(NOT DEMO) - set(DSYM_BYPRODUCTS BYPRODUCTS ${OUTPUT_FILE_PATH}.dSYM) - set(DSYM_COMMANDS - COMMAND ${CMAKE_COMMAND} -E rm -rf ${OUTPUT_FILE_PATH}.dSYM - COMMAND ${CMAKE_COMMAND} -E copy_directory ${AARCH64_LIB_PATH}.dSYM ${OUTPUT_FILE_PATH}.dSYM - COMMAND lipo -create - ${AARCH64_LIB_PATH}.dSYM/Contents/Resources/DWARF/${OUTPUT_FILE_NAME} - ${X86_64_LIB_PATH}.dSYM/Contents/Resources/DWARF/${OUTPUT_FILE_NAME} - -output ${OUTPUT_FILE_PATH}.dSYM/Contents/Resources/DWARF/${OUTPUT_FILE_NAME}) - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - ${DSYM_BYPRODUCTS} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND mkdir -p ${TARGET_DIR} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - ${DSYM_COMMANDS} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) - else() - set(DSYM_BYPRODUCTS) - set(DSYM_COMMANDS) - if(NOT DEMO) - set(DSYM_BYPRODUCTS BYPRODUCTS ${OUTPUT_FILE_PATH}.dSYM) - set(DSYM_COMMANDS - COMMAND ${CMAKE_COMMAND} -E rm -rf ${OUTPUT_FILE_PATH}.dSYM - COMMAND ${CMAKE_COMMAND} -E copy_directory ${TARGET_DIR}/${OUTPUT_FILE_NAME}.dSYM ${OUTPUT_FILE_PATH}.dSYM) - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - ${DSYM_BYPRODUCTS} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - ${DSYM_COMMANDS} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES}) -endif() diff --git a/plugins/idb_import/demo/Cargo.toml b/plugins/idb_import/demo/Cargo.toml deleted file mode 100644 index d16d84c505..0000000000 --- a/plugins/idb_import/demo/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "idb_import-static" -version = "0.1.0" -edition = "2021" -license = "Apache-2.0" -publish = false - -[lib] -crate-type = ["staticlib"] -path = "../src/lib.rs" - -[features] -demo = [] - -[dependencies] -anyhow = { version = "1.0.86", features = ["backtrace"] } -binaryninja = { workspace = true, features = ["demo"] } -binaryninjacore-sys.workspace = true -idb-rs = { git = "https://github.com/Vector35/idb-rs", tag = "0.1.15" } -tracing = "0.1" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -sha2 = "0.10" \ No newline at end of file diff --git a/plugins/idb_import/demo/build.rs b/plugins/idb_import/demo/build.rs deleted file mode 100644 index 8cbaf2b1cc..0000000000 --- a/plugins/idb_import/demo/build.rs +++ /dev/null @@ -1,30 +0,0 @@ -fn main() { - let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") - .expect("DEP_BINARYNINJACORE_PATH not specified"); - - println!("cargo::rustc-link-lib=dylib=binaryninjacore"); - println!( - "cargo::rustc-link-search={}", - link_path - .to_str() - .expect("Failed to convert link path to string") - ); - - #[cfg(target_os = "linux")] - { - println!( - "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}", - link_path.to_string_lossy() - ); - } - - #[cfg(target_os = "macos")] - { - let crate_name = std::env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME not set"); - let lib_name = crate_name.replace('-', "_"); - println!( - "cargo::rustc-link-arg=-Wl,-install_name,@rpath/lib{}.dylib", - lib_name - ); - } -} diff --git a/plugins/pdb-ng/CMakeLists.txt b/plugins/pdb-ng/CMakeLists.txt index 01e1be2b95..64f6f7c1ee 100644 --- a/plugins/pdb-ng/CMakeLists.txt +++ b/plugins/pdb-ng/CMakeLists.txt @@ -2,158 +2,32 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(pdb_import_plugin) -file(GLOB PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) - endif() -endif() - -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( + BN_API_PATH + NAMES binaryninjaapi.h + HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} + REQUIRED + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) + endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) - - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - set(CARGO_FEATURES "") - - set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) -endif() +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE pdb-import-plugin + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins + DEMO_STATIC +) -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) add_dependencies(${PROJECT_NAME} binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -file(GLOB API_SOURCES CONFIGURE_DEPENDS - ${BN_API_SOURCE_DIR}/binaryninjacore.h - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/build.rs - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/Cargo.toml - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/src/* - ${BN_API_SOURCE_DIR}/rust/Cargo.toml - ${BN_API_SOURCE_DIR}/rust/src/*.rs - ${BN_API_SOURCE_DIR}/rust/src/*/*.rs) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -endif() diff --git a/plugins/pdb-ng/demo/Cargo.toml b/plugins/pdb-ng/demo/Cargo.toml deleted file mode 100644 index 590cacca5c..0000000000 --- a/plugins/pdb-ng/demo/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "pdb-import-plugin-static" -version = "0.1.0" -edition = "2021" -license = "Apache-2.0" - -[lib] -crate-type = ["staticlib"] -path = "../src/lib.rs" - -[dependencies] -anyhow = "^1.0" -binaryninja = { workspace = true, features = ["demo"]} -binaryninjacore-sys.workspace = true -itertools = "0.14" -pdb = { git = "https://github.com/Vector35/pdb-rs", rev = "6016177" } -regex = "1" -tracing = "0.1" - -[features] -demo = [] diff --git a/plugins/pdb-ng/demo/build.rs b/plugins/pdb-ng/demo/build.rs deleted file mode 100644 index ed6cec7d27..0000000000 --- a/plugins/pdb-ng/demo/build.rs +++ /dev/null @@ -1,15 +0,0 @@ -fn main() { - let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") - .expect("DEP_BINARYNINJACORE_PATH not specified"); - - println!("cargo::rustc-link-lib=dylib=binaryninjacore"); - println!("cargo::rustc-link-search={}", link_path.to_str().unwrap()); - - #[cfg(not(target_os = "windows"))] - { - println!( - "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}", - link_path.to_string_lossy() - ); - } -} diff --git a/plugins/svd/CMakeLists.txt b/plugins/svd/CMakeLists.txt index 336651ab0c..4927b6f7f0 100644 --- a/plugins/svd/CMakeLists.txt +++ b/plugins/svd/CMakeLists.txt @@ -2,173 +2,34 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(svd_ninja) -if(NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD) - if(NOT BN_API_PATH) - # If we have not already defined the API source directory try and find it. - find_path( +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( BN_API_PATH NAMES binaryninjaapi.h - # List of paths to search for the clone of the api HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} REQUIRED - ) - endif() - set(CARGO_STABLE_VERSION 1.91.1) - add_subdirectory(${BN_API_PATH} binaryninjaapi) -endif() - -file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() - -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) - - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - # NOTE: --no-default-features is set to disable building artifacts used for testing - # NOTE: the linker is looking in the target dir and linking on it apparently. - set(CARGO_FEATURES "--no-default-features") - - set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) -endif() - +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE svd_ninja + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins + DEMO_STATIC + EXTRA_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/fixtures +) -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) add_dependencies(${PROJECT_NAME} binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB API_SOURCES CONFIGURE_DEPENDS - ${BN_API_SOURCE_DIR}/binaryninjacore.h - ${BN_API_SOURCE_DIR}/rust/src/*.rs - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/src/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -endif() diff --git a/plugins/svd/build.rs b/plugins/svd/build.rs index ce38f53970..d5b55c0fc6 100644 --- a/plugins/svd/build.rs +++ b/plugins/svd/build.rs @@ -1,4 +1,11 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; + +// For static builds, CARGO_MANIFEST_DIR points to the generated crate directory, +// so we read the original source path from source_dir.txt written by generate_static_crate.py. +#[cfg(feature = "demo")] +const SOURCE_DIR: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/source_dir.txt")); +#[cfg(not(feature = "demo"))] +const SOURCE_DIR: &str = env!("CARGO_MANIFEST_DIR"); fn main() { let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") @@ -29,8 +36,9 @@ fn main() { let out_dir_path = PathBuf::from(out_dir); // Copy all binaries to OUT_DIR for unit tests. - let bin_dir: PathBuf = "fixtures/".into(); - if let Ok(entries) = std::fs::read_dir(bin_dir) { + let fixtures_dir = Path::new(SOURCE_DIR).join("fixtures"); + println!("cargo::rerun-if-changed={}", fixtures_dir.display()); + if let Ok(entries) = std::fs::read_dir(&fixtures_dir) { for entry in entries { let entry = entry.unwrap(); let path = entry.path(); diff --git a/plugins/svd/demo/Cargo.toml b/plugins/svd/demo/Cargo.toml deleted file mode 100644 index b714757403..0000000000 --- a/plugins/svd/demo/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "svd_ninja-static" -version = "0.1.0" -edition = "2021" -license = "Apache-2.0" - -[lib] -crate-type = ["staticlib", "lib"] -path = "../src/lib.rs" - -[dependencies] -binaryninja = { workspace = true, features = ["demo"]} -binaryninjacore-sys.workspace = true -svd-parser = { version = "0.14.8", features = ["expand"] } -serde_json = "1.0" -tracing = "0.1" - -[dev-dependencies] -insta = { version = "1.42", features = ["yaml"] } - -[features] -demo = [] \ No newline at end of file diff --git a/plugins/svd/demo/build.rs b/plugins/svd/demo/build.rs deleted file mode 100644 index 637f477949..0000000000 --- a/plugins/svd/demo/build.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::path::PathBuf; - -fn main() { - let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") - .expect("DEP_BINARYNINJACORE_PATH not specified"); - - println!("cargo::rustc-link-lib=dylib=binaryninjacore"); - println!("cargo::rustc-link-search={}", link_path.to_str().unwrap()); - - #[cfg(not(target_os = "windows"))] - { - println!( - "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}", - link_path.to_string_lossy() - ); - } - - let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR specified"); - let out_dir_path = PathBuf::from(out_dir); - - // Copy all binaries to OUT_DIR for unit tests. - let bin_dir: PathBuf = "fixtures/".into(); - if let Ok(entries) = std::fs::read_dir(bin_dir) { - for entry in entries { - let entry = entry.unwrap(); - let path = entry.path(); - if path.is_file() { - let file_name = path.file_name().unwrap(); - let dest_path = out_dir_path.join(file_name); - std::fs::copy(&path, &dest_path).expect("failed to copy binary to OUT_DIR"); - } - } - } -} diff --git a/plugins/warp/CMakeLists.txt b/plugins/warp/CMakeLists.txt index ba986b7170..745f608459 100644 --- a/plugins/warp/CMakeLists.txt +++ b/plugins/warp/CMakeLists.txt @@ -2,187 +2,50 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(warp_ninja) -if(NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD) - if(NOT BN_API_PATH) - # If we have not already defined the API source directory try and find it. - find_path( +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( BN_API_PATH NAMES binaryninjaapi.h - # List of paths to search for the clone of the api HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} REQUIRED - ) + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() - set(CARGO_STABLE_VERSION 1.91.1) - add_subdirectory(${BN_API_PATH} binaryninjaapi) + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) - -# Add API library. +# Add C++ API library and UI plugin add_subdirectory(api) -# Add UI plugin. if(NOT HEADLESS) add_subdirectory(ui) endif() -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) - endif() +if(NOT DEMO) + # Non-DEMO uses --no-default-features to exclude test artifacts + set(CARGO_ARGS "--no-default-features") endif() -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE warp_ninja + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + CARGO_ARGS ${CARGO_ARGS} + GROUP plugins + DEMO_STATIC + EXTRA_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/fixtures +) + +add_dependencies(${PROJECT_NAME} binaryninjaapi) # warp_ninja_interface is the target hack im going with for now to get warp_api to build on windows add_library(${PROJECT_NAME}_interface INTERFACE) add_dependencies(${PROJECT_NAME}_interface ${PROJECT_NAME}) - -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) - - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - # NOTE: --no-default-features is set to disable building artifacts used for testing - # NOTE: the linker is looking in the target dir and linking on it apparently. - set(CARGO_FEATURES "--no-default-features") - - set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_LIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.dll.lib) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - set(OUTPUT_LIB_PATH ${BN_CORE_PLUGIN_DIR}/${PROJECT_NAME}.lib) - - set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) -endif() - - -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) -add_dependencies(${PROJECT_NAME} binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB API_SOURCES CONFIGURE_DEPENDS - ${BN_API_SOURCE_DIR}/binaryninjacore.h - ${BN_API_SOURCE_DIR}/rust/src/*.rs - ${BN_API_SOURCE_DIR}/rust/binaryninjacore-sys/src/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} ${OUTPUT_LIB_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_LIB_NAME} ${OUTPUT_LIB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -endif() diff --git a/plugins/warp/api/CMakeLists.txt b/plugins/warp/api/CMakeLists.txt index c854a200ba..a3afd75036 100644 --- a/plugins/warp/api/CMakeLists.txt +++ b/plugins/warp/api/CMakeLists.txt @@ -28,13 +28,13 @@ endif() # Link to the warp plugin. # TODO: Need to make this less scuffed, but this will do for now. if (DEMO) - target_link_libraries(${PROJECT_NAME} warp_ninja_interface ${CMAKE_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}warp_ninja_static${CMAKE_STATIC_LIBRARY_SUFFIX}) + target_link_libraries(${PROJECT_NAME} warp_ninja_interface) else () if (WIN32) # By linking to warp_ninja_interface we insure that we get built _after_ the lib has been generated. - target_link_libraries(${PROJECT_NAME} warp_ninja_interface "${BN_CORE_PLUGIN_DIR}/warp_ninja.lib") + target_link_libraries(${PROJECT_NAME} warp_ninja_interface "${BN_PLUGIN_OUTPUT_DIR}/warp_ninja.lib") else () - target_link_libraries(${PROJECT_NAME} warp_ninja_interface ${BN_CORE_PLUGIN_DIR}/libwarp_ninja${CMAKE_SHARED_LIBRARY_SUFFIX}) + target_link_libraries(${PROJECT_NAME} warp_ninja_interface ${BN_PLUGIN_OUTPUT_DIR}/libwarp_ninja${CMAKE_SHARED_LIBRARY_SUFFIX}) # Set RPATH so the library can be found at runtime if(APPLE) set_target_properties(${PROJECT_NAME} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE INSTALL_RPATH "@loader_path") diff --git a/plugins/warp/build.rs b/plugins/warp/build.rs index 25546941e1..ef2be95fb8 100644 --- a/plugins/warp/build.rs +++ b/plugins/warp/build.rs @@ -1,4 +1,11 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; + +// For static builds, CARGO_MANIFEST_DIR points to the generated crate directory, +// so we read the original source path from source_dir.txt written by generate_static_crate.py. +#[cfg(feature = "demo")] +const SOURCE_DIR: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/source_dir.txt")); +#[cfg(not(feature = "demo"))] +const SOURCE_DIR: &str = env!("CARGO_MANIFEST_DIR"); fn main() { let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") @@ -28,9 +35,10 @@ fn main() { let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR specified"); let out_dir_path = PathBuf::from(out_dir); - println!("cargo::rerun-if-changed=fixtures"); // Copy all binaries to OUT_DIR for unit tests. - let bin_dir: PathBuf = "fixtures/bin".into(); + let fixtures_dir = Path::new(SOURCE_DIR).join("fixtures"); + println!("cargo::rerun-if-changed={}", fixtures_dir.display()); + let bin_dir = fixtures_dir.join("bin"); if let Ok(entries) = std::fs::read_dir(bin_dir) { for entry in entries { let entry = entry.unwrap(); diff --git a/plugins/warp/demo/Cargo.toml b/plugins/warp/demo/Cargo.toml deleted file mode 100644 index 7c9babad68..0000000000 --- a/plugins/warp/demo/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "warp_ninja-static" -version = "0.1.0" -edition = "2021" -license = "Apache-2.0" - -[lib] -crate-type = ["lib", "staticlib"] -path = "../src/lib.rs" - -[features] -demo = [] - -[dependencies] -tracing = "0.1" -binaryninja = { workspace = true, features = ["rayon", "demo"] } -binaryninjacore-sys.workspace = true -warp = { git = "https://github.com/Vector35/warp/", tag = "1.0.0" } -itertools = "0.14.0" -dashmap = { version = "6.1", features = ["rayon"]} -rayon = "1.10" -arboard = "3.4" -walkdir = "2.5" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -uuid = { version = "1.12.0", features = ["v4", "serde"] } -thiserror = "2.0" -ar = { git = "https://github.com/mdsteele/rust-ar" } -tempdir = "0.3.7" -directories = "6.0" -compact_str = { version = "0.9.0", features = ["serde"] } -base64 = "0.22" -serde_qs = "0.15" - -[dev-dependencies] -criterion = "0.6" -insta = { version = "1.42", features = ["yaml"] } diff --git a/plugins/warp/demo/build.rs b/plugins/warp/demo/build.rs deleted file mode 100644 index 4940fe7638..0000000000 --- a/plugins/warp/demo/build.rs +++ /dev/null @@ -1,25 +0,0 @@ -fn main() { - let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") - .expect("DEP_BINARYNINJACORE_PATH not specified"); - - println!("cargo::rustc-link-lib=dylib=binaryninjacore"); - println!("cargo::rustc-link-search={}", link_path.to_str().unwrap()); - - #[cfg(not(target_os = "windows"))] - { - println!( - "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}", - link_path.to_string_lossy() - ); - } - - #[cfg(target_os = "macos")] - { - let crate_name = std::env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME not set"); - let lib_name = crate_name.replace('-', "_"); - println!( - "cargo::rustc-link-arg=-Wl,-install_name,@rpath/lib{}.dylib", - lib_name - ); - } -} diff --git a/plugins/workflow_objc/CMakeLists.txt b/plugins/workflow_objc/CMakeLists.txt index 5c5e8aec53..4acd9c7c68 100644 --- a/plugins/workflow_objc/CMakeLists.txt +++ b/plugins/workflow_objc/CMakeLists.txt @@ -2,177 +2,32 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(workflow_objc) -if(NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD) - if(NOT BN_API_PATH) - # If we have not already defined the API source directory try and find it. - find_path( +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( BN_API_PATH NAMES binaryninjaapi.h - # List of paths to search for the clone of the api HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} REQUIRED - ) - endif() - set(CARGO_STABLE_VERSION 1.91.1) - add_subdirectory(${BN_API_PATH} binaryninjaapi) -endif() - -file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() - -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) - - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - # NOTE: --no-default-features is set to disable building artifacts used for testing - # NOTE: the linker is looking in the target dir and linking on it apparently. - set(CARGO_FEATURES "--no-default-features") - - set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) -endif() - +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE workflow_objc + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins + DEMO_STATIC +) -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) add_dependencies(${PROJECT_NAME} binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB_RECURSE API_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/../../binaryninjacore.h - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/build.rs - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/src/*.rs - ${PROJECT_SOURCE_DIR}/../../rust/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../rust/src/*.rs - ${PROJECT_SOURCE_DIR}/../../rust/src/*/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -endif() diff --git a/plugins/workflow_objc/demo/Cargo.toml b/plugins/workflow_objc/demo/Cargo.toml deleted file mode 100644 index 449abee0bf..0000000000 --- a/plugins/workflow_objc/demo/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "workflow_objc-static" -version = "0.1.0" -edition = "2021" -license = "BSD-3-Clause" - -[lib] -crate-type = ["staticlib"] -path = "../src/lib.rs" - -[features] -demo = [] - -[dependencies] -binaryninja = { workspace = true, features = ["demo"] } -binaryninjacore-sys.workspace = true -dashmap = { version = "6.1", features = ["rayon"]} -once_cell = "1.20" -thiserror = "2.0" -bstr = "1.12" -tracing = "0.1" \ No newline at end of file diff --git a/plugins/workflow_objc/demo/build.rs b/plugins/workflow_objc/demo/build.rs deleted file mode 100644 index ed6cec7d27..0000000000 --- a/plugins/workflow_objc/demo/build.rs +++ /dev/null @@ -1,15 +0,0 @@ -fn main() { - let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") - .expect("DEP_BINARYNINJACORE_PATH not specified"); - - println!("cargo::rustc-link-lib=dylib=binaryninjacore"); - println!("cargo::rustc-link-search={}", link_path.to_str().unwrap()); - - #[cfg(not(target_os = "windows"))] - { - println!( - "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}", - link_path.to_string_lossy() - ); - } -} diff --git a/plugins/workflow_swift/CMakeLists.txt b/plugins/workflow_swift/CMakeLists.txt index 8a885d5289..7285e495a3 100644 --- a/plugins/workflow_swift/CMakeLists.txt +++ b/plugins/workflow_swift/CMakeLists.txt @@ -2,212 +2,32 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(workflow_swift) -if(NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD) - if(NOT BN_API_PATH) - # If we have not already defined the API source directory try and find it. - find_path( +if(NOT BN_INTERNAL_BUILD) + if(NOT BN_API_BUILD_EXAMPLES) + if(NOT BN_API_PATH) + find_path( BN_API_PATH NAMES binaryninjaapi.h - # List of paths to search for the clone of the api HINTS ../../.. ../../binaryninja/api/ binaryninjaapi binaryninja-api $ENV{BN_API_PATH} REQUIRED - ) - endif() - set(CARGO_STABLE_VERSION 1.91.1) - add_subdirectory(${BN_API_PATH} binaryninjaapi) -endif() - -file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/Cargo.toml - ${PROJECT_SOURCE_DIR}/src/*.rs) - -if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/dev-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=dev-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target) - endif() -else() - if(DEMO) - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release-demo) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --profile=release-demo) - else() - set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/release) - set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target --release) + ) + endif() + add_subdirectory(${BN_API_PATH} binaryninjaapi) endif() + get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) + list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") + include(RustBuild) + find_package(BinaryNinjaCore REQUIRED) endif() -if(FORCE_COLORED_OUTPUT) - set(CARGO_OPTS ${CARGO_OPTS} --color always) -endif() - -if(DEMO) - set(CARGO_FEATURES --features demo --manifest-path ${PROJECT_SOURCE_DIR}/demo/Cargo.toml) +bn_add_rust_crate( + TARGET ${PROJECT_NAME} + CRATE workflow_swift + WORKSPACE ${BN_API_SOURCE_DIR} + OUTPUT_TYPE SHARED + OUTPUT_DIR ${BN_PLUGIN_OUTPUT_DIR} + GROUP plugins + DEMO_STATIC +) - set(OUTPUT_FILE_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}_static${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR $) -else() - # NOTE: --no-default-features is set to disable building artifacts used for testing - # NOTE: the linker is looking in the target dir and linking on it apparently. - set(CARGO_FEATURES "--no-default-features") - - set(OUTPUT_FILE_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(OUTPUT_PDB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}.pdb) - set(OUTPUT_FILE_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_FILE_NAME}) - set(OUTPUT_PDB_PATH ${BN_CORE_PLUGIN_DIR}/${OUTPUT_PDB_NAME}) - - set(BINJA_LIB_DIR ${BN_INSTALL_BIN_DIR}) -endif() - - -add_custom_target(${PROJECT_NAME} ALL DEPENDS ${OUTPUT_FILE_PATH}) add_dependencies(${PROJECT_NAME} binaryninjaapi) -get_target_property(BN_API_SOURCE_DIR binaryninjaapi SOURCE_DIR) -list(APPEND CMAKE_MODULE_PATH "${BN_API_SOURCE_DIR}/cmake") -find_package(BinaryNinjaCore REQUIRED) - -set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_FILE_PATH ${OUTPUT_FILE_PATH}) - -# Add the whole api to the depends too -file(GLOB_RECURSE API_SOURCES CONFIGURE_DEPENDS - ${PROJECT_SOURCE_DIR}/../../binaryninjacore.h - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/build.rs - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../rust/binaryninjacore-sys/src/*.rs - ${PROJECT_SOURCE_DIR}/../../rust/Cargo.toml - ${PROJECT_SOURCE_DIR}/../../rust/src/*.rs - ${PROJECT_SOURCE_DIR}/../../rust/src/*/*.rs) - -find_program(RUSTUP_PATH rustup REQUIRED HINTS ~/.cargo/bin) -set(RUSTUP_COMMAND ${RUSTUP_PATH} run ${CARGO_STABLE_VERSION} cargo) - -if(APPLE) - set(CARGO_DSYM_ENV) - if(NOT DEMO) - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(CARGO_DSYM_ENV CARGO_PROFILE_DEV_SPLIT_DEBUGINFO=packed) - else() - set(CARGO_DSYM_ENV CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO=packed) - endif() - endif() - - if(UNIVERSAL) - if(CMAKE_BUILD_TYPE MATCHES Debug) - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/dev-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/debug/${OUTPUT_FILE_NAME}) - endif() - else() - if(DEMO) - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release-demo/${OUTPUT_FILE_NAME}) - else() - set(AARCH64_LIB_PATH ${PROJECT_BINARY_DIR}/target/aarch64-apple-darwin/release/${OUTPUT_FILE_NAME}) - set(X86_64_LIB_PATH ${PROJECT_BINARY_DIR}/target/x86_64-apple-darwin/release/${OUTPUT_FILE_NAME}) - endif() - endif() - - set(DSYM_BYPRODUCTS) - set(DSYM_COMMANDS) - if(NOT DEMO) - set(DSYM_BYPRODUCTS BYPRODUCTS ${OUTPUT_FILE_PATH}.dSYM) - set(DSYM_COMMANDS - COMMAND ${CMAKE_COMMAND} -E rm -rf ${OUTPUT_FILE_PATH}.dSYM - COMMAND ${CMAKE_COMMAND} -E copy_directory ${AARCH64_LIB_PATH}.dSYM ${OUTPUT_FILE_PATH}.dSYM - COMMAND lipo -create - ${AARCH64_LIB_PATH}.dSYM/Contents/Resources/DWARF/${OUTPUT_FILE_NAME} - ${X86_64_LIB_PATH}.dSYM/Contents/Resources/DWARF/${OUTPUT_FILE_NAME} - -output ${OUTPUT_FILE_PATH}.dSYM/Contents/Resources/DWARF/${OUTPUT_FILE_NAME}) - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - ${DSYM_BYPRODUCTS} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} clean --target=aarch64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} clean --target=x86_64-apple-darwin ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} build --target=aarch64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} build --target=x86_64-apple-darwin ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND lipo -create ${AARCH64_LIB_PATH} ${X86_64_LIB_PATH} -output ${OUTPUT_FILE_PATH} - ${DSYM_COMMANDS} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - set(DSYM_BYPRODUCTS) - set(DSYM_COMMANDS) - if(NOT DEMO) - set(DSYM_BYPRODUCTS BYPRODUCTS ${OUTPUT_FILE_PATH}.dSYM) - set(DSYM_COMMANDS - COMMAND ${CMAKE_COMMAND} -E rm -rf ${OUTPUT_FILE_PATH}.dSYM - COMMAND ${CMAKE_COMMAND} -E copy_directory ${TARGET_DIR}/${OUTPUT_FILE_NAME}.dSYM ${OUTPUT_FILE_PATH}.dSYM) - endif() - - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - ${DSYM_BYPRODUCTS} - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env - MACOSX_DEPLOYMENT_TARGET=10.14 BINARYNINJADIR=${BINJA_LIB_DIR} ${CARGO_DSYM_ENV} - ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - ${DSYM_COMMANDS} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -elseif(WIN32) - if(DEMO) - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - else() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_PDB_NAME} ${OUTPUT_PDB_PATH} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) - endif() -else() - if(DEMO) - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -E true) - else() - set(BN_FIX_RPATH_COMMAND ${CMAKE_COMMAND} -DRPATH_KIND=plugin -DBINARY_PATH=${OUTPUT_FILE_PATH} -P "${BN_API_SOURCE_DIR}/cmake/SetElfRpath.cmake") - endif() - add_custom_command( - OUTPUT ${OUTPUT_FILE_PATH} - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} clean ${CARGO_OPTS} --package binaryninjacore-sys - COMMAND ${CMAKE_COMMAND} -E env BINARYNINJADIR=${BINJA_LIB_DIR} ${RUSTUP_COMMAND} build ${CARGO_OPTS} ${CARGO_FEATURES} - COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_DIR}/${OUTPUT_FILE_NAME} ${OUTPUT_FILE_PATH} - COMMAND ${BN_FIX_RPATH_COMMAND} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${PLUGIN_SOURCES} ${API_SOURCES} - ) -endif() diff --git a/plugins/workflow_swift/demo/Cargo.toml b/plugins/workflow_swift/demo/Cargo.toml deleted file mode 100644 index a1e46891f1..0000000000 --- a/plugins/workflow_swift/demo/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "workflow_swift-static" -version = "0.1.0" -edition = "2021" -license = "BSD-3-Clause" -publish = false - -[lib] -crate-type = ["staticlib"] -path = "../src/lib.rs" - -[features] -demo = [] - -[dependencies] -binaryninja = { workspace = true, features = ["demo"] } -binaryninjacore-sys.workspace = true -tracing = "0.1" -thiserror = "2.0" -swift-demangler = { git = "https://github.com/Vector35/swift-demangler.git" } diff --git a/plugins/workflow_swift/demo/build.rs b/plugins/workflow_swift/demo/build.rs deleted file mode 100644 index ed6cec7d27..0000000000 --- a/plugins/workflow_swift/demo/build.rs +++ /dev/null @@ -1,15 +0,0 @@ -fn main() { - let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH") - .expect("DEP_BINARYNINJACORE_PATH not specified"); - - println!("cargo::rustc-link-lib=dylib=binaryninjacore"); - println!("cargo::rustc-link-search={}", link_path.to_str().unwrap()); - - #[cfg(not(target_os = "windows"))] - { - println!( - "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}", - link_path.to_string_lossy() - ); - } -}