aboutsummaryrefslogtreecommitdiff
path: root/runtime/compiler-rt/Makefile
blob: 2a2cd7b905cbb0a18b9d4e9e2d0f6287a33a7f7a (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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
##===- clang/runtime/compiler-rt/Makefile ------------------*- Makefile -*-===##
#
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
#
# This file defines support for building the Clang runtime libraries (which are
# implemented by compiler-rt) and placing them in the proper locations in the
# Clang resources directory (i.e., where the driver expects them).
#
##===----------------------------------------------------------------------===##

CLANG_LEVEL := ../..
include $(CLANG_LEVEL)/Makefile

CLANG_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \
	$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc))

ResourceDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/lib/clang/$(CLANG_VERSION)
PROJ_resources := $(DESTDIR)$(PROJ_prefix)/lib/clang/$(CLANG_VERSION)

ResourceLibDir := $(ResourceDir)/lib
PROJ_resources_lib := $(PROJ_resources)/lib

# Expect compiler-rt to be in llvm/projects/compiler-rt
COMPILERRT_SRC_ROOT := $(LLVM_SRC_ROOT)/projects/compiler-rt

# We don't currently support building runtime libraries when we are
# cross-compiling. The issue is that we really want to be set up so that the
# available compiler targets are independent of the current build.
#
# Since we have to build the runtime libraries for the target, it requires we
# have a cross compiler from the build machine to the target. Although in the
# case where for the current build (host == target), we do have such a cross
# compiler, but not defined in a way that is easy for us to reuse. Regardless,
# that also wouldn't help for other possible compiler configurations.
#
# Thus, the simple set up we currently use is to assume that we will be using
# the just built Clang to compile the compiler-rt libraries. As we grow better
# cross compilation support inside Clang and tool support in LLVM, this makes it
# easier for us to achieve the goal of having the compiler targets be easily
# selected at configure time. However, this design does currently preclude the
# building of compiler-rt libraries when the Clang itself is being cross
# compiled.
#
# There are three possible solutions:
#  1. Require building a build-target version of Clang when cross compiling. This
#     is simplest, but als greatly increases the build time of cross builds.
#
#  2. Require cross builds have a build-target version of Clang available for
#     use. This is a reasonable compromise on #1, as the compiler-rt libraries
#     are simple enough that there is not a strong desire to ensure they are
#     built with the exact version of Clang being used. Similarly, as Clang
#     becomes a better cross compiler it is also increasingly more likely that
#     the cross compiler being used will already be a version of Clang.
#
#  3. Come up with an alternate mechanism to define all the toolchain
#     information that compiler-rt would need to build libraries for all the
#     requested targets. This might be a simple short term solution, but is
#     likely to be unwieldly and irritating to maintain in the long term.
ifneq ($(LLVM_CROSS_COMPILING),1)
ifneq ($(CLANG_NO_RUNTIME),1)
ifeq ($(shell test -d $(COMPILERRT_SRC_ROOT) && echo OK),OK)

# Select the compiler-rt configuration to use, and install directory.
#
# FIXME: Eventually, we want some kind of configure support for this. We want to
# build/install runtime libraries for as many targets as clang was configured to
# support.
RuntimeDirs :=
ifeq ($(OS),Darwin)
RuntimeDirs += darwin
RuntimeLibrary.darwin.Configs := \
	eprintf.a 10.4.a osx.a ios.a cc_kext.a cc_kext_ios5.a \
	asan_osx.a asan_osx_dynamic.dylib \
	profile_osx.a profile_ios.a \
	ubsan_osx.a
endif

# On Linux, include a library which has all the runtime functions.
ifeq ($(OS),Linux)
RuntimeDirs += linux
RuntimeLibrary.linux.Configs :=

# TryCompile compiler source flags
# Returns exit code of running a compiler invocation.
TryCompile = \
  $(shell \
    cflags=""; \
    for flag in $(3); do \
      cflags="$$cflags $$flag"; \
    done; \
    $(1) $$cflags $(2) -o /dev/null > /dev/null 2> /dev/null ; \
    echo $$?)

# We currently only try to generate runtime libraries on x86.
ifeq ($(ARCH),x86)
RuntimeLibrary.linux.Configs += \
	full-i386.a profile-i386.a asan-i386.a ubsan-i386.a
endif

ifeq ($(ARCH),x86_64)
RuntimeLibrary.linux.Configs += \
	full-x86_64.a profile-x86_64.a asan-x86_64.a tsan-x86_64.a msan-x86_64.a \
	ubsan-x86_64.a
# We need to build 32-bit ASan/UBsan libraries on 64-bit platform, and add them
# to the list of runtime libraries to make
# "clang -fsanitize=(address|undefined) -m32" work.
# We check that Clang can produce working 32-bit binaries by compiling a simple
# executable.
test_source = $(LLVM_SRC_ROOT)/tools/clang/runtime/compiler-rt/clang_linux_test_input.c
ifeq ($(call TryCompile,$(ToolDir)/clang,$(test_source),-m32),0)
RuntimeLibrary.linux.Configs += asan-i386.a ubsan-i386.a
endif
ifneq ($(LLVM_ANDROID_TOOLCHAIN_DIR),)
RuntimeLibrary.linux.Configs += asan-arm-android.so
endif
endif

