Skip to content

Commit 0f89eab

Browse files
committed
Use NDK for building android target objects
1 parent 1ded138 commit 0f89eab

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-11
lines changed

src/librustc/back/link.rs

+41-9
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,18 @@ pub mod write {
167167
use back::link::{output_type_assembly, output_type_bitcode};
168168
use back::link::{output_type_exe, output_type_llvm_assembly};
169169
use back::link::{output_type_object};
170+
use back::link::output_type;
170171
use driver::session::Session;
171172
use driver::session;
172173
use lib::llvm::llvm;
173174
use lib::llvm::{False, True, ModuleRef, mk_pass_manager, mk_target_data};
174175
use lib;
175176

177+
use core::prelude::*;
176178
use core::libc::{c_char, c_int, c_uint};
177179
use core::path::Path;
178180
use core::str;
181+
use core::run;
179182

180183
pub fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
181184
if ot == output_type_assembly || ot == output_type_object ||
@@ -185,7 +188,8 @@ pub mod write {
185188
return false;
186189
}
187190

188-
pub fn run_passes(sess: Session, llmod: ModuleRef, output: &Path) {
191+
pub fn run_passes(sess: Session, llmod: ModuleRef,
192+
output_type: output_type, output: &Path) {
189193
unsafe {
190194
let opts = sess.opts;
191195
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
@@ -201,7 +205,7 @@ pub mod write {
201205

202206

203207
if opts.save_temps {
204-
match opts.output_type {
208+
match output_type {
205209
output_type_bitcode => {
206210
if opts.optimize != session::No {
207211
let filename = output.with_filetype("no-opt.bc");
@@ -262,7 +266,7 @@ pub mod write {
262266
llvm::LLVMPassManagerBuilderDispose(MPMB);
263267
}
264268
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
265-
if is_object_or_assembly_or_exe(opts.output_type) || opts.jit {
269+
if is_object_or_assembly_or_exe(output_type) || opts.jit {
266270
let LLVMOptNone = 0 as c_int; // -O0
267271
let LLVMOptLess = 1 as c_int; // -O1
268272
let LLVMOptDefault = 2 as c_int; // -O2, -Os
@@ -290,8 +294,8 @@ pub mod write {
290294
}
291295

292296
let mut FileType;
293-
if opts.output_type == output_type_object ||
294-
opts.output_type == output_type_exe {
297+
if output_type == output_type_object ||
298+
output_type == output_type_exe {
295299
FileType = lib::llvm::ObjectFile;
296300
} else { FileType = lib::llvm::AssemblyFile; }
297301
// Write optimized bitcode if --save-temps was on.
@@ -307,7 +311,7 @@ pub mod write {
307311
pm = mk_pass_manager();
308312
// Save the assembly file if -S is used
309313

310-
if opts.output_type == output_type_assembly {
314+
if output_type == output_type_assembly {
311315
let _: () = str::as_c_str(
312316
sess.targ_cfg.target_strs.target_triple,
313317
|buf_t| {
@@ -328,8 +332,8 @@ pub mod write {
328332

329333
// Save the object file for -c or --save-temps alone
330334
// This .o is needed when an exe is built
331-
if opts.output_type == output_type_object ||
332-
opts.output_type == output_type_exe {
335+
if output_type == output_type_object ||
336+
output_type == output_type_exe {
333337
let _: () = str::as_c_str(
334338
sess.targ_cfg.target_strs.target_triple,
335339
|buf_t| {
@@ -375,7 +379,7 @@ pub mod write {
375379
return;
376380
}
377381

378-
if opts.output_type == output_type_llvm_assembly {
382+
if output_type == output_type_llvm_assembly {
379383
// Given options "-S --emit-llvm": output LLVM assembly
380384
str::as_c_str(output.to_str(), |buf_o| {
381385
llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
@@ -391,6 +395,34 @@ pub mod write {
391395
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
392396
}
393397
}
398+
399+
pub fn run_ndk(sess: Session, assembly: &Path, object: &Path) {
400+
let cc_prog: ~str = match &sess.opts.android_cross_path {
401+
&Some(copy path) => {
402+
fmt!("%s/bin/arm-linux-androideabi-gcc", path)
403+
}
404+
&None => {
405+
sess.fatal(~"need Android NDK path for building \
406+
(--android-cross-path)")
407+
}
408+
};
409+
let mut cc_args = ~[];
410+
cc_args.push(~"-c");
411+
cc_args.push(~"-o");
412+
cc_args.push(object.to_str());
413+
cc_args.push(assembly.to_str());
414+
415+
let prog = run::program_output(cc_prog, cc_args);
416+
417+
if prog.status != 0 {
418+
sess.err(fmt!("building with `%s` failed with code %d",
419+
cc_prog, prog.status));
420+
sess.note(fmt!("%s arguments: %s",
421+
cc_prog, str::connect(cc_args, ~" ")));
422+
sess.note(prog.err + prog.out);
423+
sess.abort_if_errors();
424+
}
425+
}
394426
}
395427
396428

src/librustc/driver/driver.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,23 @@ pub fn compile_rest(sess: Session, cfg: ast::crate_cfg,
323323

324324
};
325325

326-
time(time_passes, ~"LLVM passes", ||
327-
link::write::run_passes(sess, llmod,
326+
// NOTE: Android hack
327+
if sess.targ_cfg.arch == session::arch_arm &&
328+
(sess.opts.output_type == link::output_type_object ||
329+
sess.opts.output_type == link::output_type_exe) {
330+
let output_type = link::output_type_assembly;
331+
let obj_filename = outputs.obj_filename.with_filetype("s");
332+
333+
time(time_passes, ~"LLVM passes", ||
334+
link::write::run_passes(sess, llmod, output_type,
335+
&obj_filename));
336+
337+
link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
338+
} else {
339+
time(time_passes, ~"LLVM passes", ||
340+
link::write::run_passes(sess, llmod, sess.opts.output_type,
328341
&outputs.obj_filename));
342+
}
329343

330344
let stop_after_codegen =
331345
sess.opts.output_type != link::output_type_exe ||

0 commit comments

Comments
 (0)