diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index bebf95a4a3ba6..a4593c1cb5afc 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -231,7 +231,7 @@ pub use funcs::bsd43::{shutdown}; #[cfg(windows)] pub use types::os::arch::extra::{HANDLE, BOOL, LPSECURITY_ATTRIBUTES}; #[cfg(windows)] pub use types::os::arch::extra::{LPCSTR, WORD, DWORD, BYTE, FILETIME}; #[cfg(windows)] pub use types::os::arch::extra::{LARGE_INTEGER, LPVOID, LONG}; -#[cfg(windows)] pub use types::os::arch::extra::{time64_t, OVERLAPPED}; +#[cfg(windows)] pub use types::os::arch::extra::{time64_t, OVERLAPPED, LPCWSTR}; #[cfg(windows)] pub use types::os::arch::extra::{LPOVERLAPPED, SIZE_T, LPDWORD}; #[cfg(windows)] pub use funcs::c95::string::{wcslen}; #[cfg(windows)] pub use funcs::posix88::stat_::{wstat, wutime, wchmod, wrmdir}; diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index e4ace2a2b9594..87db2a8362ba0 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -232,6 +232,14 @@ pub fn phase_2_configure_and_expand(sess: &Session, front::config::strip_unconfigured_items(krate)); krate = time(time_passes, "expansion", krate, |krate| { + // Windows dlls do not have rpaths, so they don't know how to find their + // dependencies. It's up to use to tell the system where to find all the + // dependent dlls. Note that this uses cfg!(windows) as opposed to + // targ_cfg because syntax extensions are always loaded for the host + // compiler, not for the target. + if cfg!(windows) { + sess.host_filesearch().add_dylib_search_paths(); + } let cfg = syntax::ext::expand::ExpansionConfig { loader: loader, deriving_hash_type_parameter: sess.features.default_type_params.get(), diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index a72e28eb805b1..ec95ef5db6529 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -13,6 +13,7 @@ use std::cell::RefCell; use std::os; use std::io::fs; +use std::unstable::dynamic_lib::DynamicLibrary; use collections::HashSet; use myfs = util::fs; @@ -132,6 +133,13 @@ impl<'a> FileSearch<'a> { triple: triple, } } + + pub fn add_dylib_search_paths(&self) { + self.for_each_lib_search_path(|lib_search_path| { + DynamicLibrary::add_search_path(lib_search_path); + FileDoesntMatch + }) + } } pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs index 441a60a518626..671cacbbb6f2f 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/unstable/dynamic_lib.rs @@ -15,12 +15,16 @@ Dynamic library facilities. A simple wrapper over the platform's dynamic library facilities */ + use c_str::ToCStr; use cast; -use path; use ops::*; use option::*; +use os; +use path::GenericPath; +use path; use result::*; +use str; pub struct DynamicLibrary { handle: *u8} @@ -59,6 +63,20 @@ impl DynamicLibrary { } } + /// Appends a path to the system search path for dynamic libraries + pub fn add_search_path(path: &path::Path) { + let (envvar, sep) = if cfg!(windows) { + ("PATH", ';' as u8) + } else if cfg!(target_os = "macos") { + ("DYLD_LIBRARY_PATH", ':' as u8) + } else { + ("LD_LIBRARY_PATH", ':' as u8) + }; + let newenv = os::getenv_as_bytes(envvar).unwrap_or(~[]); + let newenv = newenv + &[sep] + path.as_vec(); + os::setenv(envvar, str::from_utf8(newenv).unwrap()); + } + /// Access the value at the symbol of the dynamic library pub unsafe fn symbol(&self, symbol: &str) -> Result { // This function should have a lifetime constraint of 'a on @@ -237,7 +255,6 @@ pub mod dl { FreeLibrary(handle as *libc::c_void); () } - #[link_name = "kernel32"] extern "system" { fn SetLastError(error: libc::size_t); fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void; diff --git a/src/test/auxiliary/syntax-extension-with-dll-deps-1.rs b/src/test/auxiliary/syntax-extension-with-dll-deps-1.rs new file mode 100644 index 0000000000000..a6e17e73322ec --- /dev/null +++ b/src/test/auxiliary/syntax-extension-with-dll-deps-1.rs @@ -0,0 +1,18 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +// force-host + +#![crate_type = "dylib"] + +pub fn the_answer() -> int { + 2 +} diff --git a/src/test/auxiliary/syntax-extension-with-dll-deps-2.rs b/src/test/auxiliary/syntax-extension-with-dll-deps-2.rs new file mode 100644 index 0000000000000..8156e7f0e348d --- /dev/null +++ b/src/test/auxiliary/syntax-extension-with-dll-deps-2.rs @@ -0,0 +1,38 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host +// no-prefer-dynamic + +#![crate_type = "dylib"] +#![feature(macro_registrar, quote, globs)] + +extern crate other = "syntax-extension-with-dll-deps-1"; +extern crate syntax; + +use syntax::ast::{Name, TokenTree, Item, MetaItem}; +use syntax::codemap::Span; +use syntax::ext::base::*; +use syntax::parse::token; + +#[macro_registrar] +pub fn macro_registrar(register: |Name, SyntaxExtension|) { + register(token::intern("foo"), + NormalTT(~BasicMacroExpander { + expander: expand_foo, + span: None, + }, + None)); +} + +fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> ~MacResult { + let answer = other::the_answer(); + MacExpr::new(quote_expr!(cx, $answer)) +} diff --git a/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs b/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs new file mode 100644 index 0000000000000..efae04ea4fc7a --- /dev/null +++ b/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs @@ -0,0 +1,22 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:syntax-extension-with-dll-deps-1.rs +// aux-build:syntax-extension-with-dll-deps-2.rs +// ignore-stage1 + +#![feature(phase)] + +#[phase(syntax)] +extern crate extension = "syntax-extension-with-dll-deps-2"; + +fn main() { + foo!(); +}