Skip to content

Commit 7603c74

Browse files
committed
fix: IOS sysroot options
There are a few ongoing issues with the current compilation which are fixed: 1. Ensured to provide a correct sysroot required for some of the clang compilers according to rust-lang/rust-bindgen#1229 2. Automated the sysroot search both for ffmpeg build and bingen and ensured that the path is valid (new xcode version appends \n which breaks everythin) 3. Fixed some of the wronly passed parameters and enabled featuers for hardeward decoding on ioss
1 parent a13516c commit 7603c74

File tree

2 files changed

+86
-4
lines changed

2 files changed

+86
-4
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ build-lib-x265 = ["build"]
9696
build-lib-avs = ["build"]
9797
build-lib-xvid = ["build"]
9898

99+
# hardware accelleration
100+
build-videotoolbox = ["build"]
101+
build-audiotoolbox = ["build"]
102+
99103
# protocols
100104
build-lib-smbclient = ["build"]
101105
build-lib-ssh = ["build"]

build.rs

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::env;
77
use std::fmt::Write as FmtWrite;
88
use std::fs::{self, File};
99
use std::io::{self, BufRead, BufReader, Write};
10-
use std::path::PathBuf;
10+
use std::path::{Path, PathBuf};
1111
use std::process::Command;
1212
use std::str;
1313

@@ -195,7 +195,43 @@ fn get_ffmpet_target_os() -> String {
195195
}
196196
}
197197

198-
fn build() -> io::Result<()> {
198+
/// Find the sysroot required for a cross compilation by ffmpeg **and** bindgen
199+
/// @see https://github.com/rust-lang/rust-bindgen/issues/1229
200+
fn find_sysroot() -> Option<String> {
201+
if env::var("CARGO_FEATURE_BUILD").is_err() || env::var("HOST") == env::var("TARGET") {
202+
return None;
203+
}
204+
205+
if let Ok(sysroot) = env::var("SYSROOT") {
206+
return Some(sysroot.to_string());
207+
}
208+
209+
if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("ios") {
210+
let xcode_output = Command::new("xcrun")
211+
.args(["--sdk", "iphoneos", "--show-sdk-path"])
212+
.output()
213+
.expect("failed to run xcrun");
214+
215+
if !xcode_output.status.success() {
216+
panic!("Failed to run xcrun to get the ios sysroot, please install xcode tools or provide sysroot using $SYSROOT env. Error: {}", String::from_utf8_lossy(&xcode_output.stderr));
217+
}
218+
219+
let string = String::from_utf8(xcode_output.stdout)
220+
.expect("Failed to parse xcrun output")
221+
.replace("\n", "");
222+
223+
if !Path::new(&string).exists() {
224+
panic!("xcrun returned invalid sysroot path: {}", string);
225+
}
226+
227+
return Some(string);
228+
}
229+
230+
println!("cargo:warnning=Detected cross compilation but sysroot not provided");
231+
None
232+
}
233+
234+
fn build(sysroot: Option<&str>) -> io::Result<()> {
199235
let source_dir = source();
200236

201237
// Command's path is not relative to command's current_dir
@@ -233,7 +269,27 @@ fn build() -> io::Result<()> {
233269
"--arch={}",
234270
env::var("CARGO_CFG_TARGET_ARCH").unwrap()
235271
));
236-
configure.arg(format!("--target_os={}", get_ffmpet_target_os()));
272+
configure.arg(format!("--target-os={}", get_ffmpet_target_os()));
273+
}
274+
275+
// for ios it is required to provide sysroot for both configure and bindgen
276+
// for macos the easiest way is to run xcrun, for other platform we support $SYSROOT var
277+
if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("ios") {
278+
let sysroot = sysroot.expect("The sysroot is required for ios cross compilation, make sure to have available xcode or provide the $SYSROOT env var");
279+
configure.arg(format!("--sysroot={}", sysroot));
280+
281+
let cc = Command::new("xcrun")
282+
.args(["--sdk", "iphoneos", "-f", "clang"])
283+
.output()
284+
.expect("failed to run xcrun")
285+
.stdout;
286+
287+
configure.arg(format!(
288+
"--cc={}",
289+
str::from_utf8(&cc)
290+
.expect("Failed to parse xcrun output")
291+
.trim()
292+
));
237293
}
238294

239295
// control debug build
@@ -348,6 +404,23 @@ fn build() -> io::Result<()> {
348404
enable!(configure, "BUILD_LIB_AVS", "libavs");
349405
enable!(configure, "BUILD_LIB_XVID", "libxvid");
350406

407+
if env::var("CARGO_FEATURE_BUILD_VIDEOTOOLBOX").is_ok() {
408+
configure.arg("--enable-videotoolbox");
409+
410+
if target != host && env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("ios") {
411+
configure.arg("--extra-cflags=-mios-version-min=11.0");
412+
}
413+
414+
if target != host && env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("macos") {
415+
configure.arg("--extra-cflags=-mmacosx-version-min=10.11");
416+
}
417+
}
418+
419+
if env::var("CARGO_FEATURE_BUILD_AUDIOTOOLBOX").is_ok() {
420+
configure.arg("--enable-audiotoolbox");
421+
configure.arg("--extra-cflags=-mios-version-min=11.0");
422+
}
423+
351424
// other external libraries
352425
enable!(configure, "BUILD_LIB_DRM", "libdrm");
353426
enable!(configure, "BUILD_NVENC", "nvenc");
@@ -671,6 +744,7 @@ fn main() {
671744
let statik = env::var("CARGO_FEATURE_STATIC").is_ok();
672745
let ffmpeg_major_version: u32 = env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap();
673746

747+
let sysroot = find_sysroot();
674748
let include_paths: Vec<PathBuf> = if env::var("CARGO_FEATURE_BUILD").is_ok() {
675749
println!(
676750
"cargo:rustc-link-search=native={}",
@@ -680,7 +754,7 @@ fn main() {
680754
if fs::metadata(search().join("lib").join("libavutil.a")).is_err() {
681755
fs::create_dir_all(output()).expect("failed to create build directory");
682756
fetch().unwrap();
683-
build().unwrap();
757+
build(sysroot.as_deref()).unwrap();
684758
}
685759

686760
// Check additional required libraries.
@@ -1253,6 +1327,10 @@ fn main() {
12531327
.size_t_is_usize(true)
12541328
.parse_callbacks(Box::new(Callbacks));
12551329

1330+
if let Some(sysroot) = sysroot.as_deref() {
1331+
builder = builder.clang_arg(format!("--sysroot={}", sysroot));
1332+
}
1333+
12561334
// The input headers we would like to generate
12571335
// bindings for.
12581336
if env::var("CARGO_FEATURE_AVCODEC").is_ok() {

0 commit comments

Comments
 (0)