Skip to content

Commit 59ed6b1

Browse files
committed
Add option to build rust api without linking to core
1 parent 72020bd commit 59ed6b1

File tree

8 files changed

+79
-30
lines changed

8 files changed

+79
-30
lines changed

CMakeLists.txt

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,33 +39,22 @@ if(BinaryNinjaCore_FOUND)
3939
target_link_directories(binaryninjaapi PUBLIC ${BinaryNinjaCore_LIBRARY_DIRS})
4040
target_compile_definitions(binaryninjaapi PUBLIC ${BinaryNinjaCore_DEFINITIONS})
4141
else()
42+
add_subdirectory(stubs EXCLUDE_FROM_ALL)
43+
44+
# Be sure to only link against the stubs archive file
45+
add_dependencies(binaryninjaapi binaryninjacore_stubs)
46+
4247
if(APPLE)
43-
target_link_options(binaryninjaapi PUBLIC -undefined dynamic_lookup)
48+
target_link_libraries(binaryninjaapi PUBLIC "$<TARGET_PROPERTY:binaryninjacore_stubs,ARCHIVE_OUTPUT_DIRECTORY>/$<TARGET_PROPERTY:binaryninjacore_stubs,OUTPUT_NAME>.dylib")
4449
elseif(MSVC)
45-
# Generate stubs.cpp with implementations of all the BNAPI functions
46-
execute_process(COMMAND python ${PROJECT_SOURCE_DIR}/cmake/generate_stubs.py ${PROJECT_SOURCE_DIR}/binaryninjacore.h ${PROJECT_BINARY_DIR}/stubs)
47-
48-
# Compile those stubs into a stub library we can use to fool the linker
49-
add_library(binaryninjacore SHARED ${PROJECT_BINARY_DIR}/stubs/stubs.cpp)
50-
set_target_properties(binaryninjacore
51-
PROPERTIES OUTPUT_NAME binaryninjacore
52-
SOVERSION 1
53-
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/stubs
54-
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/stubs
55-
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/stubs
56-
)
57-
target_include_directories(binaryninjacore PUBLIC ${PROJECT_SOURCE_DIR})
58-
59-
# Be sure to only link against the stubs archive file
60-
add_dependencies(binaryninjaapi binaryninjacore)
6150
if(${CMAKE_GENERATOR} MATCHES "^Visual Studio")
6251
# Visual Studio's generator adds the config to the file path
63-
target_link_libraries(binaryninjaapi PUBLIC "$<TARGET_PROPERTY:binaryninjacore,ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<TARGET_PROPERTY:binaryninjacore,OUTPUT_NAME>.lib")
52+
target_link_libraries(binaryninjaapi PUBLIC "$<TARGET_PROPERTY:binaryninjacore_stubs,ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<TARGET_PROPERTY:binaryninjacore_stubs,OUTPUT_NAME>.lib")
6453
else()
65-
target_link_libraries(binaryninjaapi PUBLIC "$<TARGET_PROPERTY:binaryninjacore,ARCHIVE_OUTPUT_DIRECTORY>/$<TARGET_PROPERTY:binaryninjacore,OUTPUT_NAME>.lib")
54+
target_link_libraries(binaryninjaapi PUBLIC "$<TARGET_PROPERTY:binaryninjacore_stubs,ARCHIVE_OUTPUT_DIRECTORY>/$<TARGET_PROPERTY:binaryninjacore_stubs,OUTPUT_NAME>.lib")
6655
endif()
6756
else()
68-
target_link_options(binaryninjaapi PUBLIC "LINKER:--allow-shlib-undefined")
57+
target_link_libraries(binaryninjaapi PUBLIC "$<TARGET_PROPERTY:binaryninjacore_stubs,ARCHIVE_OUTPUT_DIRECTORY>/$<TARGET_PROPERTY:binaryninjacore_stubs,OUTPUT_NAME>.so.1")
6958
endif()
7059
endif()
7160

Cargo.lock

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,20 @@ rust-version = "1.83.0"
77
license = "Apache-2.0"
88

99
[features]
10+
default = ["core"]
1011
# This is used when statically linking to prevent exporting CorePluginABIVersion and UiPluginABIVersion.
1112
no_exports = []
1213
# Add this if you want to support the demo version of the product.
1314
# This will disable certain functions that do not exist in the demo build.
1415
demo = ["no_exports"]
16+
# If disabled, a stub binaryninjacore library will be generated and linked.
17+
# This feature should only be disabled for shared libraries that will later be loaded in the same process as the real binaryninjacore.
18+
core = ["binaryninjacore-sys/core"]
1519

