diff --git a/mk/cfg/i586-pc-windows-msvc.mk b/mk/cfg/i586-pc-windows-msvc.mk index da2680f7416..48f1ecec3a7 100644 --- a/mk/cfg/i586-pc-windows-msvc.mk +++ b/mk/cfg/i586-pc-windows-msvc.mk @@ -1,16 +1,16 @@ # i586-pc-windows-msvc configuration -CC_i586-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo -LINK_i586-pc-windows-msvc="$(CFG_MSVC_LINK_i386)" -nologo -CXX_i586-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo -CPP_i586-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo -AR_i586-pc-windows-msvc="$(CFG_MSVC_LIB_i386)" -nologo +CC_i586-pc-windows-msvc=$(CFG_MSVC_CL_i386) +LINK_i586-pc-windows-msvc=$(CFG_MSVC_LINK_i386) +CXX_i586-pc-windows-msvc=$(CFG_MSVC_CL_i386) +CPP_i586-pc-windows-msvc=$(CFG_MSVC_CL_i386) +AR_i586-pc-windows-msvc=$(CFG_MSVC_LIB_i386) CFG_LIB_NAME_i586-pc-windows-msvc=$(1).dll CFG_STATIC_LIB_NAME_i586-pc-windows-msvc=$(1).lib CFG_LIB_GLOB_i586-pc-windows-msvc=$(1)-*.{dll,lib} CFG_LIB_DSYM_GLOB_i586-pc-windows-msvc=$(1)-*.dylib.dSYM CFG_JEMALLOC_CFLAGS_i586-pc-windows-msvc := -CFG_GCCISH_CFLAGS_i586-pc-windows-msvc := -MD -arch:IA32 -CFG_GCCISH_CXXFLAGS_i586-pc-windows-msvc := -MD -arch:IA32 +CFG_GCCISH_CFLAGS_i586-pc-windows-msvc := -MD -arch:IA32 -nologo +CFG_GCCISH_CXXFLAGS_i586-pc-windows-msvc := -MD -arch:IA32 -nologo CFG_GCCISH_LINK_FLAGS_i586-pc-windows-msvc := CFG_GCCISH_DEF_FLAG_i586-pc-windows-msvc := CFG_LLC_FLAGS_i586-pc-windows-msvc := diff --git a/mk/cfg/i686-pc-windows-msvc.mk b/mk/cfg/i686-pc-windows-msvc.mk index 85b320a18a4..b0289b9892e 100644 --- a/mk/cfg/i686-pc-windows-msvc.mk +++ b/mk/cfg/i686-pc-windows-msvc.mk @@ -1,16 +1,16 @@ # i686-pc-windows-msvc configuration -CC_i686-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo -LINK_i686-pc-windows-msvc="$(CFG_MSVC_LINK_i386)" -nologo -CXX_i686-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo -CPP_i686-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo -AR_i686-pc-windows-msvc="$(CFG_MSVC_LIB_i386)" -nologo +CC_i686-pc-windows-msvc=$(CFG_MSVC_CL_i386) +LINK_i686-pc-windows-msvc=$(CFG_MSVC_LINK_i386) +CXX_i686-pc-windows-msvc=$(CFG_MSVC_CL_i386) +CPP_i686-pc-windows-msvc=$(CFG_MSVC_CL_i386) +AR_i686-pc-windows-msvc=$(CFG_MSVC_LIB_i386) CFG_LIB_NAME_i686-pc-windows-msvc=$(1).dll CFG_STATIC_LIB_NAME_i686-pc-windows-msvc=$(1).lib CFG_LIB_GLOB_i686-pc-windows-msvc=$(1)-*.{dll,lib} CFG_LIB_DSYM_GLOB_i686-pc-windows-msvc=$(1)-*.dylib.dSYM CFG_JEMALLOC_CFLAGS_i686-pc-windows-msvc := -CFG_GCCISH_CFLAGS_i686-pc-windows-msvc := -MD -CFG_GCCISH_CXXFLAGS_i686-pc-windows-msvc := -MD +CFG_GCCISH_CFLAGS_i686-pc-windows-msvc := -MD -nologo +CFG_GCCISH_CXXFLAGS_i686-pc-windows-msvc := -MD -nologo CFG_GCCISH_LINK_FLAGS_i686-pc-windows-msvc := CFG_GCCISH_DEF_FLAG_i686-pc-windows-msvc := CFG_LLC_FLAGS_i686-pc-windows-msvc := diff --git a/mk/cfg/x86_64-pc-windows-msvc.mk b/mk/cfg/x86_64-pc-windows-msvc.mk index a194dfd1a68..30e996a9727 100644 --- a/mk/cfg/x86_64-pc-windows-msvc.mk +++ b/mk/cfg/x86_64-pc-windows-msvc.mk @@ -1,16 +1,16 @@ # x86_64-pc-windows-msvc configuration -CC_x86_64-pc-windows-msvc="$(CFG_MSVC_CL_x86_64)" -nologo -LINK_x86_64-pc-windows-msvc="$(CFG_MSVC_LINK_x86_64)" -nologo -CXX_x86_64-pc-windows-msvc="$(CFG_MSVC_CL_x86_64)" -nologo -CPP_x86_64-pc-windows-msvc="$(CFG_MSVC_CL_x86_64)" -nologo -AR_x86_64-pc-windows-msvc="$(CFG_MSVC_LIB_x86_64)" -nologo +CC_x86_64-pc-windows-msvc=$(CFG_MSVC_CL_x86_64) +LINK_x86_64-pc-windows-msvc=$(CFG_MSVC_LINK_x86_64) +CXX_x86_64-pc-windows-msvc=$(CFG_MSVC_CL_x86_64) +CPP_x86_64-pc-windows-msvc=$(CFG_MSVC_CL_x86_64) +AR_x86_64-pc-windows-msvc=$(CFG_MSVC_LIB_x86_64) CFG_LIB_NAME_x86_64-pc-windows-msvc=$(1).dll CFG_STATIC_LIB_NAME_x86_64-pc-windows-msvc=$(1).lib CFG_LIB_GLOB_x86_64-pc-windows-msvc=$(1)-*.{dll,lib} CFG_LIB_DSYM_GLOB_x86_64-pc-windows-msvc=$(1)-*.dylib.dSYM CFG_JEMALLOC_CFLAGS_x86_64-pc-windows-msvc := -CFG_GCCISH_CFLAGS_x86_64-pc-windows-msvc := -MD -CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-msvc := -MD +CFG_GCCISH_CFLAGS_x86_64-pc-windows-msvc := -MD -nologo +CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-msvc := -MD -nologo CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-msvc := CFG_GCCISH_DEF_FLAG_x86_64-pc-windows-msvc := CFG_LLC_FLAGS_x86_64-pc-windows-msvc := diff --git a/mk/platform.mk b/mk/platform.mk index 83fd4509da8..59c8f7726c9 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -148,7 +148,7 @@ define CC_MACROS CFG_CC_INCLUDE_$(1)=-I $$(1) ifeq ($$(findstring msvc,$(1)),msvc) CFG_CC_OUTPUT_$(1)=-Fo:$$(1) - CFG_CREATE_ARCHIVE_$(1)=$$(AR_$(1)) -OUT:$$(1) + CFG_CREATE_ARCHIVE_$(1)='$$(AR_$(1))' -OUT:$$(1) else CFG_CC_OUTPUT_$(1)=-o $$(1) CFG_CREATE_ARCHIVE_$(1)=$$(AR_$(1)) crus $$(1) @@ -187,7 +187,7 @@ define CFG_MAKE_TOOLCHAIN endif endif - CFG_COMPILE_C_$(1) = $$(CC_$(1)) \ + CFG_COMPILE_C_$(1) = '$$(CC_$(1))' \ $$(CFLAGS) \ $$(CFG_GCCISH_CFLAGS) \ $$(CFG_GCCISH_CFLAGS_$(1)) \ @@ -198,7 +198,7 @@ define CFG_MAKE_TOOLCHAIN $$(CFG_GCCISH_LINK_FLAGS_$(1)) \ $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \ $$(call CFG_INSTALL_NAME_$(1),$$(4)) - CFG_COMPILE_CXX_$(1) = $$(CXX_$(1)) \ + CFG_COMPILE_CXX_$(1) = '$$(CXX_$(1))' \ $$(CXXFLAGS) \ $$(CFG_GCCISH_CFLAGS) \ $$(CFG_GCCISH_CXXFLAGS) \ diff --git a/mk/tests.mk b/mk/tests.mk index f5a499105be..9d45203b7b6 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -450,6 +450,7 @@ CODEGEN_RS := $(call rwildcard,$(S)src/test/codegen/,*.rs) CODEGEN_CC := $(call rwildcard,$(S)src/test/codegen/,*.cc) CODEGEN_UNITS_RS := $(call rwildcard,$(S)src/test/codegen-units/,*.rs) INCREMENTAL_RS := $(call rwildcard,$(S)src/test/incremental/,*.rs) +RMAKE_RS := $(wildcard $(S)src/test/run-make/*/Makefile) RUSTDOCCK_RS := $(call rwildcard,$(S)src/test/rustdoc/,*.rs) RPASS_TESTS := $(RPASS_RS) @@ -466,6 +467,7 @@ DEBUGINFO_LLDB_TESTS := $(DEBUGINFO_LLDB_RS) CODEGEN_TESTS := $(CODEGEN_RS) $(CODEGEN_CC) CODEGEN_UNITS_TESTS := $(CODEGEN_UNITS_RS) INCREMENTAL_TESTS := $(INCREMENTAL_RS) +RMAKE_TESTS := $(RMAKE_RS) RUSTDOCCK_TESTS := $(RUSTDOCCK_RS) CTEST_SRC_BASE_rpass = run-pass @@ -533,6 +535,11 @@ CTEST_BUILD_BASE_incremental = incremental CTEST_MODE_incremental = incremental CTEST_RUNTOOL_incremental = $(CTEST_RUNTOOL) +CTEST_SRC_BASE_rmake = run-make +CTEST_BUILD_BASE_rmake = run-make +CTEST_MODE_rmake = run-make +CTEST_RUNTOOL_rmake = $(CTEST_RUNTOOL) + CTEST_SRC_BASE_rustdocck = rustdoc CTEST_BUILD_BASE_rustdocck = rustdoc CTEST_MODE_rustdocck = rustdoc @@ -629,6 +636,11 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \ --host-rustcflags "$(RUSTC_FLAGS_$(3)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(3))" \ --lldb-python-dir=$(CFG_LLDB_PYTHON_DIR) \ --target-rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2))" \ + --cc '$$(CC_$(3))' \ + --cxx '$$(CXX_$(3))' \ + --cflags "$$(CFG_GCCISH_CFLAGS_$(3))" \ + --llvm-components "$$(LLVM_ALL_COMPONENTS_$(3))" \ + --llvm-cxxflags "$$(LLVM_CXXFLAGS_$(3))" \ $$(CTEST_TESTARGS) ifdef CFG_VALGRIND_RPASS @@ -658,6 +670,9 @@ CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) \ CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS) CTEST_DEPS_codegen-units_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_UNITS_TESTS) CTEST_DEPS_incremental_$(1)-T-$(2)-H-$(3) = $$(INCREMENTAL_TESTS) +CTEST_DEPS_rmake_$(1)-T-$(2)-H-$(3) = $$(RMAKE_TESTS) \ + $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3)) + CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \ $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \ $(S)src/etc/htmldocck.py @@ -702,6 +717,10 @@ endif endif ifeq ($$(CTEST_DONT_RUN_$(1)-T-$(2)-H-$(3)-$(4)),) +$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ + export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(3))) +$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ + export LIB := $$(CFG_MSVC_LIB_PATH_$$(HOST_$(3))) $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ $$(CTEST_DEPS_$(4)_$(1)-T-$(2)-H-$(3)) @@ -724,7 +743,8 @@ endif endef CTEST_NAMES = rpass rpass-valgrind rpass-full rfail-full cfail-full rfail cfail pfail \ - debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck incremental + debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck incremental \ + rmake $(foreach host,$(CFG_HOST), \ $(eval $(foreach target,$(CFG_TARGET), \ @@ -1009,70 +1029,3 @@ endef $(foreach crate,$(TEST_CRATES), \ $(eval $(call DEF_CHECK_CRATE,$(crate)))) - -###################################################################### -# RMAKE rules -###################################################################### - -RMAKE_TESTS := $(shell ls -d $(S)src/test/run-make/*/) -RMAKE_TESTS := $(RMAKE_TESTS:$(S)src/test/run-make/%/=%) - -define DEF_RMAKE_FOR_T_H -# $(1) the stage -# $(2) target triple -# $(3) host triple - - -ifeq ($(2)$(3),$$(CFG_BUILD)$$(CFG_BUILD)) -check-stage$(1)-T-$(2)-H-$(3)-rmake-exec: \ - $$(call TEST_OK_FILE,$(1),$(2),$(3),rmake) - -$$(call TEST_OK_FILE,$(1),$(2),$(3),rmake): \ - $$(RMAKE_TESTS:%=$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok) - @touch $$@ - -$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \ - export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(3))) -$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \ - export LIB := $$(CFG_MSVC_LIB_PATH_$$(HOST_$(3))) -$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \ - export MSVC_LIB := "$$(CFG_MSVC_LIB_$$(HOST_$(3)))" -$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \ - $(S)src/test/run-make/%/Makefile \ - $$(CSREQ$(1)_T_$(2)_H_$(3)) - @rm -rf $(3)/test/run-make/$$* - @mkdir -p $(3)/test/run-make/$$* - $$(Q)touch $$@.start_time - $$(Q)$$(CFG_PYTHON) $(S)src/etc/maketest.py $$(dir $$<) \ - $$(MAKE) \ - $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \ - $(3)/test/run-make/$$* \ - '$$(CC_$(3))' \ - "$$(CFG_GCCISH_CFLAGS_$(3))" \ - $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \ - "$$(TESTNAME)" \ - $$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3)) \ - "$$(LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3))" \ - "$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3))" \ - $(1) \ - $$(S) \ - $(3) \ - "$$(LLVM_LIBDIR_RUSTFLAGS_$(3))" \ - "$$(LLVM_ALL_COMPONENTS_$(3))" \ - "$$(LLVM_CXXFLAGS_$(3))" \ - '$$(CXX_$(3))' - @touch -r $$@.start_time $$@ && rm $$@.start_time -else -# FIXME #11094 - The above rule doesn't work right for multiple targets -check-stage$(1)-T-$(2)-H-$(3)-rmake-exec: - @true - -endif - - -endef - -$(foreach stage,$(STAGES), \ - $(foreach target,$(CFG_TARGET), \ - $(foreach host,$(CFG_HOST), \ - $(eval $(call DEF_RMAKE_FOR_T_H,$(stage),$(target),$(host)))))) diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs index 32164080947..a376b021a8a 100644 --- a/src/bootstrap/build/check.rs +++ b/src/bootstrap/build/check.rs @@ -12,6 +12,8 @@ use std::fs; use std::path::{PathBuf, Path}; use std::process::Command; +use build_helper::output; + use build::{Build, Compiler}; pub fn linkcheck(build: &Build, stage: u32, host: &str) { @@ -112,6 +114,33 @@ pub fn compiletest(build: &Build, cmd.arg("--verbose"); } + if suite == "run-make" { + let llvm_config = build.llvm_config(target); + let llvm_components = output(Command::new(&llvm_config).arg("--components")); + let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags")); + cmd.arg("--cc").arg(build.cc(target)) + .arg("--cxx").arg(build.cxx(target)) + .arg("--cflags").arg(build.cflags(target).join(" ")) + .arg("--llvm-components").arg(llvm_components.trim()) + .arg("--llvm-cxxflags").arg(llvm_cxxflags.trim()); + } else { + cmd.arg("--cc").arg("") + .arg("--cxx").arg("") + .arg("--cflags").arg("") + .arg("--llvm-components").arg("") + .arg("--llvm-cxxflags").arg(""); + } + + // Running a C compiler on MSVC requires a few env vars to be set, to be + // sure to set them here. + if target.contains("msvc") { + for &(ref k, ref v) in build.cc[target].0.env() { + if k != "PATH" { + cmd.env(k, v); + } + } + } + build.run(&mut cmd); } diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs index 3c3add3d9a1..97be285ce01 100644 --- a/src/bootstrap/build/mod.rs +++ b/src/bootstrap/build/mod.rs @@ -314,6 +314,10 @@ impl Build { CheckErrorIndex { compiler } => { check::error_index(self, &compiler); } + CheckRMake { compiler } => { + check::compiletest(self, &compiler, target.target, + "run-make", "run-make") + } DistDocs { stage } => dist::docs(self, stage, target.target), DistMingw { _dummy } => dist::mingw(self, target.target), diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index 133ae702869..59d644730a2 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -98,6 +98,7 @@ macro_rules! targets { (check_cfail_full, CheckCFailFull { compiler: Compiler<'a> }), (check_docs, CheckDocs { compiler: Compiler<'a> }), (check_error_index, CheckErrorIndex { compiler: Compiler<'a> }), + (check_rmake, CheckRMake { compiler: Compiler<'a> }), // Distribution targets, creating tarballs (dist, Dist { stage: u32 }), @@ -345,6 +346,7 @@ impl<'a> Step<'a> { self.check_cfail_full(compiler), self.check_error_index(compiler), self.check_docs(compiler), + self.check_rmake(compiler), self.check_linkcheck(stage), self.check_tidy(stage), self.dist(stage), @@ -384,7 +386,8 @@ impl<'a> Step<'a> { ] } Source::CheckRPassFull { compiler } | - Source::CheckCFailFull { compiler } => { + Source::CheckCFailFull { compiler } | + Source::CheckRMake { compiler } => { vec![self.librustc(compiler), self.tool_compiletest(compiler.stage)] } diff --git a/src/etc/maketest.py b/src/etc/maketest.py deleted file mode 100644 index c7d17b23bff..00000000000 --- a/src/etc/maketest.py +++ /dev/null @@ -1,96 +0,0 @@ -# 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 or the MIT license -# , at your -# option. This file may not be copied, modified, or distributed -# except according to those terms. - -import subprocess -import os -import sys - -target_triple = sys.argv[14] - -def normalize_path(v): - """msys1/msys2 automatically converts `/abs/path1:/abs/path2` into - `c:\real\abs\path1;c:\real\abs\path2` (semicolons) if shell thinks - the value is list of paths. - (if there is only one path, it becomes `c:/real/abs/path`.) - this causes great confusion and error: shell and Makefile doesn't like - windows paths so it is really error-prone. revert it for peace.""" - v = v.replace('\\', '/') - # c:/path -> /c/path - # "c:/path" -> "/c/path" - start = v.find(':/') - while start != -1: - v = v[:start - 1] + '/' + v[start - 1:start] + v[start + 1:] - start = v.find(':/') - return v - - -def putenv(name, value): - if os.name == 'nt': - value = normalize_path(value) - os.putenv(name, value) - - -def convert_path_spec(name, value): - if os.name == 'nt' and name != 'PATH': - value = ":".join(normalize_path(v) for v in value.split(";")) - return value - -make = sys.argv[2] -putenv('RUSTC', os.path.abspath(sys.argv[3])) -putenv('TMPDIR', os.path.abspath(sys.argv[4])) -putenv('CC', sys.argv[5] + ' ' + sys.argv[6]) -putenv('CFLAGS', sys.argv[6]) -putenv('RUSTDOC', os.path.abspath(sys.argv[7])) -filt = sys.argv[8] -putenv('LD_LIB_PATH_ENVVAR', sys.argv[9]) -putenv('HOST_RPATH_DIR', os.path.abspath(sys.argv[10])) -putenv('TARGET_RPATH_DIR', os.path.abspath(sys.argv[11])) -putenv('RUST_BUILD_STAGE', sys.argv[12]) -putenv('S', os.path.abspath(sys.argv[13])) -putenv('RUSTFLAGS', sys.argv[15]) -putenv('LLVM_COMPONENTS', sys.argv[16]) -putenv('LLVM_CXXFLAGS', sys.argv[17]) -putenv('CXX', sys.argv[18]) -putenv('PYTHON', sys.executable) -os.putenv('TARGET', target_triple) - -if 'msvc' in target_triple: - os.putenv('IS_MSVC', '1') - -if filt not in sys.argv[1]: - sys.exit(0) -print('maketest: ' + os.path.basename(os.path.dirname(sys.argv[1]))) - -path = sys.argv[1] -if path[-1] == '/': - # msys1 has a bug that `make` fails to include `../tools.mk` (parent dir) - # if `-C path` option is given and `path` is absolute directory with - # trailing slash (`c:/path/to/test/`). - # the easist workaround is to remove the slash (`c:/path/to/test`). - # msys2 seems to fix this problem. - path = path[:-1] - -proc = subprocess.Popen([make, '-C', path], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) -out, err = proc.communicate() -i = proc.wait() - -if i != 0: - print """\ ------ %s -------------------- ------- stdout --------------------------------------------- -%s ------- stderr --------------------------------------------- -%s ------- --------------------------------------------- -""" % (sys.argv[1], out, err) - - sys.exit(i) diff --git a/src/test/run-make/issue-22131/Makefile b/src/test/run-make/issue-22131/Makefile index ec1e282666a..1e8568626a6 100644 --- a/src/test/run-make/issue-22131/Makefile +++ b/src/test/run-make/issue-22131/Makefile @@ -2,6 +2,6 @@ all: foo.rs $(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs - $(HOST_RPATH_ENV) $(RUSTDOC) --test --cfg 'feature="bar"' \ + $(HOST_RPATH_ENV) '$(RUSTDOC)' --test --cfg 'feature="bar"' \ -L $(TMPDIR) foo.rs |\ grep -q 'test foo_0 ... ok' diff --git a/src/test/run-make/tools.mk b/src/test/run-make/tools.mk index dab6511eb9d..38afa42a293 100644 --- a/src/test/run-make/tools.mk +++ b/src/test/run-make/tools.mk @@ -5,7 +5,7 @@ HOST_RPATH_ENV = \ TARGET_RPATH_ENV = \ $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(TARGET_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))" -BARE_RUSTC := $(HOST_RPATH_ENV) $(RUSTC) +BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)' RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS) #CC := $(CC) -L $(TMPDIR) HTMLDOCCK := $(PYTHON) $(S)/src/etc/htmldocck.py diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 81265f6ccaf..e7019de8f43 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -27,6 +27,7 @@ pub enum Mode { Rustdoc, CodegenUnits, Incremental, + RunMake, } impl FromStr for Mode { @@ -45,6 +46,7 @@ impl FromStr for Mode { "rustdoc" => Ok(Rustdoc), "codegen-units" => Ok(CodegenUnits), "incremental" => Ok(Incremental), + "run-make" => Ok(RunMake), _ => Err(()), } } @@ -65,6 +67,7 @@ impl fmt::Display for Mode { Rustdoc => "rustdoc", CodegenUnits => "codegen-units", Incremental => "incremental", + RunMake => "run-make", }, f) } } @@ -165,4 +168,12 @@ pub struct Config { // Print one character per test instead of one line pub quiet: bool, + + // Configuration for various run-make tests frobbing things like C compilers + // or querying about various LLVM component information. + pub cc: String, + pub cxx: String, + pub cflags: String, + pub llvm_components: String, + pub llvm_cxxflags: String, } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index ef93fcfa013..c8df8739f52 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -291,6 +291,9 @@ pub fn early_props(config: &Config, testfile: &Path) -> EarlyProps { fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut FnMut(&str)) { + if testfile.is_dir() { + return + } let rdr = BufReader::new(File::open(testfile).unwrap()); for ln in rdr.lines() { // Assume that any directives will be found before the first diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index a9810099dbf..26382967c6b 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -35,7 +35,7 @@ use std::io; use std::path::{Path, PathBuf}; use getopts::{optopt, optflag, reqopt}; use common::Config; -use common::{Pretty, DebugInfoGdb, DebugInfoLldb}; +use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Mode}; use test::TestPaths; use util::logv; @@ -100,6 +100,11 @@ pub fn parse_config(args: Vec ) -> Config { optopt("", "adb-path", "path to the android debugger", "PATH"), optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"), optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH"), + reqopt("", "cc", "path to a C compiler", "PATH"), + reqopt("", "cxx", "path to a C++ compiler", "PATH"), + reqopt("", "cflags", "flags for the C compiler", "FLAGS"), + reqopt("", "llvm-components", "list of LLVM components built in", "LIST"), + reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS"), optflag("h", "help", "show this message")); let (argv0, args_) = args.split_first().unwrap(); @@ -175,6 +180,12 @@ pub fn parse_config(args: Vec ) -> Config { lldb_python_dir: matches.opt_str("lldb-python-dir"), verbose: matches.opt_present("verbose"), quiet: matches.opt_present("quiet"), + + cc: matches.opt_str("cc").unwrap(), + cxx: matches.opt_str("cxx").unwrap(), + cflags: matches.opt_str("cflags").unwrap(), + llvm_components: matches.opt_str("llvm-components").unwrap(), + llvm_cxxflags: matches.opt_str("llvm-cxxflags").unwrap(), } } @@ -307,9 +318,19 @@ fn collect_tests_from_dir(config: &Config, // `compiletest-ignore-dir`. for file in fs::read_dir(dir)? { let file = file?; - if file.file_name() == *"compiletest-ignore-dir" { + let name = file.file_name(); + if name == *"compiletest-ignore-dir" { return Ok(()); } + if name == *"Makefile" && config.mode == Mode::RunMake { + let paths = TestPaths { + file: dir.to_path_buf(), + base: base.to_path_buf(), + relative_dir: relative_dir_path.parent().unwrap().to_path_buf(), + }; + tests.push(make_test(config, &paths)); + return Ok(()) + } } let dirs = fs::read_dir(dir)?; diff --git a/src/tools/compiletest/src/procsrv.rs b/src/tools/compiletest/src/procsrv.rs index f418edf6686..53b7cd059be 100644 --- a/src/tools/compiletest/src/procsrv.rs +++ b/src/tools/compiletest/src/procsrv.rs @@ -14,16 +14,20 @@ use std::io::prelude::*; use std::path::PathBuf; use std::process::{ExitStatus, Command, Child, Output, Stdio}; -fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { - // Need to be sure to put both the lib_path and the aux path in the dylib - // search path for the child. - let var = if cfg!(windows) { +pub fn dylib_env_var() -> &'static str { + if cfg!(windows) { "PATH" } else if cfg!(target_os = "macos") { "DYLD_LIBRARY_PATH" } else { "LD_LIBRARY_PATH" - }; + } +} + +fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { + // Need to be sure to put both the lib_path and the aux path in the dylib + // search path for the child. + let var = dylib_env_var(); let mut path = env::split_paths(&env::var_os(var).unwrap_or(OsString::new())) .collect::>(); if let Some(p) = aux_path { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index e0abf8200a0..fb296d57ebf 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -11,7 +11,7 @@ use common::Config; use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind}; use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits}; -use common::{Incremental}; +use common::{Incremental, RunMake}; use errors::{self, ErrorKind, Error}; use json; use header::TestProps; @@ -24,7 +24,7 @@ use std::env; use std::collections::HashSet; use std::fmt; use std::fs::{self, File}; -use std::io::BufReader; +use std::io::{self, BufReader}; use std::io::prelude::*; use std::net::TcpStream; use std::path::{Path, PathBuf}; @@ -62,6 +62,7 @@ pub fn run(config: Config, testpaths: &TestPaths) { Rustdoc => run_rustdoc_test(&config, &props, &testpaths), CodegenUnits => run_codegen_units_test(&config, &props, &testpaths), Incremental => run_incremental_test(&config, &props, &testpaths), + RunMake => run_rmake_test(&config, &props, &testpaths), } } @@ -1233,7 +1234,7 @@ fn compose_and_run_compiler(config: &Config, props: &TestProps, testpaths: &TestPaths, args: ProcArgs, input: Option) -> ProcRes { if !props.aux_builds.is_empty() { - ensure_dir(&aux_output_dir_name(config, testpaths)); + create_dir_racy(&aux_output_dir_name(config, testpaths)); } let aux_dir = aux_output_dir_name(config, testpaths); @@ -1307,11 +1308,6 @@ fn compose_and_run_compiler(config: &Config, props: &TestProps, input) } -fn ensure_dir(path: &Path) { - if path.is_dir() { return; } - fs::create_dir_all(path).unwrap(); -} - fn compose_and_run(config: &Config, testpaths: &TestPaths, ProcArgs{ args, prog }: ProcArgs, @@ -1373,6 +1369,7 @@ fn make_compile_args(config: &Config, DebugInfoLldb | Codegen | Rustdoc | + RunMake | CodegenUnits => { // do not use JSON output } @@ -1520,6 +1517,7 @@ fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String { } fn dump_output(config: &Config, testpaths: &TestPaths, out: &str, err: &str) { + create_dir_racy(output_base_name(config, testpaths).parent().unwrap()); dump_output_file(config, testpaths, out, "out"); dump_output_file(config, testpaths, err, "err"); maybe_dump_to_stdout(config, out, err); @@ -1825,7 +1823,7 @@ fn run_rustdoc_test(config: &Config, props: &TestProps, testpaths: &TestPaths) { let out_dir = output_base_name(config, testpaths); let _ = fs::remove_dir_all(&out_dir); - ensure_dir(&out_dir); + create_dir_racy(&out_dir); let proc_res = document(config, props, testpaths, &out_dir); if !proc_res.status.success() { @@ -2029,7 +2027,7 @@ fn run_incremental_test(config: &Config, props: &TestProps, testpaths: &TestPath if incremental_dir.exists() { fs::remove_dir_all(&incremental_dir).unwrap(); } - fs::create_dir_all(&incremental_dir).unwrap(); + create_dir_racy(&incremental_dir); if config.verbose { print!("incremental_dir={}", incremental_dir.display()); @@ -2063,3 +2061,102 @@ fn run_incremental_test(config: &Config, props: &TestProps, testpaths: &TestPath } } } + +fn run_rmake_test(config: &Config, _props: &TestProps, testpaths: &TestPaths) { + let cwd = env::current_dir().unwrap(); + let src_root = config.src_base.parent().unwrap().parent().unwrap() + .parent().unwrap(); + let src_root = cwd.join(&src_root); + + let tmpdir = cwd.join(output_base_name(config, testpaths)); + if tmpdir.exists() { + aggressive_rm_rf(&tmpdir).unwrap(); + } + create_dir_racy(&tmpdir); + + let mut cmd = Command::new("make"); + cmd.current_dir(&testpaths.file) + .env("TARGET", &config.target) + .env("PYTHON", &config.docck_python) + .env("S", src_root) + .env("RUST_BUILD_STAGE", &config.stage_id) + .env("RUSTC", cwd.join(&config.rustc_path)) + .env("RUSTDOC", cwd.join(&config.rustdoc_path)) + .env("TMPDIR", &tmpdir) + .env("LD_LIB_PATH_ENVVAR", procsrv::dylib_env_var()) + .env("HOST_RPATH_DIR", cwd.join(&config.compile_lib_path)) + .env("TARGET_RPATH_DIR", cwd.join(&config.run_lib_path)) + .env("LLVM_COMPONENTS", &config.llvm_components) + .env("LLVM_CXXFLAGS", &config.llvm_cxxflags); + + if config.target.contains("msvc") { + // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe` + // and that `lib.exe` lives next to it. + let lib = Path::new(&config.cc).parent().unwrap().join("lib.exe"); + + // MSYS doesn't like passing flags of the form `/foo` as it thinks it's + // a path and instead passes `C:\msys64\foo`, so convert all + // `/`-arguments to MSVC here to `-` arguments. + let cflags = config.cflags.split(' ').map(|s| s.replace("/", "-")) + .collect::>().join(" "); + + cmd.env("IS_MSVC", "1") + .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) + .env("CC", format!("'{}' {}", config.cc, cflags)) + .env("CXX", &config.cxx); + } else { + cmd.env("CC", format!("{} {}", config.cc, config.cflags)) + .env("CXX", format!("{} {}", config.cxx, config.cflags)); + } + + let output = cmd.output().expect("failed to spawn `make`"); + if !output.status.success() { + let res = ProcRes { + status: Status::Normal(output.status), + stdout: String::from_utf8_lossy(&output.stdout).into_owned(), + stderr: String::from_utf8_lossy(&output.stderr).into_owned(), + cmdline: format!("{:?}", cmd), + }; + fatal_proc_rec(None, "make failed", &res); + } +} + +fn aggressive_rm_rf(path: &Path) -> io::Result<()> { + for e in try!(path.read_dir()) { + let entry = try!(e); + let path = entry.path(); + if try!(entry.file_type()).is_dir() { + try!(aggressive_rm_rf(&path)); + } else { + // Remove readonly files as well on windows (by default we can't) + try!(fs::remove_file(&path).or_else(|e| { + if cfg!(windows) && e.kind() == io::ErrorKind::PermissionDenied { + let mut meta = try!(entry.metadata()).permissions(); + meta.set_readonly(false); + try!(fs::set_permissions(&path, meta)); + fs::remove_file(&path) + } else { + Err(e) + } + })) + } + } + fs::remove_dir(path) +} + +// Like std::fs::create_dir_all, except handles concurrent calls among multiple +// threads or processes. +fn create_dir_racy(path: &Path) { + match fs::create_dir(path) { + Ok(()) => return, + Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return, + Err(ref e) if e.kind() == io::ErrorKind::NotFound => {} + Err(e) => panic!("failed to create dir {:?}: {}", path, e), + } + create_dir_racy(path.parent().unwrap()); + match fs::create_dir(path) { + Ok(()) => {} + Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => {} + Err(e) => panic!("failed to create dir {:?}: {}", path, e), + } +}