1use std::env;
2use std::path::{Path, PathBuf};
3
4fn link_path() -> PathBuf {
5 #[cfg(target_os = "macos")]
6 return PathBuf::from("/Applications/IDA Professional 9.2.app/Contents/MacOS");
7
8 #[cfg(target_os = "linux")]
9 return PathBuf::from(env::var("HOME").unwrap()).join("ida-pro-9.2");
10
11 #[cfg(target_os = "windows")]
12 return PathBuf::from("C:\\Program Files\\IDA Professional 9.2");
13}
14
15pub fn idalib_sdk_paths() -> (PathBuf, PathBuf, PathBuf, PathBuf) {
16 idalib_sdk_paths_with(true)
17}
18
19pub fn idalib_sdk_paths_with(check: bool) -> (PathBuf, PathBuf, PathBuf, PathBuf) {
20 let sdk_path = PathBuf::from(env!("IDALIB_SDK"));
21 let pro_h = sdk_path.join("include").join("pro.h");
22
23 if check && !pro_h.exists() {
24 panic!("`{}` does not exist; SDK is not usable", pro_h.display());
25 }
26
27 let (stubs_path, idalib, ida) = if cfg!(target_os = "linux") {
28 let path = sdk_path.join("lib/x64_linux_gcc_64");
29 let idalib = path.join("libidalib.so");
30 let ida = path.join("libida.so");
31 (path, idalib, ida)
32 } else if cfg!(target_os = "macos") {
33 let path = if cfg!(target_arch = "x86_64") {
34 sdk_path.join("lib/x64_mac_clang_64")
35 } else {
36 sdk_path.join("lib/arm64_mac_clang_64")
37 };
38 let idalib = path.join("libidalib.dylib");
39 let ida = path.join("libida.dylib");
40 (path, idalib, ida)
41 } else if cfg!(target_os = "windows") {
42 let path = sdk_path.join("lib\\x64_win_vc_64");
43 let idalib = path.join("idalib.lib");
44 let ida = path.join("ida.lib");
45 (path, idalib, ida)
46 } else {
47 panic!("unsupported platform");
48 };
49
50 (sdk_path, stubs_path, idalib, ida)
51}
52
53pub fn idalib_install_paths() -> (PathBuf, PathBuf, PathBuf) {
54 idalib_install_paths_with(true)
55}
56
57pub fn idalib_install_paths_with(check: bool) -> (PathBuf, PathBuf, PathBuf) {
58 let path = env::var("IDADIR").map_or_else(|_| link_path(), PathBuf::from);
59
60 let (idalib, ida) = if cfg!(target_os = "linux") {
61 (path.join("libidalib.so"), path.join("libida.so"))
62 } else if cfg!(target_os = "macos") {
63 (path.join("libidalib.dylib"), path.join("libida.dylib"))
64 } else if cfg!(target_os = "windows") {
65 (path.join("idalib.dll"), path.join("ida.dll"))
66 } else {
67 panic!("unsupported platform")
68 };
69
70 if check && !idalib.exists() {
71 panic!(
72 "`{}` does not exist; cannot find a compatible IDA Pro installation",
73 idalib.display()
74 );
75 }
76
77 (path, idalib, ida)
78}
79
80pub fn idalib_library_paths() -> (PathBuf, PathBuf) {
81 idalib_library_paths_with(true)
82}
83
84pub fn idalib_library_paths_with(check: bool) -> (PathBuf, PathBuf) {
85 let (_, idalib, ida) = idalib_install_paths_with(check);
86 (idalib, ida)
87}
88
89fn configure_linkage_aux(path: &Path) {
90 println!("cargo::rustc-link-search=native={}", path.display());
91 if cfg!(target_os = "windows") {
92 println!("cargo::rustc-link-lib=static=ida");
94 println!("cargo::rustc-link-lib=static=idalib");
95 } else {
96 println!("cargo::rustc-link-lib=dylib=ida");
98 println!("cargo::rustc-link-lib=dylib=idalib");
99 }
100}
101
102pub fn configure_idalib_linkage() {
103 let (install_path, _, _) = idalib_install_paths();
104 configure_linkage_aux(&install_path);
105}
106
107pub fn configure_idasdk_linkage() {
108 let (_, stubs_path, _, _) = idalib_sdk_paths();
109 configure_linkage_aux(&stubs_path);
110
111 if cfg!(target_os = "windows") {
112 println!("cargo::rustc-link-arg=/FORCE:UNRESOLVED");
115 }
116}
117
118pub fn configure_linkage() -> anyhow::Result<()> {
119 if cfg!(target_os = "windows") {
120 configure_idasdk_linkage();
121 return Ok(());
122 }
123
124 #[cfg(not(target_os = "windows"))]
125 {
126 let (install_path, _, _) = idalib_install_paths();
127 let (_, stub_path, _, _) = idalib_sdk_paths();
128
129 #[cfg(target_os = "linux")]
130 {
131 println!(
132 "cargo::rustc-link-arg=-Wl,-rpath,{},-L{},-l:libida.so",
133 install_path.display(),
134 stub_path.display(),
135 );
136 println!(
137 "cargo::rustc-link-arg=-Wl,-rpath,{},-L{},-l:libidalib.so",
138 install_path.display(),
139 stub_path.display(),
140 );
141 }
142
143 #[cfg(target_os = "macos")]
144 {
145 println!(
146 "cargo::rustc-link-arg=-Wl,-rpath,{},-L{},-lida",
147 install_path.display(),
148 stub_path.display(),
149 );
150 println!(
151 "cargo::rustc-link-arg=-Wl,-rpath,{},-L{},-lidalib",
152 install_path.display(),
153 stub_path.display(),
154 );
155 }
156 }
157
158 Ok(())
159}