Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
e29aa143
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
e29aa143
编写于
8月 11, 2014
作者:
S
Stuart Pernsteiner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
move back::link::write into a separate file
上级
0ab27b1d
变更
7
展开全部
隐藏空白更改
内联
并排
Showing
7 changed file
with
511 addition
and
506 deletion
+511
-506
src/librustc/back/link.rs
src/librustc/back/link.rs
+2
-476
src/librustc/back/lto.rs
src/librustc/back/lto.rs
+4
-3
src/librustc/back/write.rs
src/librustc/back/write.rs
+476
-0
src/librustc/driver/config.rs
src/librustc/driver/config.rs
+8
-8
src/librustc/driver/driver.rs
src/librustc/driver/driver.rs
+18
-17
src/librustc/lib.rs
src/librustc/lib.rs
+1
-0
src/librustdoc/test.rs
src/librustdoc/test.rs
+2
-2
未找到文件。
src/librustc/back/link.rs
浏览文件 @
e29aa143
此差异已折叠。
点击以展开。
src/librustc/back/lto.rs
浏览文件 @
e29aa143
...
...
@@ -9,6 +9,7 @@
// except according to those terms.
use
super
::
link
;
use
super
::
write
;
use
driver
::
session
;
use
driver
::
config
;
use
llvm
;
...
...
@@ -119,9 +120,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
if
!
llvm
::
LLVMRustLinkInExternalBitcode
(
llmod
,
ptr
as
*
const
libc
::
c_char
,
bc_decoded
.len
()
as
libc
::
size_t
)
{
link
::
llvm_err
(
sess
,
format!
(
"failed to load bc of `{}`"
,
name
.as_slice
()));
write
::
llvm_err
(
sess
,
format!
(
"failed to load bc of `{}`"
,
name
.as_slice
()));
}
});
}
...
...
src/librustc/back/write.rs
0 → 100644
浏览文件 @
e29aa143
// 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.
use
back
::
lto
;
use
back
::
link
::
get_cc_prog
;
use
driver
::
driver
::{
CrateTranslation
,
OutputFilenames
};
use
driver
::
config
::
NoDebugInfo
;
use
driver
::
session
::
Session
;
use
driver
::
config
;
use
llvm
;
use
llvm
::{
ModuleRef
,
TargetMachineRef
,
PassManagerRef
};
use
util
::
common
::
time
;
use
syntax
::
abi
;
use
std
::
c_str
::{
ToCStr
,
CString
};
use
std
::
io
::
Command
;
use
std
::
ptr
;
use
std
::
str
;
use
libc
::{
c_uint
,
c_int
};
#[deriving(Clone,
PartialEq,
PartialOrd,
Ord,
Eq)]
pub
enum
OutputType
{
OutputTypeBitcode
,
OutputTypeAssembly
,
OutputTypeLlvmAssembly
,
OutputTypeObject
,
OutputTypeExe
,
}
pub
fn
llvm_err
(
sess
:
&
Session
,
msg
:
String
)
->
!
{
unsafe
{
let
cstr
=
llvm
::
LLVMRustGetLastError
();
if
cstr
==
ptr
::
null
()
{
sess
.fatal
(
msg
.as_slice
());
}
else
{
let
err
=
CString
::
new
(
cstr
,
true
);
let
err
=
String
::
from_utf8_lossy
(
err
.as_bytes
());
sess
.fatal
(
format!
(
"{}: {}"
,
msg
.as_slice
(),
err
.as_slice
())
.as_slice
());
}
}
}
pub
fn
write_output_file
(
sess
:
&
Session
,
target
:
llvm
::
TargetMachineRef
,
pm
:
llvm
::
PassManagerRef
,
m
:
ModuleRef
,
output
:
&
Path
,
file_type
:
llvm
::
FileType
)
{
unsafe
{
output
.with_c_str
(|
output
|
{
let
result
=
llvm
::
LLVMRustWriteOutputFile
(
target
,
pm
,
m
,
output
,
file_type
);
if
!
result
{
llvm_err
(
sess
,
"could not write output"
.to_string
());
}
})
}
}
// On android, we by default compile for armv7 processors. This enables
// things like double word CAS instructions (rather than emulating them)
// which are *far* more efficient. This is obviously undesirable in some
// cases, so if any sort of target feature is specified we don't append v7
// to the feature list.
//
// On iOS only armv7 and newer are supported. So it is useful to
// get all hardware potential via VFP3 (hardware floating point)
// and NEON (SIMD) instructions supported by LLVM.
// Note that without those flags various linking errors might
// arise as some of intrinsics are converted into function calls
// and nobody provides implementations those functions
fn
target_feature
<
'a
>
(
sess
:
&
'a
Session
)
->
&
'a
str
{
match
sess
.targ_cfg.os
{
abi
::
OsAndroid
=>
{
if
""
==
sess
.opts.cg.target_feature
.as_slice
()
{
"+v7"
}
else
{
sess
.opts.cg.target_feature
.as_slice
()
}
},
abi
::
OsiOS
if
sess
.targ_cfg.arch
==
abi
::
Arm
=>
{
"+v7,+thumb2,+vfp3,+neon"
},
_
=>
sess
.opts.cg.target_feature
.as_slice
()
}
}
pub
fn
run_passes
(
sess
:
&
Session
,
trans
:
&
CrateTranslation
,
output_types
:
&
[
OutputType
],
output
:
&
OutputFilenames
)
{
let
llmod
=
trans
.module
;
let
llcx
=
trans
.context
;
unsafe
{
configure_llvm
(
sess
);
if
sess
.opts.cg.save_temps
{
output
.with_extension
(
"no-opt.bc"
)
.with_c_str
(|
buf
|
{
llvm
::
LLVMWriteBitcodeToFile
(
llmod
,
buf
);
})
}
let
opt_level
=
match
sess
.opts.optimize
{
config
::
No
=>
llvm
::
CodeGenLevelNone
,
config
::
Less
=>
llvm
::
CodeGenLevelLess
,
config
::
Default
=>
llvm
::
CodeGenLevelDefault
,
config
::
Aggressive
=>
llvm
::
CodeGenLevelAggressive
,
};
let
use_softfp
=
sess
.opts.cg.soft_float
;
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter.
// FIXME: #11954: mac64 unwinding may not work with fp elim
let
no_fp_elim
=
(
sess
.opts.debuginfo
!=
NoDebugInfo
)
||
(
sess
.targ_cfg.os
==
abi
::
OsMacos
&&
sess
.targ_cfg.arch
==
abi
::
X86_64
);
// OSX has -dead_strip, which doesn't rely on ffunction_sections
// FIXME(#13846) this should be enabled for windows
let
ffunction_sections
=
sess
.targ_cfg.os
!=
abi
::
OsMacos
&&
sess
.targ_cfg.os
!=
abi
::
OsWindows
;
let
fdata_sections
=
ffunction_sections
;
let
reloc_model
=
match
sess
.opts.cg.relocation_model
.as_slice
()
{
"pic"
=>
llvm
::
RelocPIC
,
"static"
=>
llvm
::
RelocStatic
,
"default"
=>
llvm
::
RelocDefault
,
"dynamic-no-pic"
=>
llvm
::
RelocDynamicNoPic
,
_
=>
{
sess
.err
(
format!
(
"{} is not a valid relocation mode"
,
sess
.opts
.cg
.relocation_model
)
.as_slice
());
sess
.abort_if_errors
();
return
;
}
};
let
code_model
=
match
sess
.opts.cg.code_model
.as_slice
()
{
"default"
=>
llvm
::
CodeModelDefault
,
"small"
=>
llvm
::
CodeModelSmall
,
"kernel"
=>
llvm
::
CodeModelKernel
,
"medium"
=>
llvm
::
CodeModelMedium
,
"large"
=>
llvm
::
CodeModelLarge
,
_
=>
{
sess
.err
(
format!
(
"{} is not a valid code model"
,
sess
.opts
.cg
.code_model
)
.as_slice
());
sess
.abort_if_errors
();
return
;
}
};
let
tm
=
sess
.targ_cfg
.target_strs
.target_triple
.as_slice
()
.with_c_str
(|
t
|
{
sess
.opts.cg.target_cpu
.as_slice
()
.with_c_str
(|
cpu
|
{
target_feature
(
sess
)
.with_c_str
(|
features
|
{
llvm
::
LLVMRustCreateTargetMachine
(
t
,
cpu
,
features
,
code_model
,
reloc_model
,
opt_level
,
true
/* EnableSegstk */
,
use_softfp
,
no_fp_elim
,
ffunction_sections
,
fdata_sections
,
)
})
})
});
// Create the two optimizing pass managers. These mirror what clang
// does, and are by populated by LLVM's default PassManagerBuilder.
// Each manager has a different set of passes, but they also share
// some common passes.
let
fpm
=
llvm
::
LLVMCreateFunctionPassManagerForModule
(
llmod
);
let
mpm
=
llvm
::
LLVMCreatePassManager
();
// If we're verifying or linting, add them to the function pass
// manager.
let
addpass
=
|
pass
:
&
str
|
{
pass
.as_slice
()
.with_c_str
(|
s
|
llvm
::
LLVMRustAddPass
(
fpm
,
s
))
};
if
!
sess
.no_verify
()
{
assert
!
(
addpass
(
"verify"
));
}
if
!
sess
.opts.cg.no_prepopulate_passes
{
llvm
::
LLVMRustAddAnalysisPasses
(
tm
,
fpm
,
llmod
);
llvm
::
LLVMRustAddAnalysisPasses
(
tm
,
mpm
,
llmod
);
populate_llvm_passes
(
fpm
,
mpm
,
llmod
,
opt_level
,
trans
.no_builtins
);
}
for
pass
in
sess
.opts.cg.passes
.iter
()
{
pass
.as_slice
()
.with_c_str
(|
s
|
{
if
!
llvm
::
LLVMRustAddPass
(
mpm
,
s
)
{
sess
.warn
(
format!
(
"unknown pass {}, ignoring"
,
*
pass
)
.as_slice
());
}
})
}
// Finally, run the actual optimization passes
time
(
sess
.time_passes
(),
"llvm function passes"
,
(),
|()|
llvm
::
LLVMRustRunFunctionPassManager
(
fpm
,
llmod
));
time
(
sess
.time_passes
(),
"llvm module passes"
,
(),
|()|
llvm
::
LLVMRunPassManager
(
mpm
,
llmod
));
// Deallocate managers that we're now done with
llvm
::
LLVMDisposePassManager
(
fpm
);
llvm
::
LLVMDisposePassManager
(
mpm
);
// Emit the bytecode if we're either saving our temporaries or
// emitting an rlib. Whenever an rlib is created, the bytecode is
// inserted into the archive in order to allow LTO against it.
if
sess
.opts.cg.save_temps
||
(
sess
.crate_types
.borrow
()
.contains
(
&
config
::
CrateTypeRlib
)
&&
sess
.opts.output_types
.contains
(
&
OutputTypeExe
))
{
output
.temp_path
(
OutputTypeBitcode
)
.with_c_str
(|
buf
|
{
llvm
::
LLVMWriteBitcodeToFile
(
llmod
,
buf
);
})
}
if
sess
.lto
()
{
time
(
sess
.time_passes
(),
"all lto passes"
,
(),
|()|
lto
::
run
(
sess
,
llmod
,
tm
,
trans
.reachable
.as_slice
()));
if
sess
.opts.cg.save_temps
{
output
.with_extension
(
"lto.bc"
)
.with_c_str
(|
buf
|
{
llvm
::
LLVMWriteBitcodeToFile
(
llmod
,
buf
);
})
}
}
// A codegen-specific pass manager is used to generate object
// files for an LLVM module.
//
// Apparently each of these pass managers is a one-shot kind of
// thing, so we create a new one for each type of output. The
// pass manager passed to the closure should be ensured to not
// escape the closure itself, and the manager should only be
// used once.
fn
with_codegen
(
tm
:
TargetMachineRef
,
llmod
:
ModuleRef
,
no_builtins
:
bool
,
f
:
|
PassManagerRef
|)
{
unsafe
{
let
cpm
=
llvm
::
LLVMCreatePassManager
();
llvm
::
LLVMRustAddAnalysisPasses
(
tm
,
cpm
,
llmod
);
llvm
::
LLVMRustAddLibraryInfo
(
cpm
,
llmod
,
no_builtins
);
f
(
cpm
);
llvm
::
LLVMDisposePassManager
(
cpm
);
}
}
let
mut
object_file
=
None
;
let
mut
needs_metadata
=
false
;
for
output_type
in
output_types
.iter
()
{
let
path
=
output
.path
(
*
output_type
);
match
*
output_type
{
OutputTypeBitcode
=>
{
path
.with_c_str
(|
buf
|
{
llvm
::
LLVMWriteBitcodeToFile
(
llmod
,
buf
);
})
}
OutputTypeLlvmAssembly
=>
{
path
.with_c_str
(|
output
|
{
with_codegen
(
tm
,
llmod
,
trans
.no_builtins
,
|
cpm
|
{
llvm
::
LLVMRustPrintModule
(
cpm
,
llmod
,
output
);
})
})
}
OutputTypeAssembly
=>
{
// If we're not using the LLVM assembler, this function
// could be invoked specially with output_type_assembly,
// so in this case we still want the metadata object
// file.
let
ty
=
OutputTypeAssembly
;
let
path
=
if
sess
.opts.output_types
.contains
(
&
ty
)
{
path
}
else
{
needs_metadata
=
true
;
output
.temp_path
(
OutputTypeAssembly
)
};
with_codegen
(
tm
,
llmod
,
trans
.no_builtins
,
|
cpm
|
{
write_output_file
(
sess
,
tm
,
cpm
,
llmod
,
&
path
,
llvm
::
AssemblyFile
);
});
}
OutputTypeObject
=>
{
object_file
=
Some
(
path
);
}
OutputTypeExe
=>
{
object_file
=
Some
(
output
.temp_path
(
OutputTypeObject
));
needs_metadata
=
true
;
}
}
}
time
(
sess
.time_passes
(),
"codegen passes"
,
(),
|()|
{
match
object_file
{
Some
(
ref
path
)
=>
{
with_codegen
(
tm
,
llmod
,
trans
.no_builtins
,
|
cpm
|
{
write_output_file
(
sess
,
tm
,
cpm
,
llmod
,
path
,
llvm
::
ObjectFile
);
});
}
None
=>
{}
}
if
needs_metadata
{
with_codegen
(
tm
,
trans
.metadata_module
,
trans
.no_builtins
,
|
cpm
|
{
let
out
=
output
.temp_path
(
OutputTypeObject
)
.with_extension
(
"metadata.o"
);
write_output_file
(
sess
,
tm
,
cpm
,
trans
.metadata_module
,
&
out
,
llvm
::
ObjectFile
);
})
}
});
llvm
::
LLVMRustDisposeTargetMachine
(
tm
);
llvm
::
LLVMDisposeModule
(
trans
.metadata_module
);
llvm
::
LLVMDisposeModule
(
llmod
);
llvm
::
LLVMContextDispose
(
llcx
);
if
sess
.time_llvm_passes
()
{
llvm
::
LLVMRustPrintPassTimings
();
}
}
}
pub
fn
run_assembler
(
sess
:
&
Session
,
outputs
:
&
OutputFilenames
)
{
let
pname
=
get_cc_prog
(
sess
);
let
mut
cmd
=
Command
::
new
(
pname
.as_slice
());
cmd
.arg
(
"-c"
)
.arg
(
"-o"
)
.arg
(
outputs
.path
(
OutputTypeObject
))
.arg
(
outputs
.temp_path
(
OutputTypeAssembly
));
debug!
(
"{}"
,
&
cmd
);
match
cmd
.output
()
{
Ok
(
prog
)
=>
{
if
!
prog
.status
.success
()
{
sess
.err
(
format!
(
"linking with `{}` failed: {}"
,
pname
,
prog
.status
)
.as_slice
());
sess
.note
(
format!
(
"{}"
,
&
cmd
)
.as_slice
());
let
mut
note
=
prog
.error
.clone
();
note
.push_all
(
prog
.output
.as_slice
());
sess
.note
(
str
::
from_utf8
(
note
.as_slice
())
.unwrap
());
sess
.abort_if_errors
();
}
},
Err
(
e
)
=>
{
sess
.err
(
format!
(
"could not exec the linker `{}`: {}"
,
pname
,
e
)
.as_slice
());
sess
.abort_if_errors
();
}
}
}
unsafe
fn
configure_llvm
(
sess
:
&
Session
)
{
use
std
::
sync
::{
Once
,
ONCE_INIT
};
static
mut
INIT
:
Once
=
ONCE_INIT
;
// Copy what clang does by turning on loop vectorization at O2 and
// slp vectorization at O3
let
vectorize_loop
=
!
sess
.opts.cg.no_vectorize_loops
&&
(
sess
.opts.optimize
==
config
::
Default
||
sess
.opts.optimize
==
config
::
Aggressive
);
let
vectorize_slp
=
!
sess
.opts.cg.no_vectorize_slp
&&
sess
.opts.optimize
==
config
::
Aggressive
;
let
mut
llvm_c_strs
=
Vec
::
new
();
let
mut
llvm_args
=
Vec
::
new
();
{
let
add
=
|
arg
:
&
str
|
{
let
s
=
arg
.to_c_str
();
llvm_args
.push
(
s
.as_ptr
());
llvm_c_strs
.push
(
s
);
};
add
(
"rustc"
);
// fake program name
if
vectorize_loop
{
add
(
"-vectorize-loops"
);
}
if
vectorize_slp
{
add
(
"-vectorize-slp"
);
}
if
sess
.time_llvm_passes
()
{
add
(
"-time-passes"
);
}
if
sess
.print_llvm_passes
()
{
add
(
"-debug-pass=Structure"
);
}
for
arg
in
sess
.opts.cg.llvm_args
.iter
()
{
add
((
*
arg
)
.as_slice
());
}
}
INIT
.doit
(||
{
llvm
::
LLVMInitializePasses
();
// Only initialize the platforms supported by Rust here, because
// using --llvm-root will have multiple platforms that rustllvm
// doesn't actually link to and it's pointless to put target info
// into the registry that Rust cannot generate machine code for.
llvm
::
LLVMInitializeX86TargetInfo
();
llvm
::
LLVMInitializeX86Target
();
llvm
::
LLVMInitializeX86TargetMC
();
llvm
::
LLVMInitializeX86AsmPrinter
();
llvm
::
LLVMInitializeX86AsmParser
();
llvm
::
LLVMInitializeARMTargetInfo
();
llvm
::
LLVMInitializeARMTarget
();
llvm
::
LLVMInitializeARMTargetMC
();
llvm
::
LLVMInitializeARMAsmPrinter
();
llvm
::
LLVMInitializeARMAsmParser
();
llvm
::
LLVMInitializeMipsTargetInfo
();
llvm
::
LLVMInitializeMipsTarget
();
llvm
::
LLVMInitializeMipsTargetMC
();
llvm
::
LLVMInitializeMipsAsmPrinter
();
llvm
::
LLVMInitializeMipsAsmParser
();
llvm
::
LLVMRustSetLLVMOptions
(
llvm_args
.len
()
as
c_int
,
llvm_args
.as_ptr
());
});
}
unsafe
fn
populate_llvm_passes
(
fpm
:
llvm
::
PassManagerRef
,
mpm
:
llvm
::
PassManagerRef
,
llmod
:
ModuleRef
,
opt
:
llvm
::
CodeGenOptLevel
,
no_builtins
:
bool
)
{
// Create the PassManagerBuilder for LLVM. We configure it with
// reasonable defaults and prepare it to actually populate the pass
// manager.
let
builder
=
llvm
::
LLVMPassManagerBuilderCreate
();
match
opt
{
llvm
::
CodeGenLevelNone
=>
{
// Don't add lifetime intrinsics at O0
llvm
::
LLVMRustAddAlwaysInlinePass
(
builder
,
false
);
}
llvm
::
CodeGenLevelLess
=>
{
llvm
::
LLVMRustAddAlwaysInlinePass
(
builder
,
true
);
}
// numeric values copied from clang
llvm
::
CodeGenLevelDefault
=>
{
llvm
::
LLVMPassManagerBuilderUseInlinerWithThreshold
(
builder
,
225
);
}
llvm
::
CodeGenLevelAggressive
=>
{
llvm
::
LLVMPassManagerBuilderUseInlinerWithThreshold
(
builder
,
275
);
}
}
llvm
::
LLVMPassManagerBuilderSetOptLevel
(
builder
,
opt
as
c_uint
);
llvm
::
LLVMRustAddBuilderLibraryInfo
(
builder
,
llmod
,
no_builtins
);
// Use the builder to populate the function/module pass managers.
llvm
::
LLVMPassManagerBuilderPopulateFunctionPassManager
(
builder
,
fpm
);
llvm
::
LLVMPassManagerBuilderPopulateModulePassManager
(
builder
,
mpm
);
llvm
::
LLVMPassManagerBuilderDispose
(
builder
);
match
opt
{
llvm
::
CodeGenLevelDefault
|
llvm
::
CodeGenLevelAggressive
=>
{
"mergefunc"
.with_c_str
(|
s
|
llvm
::
LLVMRustAddPass
(
mpm
,
s
));
}
_
=>
{}
};
}
src/librustc/driver/config.rs
浏览文件 @
e29aa143
...
...
@@ -16,7 +16,7 @@
use
driver
::
session
::
Session
;
use
back
;
use
back
::
link
;
use
back
::
write
;
use
back
::
target_strs
;
use
back
::{
arm
,
x86
,
x86_64
,
mips
,
mipsel
};
use
lint
;
...
...
@@ -72,7 +72,7 @@ pub struct Options {
pub
debuginfo
:
DebugInfoLevel
,
pub
lint_opts
:
Vec
<
(
String
,
lint
::
Level
)
>
,
pub
describe_lints
:
bool
,
pub
output_types
:
Vec
<
back
::
link
::
OutputType
>
,
pub
output_types
:
Vec
<
back
::
write
::
OutputType
>
,
// This was mutable for rustpkg, which updates search paths based on the
// parsed code. It remains mutable in case its replacements wants to use
// this.
...
...
@@ -646,11 +646,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
for
unparsed_output_type
in
unparsed_output_types
.iter
()
{
for
part
in
unparsed_output_type
.as_slice
()
.split
(
','
)
{
let
output_type
=
match
part
.as_slice
()
{
"asm"
=>
link
::
OutputTypeAssembly
,
"ir"
=>
link
::
OutputTypeLlvmAssembly
,
"bc"
=>
link
::
OutputTypeBitcode
,
"obj"
=>
link
::
OutputTypeObject
,
"link"
=>
link
::
OutputTypeExe
,
"asm"
=>
write
::
OutputTypeAssembly
,
"ir"
=>
write
::
OutputTypeLlvmAssembly
,
"bc"
=>
write
::
OutputTypeBitcode
,
"obj"
=>
write
::
OutputTypeObject
,
"link"
=>
write
::
OutputTypeExe
,
_
=>
{
early_error
(
format!
(
"unknown emission type: `{}`"
,
part
)
.as_slice
())
...
...
@@ -663,7 +663,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
output_types
.as_mut_slice
()
.sort
();
output_types
.dedup
();
if
output_types
.len
()
==
0
{
output_types
.push
(
link
::
OutputTypeExe
);
output_types
.push
(
write
::
OutputTypeExe
);
}
let
sysroot_opt
=
matches
.opt_str
(
"sysroot"
)
.map
(|
m
|
Path
::
new
(
m
));
...
...
src/librustc/driver/driver.rs
浏览文件 @
e29aa143
...
...
@@ -10,6 +10,7 @@
use
back
::
link
;
use
back
::
write
;
use
driver
::
session
::
Session
;
use
driver
::
config
;
use
front
;
...
...
@@ -473,23 +474,23 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
trans
:
&
CrateTranslation
,
outputs
:
&
OutputFilenames
)
{
if
sess
.opts.cg.no_integrated_as
{
let
output_type
=
link
::
OutputTypeAssembly
;
let
output_type
=
write
::
OutputTypeAssembly
;
time
(
sess
.time_passes
(),
"LLVM passes"
,
(),
|
_
|
link
::
write
::
run_passes
(
sess
,
trans
,
[
output_type
],
outputs
));
write
::
run_passes
(
sess
,
trans
,
[
output_type
],
outputs
));
link
::
write
::
run_assembler
(
sess
,
outputs
);
write
::
run_assembler
(
sess
,
outputs
);
// Remove assembly source, unless --save-temps was specified
if
!
sess
.opts.cg.save_temps
{
fs
::
unlink
(
&
outputs
.temp_path
(
link
::
OutputTypeAssembly
))
.unwrap
();
fs
::
unlink
(
&
outputs
.temp_path
(
write
::
OutputTypeAssembly
))
.unwrap
();
}
}
else
{
time
(
sess
.time_passes
(),
"LLVM passes"
,
(),
|
_
|
link
::
write
::
run_passes
(
sess
,
trans
,
sess
.opts.output_types
.as_slice
(),
outputs
));
write
::
run_passes
(
sess
,
trans
,
sess
.opts.output_types
.as_slice
(),
outputs
));
}
}
...
...
@@ -533,7 +534,7 @@ pub fn stop_after_phase_2(sess: &Session) -> bool {
}
pub
fn
stop_after_phase_5
(
sess
:
&
Session
)
->
bool
{
if
!
sess
.opts.output_types
.iter
()
.any
(|
&
i
|
i
==
link
::
OutputTypeExe
)
{
if
!
sess
.opts.output_types
.iter
()
.any
(|
&
i
|
i
==
write
::
OutputTypeExe
)
{
debug!
(
"not building executable, returning early from compile_input"
);
return
true
;
}
...
...
@@ -549,7 +550,7 @@ fn write_out_deps(sess: &Session,
for
output_type
in
sess
.opts.output_types
.iter
()
{
let
file
=
outputs
.path
(
*
output_type
);
match
*
output_type
{
link
::
OutputTypeExe
=>
{
write
::
OutputTypeExe
=>
{
for
output
in
sess
.crate_types
.borrow
()
.iter
()
{
let
p
=
link
::
filename_for_input
(
sess
,
*
output
,
id
,
&
file
);
...
...
@@ -688,7 +689,7 @@ pub struct OutputFilenames {
}
impl
OutputFilenames
{
pub
fn
path
(
&
self
,
flavor
:
link
::
OutputType
)
->
Path
{
pub
fn
path
(
&
self
,
flavor
:
write
::
OutputType
)
->
Path
{
match
self
.single_output_file
{
Some
(
ref
path
)
=>
return
path
.clone
(),
None
=>
{}
...
...
@@ -696,14 +697,14 @@ pub fn path(&self, flavor: link::OutputType) -> Path {
self
.temp_path
(
flavor
)
}
pub
fn
temp_path
(
&
self
,
flavor
:
link
::
OutputType
)
->
Path
{
pub
fn
temp_path
(
&
self
,
flavor
:
write
::
OutputType
)
->
Path
{
let
base
=
self
.out_directory
.join
(
self
.filestem
());
match
flavor
{
link
::
OutputTypeBitcode
=>
base
.with_extension
(
"bc"
),
link
::
OutputTypeAssembly
=>
base
.with_extension
(
"s"
),
link
::
OutputTypeLlvmAssembly
=>
base
.with_extension
(
"ll"
),
link
::
OutputTypeObject
=>
base
.with_extension
(
"o"
),
link
::
OutputTypeExe
=>
base
,
write
::
OutputTypeBitcode
=>
base
.with_extension
(
"bc"
),
write
::
OutputTypeAssembly
=>
base
.with_extension
(
"s"
),
write
::
OutputTypeLlvmAssembly
=>
base
.with_extension
(
"ll"
),
write
::
OutputTypeObject
=>
base
.with_extension
(
"o"
),
write
::
OutputTypeExe
=>
base
,
}
}
...
...
src/librustc/lib.rs
浏览文件 @
e29aa143
...
...
@@ -69,6 +69,7 @@ pub mod back {
pub
mod
link
;
pub
mod
lto
;
pub
mod
write
;
}
...
...
src/librustdoc/test.rs
浏览文件 @
e29aa143
...
...
@@ -20,7 +20,7 @@
use
std
::
collections
::{
HashSet
,
HashMap
};
use
testing
;
use
rustc
::
back
::
link
;
use
rustc
::
back
::
write
;
use
rustc
::
driver
::
config
;
use
rustc
::
driver
::
driver
;
use
rustc
::
driver
::
session
;
...
...
@@ -120,7 +120,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, externs: core::Exte
maybe_sysroot
:
Some
(
os
::
self_exe_path
()
.unwrap
()
.dir_path
()),
addl_lib_search_paths
:
RefCell
::
new
(
libs
),
crate_types
:
vec!
(
config
::
CrateTypeExecutable
),
output_types
:
vec!
(
link
::
OutputTypeExe
),
output_types
:
vec!
(
write
::
OutputTypeExe
),
no_trans
:
no_run
,
externs
:
externs
,
cg
:
config
::
CodegenOptions
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录