2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 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.
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
//! Finds crate binaries and loads their metadata
|
2012-05-15 22:23:06 -05:00
|
|
|
|
2013-12-16 22:58:21 -06:00
|
|
|
use back::archive::{ArchiveRO, METADATA_FILENAME};
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
use driver::session::Session;
|
|
|
|
use lib::llvm::{False, llvm, ObjectFile, mk_section_iter};
|
2013-12-16 22:58:21 -06:00
|
|
|
use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
|
2012-12-23 16:41:37 -06:00
|
|
|
use metadata::decoder;
|
|
|
|
use metadata::encoder;
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
use metadata::filesearch::{FileMatches, FileDoesntMatch};
|
2013-08-31 11:13:04 -05:00
|
|
|
use syntax::codemap::Span;
|
2013-12-31 08:17:59 -06:00
|
|
|
use syntax::diagnostic::SpanHandler;
|
2014-01-09 07:05:33 -06:00
|
|
|
use syntax::parse::token::IdentInterner;
|
2013-12-28 11:16:48 -06:00
|
|
|
use syntax::crateid::CrateId;
|
2013-12-09 15:56:53 -06:00
|
|
|
use syntax::attr;
|
2013-07-19 06:51:37 -05:00
|
|
|
use syntax::attr::AttrMetaMethods;
|
2012-12-23 16:41:37 -06:00
|
|
|
|
2013-08-03 19:13:14 -05:00
|
|
|
use std::c_str::ToCStr;
|
2013-06-28 17:32:26 -05:00
|
|
|
use std::cast;
|
2013-11-11 00:46:32 -06:00
|
|
|
use std::io;
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 11:05:17 -05:00
|
|
|
use std::num;
|
2013-06-28 17:32:26 -05:00
|
|
|
use std::option;
|
|
|
|
use std::os::consts::{macos, freebsd, linux, android, win32};
|
|
|
|
use std::ptr;
|
|
|
|
use std::str;
|
|
|
|
use std::vec;
|
2014-01-24 23:00:31 -06:00
|
|
|
use flate;
|
2012-05-15 22:23:06 -05:00
|
|
|
|
2013-08-31 11:13:04 -05:00
|
|
|
pub enum Os {
|
|
|
|
OsMacos,
|
|
|
|
OsWin32,
|
|
|
|
OsLinux,
|
|
|
|
OsAndroid,
|
|
|
|
OsFreebsd
|
2012-05-22 19:16:26 -05:00
|
|
|
}
|
2012-05-15 22:23:06 -05:00
|
|
|
|
2013-02-19 01:40:42 -06:00
|
|
|
pub struct Context {
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
sess: Session,
|
2013-08-31 11:13:04 -05:00
|
|
|
span: Span,
|
2013-07-31 15:47:32 -05:00
|
|
|
ident: @str,
|
2013-12-09 15:56:53 -06:00
|
|
|
name: @str,
|
|
|
|
version: @str,
|
2013-06-12 12:02:55 -05:00
|
|
|
hash: @str,
|
2013-08-31 11:13:04 -05:00
|
|
|
os: Os,
|
2014-01-09 07:05:33 -06:00
|
|
|
intr: @IdentInterner
|
2013-02-19 01:40:42 -06:00
|
|
|
}
|
2012-05-22 19:16:26 -05:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
pub struct Library {
|
|
|
|
dylib: Option<Path>,
|
|
|
|
rlib: Option<Path>,
|
2013-12-18 16:10:28 -06:00
|
|
|
metadata: MetadataBlob,
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
|
|
|
|
2013-12-16 22:58:21 -06:00
|
|
|
pub struct ArchiveMetadata {
|
|
|
|
priv archive: ArchiveRO,
|
|
|
|
// See comments in ArchiveMetadata::new for why this is static
|
|
|
|
priv data: &'static [u8],
|
|
|
|
}
|
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
impl Context {
|
|
|
|
pub fn load_library_crate(&self) -> Library {
|
|
|
|
match self.find_library_crate() {
|
|
|
|
Some(t) => t,
|
|
|
|
None => {
|
|
|
|
self.sess.span_fatal(self.span,
|
|
|
|
format!("can't find crate for `{}`",
|
|
|
|
self.ident));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 22:23:06 -05:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
fn find_library_crate(&self) -> Option<Library> {
|
|
|
|
let filesearch = self.sess.filesearch;
|
2013-12-09 15:56:53 -06:00
|
|
|
let crate_name = self.name;
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
let (dyprefix, dysuffix) = self.dylibname();
|
2013-02-19 01:40:42 -06:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
|
|
|
|
let dylib_prefix = format!("{}{}-", dyprefix, crate_name);
|
|
|
|
let rlib_prefix = format!("lib{}-", crate_name);
|
2012-05-15 22:23:06 -05:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
let mut matches = ~[];
|
2014-01-13 10:31:57 -06:00
|
|
|
filesearch.search(|path| {
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
match path.filename_str() {
|
|
|
|
None => FileDoesntMatch,
|
|
|
|
Some(file) => {
|
|
|
|
let (candidate, existing) = if file.starts_with(rlib_prefix) &&
|
|
|
|
file.ends_with(".rlib") {
|
|
|
|
debug!("{} is an rlib candidate", path.display());
|
|
|
|
(true, self.add_existing_rlib(matches, path, file))
|
|
|
|
} else if file.starts_with(dylib_prefix) &&
|
|
|
|
file.ends_with(dysuffix) {
|
|
|
|
debug!("{} is a dylib candidate", path.display());
|
|
|
|
(true, self.add_existing_dylib(matches, path, file))
|
|
|
|
} else {
|
|
|
|
(false, false)
|
|
|
|
};
|
2012-05-15 22:23:06 -05:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
if candidate && existing {
|
|
|
|
FileMatches
|
|
|
|
} else if candidate {
|
2013-12-16 22:58:21 -06:00
|
|
|
match get_metadata_section(self.os, path) {
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
Some(cvec) =>
|
2013-12-18 16:10:28 -06:00
|
|
|
if crate_matches(cvec.as_slice(), self.name,
|
|
|
|
self.version, self.hash) {
|
2013-12-28 11:16:48 -06:00
|
|
|
debug!("found {} with matching crate_id",
|
2013-12-18 16:10:28 -06:00
|
|
|
path.display());
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
let (rlib, dylib) = if file.ends_with(".rlib") {
|
|
|
|
(Some(path.clone()), None)
|
|
|
|
} else {
|
|
|
|
(None, Some(path.clone()))
|
|
|
|
};
|
|
|
|
matches.push(Library {
|
|
|
|
rlib: rlib,
|
|
|
|
dylib: dylib,
|
|
|
|
metadata: cvec,
|
|
|
|
});
|
|
|
|
FileMatches
|
|
|
|
} else {
|
2013-12-28 11:16:48 -06:00
|
|
|
debug!("skipping {}, crate_id doesn't match",
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
path.display());
|
|
|
|
FileDoesntMatch
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
debug!("could not load metadata for {}",
|
|
|
|
path.display());
|
|
|
|
FileDoesntMatch
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
FileDoesntMatch
|
|
|
|
}
|
2013-06-24 14:38:14 -05:00
|
|
|
}
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
}
|
2013-11-28 20:03:38 -06:00
|
|
|
});
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
|
|
|
|
match matches.len() {
|
|
|
|
0 => None,
|
|
|
|
1 => Some(matches[0]),
|
|
|
|
_ => {
|
|
|
|
self.sess.span_err(self.span,
|
|
|
|
format!("multiple matching crates for `{}`", crate_name));
|
|
|
|
self.sess.note("candidates:");
|
|
|
|
for lib in matches.iter() {
|
|
|
|
match lib.dylib {
|
|
|
|
Some(ref p) => {
|
|
|
|
self.sess.note(format!("path: {}", p.display()));
|
|
|
|
}
|
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
match lib.rlib {
|
|
|
|
Some(ref p) => {
|
|
|
|
self.sess.note(format!("path: {}", p.display()));
|
|
|
|
}
|
|
|
|
None => {}
|
|
|
|
}
|
2013-12-18 16:10:28 -06:00
|
|
|
let data = lib.metadata.as_slice();
|
|
|
|
let attrs = decoder::get_crate_attributes(data);
|
2013-12-27 18:14:01 -06:00
|
|
|
match attr::find_crateid(attrs) {
|
2013-12-09 15:56:53 -06:00
|
|
|
None => {}
|
2013-12-28 11:16:48 -06:00
|
|
|
Some(crateid) => {
|
|
|
|
note_crateid_attr(self.sess.diagnostic(), &crateid);
|
2013-12-09 15:56:53 -06:00
|
|
|
}
|
|
|
|
}
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
}
|
|
|
|
self.sess.abort_if_errors();
|
2013-06-24 14:38:14 -05:00
|
|
|
None
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_existing_rlib(&self, libs: &mut [Library],
|
|
|
|
path: &Path, file: &str) -> bool {
|
|
|
|
let (prefix, suffix) = self.dylibname();
|
|
|
|
let file = file.slice_from(3); // chop off 'lib'
|
|
|
|
let file = file.slice_to(file.len() - 5); // chop off '.rlib'
|
|
|
|
let file = format!("{}{}{}", prefix, file, suffix);
|
|
|
|
|
|
|
|
for lib in libs.mut_iter() {
|
|
|
|
match lib.dylib {
|
|
|
|
Some(ref p) if p.filename_str() == Some(file.as_slice()) => {
|
2014-01-26 02:43:42 -06:00
|
|
|
assert!(lib.rlib.is_none()); // FIXME: legit compiler error
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
lib.rlib = Some(path.clone());
|
|
|
|
return true;
|
|
|
|
}
|
2013-11-28 20:03:38 -06:00
|
|
|
Some(..) | None => {}
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_existing_dylib(&self, libs: &mut [Library],
|
|
|
|
path: &Path, file: &str) -> bool {
|
|
|
|
let (prefix, suffix) = self.dylibname();
|
|
|
|
let file = file.slice_from(prefix.len());
|
|
|
|
let file = file.slice_to(file.len() - suffix.len());
|
|
|
|
let file = format!("lib{}.rlib", file);
|
|
|
|
|
|
|
|
for lib in libs.mut_iter() {
|
|
|
|
match lib.rlib {
|
|
|
|
Some(ref p) if p.filename_str() == Some(file.as_slice()) => {
|
2014-01-26 02:43:42 -06:00
|
|
|
assert!(lib.dylib.is_none()); // FIXME: legit compiler error
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
lib.dylib = Some(path.clone());
|
|
|
|
return true;
|
|
|
|
}
|
2013-11-28 20:03:38 -06:00
|
|
|
Some(..) | None => {}
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the corresponding (prefix, suffix) that files need to have for
|
|
|
|
// dynamic libraries
|
|
|
|
fn dylibname(&self) -> (&'static str, &'static str) {
|
|
|
|
match self.os {
|
|
|
|
OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
|
|
|
|
OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
|
|
|
|
OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
|
|
|
|
OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX),
|
|
|
|
OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
2013-07-31 15:47:32 -05:00
|
|
|
}
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
|
|
|
|
2013-12-27 15:48:00 -06:00
|
|
|
pub fn note_crateid_attr(diag: @SpanHandler, crateid: &CrateId) {
|
2013-12-28 11:16:48 -06:00
|
|
|
diag.handler().note(format!("crate_id: {}", crateid.to_str()));
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
|
|
|
|
2013-12-18 16:10:28 -06:00
|
|
|
fn crate_matches(crate_data: &[u8],
|
2013-12-09 15:56:53 -06:00
|
|
|
name: @str,
|
|
|
|
version: @str,
|
2013-06-12 12:02:55 -05:00
|
|
|
hash: @str) -> bool {
|
2012-05-15 22:23:06 -05:00
|
|
|
let attrs = decoder::get_crate_attributes(crate_data);
|
2013-12-27 18:14:01 -06:00
|
|
|
match attr::find_crateid(attrs) {
|
2013-12-09 15:56:53 -06:00
|
|
|
None => false,
|
2013-12-28 11:16:48 -06:00
|
|
|
Some(crateid) => {
|
2013-12-09 15:56:53 -06:00
|
|
|
if !hash.is_empty() {
|
|
|
|
let chash = decoder::get_crate_hash(crate_data);
|
|
|
|
if chash != hash { return false; }
|
|
|
|
}
|
2013-12-28 11:16:48 -06:00
|
|
|
name == crateid.name.to_managed() &&
|
|
|
|
(version.is_empty() || version == crateid.version_or_default().to_managed())
|
2013-12-09 15:56:53 -06:00
|
|
|
}
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-16 22:58:21 -06:00
|
|
|
impl ArchiveMetadata {
|
|
|
|
fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
|
|
|
|
let data: &'static [u8] = {
|
|
|
|
let data = match ar.read(METADATA_FILENAME) {
|
|
|
|
Some(data) => data,
|
|
|
|
None => {
|
|
|
|
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// This data is actually a pointer inside of the archive itself, but
|
|
|
|
// we essentially want to cache it because the lookup inside the
|
|
|
|
// archive is a fairly expensive operation (and it's queried for
|
|
|
|
// *very* frequently). For this reason, we transmute it to the
|
|
|
|
// static lifetime to put into the struct. Note that the buffer is
|
|
|
|
// never actually handed out with a static lifetime, but rather the
|
|
|
|
// buffer is loaned with the lifetime of this containing object.
|
|
|
|
// Hence, we're guaranteed that the buffer will never be used after
|
|
|
|
// this object is dead, so this is a safe operation to transmute and
|
|
|
|
// store the data as a static buffer.
|
|
|
|
unsafe { cast::transmute(data) }
|
|
|
|
};
|
|
|
|
Some(ArchiveMetadata {
|
|
|
|
archive: ar,
|
|
|
|
data: data,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_slice<'a>(&'a self) -> &'a [u8] { self.data }
|
|
|
|
}
|
|
|
|
|
|
|
|
// Just a small wrapper to time how long reading metadata takes.
|
|
|
|
fn get_metadata_section(os: Os, filename: &Path) -> Option<MetadataBlob> {
|
|
|
|
use extra::time;
|
|
|
|
let start = time::precise_time_ns();
|
|
|
|
let ret = get_metadata_section_imp(os, filename);
|
|
|
|
info!("reading {} => {}ms", filename.filename_display(),
|
|
|
|
(time::precise_time_ns() - start) / 1000000);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> {
|
Store metadata separately in rlib files
Right now whenever an rlib file is linked against, all of the metadata from the
rlib is pulled in to the final staticlib or binary. The reason for this is that
the metadata is currently stored in a section of the object file. Note that this
is intentional for dynamic libraries in order to distribute metadata bundled
with static libraries.
This commit alters the situation for rlib libraries to instead store the
metadata in a separate file in the archive. In doing so, when the archive is
passed to the linker, none of the metadata will get pulled into the result
executable. Furthermore, the metadata file is skipped when assembling rlibs into
an archive.
The snag in this implementation comes with multiple output formats. When
generating a dylib, the metadata needs to be in the object file, but when
generating an rlib this needs to be separate. In order to accomplish this, the
metadata variable is inserted into an entirely separate LLVM Module which is
then codegen'd into a different location (foo.metadata.o). This is then linked
into dynamic libraries and silently ignored for rlib files.
While changing how metadata is inserted into archives, I have also stopped
compressing metadata when inserted into rlib files. We have wanted to stop
compressing metadata, but the sections it creates in object file sections are
apparently too large. Thankfully if it's just an arbitrary file it doesn't
matter how large it is.
I have seen massive reductions in executable sizes, as well as staticlib output
sizes (to confirm that this is all working).
2013-12-03 19:41:01 -06:00
|
|
|
if filename.filename_str().unwrap().ends_with(".rlib") {
|
2013-12-16 22:58:21 -06:00
|
|
|
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
|
|
|
|
// internally to read the file. We also avoid even using a memcpy by
|
|
|
|
// just keeping the archive along while the metadata is in use.
|
|
|
|
let archive = match ArchiveRO::open(filename) {
|
|
|
|
Some(ar) => ar,
|
|
|
|
None => {
|
|
|
|
debug!("llvm didn't like `{}`", filename.display());
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar));
|
Store metadata separately in rlib files
Right now whenever an rlib file is linked against, all of the metadata from the
rlib is pulled in to the final staticlib or binary. The reason for this is that
the metadata is currently stored in a section of the object file. Note that this
is intentional for dynamic libraries in order to distribute metadata bundled
with static libraries.
This commit alters the situation for rlib libraries to instead store the
metadata in a separate file in the archive. In doing so, when the archive is
passed to the linker, none of the metadata will get pulled into the result
executable. Furthermore, the metadata file is skipped when assembling rlibs into
an archive.
The snag in this implementation comes with multiple output formats. When
generating a dylib, the metadata needs to be in the object file, but when
generating an rlib this needs to be separate. In order to accomplish this, the
metadata variable is inserted into an entirely separate LLVM Module which is
then codegen'd into a different location (foo.metadata.o). This is then linked
into dynamic libraries and silently ignored for rlib files.
While changing how metadata is inserted into archives, I have also stopped
compressing metadata when inserted into rlib files. We have wanted to stop
compressing metadata, but the sections it creates in object file sections are
apparently too large. Thankfully if it's just an arbitrary file it doesn't
matter how large it is.
I have seen massive reductions in executable sizes, as well as staticlib output
sizes (to confirm that this is all working).
2013-12-03 19:41:01 -06:00
|
|
|
}
|
2013-01-23 13:43:58 -06:00
|
|
|
unsafe {
|
Store metadata separately in rlib files
Right now whenever an rlib file is linked against, all of the metadata from the
rlib is pulled in to the final staticlib or binary. The reason for this is that
the metadata is currently stored in a section of the object file. Note that this
is intentional for dynamic libraries in order to distribute metadata bundled
with static libraries.
This commit alters the situation for rlib libraries to instead store the
metadata in a separate file in the archive. In doing so, when the archive is
passed to the linker, none of the metadata will get pulled into the result
executable. Furthermore, the metadata file is skipped when assembling rlibs into
an archive.
The snag in this implementation comes with multiple output formats. When
generating a dylib, the metadata needs to be in the object file, but when
generating an rlib this needs to be separate. In order to accomplish this, the
metadata variable is inserted into an entirely separate LLVM Module which is
then codegen'd into a different location (foo.metadata.o). This is then linked
into dynamic libraries and silently ignored for rlib files.
While changing how metadata is inserted into archives, I have also stopped
compressing metadata when inserted into rlib files. We have wanted to stop
compressing metadata, but the sections it creates in object file sections are
apparently too large. Thankfully if it's just an arbitrary file it doesn't
matter how large it is.
I have seen massive reductions in executable sizes, as well as staticlib output
sizes (to confirm that this is all working).
2013-12-03 19:41:01 -06:00
|
|
|
let mb = filename.with_c_str(|buf| {
|
|
|
|
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
|
|
|
});
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 16:03:29 -06:00
|
|
|
if mb as int == 0 { return None }
|
|
|
|
let of = match ObjectFile::new(mb) {
|
|
|
|
Some(of) => of,
|
|
|
|
_ => return None
|
2013-01-23 13:43:58 -06:00
|
|
|
};
|
2013-08-25 22:21:13 -05:00
|
|
|
let si = mk_section_iter(of.llof);
|
2013-01-23 13:43:58 -06:00
|
|
|
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
|
|
|
|
let name_buf = llvm::LLVMGetSectionName(si.llsi);
|
2013-06-20 00:52:02 -05:00
|
|
|
let name = str::raw::from_c_str(name_buf);
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("get_metadata_section: name {}", name);
|
2013-08-31 11:13:04 -05:00
|
|
|
if read_meta_section_name(os) == name {
|
2013-01-23 13:43:58 -06:00
|
|
|
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
|
|
|
|
let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
|
2013-08-25 22:21:13 -05:00
|
|
|
let mut found = None;
|
2013-06-20 00:52:02 -05:00
|
|
|
let cvbuf: *u8 = cast::transmute(cbuf);
|
|
|
|
let vlen = encoder::metadata_encoding_version.len();
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("checking {} bytes of metadata-version stamp",
|
2013-06-20 00:52:02 -05:00
|
|
|
vlen);
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 11:05:17 -05:00
|
|
|
let minsz = num::min(vlen, csz);
|
2013-06-20 00:52:02 -05:00
|
|
|
let mut version_ok = false;
|
2013-11-21 17:42:55 -06:00
|
|
|
vec::raw::buf_as_slice(cvbuf, minsz, |buf0| {
|
2013-06-20 00:52:02 -05:00
|
|
|
version_ok = (buf0 ==
|
|
|
|
encoder::metadata_encoding_version);
|
2013-11-21 17:42:55 -06:00
|
|
|
});
|
2013-06-20 00:52:02 -05:00
|
|
|
if !version_ok { return None; }
|
|
|
|
|
2013-08-24 22:57:35 -05:00
|
|
|
let cvbuf1 = ptr::offset(cvbuf, vlen as int);
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("inflating {} bytes of compressed metadata",
|
2013-08-25 22:21:13 -05:00
|
|
|
csz - vlen);
|
2013-11-21 17:42:55 -06:00
|
|
|
vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
|
2013-08-25 22:21:13 -05:00
|
|
|
let inflated = flate::inflate_bytes(bytes);
|
2013-12-18 16:10:28 -06:00
|
|
|
found = Some(MetadataVec(inflated));
|
2013-11-21 17:42:55 -06:00
|
|
|
});
|
2013-12-18 16:10:28 -06:00
|
|
|
if found.is_some() {
|
2013-08-25 22:21:13 -05:00
|
|
|
return found;
|
|
|
|
}
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
2013-01-23 13:43:58 -06:00
|
|
|
llvm::LLVMMoveToNextSection(si.llsi);
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
2013-12-18 16:10:28 -06:00
|
|
|
return None;
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-31 11:13:04 -05:00
|
|
|
pub fn meta_section_name(os: Os) -> &'static str {
|
2012-08-06 14:34:08 -05:00
|
|
|
match os {
|
2013-08-31 11:13:04 -05:00
|
|
|
OsMacos => "__DATA,__note.rustc",
|
|
|
|
OsWin32 => ".note.rustc",
|
|
|
|
OsLinux => ".note.rustc",
|
|
|
|
OsAndroid => ".note.rustc",
|
|
|
|
OsFreebsd => ".note.rustc"
|
2012-05-22 19:16:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-31 11:13:04 -05:00
|
|
|
pub fn read_meta_section_name(os: Os) -> &'static str {
|
2013-03-13 03:22:01 -05:00
|
|
|
match os {
|
2013-08-31 11:13:04 -05:00
|
|
|
OsMacos => "__note.rustc",
|
|
|
|
OsWin32 => ".note.rustc",
|
|
|
|
OsLinux => ".note.rustc",
|
|
|
|
OsAndroid => ".note.rustc",
|
|
|
|
OsFreebsd => ".note.rustc"
|
2013-03-13 03:22:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-15 22:23:06 -05:00
|
|
|
// A diagnostic function for dumping crate metadata to an output stream
|
2014-01-09 07:05:33 -06:00
|
|
|
pub fn list_file_metadata(intr: @IdentInterner,
|
2013-08-31 11:13:04 -05:00
|
|
|
os: Os,
|
2013-03-12 15:00:50 -05:00
|
|
|
path: &Path,
|
2013-12-21 17:24:10 -06:00
|
|
|
out: &mut io::Writer) {
|
2013-12-16 22:58:21 -06:00
|
|
|
match get_metadata_section(os, path) {
|
|
|
|
option::Some(bytes) => decoder::list_crate_metadata(intr,
|
|
|
|
bytes.as_slice(),
|
2013-12-18 16:10:28 -06:00
|
|
|
out),
|
2012-08-20 14:23:37 -05:00
|
|
|
option::None => {
|
2013-10-13 20:48:47 -05:00
|
|
|
write!(out, "could not find metadata in {}.\n", path.display())
|
2012-05-15 22:23:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|