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