diff options
| author | bors <bors@rust-lang.org> | 2016-08-21 22:30:46 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-08-21 22:30:46 -0700 |
| commit | c44534ef5a6b95cb032c6ce28c8893cf530903b9 (patch) | |
| tree | 64defd927884f2ffdd0319e3e7ca41ff49dff311 | |
| parent | 42584d36f6a2d8021c0b642ec0cbf1afed750f32 (diff) | |
| parent | c08b7b9f754c6969e3cc630cfea76a8b8ce8876b (diff) | |
| download | rust-c44534ef5a6b95cb032c6ce28c8893cf530903b9.tar.gz rust-c44534ef5a6b95cb032c6ce28c8893cf530903b9.zip | |
Auto merge of #35821 - nbaksalyar:solaris-trans-fix, r=alexcrichton
Fix linker on Solaris/Illumos This patch provides a fix for the `GnuLinker::export_symbols` function that currently relies on a `--retain-symbols-file` option which is not supported by the Solaris & Illumos linker. Instead, a [version script](https://www.gnu.org/software/gnulib/manual/html_node/LD-Version-Scripts.html) is used on this platform to achieve the same goal. Here's an example of a similar approach in LLVM's CMake script: https://github.com/llvm-mirror/llvm/blob/master/cmake/modules/AddLLVM.cmake#L88-L94. Perhaps other platforms like OpenBSD could benefit from this as well. /cc @semarie
| -rw-r--r-- | src/librustc_trans/back/linker.rs | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index cb990ead8e8..f2d5b128d27 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -247,29 +247,49 @@ impl<'a> Linker for GnuLinker<'a> { return } + let mut arg = OsString::new(); let path = tmpdir.join("list"); - let prefix = if self.sess.target.target.options.is_like_osx { - "_" - } else { - "" - }; - let res = (|| -> io::Result<()> { - let mut f = BufWriter::new(File::create(&path)?); - for sym in &self.info.cdylib_exports { - writeln!(f, "{}{}", prefix, sym)?; + + if self.sess.target.target.options.is_like_solaris { + let res = (|| -> io::Result<()> { + let mut f = BufWriter::new(File::create(&path)?); + writeln!(f, "{{\n global:")?; + for sym in &self.info.cdylib_exports { + writeln!(f, " {};", sym)?; + } + writeln!(f, "\n local:\n *;\n}};")?; + Ok(()) + })(); + if let Err(e) = res { + self.sess.fatal(&format!("failed to write version script: {}", e)); } - Ok(()) - })(); - if let Err(e) = res { - self.sess.fatal(&format!("failed to write lib.def file: {}", e)); - } - let mut arg = OsString::new(); - if self.sess.target.target.options.is_like_osx { - arg.push("-Wl,-exported_symbols_list,"); + + arg.push("-Wl,-M,"); + arg.push(&path); } else { - arg.push("-Wl,--retain-symbols-file="); + let prefix = if self.sess.target.target.options.is_like_osx { + "_" + } else { + "" + }; + let res = (|| -> io::Result<()> { + let mut f = BufWriter::new(File::create(&path)?); + for sym in &self.info.cdylib_exports { + writeln!(f, "{}{}", prefix, sym)?; + } + Ok(()) + })(); + if let Err(e) = res { + self.sess.fatal(&format!("failed to write lib.def file: {}", e)); + } + if self.sess.target.target.options.is_like_osx { + arg.push("-Wl,-exported_symbols_list,"); + } else { + arg.push("-Wl,--retain-symbols-file="); + } + arg.push(&path); } - arg.push(&path); + self.cmd.arg(arg); } } |
