5830ca216d
It lints against features that are inteded to be internal to the compiler and standard library. Implements MCP #596. We allow `internal_features` in the standard library and compiler as those use many features and this _is_ the standard library from the "internal to the compiler and standard library" after all. Marking some features as internal wasn't exactly the most scientific approach, I just marked some mostly obvious features. While there is a categorization in the macro, it's not very well upheld (should probably be fixed in another PR). We always pass `-Ainternal_features` in the testsuite About 400 UI tests and several other tests use internal features. Instead of throwing the attribute on each one, just always allow them. There's nothing wrong with testing internal features^^
188 lines
6.1 KiB
Makefile
188 lines
6.1 KiB
Makefile
# These deliberately use `=` and not `:=` so that client makefiles can
|
|
# augment HOST_RPATH_DIR / TARGET_RPATH_DIR.
|
|
HOST_RPATH_ENV = \
|
|
$(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(HOST_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))"
|
|
TARGET_RPATH_ENV = \
|
|
$(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(TARGET_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))"
|
|
|
|
RUSTC_ORIGINAL := $(RUSTC)
|
|
BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)'
|
|
BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)'
|
|
RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS) -Ainternal_features
|
|
RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR)
|
|
ifdef RUSTC_LINKER
|
|
RUSTC := $(RUSTC) -Clinker='$(RUSTC_LINKER)'
|
|
RUSTDOC := $(RUSTDOC) -Clinker='$(RUSTC_LINKER)'
|
|
endif
|
|
#CC := $(CC) -L $(TMPDIR)
|
|
HTMLDOCCK := '$(PYTHON)' '$(S)/src/etc/htmldocck.py'
|
|
CGREP := "$(S)/src/etc/cat-and-grep.sh"
|
|
|
|
# diff with common flags for multi-platform diffs against text output
|
|
DIFF := diff -u --strip-trailing-cr
|
|
|
|
# Some of the Rust CI platforms use `/bin/dash` to run `shell` script in
|
|
# Makefiles. Other platforms, including many developer platforms, default to
|
|
# `/bin/bash`. (In many cases, `make` is actually using `/bin/sh`, but `sh`
|
|
# is configured to execute one or the other shell binary). `dash` features
|
|
# support only a small subset of `bash` features, so `dash` can be thought of as
|
|
# the lowest common denominator, and tests should be validated against `dash`
|
|
# whenever possible. Most developer platforms include `/bin/dash`, but to ensure
|
|
# tests still work when `/bin/dash`, if not available, this `SHELL` override is
|
|
# conditional:
|
|
ifndef IS_WINDOWS # dash interprets backslashes in executable paths incorrectly
|
|
ifneq (,$(wildcard /bin/dash))
|
|
SHELL := /bin/dash
|
|
endif
|
|
endif
|
|
|
|
# This is the name of the binary we will generate and run; use this
|
|
# e.g. for `$(CC) -o $(RUN_BINFILE)`.
|
|
RUN_BINFILE = $(TMPDIR)/$(1)
|
|
|
|
# Invoke the generated binary on the remote machine if compiletest was
|
|
# configured to use a remote test device, otherwise run it on the current host.
|
|
ifdef REMOTE_TEST_CLIENT
|
|
# FIXME: if a test requires additional files, this will need to be changed to
|
|
# also push them (by changing the 0 to the number of additional files, and
|
|
# providing the path of the additional files as the last arguments).
|
|
EXECUTE = $(REMOTE_TEST_CLIENT) run 0 $(RUN_BINFILE)
|
|
else
|
|
EXECUTE = $(RUN_BINFILE)
|
|
endif
|
|
|
|
# RUN and FAIL are basic way we will invoke the generated binary. On
|
|
# non-windows platforms, they set the LD_LIBRARY_PATH environment
|
|
# variable before running the binary.
|
|
|
|
RLIB_GLOB = lib$(1)*.rlib
|
|
BIN = $(1)
|
|
|
|
UNAME = $(shell uname)
|
|
|
|
ifeq ($(UNAME),Darwin)
|
|
RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
|
|
FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
|
|
DYLIB_GLOB = lib$(1)*.dylib
|
|
DYLIB = $(TMPDIR)/lib$(1).dylib
|
|
STATICLIB = $(TMPDIR)/lib$(1).a
|
|
STATICLIB_GLOB = lib$(1)*.a
|
|
else
|
|
ifdef IS_WINDOWS
|
|
RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE)
|
|
FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) && exit 1 || exit 0
|
|
DYLIB_GLOB = $(1)*.dll
|
|
DYLIB = $(TMPDIR)/$(1).dll
|
|
ifdef IS_MSVC
|
|
STATICLIB = $(TMPDIR)/$(1).lib
|
|
STATICLIB_GLOB = $(1)*.lib
|
|
else
|
|
IMPLIB = $(TMPDIR)/lib$(1).dll.a
|
|
STATICLIB = $(TMPDIR)/lib$(1).a
|
|
STATICLIB_GLOB = lib$(1)*.a
|
|
endif
|
|
BIN = $(1).exe
|
|
LLVM_FILECHECK := $(shell cygpath -u "$(LLVM_FILECHECK)")
|
|
else
|
|
RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
|
|
FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
|
|
DYLIB_GLOB = lib$(1)*.so
|
|
DYLIB = $(TMPDIR)/lib$(1).so
|
|
STATICLIB = $(TMPDIR)/lib$(1).a
|
|
STATICLIB_GLOB = lib$(1)*.a
|
|
endif
|
|
endif
|
|
|
|
ifdef IS_MSVC
|
|
COMPILE_OBJ = $(CC) -c -Fo:`cygpath -w $(1)` $(2)
|
|
COMPILE_OBJ_CXX = $(CXX) -EHs -c -Fo:`cygpath -w $(1)` $(2)
|
|
NATIVE_STATICLIB_FILE = $(1).lib
|
|
NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1))
|
|
OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
|
|
-Fo:`cygpath -w $(TMPDIR)/$(1).obj`
|
|
else
|
|
COMPILE_OBJ = $(CC) -v -c -o $(1) $(2)
|
|
COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2)
|
|
NATIVE_STATICLIB_FILE = lib$(1).a
|
|
NATIVE_STATICLIB = $(call STATICLIB,$(1))
|
|
OUT_EXE=-o $(TMPDIR)/$(1)
|
|
endif
|
|
|
|
|
|
# Extra flags needed to compile a working executable with the standard library
|
|
ifdef IS_WINDOWS
|
|
ifdef IS_MSVC
|
|
EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib
|
|
else
|
|
EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll
|
|
EXTRACXXFLAGS := -lstdc++
|
|
# So this is a bit hacky: we can't use the DLL version of libstdc++ because
|
|
# it pulls in the DLL version of libgcc, which means that we end up with 2
|
|
# instances of the DW2 unwinding implementation. This is a problem on
|
|
# i686-pc-windows-gnu because each module (DLL/EXE) needs to register its
|
|
# unwind information with the unwinding implementation, and libstdc++'s
|
|
# __cxa_throw won't see the unwinding info we registered with our statically
|
|
# linked libgcc.
|
|
#
|
|
# Now, simply statically linking libstdc++ would fix this problem, except
|
|
# that it is compiled with the expectation that pthreads is dynamically
|
|
# linked as a DLL and will fail to link with a statically linked libpthread.
|
|
#
|
|
# So we end up with the following hack: we link use static:-bundle to only
|
|
# link the parts of libstdc++ that we actually use, which doesn't include
|
|
# the dependency on the pthreads DLL.
|
|
EXTRARSCXXFLAGS := -l static:-bundle=stdc++
|
|
endif
|
|
else
|
|
ifeq ($(UNAME),Darwin)
|
|
EXTRACFLAGS := -lresolv
|
|
EXTRACXXFLAGS := -lc++
|
|
EXTRARSCXXFLAGS := -lc++
|
|
else
|
|
ifeq ($(UNAME),FreeBSD)
|
|
EXTRACFLAGS := -lm -lpthread -lgcc_s
|
|
else
|
|
ifeq ($(UNAME),SunOS)
|
|
EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
|
|
else
|
|
ifeq ($(UNAME),OpenBSD)
|
|
EXTRACFLAGS := -lm -lpthread -lc++abi
|
|
RUSTC := $(RUSTC) -C linker="$(word 1,$(CC:ccache=))"
|
|
else
|
|
EXTRACFLAGS := -lm -lrt -ldl -lpthread
|
|
EXTRACXXFLAGS := -lstdc++
|
|
EXTRARSCXXFLAGS := -lstdc++
|
|
endif
|
|
endif
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
REMOVE_DYLIBS = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1))
|
|
REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1))
|
|
|
|
%.a: %.o
|
|
$(AR) crus $@ $<
|
|
ifdef IS_MSVC
|
|
%.lib: lib%.o
|
|
$(MSVC_LIB) -out:`cygpath -w $@` $<
|
|
else
|
|
%.lib: lib%.o
|
|
$(AR) crus $@ $<
|
|
endif
|
|
%.dylib: %.o
|
|
$(CC) -dynamiclib -Wl,-dylib -o $@ $<
|
|
%.so: %.o
|
|
$(CC) -o $@ $< -shared
|
|
|
|
ifdef IS_MSVC
|
|
%.dll: lib%.o
|
|
$(CC) $< -link -dll -out:`cygpath -w $@`
|
|
else
|
|
%.dll: lib%.o
|
|
$(CC) -o $@ $< -shared -Wl,--out-implib=$@.a
|
|
endif
|
|
|
|
$(TMPDIR)/lib%.o: %.c
|
|
$(call COMPILE_OBJ,$@,$<)
|