From 34bbf432f20e1d89f71940df570a22d14eee268b Mon Sep 17 00:00:00 2001 From: Guillaume Bonnet Date: Sun, 24 Jan 2016 20:40:36 +0100 Subject: [PATCH 1/2] Add support for setting the soname of generated dynamic libraries --- configure | 1 + mk/target.mk | 23 +++++++++++++++++++++++ src/librustc/session/config.rs | 2 ++ src/librustc_trans/back/link.rs | 5 +++++ src/librustc_trans/back/linker.rs | 9 +++++++++ 5 files changed, 40 insertions(+) diff --git a/configure b/configure index 7df98d1bd565d..e2c9600cd91d9 100755 --- a/configure +++ b/configure @@ -595,6 +595,7 @@ opt fast-make 0 "use .gitmodules as timestamp for submodule deps" opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds" opt local-rust 0 "use an installed rustc rather than downloading a snapshot" opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM" +opt soname 0 "set the soname when building dynamic libraries" opt rpath 1 "build rpaths into rustc itself" opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0" # This is used by the automation to produce single-target nightlies diff --git a/mk/target.mk b/mk/target.mk index f90b09479c985..4265be8e870bb 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -25,6 +25,28 @@ RUST_LIB_FLAGS_ST0 += -W warnings RUST_LIB_FLAGS_ST1 += -D warnings RUST_LIB_FLAGS_ST2 += -D warnings +# Macro that declares additional RUST_LIB_FLAGS for a crate at a particular +# stage and target. Currently this is used to set the soname codegen flag. +# +# $(1) - stage +# $(2) - target +# $(3) - crate +define RUST_CRATE_LIB_FLAGS +ifdef CFG_ENABLE_SONAME +# We do not set the soname at stage 0 since the bootstrap compiler does not +# necessarily support it. +ifneq ($(1),0) +RUST_LIB_FLAGS_ST$(1)_$(3)_T_$(2) += \ + -C soname=$$(call CFG_LIB_NAME_$(2),$(3)-$(CFG_FILENAME_EXTRA)) +endif +endif +endef + +$(foreach target,$(CFG_TARGET), \ + $(foreach stage,$(STAGES), \ + $(foreach crate,$(CRATES), \ + $(eval $(call RUST_CRATE_LIB_FLAGS,$(stage),$(target),$(crate)))))) + # Macro that generates the full list of dependencies for a crate at a particular # stage/target/host tuple. # @@ -89,6 +111,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \ $(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(2)) \ $$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) \ $$(RUST_LIB_FLAGS_ST$(1)) \ + $$(RUST_LIB_FLAGS_ST$(1)_$(4)_T_$(2)) \ -L "$$(RT_OUTPUT_DIR_$(2))" \ $$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \ $$(LLVM_STDCPP_RUSTFLAGS_$(2)) \ diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1a99aba591a8c..770a1ee6aa934 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -513,6 +513,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "a list of arguments to pass to llvm (space separated)"), save_temps: bool = (false, parse_bool, "save all temporary output files during compilation"), + soname: Option = (None, parse_opt_string, + "set soname value in ELF shared libraries"), rpath: bool = (false, parse_bool, "set rpath values in libs/exes"), no_prepopulate_passes: bool = (false, parse_bool, diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 0f327d5c84cfd..bc6a35073a3e0 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1044,6 +1044,11 @@ fn link_args(cmd: &mut Linker, cmd.build_dylib(out_filename); } + // Optionally set the soname flag. + if let Some(ref soname) = sess.opts.cg.soname { + cmd.soname(soname); + } + // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 9c445737b10ee..82b5a7a866040 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -54,6 +54,7 @@ pub trait Linker { fn hint_dynamic(&mut self); fn whole_archives(&mut self); fn no_whole_archives(&mut self); + fn soname(&mut self, soname: &str); fn export_symbols(&mut self, sess: &Session, trans: &CrateTranslation, tmpdir: &Path); } @@ -196,6 +197,10 @@ impl<'a> Linker for GnuLinker<'a> { self.cmd.arg("-Wl,-Bdynamic"); } + fn soname(&mut self, soname: &str) { + self.cmd.arg(["-Wl,-soname,", soname].concat()); + } + fn export_symbols(&mut self, _: &Session, _: &CrateTranslation, _: &Path) { // noop, visibility in object files takes care of this } @@ -308,6 +313,10 @@ impl<'a> Linker for MsvcLinker<'a> { fn hint_static(&mut self) {} fn hint_dynamic(&mut self) {} + fn soname(&mut self, _: &str) { + // not supported? + } + // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to // export symbols from a dynamic library. When building a dynamic library, // however, we're going to want some symbols exported, so this function From 69c99cfec1163c0c4e798e3387baae45be4c87cd Mon Sep 17 00:00:00 2001 From: Guillaume Bonnet Date: Mon, 25 Jan 2016 20:01:36 +0100 Subject: [PATCH 2/2] Use -C link-args rather than a new codegen flag to set the soname --- mk/target.mk | 6 +----- src/librustc/session/config.rs | 2 -- src/librustc_trans/back/link.rs | 5 ----- src/librustc_trans/back/linker.rs | 9 --------- 4 files changed, 1 insertion(+), 21 deletions(-) diff --git a/mk/target.mk b/mk/target.mk index 4265be8e870bb..fa65dfa2a34cb 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -33,12 +33,8 @@ RUST_LIB_FLAGS_ST2 += -D warnings # $(3) - crate define RUST_CRATE_LIB_FLAGS ifdef CFG_ENABLE_SONAME -# We do not set the soname at stage 0 since the bootstrap compiler does not -# necessarily support it. -ifneq ($(1),0) RUST_LIB_FLAGS_ST$(1)_$(3)_T_$(2) += \ - -C soname=$$(call CFG_LIB_NAME_$(2),$(3)-$(CFG_FILENAME_EXTRA)) -endif + -C link-args=-Wl,-soname,$$(call CFG_LIB_NAME_$(2),$(3)-$(CFG_FILENAME_EXTRA)) endif endef diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 770a1ee6aa934..1a99aba591a8c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -513,8 +513,6 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "a list of arguments to pass to llvm (space separated)"), save_temps: bool = (false, parse_bool, "save all temporary output files during compilation"), - soname: Option = (None, parse_opt_string, - "set soname value in ELF shared libraries"), rpath: bool = (false, parse_bool, "set rpath values in libs/exes"), no_prepopulate_passes: bool = (false, parse_bool, diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index bc6a35073a3e0..0f327d5c84cfd 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1044,11 +1044,6 @@ fn link_args(cmd: &mut Linker, cmd.build_dylib(out_filename); } - // Optionally set the soname flag. - if let Some(ref soname) = sess.opts.cg.soname { - cmd.soname(soname); - } - // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 82b5a7a866040..9c445737b10ee 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -54,7 +54,6 @@ pub trait Linker { fn hint_dynamic(&mut self); fn whole_archives(&mut self); fn no_whole_archives(&mut self); - fn soname(&mut self, soname: &str); fn export_symbols(&mut self, sess: &Session, trans: &CrateTranslation, tmpdir: &Path); } @@ -197,10 +196,6 @@ impl<'a> Linker for GnuLinker<'a> { self.cmd.arg("-Wl,-Bdynamic"); } - fn soname(&mut self, soname: &str) { - self.cmd.arg(["-Wl,-soname,", soname].concat()); - } - fn export_symbols(&mut self, _: &Session, _: &CrateTranslation, _: &Path) { // noop, visibility in object files takes care of this } @@ -313,10 +308,6 @@ impl<'a> Linker for MsvcLinker<'a> { fn hint_static(&mut self) {} fn hint_dynamic(&mut self) {} - fn soname(&mut self, _: &str) { - // not supported? - } - // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to // export symbols from a dynamic library. When building a dynamic library, // however, we're going to want some symbols exported, so this function