endif

####
# The build rules below are designed to be generic and should only need to be
# modified based on changes in the compiler-rt layout or build system.
####

# Rule to build the compiler-rt libraries we need.
#
# We build all the libraries in a single shot to avoid recursive make as much as
# possible.
BuildRuntimeLibraries:
	$(Verb) $(MAKE) -C $(COMPILERRT_SRC_ROOT) \
	  ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \
	  ProjObjRoot=$(PROJ_OBJ_DIR) \
	  CC="$(ToolDir)/clang" \
	  LLVM_ANDROID_TOOLCHAIN_DIR="$(LLVM_ANDROID_TOOLCHAIN_DIR)" \
	  $(RuntimeDirs:%=clang_%)
.PHONY: BuildRuntimeLibraries
CleanRuntimeLibraries:
	$(Verb) $(MAKE) -C $(COMPILERRT_SRC_ROOT) \
	  ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \
	  ProjObjRoot=$(PROJ_OBJ_DIR) \
	  clean
.PHONY: CleanRuntimeLibraries

$(PROJ_resources_lib):
	$(Verb) $(MKDIR) $@

# Expand rules for copying/installing each individual library. We can't use
# implicit rules here because we need to match against multiple things.
define RuntimeLibraryTemplate
$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a: BuildRuntimeLibraries
	@true
$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.so: BuildRuntimeLibraries
	@true
$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.dylib: BuildRuntimeLibraries
	@true
.PRECIOUS: $(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a

# Rule to copy the libraries to their resource directory location.
$(ResourceLibDir)/$1/libclang_rt.%.a: \
		$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a \
		$(ResourceLibDir)/$1/.dir
	$(Echo) Copying runtime library $1/$$* to build dir
	$(Verb) cp $(PROJ_OBJ_DIR)/clang_$1/$$*/libcompiler_rt.a $$@
$(ResourceLibDir)/$1/libclang_rt.%.so: \
		$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.so \
		$(ResourceLibDir)/$1/.dir
	$(Echo) Copying runtime library $1/$$* to build dir
	$(Verb) cp $(PROJ_OBJ_DIR)/clang_$1/$$*/libcompiler_rt.so $$@
$(ResourceLibDir)/$1/libclang_rt.%.dylib: \
		$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.dylib \
		$(ResourceLibDir)/$1/.dir
	$(Echo) Copying runtime library $1/$$* to build dir
	$(Verb) cp $(PROJ_OBJ_DIR)/clang_$1/$$*/libcompiler_rt.dylib $$@
	$(Echo) Fixing LC_ID_DYLIB of $$@
	$(Verb) install_name_tool $$@ -id $$@
RuntimeLibrary.$1: \
		$(RuntimeLibrary.$1.Configs:%=$(ResourceLibDir)/$1/libclang_rt.%)
.PHONY: RuntimeLibrary.$1

$(PROJ_resources_lib)/$1: $(PROJ_resources_lib)
	$(Verb) $(MKDIR) $$@

$(PROJ_resources_lib)/$1/libclang_rt.%.a: \
		$(ResourceLibDir)/$1/libclang_rt.%.a | $(PROJ_resources_lib)/$1
	$(Echo) Installing compiler runtime library: $1/$$*
	$(Verb) $(DataInstall) $$< $(PROJ_resources_lib)/$1
$(PROJ_resources_lib)/$1/libclang_rt.%.so: \
		$(ResourceLibDir)/$1/libclang_rt.%.so | $(PROJ_resources_lib)/$1
	$(Echo) Installing compiler runtime library: $1/$$*
	$(Verb) $(DataInstall) $$< $(PROJ_resources_lib)/$1
$(PROJ_resources_lib)/$1/libclang_rt.%.dylib: \
		$(ResourceLibDir)/$1/libclang_rt.%.dylib | $(PROJ_resources_lib)/$1
	$(Echo) Installing compiler runtime library: $1/$$*
	$(Verb) $(DataInstall) $$< $(PROJ_resources_lib)/$1

# Rule to install runtime libraries.
RuntimeLibraryInstall.$1: \
		$(RuntimeLibrary.$1.Configs:%=$(PROJ_resources_lib)/$1/libclang_rt.%)
.PHONY: RuntimeLibraryInstall.$1
endef
$(foreach lib,$(RuntimeDirs), $(eval $(call RuntimeLibraryTemplate,$(lib))))

# Hook into the standard Makefile rules.
all-local:: $(RuntimeDirs:%=RuntimeLibrary.%)
install-local:: $(RuntimeDirs:%=RuntimeLibraryInstall.%)
clean-local:: CleanRuntimeLibraries

endif
endif
endif