Skip to content

Commit b5cec78

Browse files
committed
Add JS linking via a separate feature
1 parent 128aa26 commit b5cec78

File tree

7 files changed

+69
-5
lines changed

7 files changed

+69
-5
lines changed

src/librustc/middle/cstore.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub enum NativeLibraryKind {
124124
NativeStatic, // native static library (.a archive)
125125
NativeStaticNobundle, // native static library, which doesn't get bundled into .rlibs
126126
NativeFramework, // macOS-specific
127+
NativeJS, // Emscripten-specific
127128
NativeUnknown, // default way to specify a dynamic library
128129
}
129130

src/librustc/session/config.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -1564,11 +1564,12 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
15641564
// Parse string of the form "[KIND=]lib[:new_name]",
15651565
// where KIND is one of "dylib", "framework", "static".
15661566
let mut parts = s.splitn(2, '=');
1567-
let kind = parts.next().unwrap();
1568-
let (name, kind) = match (parts.next(), kind) {
1567+
let kind_name = parts.next().unwrap();
1568+
let (name, kind) = match (parts.next(), kind_name) {
15691569
(None, name) => (name, None),
15701570
(Some(name), "dylib") => (name, Some(cstore::NativeUnknown)),
15711571
(Some(name), "framework") => (name, Some(cstore::NativeFramework)),
1572+
(Some(name), "js") => (name, Some(cstore::NativeJS)),
15721573
(Some(name), "static") => (name, Some(cstore::NativeStatic)),
15731574
(Some(name), "static-nobundle") => (name, Some(cstore::NativeStaticNobundle)),
15741575
(_, s) => {
@@ -1577,9 +1578,13 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
15771578
s));
15781579
}
15791580
};
1580-
if kind == Some(cstore::NativeStaticNobundle) && !nightly_options::is_nightly_build() {
1581-
early_error(error_format, &format!("the library kind 'static-nobundle' is only \
1582-
accepted on the nightly compiler"));
1581+
match kind {
1582+
Some(cstore::NativeStaticNobundle) | Some(cstore::NativeJS)
1583+
if !nightly_options::is_nightly_build() => {
1584+
early_error(error_format, &format!("the library kind '{}' is only \
1585+
accepted on the nightly compiler", kind_name));
1586+
}
1587+
_ => {}
15831588
}
15841589
let mut name_parts = name.splitn(2, ':');
15851590
let name = name_parts.next().unwrap();

src/librustc_metadata/creader.rs

+17
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,22 @@ fn register_native_lib(sess: &Session,
105105
None => sess.err(msg),
106106
}
107107
}
108+
if lib.kind == cstore::NativeJS {
109+
if !sess.target.target.options.is_like_emscripten {
110+
let msg = "JavaScript libraries are only available on Emscripten targets";
111+
match span {
112+
Some(span) => span_err!(sess, span, E0455, "{}", msg),
113+
None => sess.err(msg),
114+
}
115+
}
116+
if !sess.features.borrow().link_js {
117+
feature_gate::emit_feature_err(&sess.parse_sess,
118+
"link_js",
119+
span.unwrap(),
120+
GateIssue::Language,
121+
"kind=\"js\" is feature gated");
122+
}
123+
}
108124
if lib.cfg.is_some() && !sess.features.borrow().link_cfg {
109125
feature_gate::emit_feature_err(&sess.parse_sess,
110126
"link_cfg",
@@ -1026,6 +1042,7 @@ impl<'a> CrateLoader<'a> {
10261042
Some("static-nobundle") => cstore::NativeStaticNobundle,
10271043
Some("dylib") => cstore::NativeUnknown,
10281044
Some("framework") => cstore::NativeFramework,
1045+
Some("js") => cstore::NativeJS,
10291046
Some(k) => {
10301047
struct_span_err!(self.sess, m.span, E0458,
10311048
"unknown kind: `{}`", k)

src/librustc_trans/back/link.rs

+4
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ fn link_rlib<'a>(sess: &'a Session,
485485
NativeLibraryKind::NativeStatic => {}
486486
NativeLibraryKind::NativeStaticNobundle |
487487
NativeLibraryKind::NativeFramework |
488+
NativeLibraryKind::NativeJS |
488489
NativeLibraryKind::NativeUnknown => continue,
489490
}
490491
ab.add_native_library(&lib.name.as_str());
@@ -683,6 +684,7 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
683684
for lib in all_native_libs.iter().filter(|l| relevant_lib(sess, l)) {
684685
let name = match lib.kind {
685686
NativeLibraryKind::NativeStaticNobundle |
687+
NativeLibraryKind::NativeJS |
686688
NativeLibraryKind::NativeUnknown => "library",
687689
NativeLibraryKind::NativeFramework => "framework",
688690
// These are included, no need to print them
@@ -1035,6 +1037,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
10351037
match lib.kind {
10361038
NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
10371039
NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
1040+
NativeLibraryKind::NativeJS => cmd.link_js(&lib.name.as_str()),
10381041
NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&lib.name.as_str()),
10391042
NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(&lib.name.as_str(),
10401043
&search_path)
@@ -1329,6 +1332,7 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: c
13291332
}
13301333
match lib.kind {
13311334
NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
1335+
NativeLibraryKind::NativeJS => cmd.link_js(&lib.name.as_str()),
13321336
NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
13331337
NativeLibraryKind::NativeStaticNobundle => {
13341338
// Link "static-nobundle" native libs only if the crate they originate from

src/librustc_trans/back/linker.rs

+14
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub trait Linker {
9494
fn link_dylib(&mut self, lib: &str);
9595
fn link_rust_dylib(&mut self, lib: &str, path: &Path);
9696
fn link_framework(&mut self, framework: &str);
97+
fn link_js(&mut self, lib: &str);
9798
fn link_staticlib(&mut self, lib: &str);
9899
fn link_rlib(&mut self, lib: &Path);
99100
fn link_whole_rlib(&mut self, lib: &Path);
@@ -187,6 +188,10 @@ impl<'a> Linker for GccLinker<'a> {
187188
self.cmd.arg("-framework").arg(framework);
188189
}
189190

191+
fn link_js(&mut self, _lib: &str) {
192+
bug!("JS libraries are not supported on macOS")
193+
}
194+
190195
// Here we explicitly ask that the entire archive is included into the
191196
// result artifact. For more details see #15460, but the gist is that
192197
// the linker will strip away any unused objects in the archive if we
@@ -455,10 +460,15 @@ impl<'a> Linker for MsvcLinker<'a> {
455460
fn framework_path(&mut self, _path: &Path) {
456461
bug!("frameworks are not supported on windows")
457462
}
463+
458464
fn link_framework(&mut self, _framework: &str) {
459465
bug!("frameworks are not supported on windows")
460466
}
461467

468+
fn link_js(&mut self, _lib: &str) {
469+
bug!("JS libraries are not supported on windows")
470+
}
471+
462472
fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
463473
// not supported?
464474
self.link_staticlib(lib);
@@ -607,6 +617,10 @@ impl<'a> Linker for EmLinker<'a> {
607617
bug!("frameworks are not supported on Emscripten")
608618
}
609619

620+
fn link_js(&mut self, lib: &str) {
621+
self.cmd.args(&["--js-library", lib]);
622+
}
623+
610624
fn gc_sections(&mut self, _keep_metadata: bool) {
611625
// noop
612626
}

src/libsyntax/feature_gate.rs

+3
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ declare_features! (
321321
// Allows #[link(kind="static-nobundle"...]
322322
(active, static_nobundle, "1.16.0", Some(37403)),
323323

324+
// Allows #[link(kind="js"...)]
325+
(active, link_js, "1.18.0", None),
326+
324327
// `extern "msp430-interrupt" fn()`
325328
(active, abi_msp430_interrupt, "1.16.0", Some(38487)),
326329

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ignore-asmjs
12+
// ignore-wasm32
13+
// ignore-wasm64
14+
15+
#[link(name = "foo", kind = "js")]
16+
extern {}
17+
//~^^ ERROR: JavaScript libraries are only available on Emscripten
18+
19+
fn main() {
20+
}

0 commit comments

Comments
 (0)