1620
[dependencies]
1721
log = { version = "0.4", features = ["std"] }
1822
rayon = { version = "1.10", optional = true }
19-
binaryninjacore-sys = { path = "binaryninjacore-sys" }
23+
binaryninjacore-sys = { path = "binaryninjacore-sys", default-features = false}
2024
thiserror = "2.0"
2125
serde = "1.0"
2226
serde_derive = "1.0"

rust/binaryninjacore-sys/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,15 @@ edition = "2021"
77
links = "binaryninjacore"
88
license = "Apache-2.0"
99

10+
[features]
11+
default = ["core"]
12+
# If disabled, a stub binaryninjacore library will be generated and linked.
13+
# This feature should only be disabled for shared libraries that will later be loaded in the same process as the real binaryninjacore.
14+
core = []
15+
1016
[build-dependencies]
1117
bindgen = "0.71.1"
1218
# TODO: Remove this once bindgen correctly pins the version.
1319
# proc-macro2 v1.0.79 does not have https://docs.rs/proc-macro2/1.0.80/proc_macro2/struct.Literal.html#method.c_string
14-
proc-macro2 = ">=1.0.80"
20+
proc-macro2 = ">=1.0.80"
21+
cmake = "0.1"

rust/binaryninjacore-sys/build.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,32 @@ fn link_path() -> PathBuf {
4141
})
4242
}
4343

44+
// Generate and compile stub shared library and return the path to the folder containing the built stub library
45+
fn generate_stubs() -> PathBuf {
46+
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
47+
48+
let api_base_path = std::path::PathBuf::from(manifest_dir)
49+
.join("../../")
50+
.canonicalize()
51+
.unwrap();
52+
53+
let stubs_path = api_base_path.join("stubs");
54+
cmake::build(stubs_path).join("build")
55+
}
56+
4457
fn main() {
4558
println!("cargo:rerun-if-env-changed=BINARYNINJADIR");
4659
println!("cargo:rerun-if-changed=../../binaryninjacore.h");
4760

4861
//Cargo's output directory
4962
let out_dir = env::var("OUT_DIR").unwrap();
5063

51-
let link_path = env::var("BINARYNINJADIR")
52-
.map(PathBuf::from)
53-
.unwrap_or_else(|_| link_path());
64+
let link_path = match env::var("CARGO_FEATURE_CORE") {
65+
Ok(_) => env::var("BINARYNINJADIR")
66+
.map(PathBuf::from)
67+
.unwrap_or_else(|_| link_path()),
68+
Err(_) => generate_stubs(),
69+
};
5470

5571
// Linux builds of binaryninja ship with libbinaryninjacore.so.1 in the
5672
// application folder and no symlink. The linker will attempt to link with

rust/build.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::path::PathBuf;
22

33
fn main() {
4-
let link_path =
5-
std::env::var_os("DEP_BINARYNINJACORE_PATH").expect("DEP_BINARYNINJACORE_PATH specified");
4+
let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH")
5+
.expect("DEP_BINARYNINJACORE_PATH not specified");
66

77
println!("cargo::rustc-link-lib=dylib=binaryninjacore");
88
println!("cargo::rustc-link-search={}", link_path.to_str().unwrap());
@@ -15,7 +15,7 @@ fn main() {
1515
);
1616
}
1717

18-
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR specified");
18+
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not specified");
1919
let out_dir_path = PathBuf::from(out_dir);
2020

2121
// Copy all binaries to OUT_DIR for unit tests.

stubs/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
2+
project(binaryninjacore_stubs)
3+
4+
5+
# Generate stubs.cpp with implementations of all the BNAPI functions
6+
execute_process(COMMAND python ${PROJECT_SOURCE_DIR}/generate_stubs.py ${PROJECT_SOURCE_DIR}/../binaryninjacore.h ${PROJECT_BINARY_DIR})
7+
8+
# Compile those stubs into a stub library we can use to fool the linker
9+
add_library(binaryninjacore_stubs SHARED ${PROJECT_BINARY_DIR}/stubs.cpp)
10+
11+
set_target_properties(binaryninjacore_stubs
12+
PROPERTIES OUTPUT_NAME binaryninjacore
13+
SOVERSION 1
14+
CXX_STANDARD 20
15+
CXX_VISIBILITY_PRESET hidden
16+
CXX_STANDARD_REQUIRED ON
17+
VISIBILITY_INLINES_HIDDEN ON
18+
POSITION_INDEPENDENT_CODE ON
19+
)
20+
21+
target_include_directories(binaryninjacore_stubs PUBLIC ${PROJECT_SOURCE_DIR}/..)
22+
23+
install(TARGETS binaryninjacore_stubs LIBRARY DESTINATION ${PROJECT_BINARY_DIR})
File renamed without changes.

0 commit comments

Comments
 (0)