Skip to content

Commit 8c643bb

Browse files
fix: make build feature works on windows (zmwangx#102)
* fix: make building works on windows * fix: make some options only used on msvc * Support also cross compilation to windows from other platforms --------- Co-authored-by: Dmitriy Kovalenko <dmtr.kovalenko@outlook.com>
1 parent f969434 commit 8c643bb

1 file changed

Lines changed: 61 additions & 3 deletions

File tree

build.rs

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ fn fetch() -> io::Result<()> {
163163
let _ = std::fs::remove_dir_all(output_base_path.join(&clone_dest_dir));
164164
let status = Command::new("git")
165165
.current_dir(&output_base_path)
166+
.args(if cfg!(target_os = "windows") {
167+
vec!["-c", "core.autocrlf=false"]
168+
} else {
169+
vec![]
170+
})
166171
.arg("clone")
167172
.arg("--depth=1")
168173
.arg("-b")
@@ -243,13 +248,49 @@ fn find_sysroot() -> Option<String> {
243248

244249
fn build(sysroot: Option<&str>) -> io::Result<()> {
245250
let source_dir = source();
251+
if cfg!(target_os = "windows") {
252+
let path = env::var("PATH").unwrap_or_default();
253+
let mut paths = env::split_paths(&path).collect::<Vec<_>>();
254+
paths.push(source_dir.clone());
255+
let new_path = env::join_paths(paths).unwrap();
256+
257+
let include = env::var("INCLUDE").unwrap_or_default();
258+
let mut includes = env::split_paths(&include).collect::<Vec<_>>();
259+
includes.push(source_dir.clone());
260+
let new_include = env::join_paths(includes).unwrap();
261+
262+
env::set_var("PATH", &new_path);
263+
env::set_var("INCLUDE", &new_include);
264+
}
246265

247266
// Command's path is not relative to command's current_dir
248267
let configure_path = source_dir.join("configure");
249268
assert!(configure_path.exists());
250-
let mut configure = Command::new(&configure_path);
251-
configure.current_dir(&source_dir);
269+
let mut configure = if cfg!(target_os = "windows") {
270+
if Command::new("sh")
271+
.arg("-c")
272+
.arg("echo ok")
273+
.output()
274+
.is_err()
275+
{
276+
return Err(io::Error::new(
277+
io::ErrorKind::Other,
278+
"Failed to find 'sh.exe', which is required for building FFmpeg",
279+
));
280+
}
281+
282+
let mut configure = Command::new("sh");
283+
configure.arg(configure_path);
284+
if cfg!(target_env = "msvc") {
285+
configure.arg("--toolchain=msvc");
286+
}
252287

288+
configure
289+
} else {
290+
Command::new(&configure_path)
291+
};
292+
293+
configure.current_dir(&source_dir);
253294
configure.arg(format!("--prefix={}", search().to_string_lossy()));
254295

255296
let target = env::var("TARGET").unwrap();
@@ -292,6 +333,19 @@ fn build(sysroot: Option<&str>) -> io::Result<()> {
292333
configure.arg("--extra-cflags=-march=native -mtune=native");
293334
}
294335

336+
if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("windows") {
337+
// essential librareis on windowsw
338+
println!("cargo:rustc-link-lib=dylib=ole32");
339+
println!("cargo:rustc-link-lib=dylib=oleaut32");
340+
println!("cargo:rustc-link-lib=dylib=gdi32");
341+
println!("cargo:rustc-link-lib=dylib=user32");
342+
println!("cargo:rustc-link-lib=dylib=vfw32");
343+
println!("cargo:rustc-link-lib=dylib=strmiids");
344+
println!("cargo:rustc-link-lib=dylib=bcrypt");
345+
println!("cargo:rustc-link-lib=dylib=shlwapi");
346+
println!("cargo:rustc-link-lib=dylib=shell32");
347+
}
348+
295349
// for ios it is required to provide sysroot for both configure and bindgen
296350
// for macos the easiest way is to run xcrun, for other platform we support $SYSROOT var
297351
if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("ios") {
@@ -368,7 +422,11 @@ fn build(sysroot: Option<&str>) -> io::Result<()> {
368422
// make it static
369423
configure.arg("--enable-static");
370424
configure.arg("--disable-shared");
371-
configure.arg("--enable-pthreads");
425+
// windows includes threading in the standard library
426+
#[cfg(not(target_env = "msvc"))]
427+
{
428+
configure.arg("--enable-pthreads");
429+
}
372430

373431
// position independent code
374432
configure.arg("--enable-pic");

0 commit comments

Comments
 (0)