Skip to content

Commit

Permalink
Add JS linking via a separate feature
Browse files Browse the repository at this point in the history
  • Loading branch information
RReverser committed Apr 28, 2017
1 parent 128aa26 commit b5cec78
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ pub enum NativeLibraryKind {
NativeStatic, // native static library (.a archive)
NativeStaticNobundle, // native static library, which doesn't get bundled into .rlibs
NativeFramework, // macOS-specific
NativeJS, // Emscripten-specific
NativeUnknown, // default way to specify a dynamic library
}

Expand Down
15 changes: 10 additions & 5 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1564,11 +1564,12 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
// Parse string of the form "[KIND=]lib[:new_name]",
// where KIND is one of "dylib", "framework", "static".
let mut parts = s.splitn(2, '=');
let kind = parts.next().unwrap();
let (name, kind) = match (parts.next(), kind) {
let kind_name = parts.next().unwrap();
let (name, kind) = match (parts.next(), kind_name) {
(None, name) => (name, None),
(Some(name), "dylib") => (name, Some(cstore::NativeUnknown)),
(Some(name), "framework") => (name, Some(cstore::NativeFramework)),
(Some(name), "js") => (name, Some(cstore::NativeJS)),
(Some(name), "static") => (name, Some(cstore::NativeStatic)),
(Some(name), "static-nobundle") => (name, Some(cstore::NativeStaticNobundle)),
(_, s) => {
Expand All @@ -1577,9 +1578,13 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
s));
}
};
if kind == Some(cstore::NativeStaticNobundle) && !nightly_options::is_nightly_build() {
early_error(error_format, &format!("the library kind 'static-nobundle' is only \
accepted on the nightly compiler"));
match kind {
Some(cstore::NativeStaticNobundle) | Some(cstore::NativeJS)
if !nightly_options::is_nightly_build() => {
early_error(error_format, &format!("the library kind '{}' is only \
accepted on the nightly compiler", kind_name));
}
_ => {}
}
let mut name_parts = name.splitn(2, ':');
let name = name_parts.next().unwrap();
Expand Down
17 changes: 17 additions & 0 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,22 @@ fn register_native_lib(sess: &Session,
None => sess.err(msg),
}
}
if lib.kind == cstore::NativeJS {
if !sess.target.target.options.is_like_emscripten {
let msg = "JavaScript libraries are only available on Emscripten targets";
match span {
Some(span) => span_err!(sess, span, E0455, "{}", msg),
None => sess.err(msg),
}
}
if !sess.features.borrow().link_js {
feature_gate::emit_feature_err(&sess.parse_sess,
"link_js",
span.unwrap(),
GateIssue::Language,
"kind=\"js\" is feature gated");
}
}
if lib.cfg.is_some() && !sess.features.borrow().link_cfg {
feature_gate::emit_feature_err(&sess.parse_sess,
"link_cfg",
Expand Down Expand Up @@ -1026,6 +1042,7 @@ impl<'a> CrateLoader<'a> {
Some("static-nobundle") => cstore::NativeStaticNobundle,
Some("dylib") => cstore::NativeUnknown,
Some("framework") => cstore::NativeFramework,
Some("js") => cstore::NativeJS,
Some(k) => {
struct_span_err!(self.sess, m.span, E0458,
"unknown kind: `{}`", k)
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_trans/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ fn link_rlib<'a>(sess: &'a Session,
NativeLibraryKind::NativeStatic => {}
NativeLibraryKind::NativeStaticNobundle |
NativeLibraryKind::NativeFramework |
NativeLibraryKind::NativeJS |
NativeLibraryKind::NativeUnknown => continue,
}
ab.add_native_library(&lib.name.as_str());
Expand Down Expand Up @@ -683,6 +684,7 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
for lib in all_native_libs.iter().filter(|l| relevant_lib(sess, l)) {
let name = match lib.kind {
NativeLibraryKind::NativeStaticNobundle |
NativeLibraryKind::NativeJS |
NativeLibraryKind::NativeUnknown => "library",
NativeLibraryKind::NativeFramework => "framework",
// These are included, no need to print them
Expand Down Expand Up @@ -1035,6 +1037,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
match lib.kind {
NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
NativeLibraryKind::NativeJS => cmd.link_js(&lib.name.as_str()),
NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&lib.name.as_str()),
NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(&lib.name.as_str(),
&search_path)
Expand Down Expand Up @@ -1329,6 +1332,7 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: c
}
match lib.kind {
NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
NativeLibraryKind::NativeJS => cmd.link_js(&lib.name.as_str()),
NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
NativeLibraryKind::NativeStaticNobundle => {
// Link "static-nobundle" native libs only if the crate they originate from
Expand Down
14 changes: 14 additions & 0 deletions src/librustc_trans/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pub trait Linker {
fn link_dylib(&mut self, lib: &str);
fn link_rust_dylib(&mut self, lib: &str, path: &Path);
fn link_framework(&mut self, framework: &str);
fn link_js(&mut self, lib: &str);
fn link_staticlib(&mut self, lib: &str);
fn link_rlib(&mut self, lib: &Path);
fn link_whole_rlib(&mut self, lib: &Path);
Expand Down Expand Up @@ -187,6 +188,10 @@ impl<'a> Linker for GccLinker<'a> {
self.cmd.arg("-framework").arg(framework);
}

fn link_js(&mut self, _lib: &str) {
bug!("JS libraries are not supported on macOS")
}

// Here we explicitly ask that the entire archive is included into the
// result artifact. For more details see #15460, but the gist is that
// the linker will strip away any unused objects in the archive if we
Expand Down Expand Up @@ -455,10 +460,15 @@ impl<'a> Linker for MsvcLinker<'a> {
fn framework_path(&mut self, _path: &Path) {
bug!("frameworks are not supported on windows")
}

fn link_framework(&mut self, _framework: &str) {
bug!("frameworks are not supported on windows")
}

fn link_js(&mut self, _lib: &str) {
bug!("JS libraries are not supported on windows")
}

fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
// not supported?
self.link_staticlib(lib);
Expand Down Expand Up @@ -607,6 +617,10 @@ impl<'a> Linker for EmLinker<'a> {
bug!("frameworks are not supported on Emscripten")
}

fn link_js(&mut self, lib: &str) {
self.cmd.args(&["--js-library", lib]);
}

fn gc_sections(&mut self, _keep_metadata: bool) {
// noop
}
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ declare_features! (
// Allows #[link(kind="static-nobundle"...]
(active, static_nobundle, "1.16.0", Some(37403)),

// Allows #[link(kind="js"...)]
(active, link_js, "1.18.0", None),

// `extern "msp430-interrupt" fn()`
(active, abi_msp430_interrupt, "1.16.0", Some(38487)),

Expand Down
20 changes: 20 additions & 0 deletions src/test/compile-fail/emscripten-libraries.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-asmjs
// ignore-wasm32
// ignore-wasm64

#[link(name = "foo", kind = "js")]
extern {}
//~^^ ERROR: JavaScript libraries are only available on Emscripten

fn main() {
}

0 comments on commit b5cec78

Please sign in to comment.