Use NDK for building android target objects
This commit is contained in:
parent
1ded138851
commit
0f89eab89d
@ -167,15 +167,18 @@ pub mod write {
|
|||||||
use back::link::{output_type_assembly, output_type_bitcode};
|
use back::link::{output_type_assembly, output_type_bitcode};
|
||||||
use back::link::{output_type_exe, output_type_llvm_assembly};
|
use back::link::{output_type_exe, output_type_llvm_assembly};
|
||||||
use back::link::{output_type_object};
|
use back::link::{output_type_object};
|
||||||
|
use back::link::output_type;
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use driver::session;
|
use driver::session;
|
||||||
use lib::llvm::llvm;
|
use lib::llvm::llvm;
|
||||||
use lib::llvm::{False, True, ModuleRef, mk_pass_manager, mk_target_data};
|
use lib::llvm::{False, True, ModuleRef, mk_pass_manager, mk_target_data};
|
||||||
use lib;
|
use lib;
|
||||||
|
|
||||||
|
use core::prelude::*;
|
||||||
use core::libc::{c_char, c_int, c_uint};
|
use core::libc::{c_char, c_int, c_uint};
|
||||||
use core::path::Path;
|
use core::path::Path;
|
||||||
use core::str;
|
use core::str;
|
||||||
|
use core::run;
|
||||||
|
|
||||||
pub fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
|
pub fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
|
||||||
if ot == output_type_assembly || ot == output_type_object ||
|
if ot == output_type_assembly || ot == output_type_object ||
|
||||||
@ -185,7 +188,8 @@ pub mod write {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_passes(sess: Session, llmod: ModuleRef, output: &Path) {
|
pub fn run_passes(sess: Session, llmod: ModuleRef,
|
||||||
|
output_type: output_type, output: &Path) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let opts = sess.opts;
|
let opts = sess.opts;
|
||||||
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
|
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
|
||||||
@ -201,7 +205,7 @@ pub mod write {
|
|||||||
|
|
||||||
|
|
||||||
if opts.save_temps {
|
if opts.save_temps {
|
||||||
match opts.output_type {
|
match output_type {
|
||||||
output_type_bitcode => {
|
output_type_bitcode => {
|
||||||
if opts.optimize != session::No {
|
if opts.optimize != session::No {
|
||||||
let filename = output.with_filetype("no-opt.bc");
|
let filename = output.with_filetype("no-opt.bc");
|
||||||
@ -262,7 +266,7 @@ pub mod write {
|
|||||||
llvm::LLVMPassManagerBuilderDispose(MPMB);
|
llvm::LLVMPassManagerBuilderDispose(MPMB);
|
||||||
}
|
}
|
||||||
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
|
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
|
||||||
if is_object_or_assembly_or_exe(opts.output_type) || opts.jit {
|
if is_object_or_assembly_or_exe(output_type) || opts.jit {
|
||||||
let LLVMOptNone = 0 as c_int; // -O0
|
let LLVMOptNone = 0 as c_int; // -O0
|
||||||
let LLVMOptLess = 1 as c_int; // -O1
|
let LLVMOptLess = 1 as c_int; // -O1
|
||||||
let LLVMOptDefault = 2 as c_int; // -O2, -Os
|
let LLVMOptDefault = 2 as c_int; // -O2, -Os
|
||||||
@ -290,8 +294,8 @@ pub mod write {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut FileType;
|
let mut FileType;
|
||||||
if opts.output_type == output_type_object ||
|
if output_type == output_type_object ||
|
||||||
opts.output_type == output_type_exe {
|
output_type == output_type_exe {
|
||||||
FileType = lib::llvm::ObjectFile;
|
FileType = lib::llvm::ObjectFile;
|
||||||
} else { FileType = lib::llvm::AssemblyFile; }
|
} else { FileType = lib::llvm::AssemblyFile; }
|
||||||
// Write optimized bitcode if --save-temps was on.
|
// Write optimized bitcode if --save-temps was on.
|
||||||
@ -307,7 +311,7 @@ pub mod write {
|
|||||||
pm = mk_pass_manager();
|
pm = mk_pass_manager();
|
||||||
// Save the assembly file if -S is used
|
// Save the assembly file if -S is used
|
||||||
|
|
||||||
if opts.output_type == output_type_assembly {
|
if output_type == output_type_assembly {
|
||||||
let _: () = str::as_c_str(
|
let _: () = str::as_c_str(
|
||||||
sess.targ_cfg.target_strs.target_triple,
|
sess.targ_cfg.target_strs.target_triple,
|
||||||
|buf_t| {
|
|buf_t| {
|
||||||
@ -328,8 +332,8 @@ pub mod write {
|
|||||||
|
|
||||||
// Save the object file for -c or --save-temps alone
|
// Save the object file for -c or --save-temps alone
|
||||||
// This .o is needed when an exe is built
|
// This .o is needed when an exe is built
|
||||||
if opts.output_type == output_type_object ||
|
if output_type == output_type_object ||
|
||||||
opts.output_type == output_type_exe {
|
output_type == output_type_exe {
|
||||||
let _: () = str::as_c_str(
|
let _: () = str::as_c_str(
|
||||||
sess.targ_cfg.target_strs.target_triple,
|
sess.targ_cfg.target_strs.target_triple,
|
||||||
|buf_t| {
|
|buf_t| {
|
||||||
@ -375,7 +379,7 @@ pub mod write {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.output_type == output_type_llvm_assembly {
|
if output_type == output_type_llvm_assembly {
|
||||||
// Given options "-S --emit-llvm": output LLVM assembly
|
// Given options "-S --emit-llvm": output LLVM assembly
|
||||||
str::as_c_str(output.to_str(), |buf_o| {
|
str::as_c_str(output.to_str(), |buf_o| {
|
||||||
llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
|
llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
|
||||||
@ -391,6 +395,34 @@ pub mod write {
|
|||||||
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
|
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn run_ndk(sess: Session, assembly: &Path, object: &Path) {
|
||||||
|
let cc_prog: ~str = match &sess.opts.android_cross_path {
|
||||||
|
&Some(copy path) => {
|
||||||
|
fmt!("%s/bin/arm-linux-androideabi-gcc", path)
|
||||||
|
}
|
||||||
|
&None => {
|
||||||
|
sess.fatal(~"need Android NDK path for building \
|
||||||
|
(--android-cross-path)")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut cc_args = ~[];
|
||||||
|
cc_args.push(~"-c");
|
||||||
|
cc_args.push(~"-o");
|
||||||
|
cc_args.push(object.to_str());
|
||||||
|
cc_args.push(assembly.to_str());
|
||||||
|
|
||||||
|
let prog = run::program_output(cc_prog, cc_args);
|
||||||
|
|
||||||
|
if prog.status != 0 {
|
||||||
|
sess.err(fmt!("building with `%s` failed with code %d",
|
||||||
|
cc_prog, prog.status));
|
||||||
|
sess.note(fmt!("%s arguments: %s",
|
||||||
|
cc_prog, str::connect(cc_args, ~" ")));
|
||||||
|
sess.note(prog.err + prog.out);
|
||||||
|
sess.abort_if_errors();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,9 +323,23 @@ pub fn compile_rest(sess: Session, cfg: ast::crate_cfg,
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NOTE: Android hack
|
||||||
|
if sess.targ_cfg.arch == session::arch_arm &&
|
||||||
|
(sess.opts.output_type == link::output_type_object ||
|
||||||
|
sess.opts.output_type == link::output_type_exe) {
|
||||||
|
let output_type = link::output_type_assembly;
|
||||||
|
let obj_filename = outputs.obj_filename.with_filetype("s");
|
||||||
|
|
||||||
time(time_passes, ~"LLVM passes", ||
|
time(time_passes, ~"LLVM passes", ||
|
||||||
link::write::run_passes(sess, llmod,
|
link::write::run_passes(sess, llmod, output_type,
|
||||||
|
&obj_filename));
|
||||||
|
|
||||||
|
link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
|
||||||
|
} else {
|
||||||
|
time(time_passes, ~"LLVM passes", ||
|
||||||
|
link::write::run_passes(sess, llmod, sess.opts.output_type,
|
||||||
&outputs.obj_filename));
|
&outputs.obj_filename));
|
||||||
|
}
|
||||||
|
|
||||||
let stop_after_codegen =
|
let stop_after_codegen =
|
||||||
sess.opts.output_type != link::output_type_exe ||
|
sess.opts.output_type != link::output_type_exe ||
|
||||||
|
Loading…
Reference in New Issue
Block a user