diff --git a/configure b/configure index 884ececa24b..0c4afa0566d 100755 --- a/configure +++ b/configure @@ -439,6 +439,10 @@ then probe CFG_ZCAT zcat fi +step_msg "looking for target specific programs" + +probe CFG_ADB adb + if [ ! -z "$CFG_PANDOC" ] then PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc ' | diff --git a/mk/install.mk b/mk/install.mk index a84f527a165..5fa477a790d 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -154,3 +154,76 @@ uninstall: done $(Q)rm -Rf $(PHL)/rustc $(Q)rm -f $(PREFIX_ROOT)/share/man/man1/rustc.1 + +# target platform specific variables +# for arm-linux-androidabi +define DEF_ADB_DEVICE_STATUS +CFG_ADB_DEVICE_STATUS=$(1) +endef + +$(foreach target,$(CFG_TARGET_TRIPLES), \ + $(if $(findstring $(target),"arm-linux-androideabi"), \ + $(if $(findstring adb,$(CFG_ADB)), \ + $(if $(findstring device,$(shell adb devices 2>/dev/null | grep -E '^[_A-Za-z0-9-]+[[:blank:]]+device')), \ + $(info install: install-runtime-target for $(target) enabled \ + $(info install: android device attached) \ + $(eval $(call DEF_ADB_DEVICE_STATUS, true))), \ + $(info install: install-runtime-target for $(target) disabled \ + $(info install: android device not attached) \ + $(eval $(call DEF_ADB_DEVICE_STATUS, false))) \ + ), \ + $(info install: install-runtime-target for $(target) disabled \ + $(info install: adb not found) \ + $(eval $(call DEF_ADB_DEVICE_STATUS, false))) \ + ), \ + ) \ +) + +ifeq (install-runtime-target,$(firstword $(MAKECMDGOALS))) +$(eval $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)):;@:) +L_TOKEN := $(word 2,$(MAKECMDGOALS)) +ifeq ($(L_TOKEN),) +CFG_RUNTIME_PUSH_DIR=/system/lib +else +CFG_RUNTIME_PUSH_DIR=$(L_TOKEN) +endif + +ifeq ($(CFG_ADB_DEVICE_STATUS),true) +ifdef VERBOSE + ADB = adb $(1) + ADB_PUSH = adb push $(1) $(2) + ADB_SHELL = adb shell $(1) $(2) +else + ADB = $(Q)$(call E, adb $(1)) && adb $(1) 1>/dev/null + ADB_PUSH = $(Q)$(call E, adb push $(1)) && adb push $(1) $(2) 1>/dev/null + ADB_SHELL = $(Q)$(call E, adb shell $(1) $(2)) && adb shell $(1) $(2) 1>/dev/null +endif + +define INSTALL_RUNTIME_TARGET_N +install-runtime-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2)) + $(Q)$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR)) + $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(CFG_RUNTIME_$(1)),$(CFG_RUNTIME_PUSH_DIR)) + $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(CORELIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR)) + $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(STDLIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR)) +endef + +define INSTALL_RUNTIME_TARGET_CLEANUP_N +install-runtime-target-$(1)-cleanup: + $(Q)$(call ADB,remount) + $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(CFG_RUNTIME_$(1))) + $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(CORELIB_GLOB_$(1))) + $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(STDLIB_GLOB_$(1))) +endef + +$(eval $(call INSTALL_RUNTIME_TARGET_N,arm-linux-androideabi,$(CFG_BUILD_TRIPLE))) +$(eval $(call INSTALL_RUNTIME_TARGET_CLEANUP_N,arm-linux-androideabi)) + +install-runtime-target: \ + install-runtime-target-arm-linux-androideabi-cleanup \ + install-runtime-target-arm-linux-androideabi-host-$(CFG_BUILD_TRIPLE) +else +install-runtime-target: + @echo "No device to install runtime library" + @echo +endif +endif diff --git a/mk/tests.mk b/mk/tests.mk index 175e33c6654..a04ec3e6514 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -92,6 +92,43 @@ endef $(foreach target,$(CFG_TARGET_TRIPLES), \ $(eval $(call DEF_TARGET_COMMANDS,$(target)))) +# Target platform specific variables +# for arm-linux-androidabi +define DEF_ADB_DEVICE_STATUS +CFG_ADB_DEVICE_STATUS=$(1) +endef + +$(foreach target,$(CFG_TARGET_TRIPLES), \ + $(if $(findstring $(target),"arm-linux-androideabi"), \ + $(if $(findstring adb,$(CFG_ADB)), \ + $(if $(findstring device,$(shell adb devices 2>/dev/null | grep -E '^[_A-Za-z0-9-]+[[:blank:]]+device')), \ + $(info check: $(target) test enabled \ + $(info check: android device attached) \ + $(eval $(call DEF_ADB_DEVICE_STATUS, true))), \ + $(info check: $(target) test disabled \ + $(info check: android device not attached) \ + $(eval $(call DEF_ADB_DEVICE_STATUS, false))) \ + ), \ + $(info check: $(target) test disabled \ + $(info check: adb not found) \ + $(eval $(call DEF_ADB_DEVICE_STATUS, false))) \ + ), \ + ) \ +) + +ifeq ($(CFG_ADB_DEVICE_STATUS),true) +CFG_ADB_TEST_DIR=/data/tmp + +$(info check: android device test dir $(CFG_ADB_TEST_DIR) ready \ + $(shell adb remount 1>/dev/null) \ + $(shell adb shell mkdir $(CFG_ADB_TEST_DIR) 1>/dev/null) \ + $(shell adb push $(CFG_ANDROID_CROSS_PATH)/arm-linux-androideabi/lib/armv7-a/libgnustl_shared.so \ + $(CFG_ADB_TEST_DIR) 1>/dev/null) \ + ) +else +CFG_ADB_TEST_DIR= +endif + ###################################################################### # Main test targets @@ -319,11 +356,53 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ && touch $$@ endef +define DEF_TEST_CRATE_RULES_arm-linux-androideabi +check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)) + +$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ + $(3)/test/$(4)test.stage$(1)-$(2)$$(X_$(2)) + @$$(call E, run: $$< via adb) + @$(CFG_ADB) push $$< $(CFG_ADB_TEST_DIR) + @$(CFG_ADB) shell LD_LIBRARY_PATH=$(CFG_ADB_TEST_DIR) \ + $(CFG_ADB_TEST_DIR)/`echo $$< | sed 's/.*\///'` \ + --logfile $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log > \ + tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp + @cat tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp + @touch tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).log + @$(CFG_ADB) pull $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log tmp/ + @$(CFG_ADB) shell rm $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log + @if grep -q "result: ok" tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \ + then \ + rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \ + touch $$@; \ + else \ + rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \ + exit 101; \ + fi +endef + +define DEF_TEST_CRATE_RULES_null +check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)) + +$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ + $(3)/test/$(4)test.stage$(1)-$(2)$$(X_$(2)) + @$$(call E, run: skipped $$< ) + @touch $$@ +endef + $(foreach host,$(CFG_HOST_TRIPLES), \ $(foreach target,$(CFG_TARGET_TRIPLES), \ $(foreach stage,$(STAGES), \ $(foreach crate, $(TEST_CRATES), \ - $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))))))) + $(if $(findstring $(target),$(CFG_BUILD_TRIPLE)), \ + $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))), \ + $(if $(findstring $(target),"arm-linux-androideabi"), \ + $(if $(findstring $(CFG_ADB_DEVICE_STATUS),"true"), \ + $(eval $(call DEF_TEST_CRATE_RULES_arm-linux-androideabi,$(stage),$(target),$(host),$(crate))), \ + $(eval $(call DEF_TEST_CRATE_RULES_null,$(stage),$(target),$(host),$(crate))) \ + ), \ + $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))) \ + )))))) ###################################################################### @@ -420,6 +499,9 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \ --rustc-path $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \ --aux-base $$(S)src/test/auxiliary/ \ --stage-id stage$(1)-$(2) \ + --target $(2) \ + --adb-path=$(CFG_ADB) \ + --adb-test-dir=$(CFG_ADB_TEST_DIR) \ --rustcflags "$(RUSTC_FLAGS_$(2)) $$(CFG_RUSTC_FLAGS) --target=$(2)" \ $$(CTEST_TESTARGS) @@ -454,7 +536,7 @@ ifeq ($$(CTEST_DISABLE_$(4)),) $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ $$(CTEST_DEPS_$(4)_$(1)-T-$(2)-H-$(3)) - @$$(call E, run $(4): $$<) + @$$(call E, run $(4) [$(2)]: $$<) $$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \ $$(CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \ --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \ @@ -465,7 +547,7 @@ else $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ $$(CTEST_DEPS_$(4)_$(1)-T-$(2)-H-$(3)) - @$$(call E, run $(4): $$<) + @$$(call E, run $(4) [$(2)]: $$<) @$$(call E, warning: tests disabled: $$(CTEST_DISABLE_$(4))) touch $$@ @@ -506,7 +588,7 @@ check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4 $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ $$(PRETTY_DEPS_$(4)) - @$$(call E, run pretty-rpass: $$<) + @$$(call E, run pretty-rpass [$(2)]: $$<) $$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \ $$(PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \ --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \ @@ -533,7 +615,7 @@ check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3) $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ doc-$(4)-extract$(3) - @$$(call E, run doc-$(4): $$<) + @$$(call E, run doc-$(4) [$(2)]: $$<) $$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \ $$(DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-doc-$(4)) \ --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),doc-$(4)) \ diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index e515ef302f6..38289f62741 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -64,6 +64,18 @@ pub struct config { // Run tests using the new runtime newrt: bool, + // Target system to be tested + target: ~str, + + // Extra parameter to run adb on arm-linux-androideabi + adb_path: ~str, + + // Extra parameter to run test sute on arm-linux-androideabi + adb_test_dir: ~str, + + // status whether android device available or not + adb_device_status: bool, + // Explain what's going on verbose: bool diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index b6d690f8307..6db926b29e3 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -60,7 +60,11 @@ pub fn parse_config(args: ~[~str]) -> config { getopts::optflag(~"verbose"), getopts::optopt(~"logfile"), getopts::optflag(~"jit"), - getopts::optflag(~"newrt")]; + getopts::optflag(~"newrt"), + getopts::optopt(~"target"), + getopts::optopt(~"adb-path"), + getopts::optopt(~"adb-test-dir") + ]; assert!(!args.is_empty()); let args_ = vec::tail(args); @@ -93,6 +97,18 @@ pub fn parse_config(args: ~[~str]) -> config { rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), jit: getopts::opt_present(matches, ~"jit"), newrt: getopts::opt_present(matches, ~"newrt"), + target: opt_str(getopts::opt_maybe_str(matches, ~"target")), + adb_path: opt_str(getopts::opt_maybe_str(matches, ~"adb-path")), + adb_test_dir: opt_str(getopts::opt_maybe_str(matches, ~"adb-test-dir")), + adb_device_status: + if (opt_str(getopts::opt_maybe_str(matches, ~"target")) == + ~"arm-linux-androideabi") { + if (opt_str(getopts::opt_maybe_str(matches, ~"adb-test-dir")) != + ~"(none)" && + opt_str(getopts::opt_maybe_str(matches, ~"adb-test-dir")) != + ~"") { true } + else { false } + } else { false }, verbose: getopts::opt_present(matches, ~"verbose") } } @@ -113,6 +129,10 @@ pub fn log_config(config: config) { logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags))); logv(c, fmt!("jit: %b", config.jit)); logv(c, fmt!("newrt: %b", config.newrt)); + logv(c, fmt!("target: %s", config.target)); + logv(c, fmt!("adb_path: %s", config.adb_path)); + logv(c, fmt!("adb_test_dir: %s", config.adb_test_dir)); + logv(c, fmt!("adb_device_status: %b", config.adb_device_status)); logv(c, fmt!("verbose: %b", config.verbose)); logv(c, fmt!("\n")); } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 5805c173029..8777eedd7da 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -77,8 +77,20 @@ fn run_rfail_test(config: config, props: TestProps, testfile: &Path) { fatal_ProcRes(~"run-fail test isn't valgrind-clean!", ProcRes); } - check_correct_failure_status(ProcRes); - check_error_patterns(props, testfile, ProcRes); + match config.target { + + ~"arm-linux-androideabi" => { + if (config.adb_device_status) { + check_correct_failure_status(ProcRes); + check_error_patterns(props, testfile, ProcRes); + } + } + + _=> { + check_correct_failure_status(ProcRes); + check_error_patterns(props, testfile, ProcRes); + } + } } fn check_correct_failure_status(ProcRes: ProcRes) { @@ -483,10 +495,23 @@ fn exec_compiled_test(config: config, props: TestProps, props.exec_env }; - compose_and_run(config, testfile, - make_run_args(config, props, testfile), - env, - config.run_lib_path, None) + match config.target { + + ~"arm-linux-androideabi" => { + if (config.adb_device_status) { + _arm_exec_compiled_test(config, props, testfile) + } else { + _dummy_exec_compiled_test(config, props, testfile) + } + } + + _=> { + compose_and_run(config, testfile, + make_run_args(config, props, testfile), + env, + config.run_lib_path, None) + } + } } fn compose_and_run_compiler( @@ -516,6 +541,17 @@ fn compose_and_run_compiler( abs_ab.to_str()), auxres); } + + match config.target { + + ~"arm-linux-androideabi" => { + if (config.adb_device_status) { + _arm_push_aux_shared_library(config, testfile); + } + } + + _=> { } + } } compose_and_run(config, testfile, args, ~[], @@ -700,3 +736,108 @@ stderr:\n\ io::stdout().write_str(msg); fail!(); } + +fn _arm_exec_compiled_test(config: config, props: TestProps, + testfile: &Path) -> ProcRes { + + let args = make_run_args(config, props, testfile); + let cmdline = make_cmdline(~"", args.prog, args.args); + + // get bare program string + let mut tvec = ~[]; + let tstr = args.prog; + for str::each_split_char(tstr, '/') |ts| { tvec.push(ts.to_owned()) } + let prog_short = tvec.pop(); + + // copy to target + let copy_result = procsrv::run(~"", config.adb_path, + ~[~"push", args.prog, config.adb_test_dir], + ~[(~"",~"")], Some(~"")); + + if config.verbose { + io::stdout().write_str(fmt!("push (%s) %s %s %s", + config.target, args.prog, + copy_result.out, copy_result.err)); + } + + // execute program + logv(config, fmt!("executing (%s) %s", config.target, cmdline)); + + // adb shell dose not forward stdout and stderr of internal result + // to stdout and stderr seperately but to stdout only + let mut newargs_out = ~[]; + let mut newargs_err = ~[]; + let subargs = args.args; + newargs_out.push(~"shell"); + newargs_err.push(~"shell"); + + let mut newcmd_out = ~""; + let mut newcmd_err = ~""; + + newcmd_out.push_str(fmt!("LD_LIBRARY_PATH=%s %s/%s", + config.adb_test_dir, config.adb_test_dir, prog_short)); + + newcmd_err.push_str(fmt!("LD_LIBRARY_PATH=%s %s/%s", + config.adb_test_dir, config.adb_test_dir, prog_short)); + + for vec::each(subargs) |tv| { + newcmd_out.push_str(" "); + newcmd_err.push_str(" "); + newcmd_out.push_str(tv.to_owned()); + newcmd_err.push_str(tv.to_owned()); + } + + newcmd_out.push_str(" 2>/dev/null"); + newcmd_err.push_str(" 1>/dev/null"); + + newargs_out.push(newcmd_out); + newargs_err.push(newcmd_err); + + let exe_result_out = procsrv::run(~"", config.adb_path, + newargs_out, ~[(~"",~"")], Some(~"")); + let exe_result_err = procsrv::run(~"", config.adb_path, + newargs_err, ~[(~"",~"")], Some(~"")); + + dump_output(config, testfile, exe_result_out.out, exe_result_err.out); + + match exe_result_err.out { + ~"" => ProcRes {status: exe_result_out.status, stdout: exe_result_out.out, + stderr: exe_result_err.out, cmdline: cmdline }, + _ => ProcRes {status: 101, stdout: exe_result_out.out, + stderr: exe_result_err.out, cmdline: cmdline } + } +} + +fn _dummy_exec_compiled_test(config: config, props: TestProps, + testfile: &Path) -> ProcRes { + + let args = make_run_args(config, props, testfile); + let cmdline = make_cmdline(~"", args.prog, args.args); + + match config.mode { + mode_run_fail => ProcRes {status: 101, stdout: ~"", + stderr: ~"", cmdline: cmdline}, + _ => ProcRes {status: 0, stdout: ~"", + stderr: ~"", cmdline: cmdline} + } +} + +fn _arm_push_aux_shared_library(config: config, testfile: &Path) { + let tstr = aux_output_dir_name(config, testfile).to_str(); + + for os::list_dir_path(&Path(tstr)).each |file| { + + if (file.filetype() == Some(~".so")) { + + let copy_result = procsrv::run(~"", config.adb_path, + ~[~"push", file.to_str(), config.adb_test_dir], + ~[(~"",~"")], Some(~"")); + + if config.verbose { + io::stdout().write_str(fmt!("push (%s) %s %s %s", + config.target, file.to_str(), + copy_result.out, copy_result.err)); + } + } + } +}