forked from touchHLE/touchHLE
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
130 lines (117 loc) · 5.51 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
use cargo_license::{get_dependencies_from_cargo_lock, GetDependenciesOpt};
use std::fmt::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
fn rerun_if_changed(path: &Path) {
println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
}
pub fn main() {
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let package_root = Path::new(env!("CARGO_MANIFEST_DIR"));
// Try to get the version using `git describe`, otherwise fall back to the
// Cargo.toml version. This is used in main.rs
let toml_version = std::env::var("CARGO_PKG_VERSION").unwrap();
let version = Command::new("git").arg("describe").arg("--always").output();
let version = if version.is_ok() && version.as_ref().unwrap().status.success() {
rerun_if_changed(&package_root.join(".git/HEAD"));
rerun_if_changed(&package_root.join(".git/refs"));
let git_version = std::str::from_utf8(&version.unwrap().stdout)
.unwrap()
.trim_end()
.to_string();
if git_version
.strip_prefix('v')
.is_some_and(|v| !v.starts_with(&toml_version))
|| !git_version.starts_with('v')
{
println!("cargo:warning=Cargo.toml version (v{}) is not a prefix of `git describe` version ({})!", toml_version, git_version);
}
git_version
} else {
rerun_if_changed(&package_root.join("Cargo.toml"));
format!("v{} (git rev. unknown)", toml_version)
};
std::fs::write(out_dir.join("version.txt"), version).unwrap();
// Generate a list of dependencies with license and author information.
// This is used in license.rs
let deps = get_dependencies_from_cargo_lock(
Default::default(),
GetDependenciesOpt {
// The goal is to get a list of dependencies which are used in the
// final binary, so we can comply with license terms for binary
// distribution. Therefore, dev- and build-time dependencies don't
// matter.
avoid_dev_deps: true,
avoid_build_deps: true,
direct_deps_only: false,
root_only: false,
},
)
.unwrap();
let mut deps_string = String::new();
for dep in deps {
// Exclude internal packages, they all use the same license and are
// handled specially.
if dep.name.starts_with("touchHLE") {
continue;
}
write!(&mut deps_string, "- {} version {}", dep.name, dep.version).unwrap();
if let Some(authors) = dep.authors {
let authors: Vec<&str> = authors.split('|').collect();
write!(&mut deps_string, " by {}", authors.join(", ")).unwrap();
} else {
write!(&mut deps_string, " (author unspecified)").unwrap();
}
if let Some(license) = dep.license {
write!(&mut deps_string, ", licensed under {}", license).unwrap();
} else {
panic!("Dependency {} has an unspecified license!", dep.name);
}
writeln!(&mut deps_string).unwrap();
}
std::fs::write(out_dir.join("rust_dependencies.txt"), deps_string).unwrap();
rerun_if_changed(&package_root.join("Cargo.lock"));
// Summarise the licensing of Dynarmic
let dynarmic_readme_path = package_root.join("vendor/dynarmic/README.md");
let dynarmic_readme = std::fs::read_to_string(&dynarmic_readme_path).unwrap();
rerun_if_changed(&dynarmic_readme_path);
let dynarmic_license_path = package_root.join("vendor/dynarmic/LICENSE.txt");
let dynarmic_license = std::fs::read_to_string(&dynarmic_license_path).unwrap();
rerun_if_changed(&dynarmic_license_path);
// Attempt to support Windows where git autocrlf may confuse things.
let dynarmic_readme = dynarmic_readme.replace("\r\n", "\n");
let (_, dynarmic_legal) = dynarmic_readme.split_once("\nLegal\n-----\n").unwrap();
// Strip out the code block start and end lines. They're visual noise when
// displayed in ASCII and there's one of these that ends up as its own page
// in the license text viewer!
let dynarmic_legal = dynarmic_legal.replace("\n```\n", "\n");
let dynarmic_license_oneline =
"dynarmic is under a 0BSD license. See LICENSE.txt for more details.";
assert!(dynarmic_legal.contains(dynarmic_license_oneline));
let dynarmic_summary = dynarmic_legal.replace(dynarmic_license_oneline, &dynarmic_license);
std::fs::write(out_dir.join("dynarmic_license.txt"), dynarmic_summary).unwrap();
// libc++_shared.so has to be copied into the APK. See README of cargo-ndk.
if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "android" {
println!("cargo:rustc-link-lib=c++_shared");
let sysroot_libs_path =
PathBuf::from(std::env::var_os("CARGO_NDK_SYSROOT_LIBS_PATH").unwrap());
let lib_path = sysroot_libs_path.join("libc++_shared.so");
std::fs::copy(
lib_path,
// cargo-ndk as invoked by cargo-ndk-android-gradle actually
// copies from the target directory, using this hacky path
// concatenation approach. :(
package_root
.join("target")
.join(std::env::var("TARGET").unwrap())
.join(std::env::var("PROFILE").unwrap())
.join("libc++_shared.so"),
)
.unwrap();
}
}