summaryrefslogtreecommitdiffstats
path: root/tests/run-make/tools.mk
blob: ea06b620c4cff7b24b41adb586fa0a038caf6ebf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# 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)
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,$@,$<)