From 5ebd99012ddb83ea27137f121873ade79d06a024 Mon Sep 17 00:00:00 2001 From: Uttarayan Mondal Date: Mon, 5 Feb 2024 15:13:19 +0530 Subject: [PATCH] [feat] Use cc for build --- .justfile | 2 + Cargo.toml | 6 +- build.rs | 319 +++++++++++++++++++++++++++++++---------------------- src/lib.rs | 4 +- 4 files changed, 199 insertions(+), 132 deletions(-) create mode 100644 .justfile diff --git a/.justfile b/.justfile new file mode 100644 index 0000000..e674f0f --- /dev/null +++ b/.justfile @@ -0,0 +1,2 @@ +bindings: + bindgen vendor/jpeglib.h -I diff --git a/Cargo.toml b/Cargo.toml index f3d6a0a..d05fd65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,11 +19,13 @@ nasm-rs = { version = "0.2.5", features = ["parallel"] } sorse = { path = "../sorse/" } [features] -default = ["build", "simd"] +default = ["simd"] +bindgen = [] jpeg80_abi = ["jpeg70_abi"] jpeg70_abi = ["arith_dec", "arith_enc"] arith_enc = [] arith_dec = [] jpegtran = [] simd = [] -build = [] +c_lossless = [] +d_lossless = [] diff --git a/build.rs b/build.rs index f88dd56..18e3b4d 100644 --- a/build.rs +++ b/build.rs @@ -4,97 +4,146 @@ use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::Path; use std::str::FromStr; -// pub type Error = Box; -// pub type Result = std::result::Result; -static MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); +const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); pub fn main() -> Result<()> { let out_dir = env::var("OUT_DIR")?; - #[cfg(all(feature = "build", not(feature = "no-build")))] build(&out_dir)?; + // compile::configure_jconfigint().expect("Configure jconfigint.h"); + // compile::configure_jversion().expect("Configure jversion.h"); + // compile::configure_jconfig().expect("Configure jconfig.h"); + bindgen::builder() + .header(format!("{MANIFEST_DIR}/vendor/jpeglib.h")) + .generate() + .expect("Unable to generate bindings"); + Ok(()) } -#[cfg(all(feature = "build", not(feature = "no-build")))] pub fn build(out_dir: impl AsRef) -> Result<()> { use std::path::PathBuf; env::set_current_dir(&out_dir)?; let mut libjpeg = cc::Build::new(); + libjpeg.flag("-Wno-unused-parameter"); + libjpeg.flag("-Wno-unused-variable"); + libjpeg.flag("-Wno-shift-negative-value"); std::fs::create_dir_all(out_dir.as_ref().join("configured")) .expect("Failed to create configured dir"); - compile::configure_jconfigint().expect("Configure jconfigint.h"); - compile::configure_jversion().expect("Configure jversion.h"); - compile::configure_jconfig().expect("Configure jconfig.h"); + // compile::configure_jconfigint().expect("Configure jconfigint.h"); + // compile::configure_jversion().expect("Configure jversion.h"); + // compile::configure_jconfig().expect("Configure jconfig.h"); libjpeg.include(out_dir.as_ref().join("configured")); libjpeg.include(std::path::PathBuf::from(MANIFEST_DIR).join("vendor")); - // libjpeg.file("libjpeg/jpeglib.h"); - // std::fs::write("/tmp/file.txt", libjpeg.expand())?; let sources = [ - "vendor/jcapimin.c", - "vendor/jcapistd.c", - "vendor/jccoefct.c", - "vendor/jccolor.c", - "vendor/jcdctmgr.c", - "vendor/jchuff.c", - "vendor/jcicc.c", - "vendor/jcinit.c", - "vendor/jcmainct.c", - "vendor/jcmarker.c", - "vendor/jcmaster.c", - "vendor/jcomapi.c", - "vendor/jcparam.c", - "vendor/jcphuff.c", - "vendor/jcprepct.c", - "vendor/jcsample.c", - "vendor/jctrans.c", - "vendor/jdapimin.c", - "vendor/jdapistd.c", - "vendor/jdatadst.c", - "vendor/jdatasrc.c", - "vendor/jdcoefct.c", - "vendor/jdcolor.c", - "vendor/jddctmgr.c", - "vendor/jdhuff.c", - "vendor/jdicc.c", - "vendor/jdinput.c", - "vendor/jdmainct.c", - "vendor/jdmarker.c", - "vendor/jdmaster.c", - "vendor/jdmerge.c", - "vendor/jdphuff.c", - "vendor/jdpostct.c", - "vendor/jdsample.c", - "vendor/jdtrans.c", - "vendor/jerror.c", - "vendor/jfdctflt.c", - "vendor/jfdctfst.c", - "vendor/jfdctint.c", - "vendor/jidctflt.c", - "vendor/jidctfst.c", - "vendor/jidctint.c", - "vendor/jidctred.c", - "vendor/jquant1.c", - "vendor/jquant2.c", - "vendor/jutils.c", - "vendor/jmemmgr.c", - "vendor/jmemnobs.c", + "jcapimin.c", + "jcapistd.c", + "jccoefct.c", + "jccolor.c", + "jcdctmgr.c", + "jcdiffct.c", + "jchuff.c", + "jcicc.c", + "jcinit.c", + "jclhuff.c", + "jclossls.c", + "jcmainct.c", + "jcmarker.c", + "jcmaster.c", + "jcomapi.c", + "jcparam.c", + "jcphuff.c", + "jcprepct.c", + "jcsample.c", + "jctrans.c", + "jdapimin.c", + "jdapistd.c", + "jdatadst.c", + "jdatasrc.c", + "jdcoefct.c", + "jdcolor.c", + "jddctmgr.c", + "jddiffct.c", + "jdhuff.c", + "jdicc.c", + "jdinput.c", + "jdlhuff.c", + "jdlossls.c", + "jdmainct.c", + "jdmarker.c", + "jdmaster.c", + "jdmerge.c", + "jdphuff.c", + "jdpostct.c", + "jdsample.c", + "jdtrans.c", + "jerror.c", + "jfdctflt.c", + "jfdctfst.c", + "jfdctint.c", + "jidctflt.c", + "jidctfst.c", + "jidctint.c", + "jidctred.c", + "jquant1.c", + "jquant2.c", + "jutils.c", + "jmemmgr.c", + "jmemnobs.c", ]; - let sources = sources - .into_iter() - .map(|p| std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(p)); - libjpeg.files(sources); - // libjpeg.file("libjpeg/jsimd.c"); + let jpeg12 = [ + "jcapistd.c", + "jccoefct.c", + "jccolor.c", + "jcdctmgr.c", + "jcdiffct.c", + "jclossls.c", + "jcmainct.c", + "jcprepct.c", + "jcsample.c", + "jdapistd.c", + "jdcoefct.c", + "jdcolor.c", + "jddctmgr.c", + "jddiffct.c", + "jdlossls.c", + "jdmainct.c", + "jdmerge.c", + "jdpostct.c", + "jdsample.c", + "jfdctfst.c", + "jfdctint.c", + "jidctflt.c", + "jidctfst.c", + "jidctint.c", + "jidctred.c", + "jquant1.c", + "jquant2.c", + "jutils.c", + ]; + + let sources = sources.into_iter().map(|p| { + std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("vendor") + .join(p) + }); - #[cfg(feature = "simd")] - let simd = compile::simd::simd()?; + let jpeg12_source = jpeg12.into_iter().map(|p| { + std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("vendor") + .join(p) + }); + + // Build and link to jpeg12 + compile::jpeg(jpeg12_source, compile::BitsInJSample::Bits12)?; + libjpeg.files(sources); println!( "cargo:include={}", @@ -107,34 +156,27 @@ pub fn build(out_dir: impl AsRef) -> Result<()> { // libjpeg.flag(&format!("-L{}", simd.0.to_string_lossy())); // libjpeg.flag(&format!("-l{}", simd.1)); - println!( - "cargo:rustc-link-search=native={}", - simd.0.to_string_lossy() - ); - println!("cargo:rustc-link-lib=static={}", simd.1); libjpeg.flag("-Wno-unused-parameter"); libjpeg.flag("-Wno-unused-variable"); libjpeg.flag("-Wno-shift-negative-value"); // #[cfg(feature = "simd")] - libjpeg.define("WITH_SIMD", None); + // #[cfg(feature = "simd")] + // { + // let simd = compile::simd::simd()?; + // libjpeg.define("WITH_SIMD", None); + // println!( + // "cargo:rustc-link-search=native={}", + // simd.0.to_string_lossy() + // ); + // println!("cargo:rustc-link-lib=static={}", simd.1); + // } libjpeg.compile("jpeg"); - println!( - "cargo:rustc-link-search=native={}", - out_dir.as_ref().join("lib").display() - ); - - // println!( - // "cargo:rustc-link-search=native={}", - // libjpeg.join("lib").display() - // ); - println!("cargo:rustc-link-lib=static=jpeg"); Ok(()) } -#[cfg(all(feature = "build", not(feature = "no-build")))] mod compile { use std::io::Write; use std::path::PathBuf; @@ -146,6 +188,35 @@ mod compile { Jpeg7, } + #[derive(Clone, Copy, Eq, PartialEq, Debug)] + #[repr(u8)] + pub enum BitsInJSample { + Bits8 = 8, + Bits12 = 12, + Bits16 = 16, + } + + pub fn jpeg>( + sources: impl IntoIterator, + bits: BitsInJSample, + ) -> Result<()> { + let mut cc = cc::Build::new(); + cc.flag("-Wno-unused-parameter"); + cc.flag("-Wno-unused-variable"); + cc.flag("-Wno-shift-negative-value"); + cc.define("BITS_IN_JSAMPLE", (bits as u8).to_string().as_str()); + cc.static_flag(true); + cc.files(sources); + // cc.cargo_metadata(false); + let name = format!("jpeg{}", bits as u8); + cc.try_compile(&name)?; + // Ok(PathBuf::from( + // std::env::var_os("OUT_DIR").ok_or_else(|| anyhow::anyhow!("OUT_DIR not set"))?, + // ) + // .join(format!("lib{}.a", name))) + Ok(()) + } + impl FromStr for JpegLib { type Err = Error; @@ -194,7 +265,7 @@ mod compile { } } - pub fn configure_jversion() -> Result<()> { + pub fn configure_jversion() -> Result { let mut jversion = sorse::SorseHeader::new( PathBuf::from(env::var("OUT_DIR")?) .join("configured") @@ -213,36 +284,23 @@ mod compile { jversion.define("JVERSION", "\"6b 27-Mar-1998\""); } } - // #define JCOPYRIGHT \ - // "Copyright (C) 2009-2022 D. R. Commander\n" \ - // "Copyright (C) 2015, 2020 Google, Inc.\n" \ - // "Copyright (C) 2019-2020 Arm Limited\n" \ - // "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ - // "Copyright (C) 2011-2016 Siarhei Siamashka\n" \ - // "Copyright (C) 2015 Intel Corporation\n" \ - // "Copyright (C) 2013-2014 Linaro Limited\n" \ - // "Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \ - // "Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \ - // "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \ - // "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \ - // "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding" jversion.define( - "JCOPYRIGHT \\", + "JCOPYRIGHT", r#" -"Copyright (C) 2009-2022 D. R. Commander\n" \ -"Copyright (C) 2015, 2020 Google, Inc.\n" \ -"Copyright (C) 2019-2020 Arm Limited\n" \ -"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ -"Copyright (C) 2011-2016 Siarhei Siamashka\n" \ -"Copyright (C) 2015 Intel Corporation\n" \ -"Copyright (C) 2013-2014 Linaro Limited\n" \ -"Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \ -"Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \ -"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \ -"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \ -"Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding" -"#, + "Copyright (C) 2009-2022 D. R. Commander\n" \ + "Copyright (C) 2015, 2020 Google, Inc.\n" \ + "Copyright (C) 2019-2020 Arm Limited\n" \ + "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ + "Copyright (C) 2011-2016 Siarhei Siamashka\n" \ + "Copyright (C) 2015 Intel Corporation\n" \ + "Copyright (C) 2013-2014 Linaro Limited\n" \ + "Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \ + "Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \ + "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \ + "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \ + "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding" + "#, ); jversion.define( @@ -251,10 +309,10 @@ mod compile { ); jversion.write()?; - Ok(()) + Ok(jversion.path) } - pub fn configure_jconfigint() -> Result<()> { + pub fn configure_jconfigint() -> Result { let mut jconfigint = sorse::SorseHeader::new( PathBuf::from(env::var("OUT_DIR")?) .join("configured") @@ -282,7 +340,7 @@ mod compile { }; jconfigint.define("THREAD_LOCAL", thread_local); if try_build_c(&format!( - "${thread_local} int i; int main(void) {{ i = 0; return i; }}" + "{thread_local} int i; int main(void) {{ i = 0; return i; }}" )) .is_ok() { @@ -308,23 +366,23 @@ mod compile { } jconfigint.write_all( br##" -#if defined(__has_attribute) -#if __has_attribute(fallthrough) -#define FALLTHROUGH __attribute__((fallthrough)); -#else -#define FALLTHROUGH -#endif -#else -#define FALLTHROUGH -#endif -"##, + #if defined(__has_attribute) + #if __has_attribute(fallthrough) + #define FALLTHROUGH __attribute__((fallthrough)); + #else + #define FALLTHROUGH + #endif + #else + #define FALLTHROUGH + #endif + "##, )?; jconfigint.write()?; - Ok(()) + Ok(jconfigint.path) } - pub fn configure_jconfig() -> Result<()> { + pub fn configure_jconfig() -> Result { let mut jconfig = sorse::SorseHeader::new( PathBuf::from(env::var("OUT_DIR")?) .join("configured") @@ -376,8 +434,9 @@ mod compile { } jconfig.define("BITS_IN_JSAMPLE", "8"); + // jconfig.define("JCONFIG_INCLUDED", None); jconfig.write()?; - Ok(()) + Ok(jconfig.path) } fn inline(compiler: &cc::Tool, force_inline: bool) -> Result<&'static str> { @@ -420,9 +479,9 @@ mod compile { let pwd = env::current_dir()?; env::set_current_dir(out_dir)?; let mut config = cc::Build::new(); - // config.flag("-Wno-unused-parameter"); - // config.flag("-Wno-unused-variable"); - // config.flag("-Wno-shift-negative-value"); + config.flag("-Wno-unused-parameter"); + config.flag("-Wno-unused-variable"); + config.flag("-Wno-shift-negative-value"); std::fs::write("test.c", c)?; config.file("test.c"); env::set_current_dir(pwd)?; @@ -520,6 +579,8 @@ mod compile { neon.flag("-Wno-shift-negative-value"); neon.include(PathBuf::from(MANIFEST_DIR).join("vendor")); neon.include(PathBuf::from(env::var("OUT_DIR")?).join("configured")); + // neon.define("BITS_IN_JSAMPLE", "8"); + // neon.define("JCONFIG_INCLUDED", None); let mut simd_sources = vec![ "arm/jcgray-neon.c", diff --git a/src/lib.rs b/src/lib.rs index 0f953ac..53bdfd6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,3 @@ -// #![no_std] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +#[test] +pub fn test_libjpeg() {}