diff --git a/src/lib.rs b/src/lib.rs index f3bf669..e9d4709 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,7 @@ pub struct Config { compiler: Option, archiver: Option, cargo_metadata: bool, + pic: Option, } /// Configuration used to represent an invocation of a C compiler. @@ -134,7 +135,8 @@ impl Config { env: Vec::new(), compiler: None, archiver: None, - cargo_metadata: true + cargo_metadata: true, + pic: None, } } @@ -295,6 +297,15 @@ impl Config { self } + /// Configures whether the compiler will emit position independent code. + /// + /// This option defaults to `false` for `i686` and `windows-gnu` targets and to `true` for all + /// other targets. + pub fn pic(&mut self, pic: bool) -> &mut Config { + self.pic = Some(pic); + self + } + #[doc(hidden)] pub fn __set_env(&mut self, a: A, b: B) -> &mut Config @@ -415,7 +426,7 @@ impl Config { cmd.args.push("-m64".into()); } - if !target.contains("i686") && !target.contains("windows-gnu") { + if self.pic.unwrap_or(!target.contains("i686") && !target.contains("windows-gnu")) { cmd.args.push("-fPIC".into()); } if target.contains("musl") { diff --git a/tests/test.rs b/tests/test.rs index e581548..9683ba3 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -160,6 +160,21 @@ fn gnu_x86_64() { } } +#[test] +fn gnu_x86_64_no_pic() { + for vendor in &["unknown-linux-gnu", "apple-darwin"] { + let target = format!("x86_64-{}", vendor); + let test = Test::gnu(); + test.gcc() + .pic(false) + .target(&target) + .host(&target) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_not_have("-fPIC"); + } +} + #[test] fn gnu_i686() { for vendor in &["unknown-linux-gnu", "apple-darwin"] { @@ -175,6 +190,21 @@ fn gnu_i686() { } } +#[test] +fn gnu_i686_pic() { + for vendor in &["unknown-linux-gnu", "apple-darwin"] { + let target = format!("i686-{}", vendor); + let test = Test::gnu(); + test.gcc() + .pic(true) + .target(&target) + .host(&target) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-fPIC"); + } +} + #[test] fn gnu_set_stdlib() { let test = Test::gnu();