1#
2# Copyright (c) 2017, Google, Inc. All rights reserved
3#
4# Permission is hereby granted, free of charge, to any person obtaining
5# a copy of this software and associated documentation files
6# (the "Software"), to deal in the Software without restriction,
7# including without limitation the rights to use, copy, modify, merge,
8# publish, distribute, sublicense, and/or sell copies of the Software,
9# and to permit persons to whom the Software is furnished to do so,
10# subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be
13# included in all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22#
23
24# args:
25# HOST_TOOL_NAME : name of the host binary (required)
26# HOST_SRCS : list of source files (required)
27# HOST_INCLUDE_DIRS : list of include directories
28# HOST_FLAGS : list of flags for the compiler
29# HOST_LDFLAGS : list of flags for the compiler
30# HOST_LIBS : list of host-provided libraries to link against
31# HOST_DEPS : list of libraries to build and link against. Recursive
32#             dependencies are not supported.
33# HOST_SRCDEPS : extra source dependencies
34# HOST_STATIC_LINK : statically link the host tool
35# HOST_COVERAGE_ENABLED : true/false enable LLVM Source-based code coverage
36
37# Validate arguments.
38ifeq ($(HOST_TOOL_NAME), )
39$(error HOST_TOOL_NAME must be specified)
40endif
41
42ifeq ($(HOST_SRCS), )
43$(error HOST_SRCS must be specified)
44endif
45
46HOST_CC := $(CLANG_BINDIR)/clang
47
48ifeq (false, $(call TOBOOL,$(HOST_STATIC_LINK)))
49# ASAN is not compatible with GDB or static linking.
50HOST_SANITIZER_FLAGS := -fsanitize=address -fno-omit-frame-pointer
51else
52HOST_FLAGS += -static
53HOST_LDFLAGS += -static
54HOST_SANITIZER_FLAGS :=
55# b/319927400: There is a bug that causes a linker conflict if pthread is
56# linked _after_ libc.  Add pthread explicitly to avoid this possibility.
57HOST_LDFLAGS += -lpthread
58endif
59
60# We should use the prebuilt linker rather than the host linker
61HOST_LDFLAGS += -B$(CLANG_BINDIR) -fuse-ld=lld
62
63# When using clang, we need to always use the prebuilt libc++ library
64# because we can't be sure what version of libstdc++ the host system
65# has, or even if it exists at all.
66ifneq ($(filter stdc++ c++,$(HOST_LIBS)),)
67# Add the prebuilt libraries directory to the tool's rpath,
68# so it can use those libraries, e.g., libc++.so
69HOST_LIBCXX_CPPFLAGS := -stdlib=libc++ -isystem$(CLANG_BINDIR)/../include/c++/v1
70HOST_LIBCXX_LDFLAGS := -L$(CLANG_HOST_LIBDIR) -stdlib=libc++ -Wl,-rpath,$(CLANG_HOST_LIBDIR)
71# Add relative path inside the SDK package to RPATH
72HOST_SDK_LIBCXX_DIR := $(subst $(CLANG_BINDIR)/..,clang,$(CLANG_HOST_LIBDIR))
73HOST_LIBCXX_LDFLAGS += -Wl,-rpath,'$$ORIGIN/../../../toolchain/$(HOST_SDK_LIBCXX_DIR)'
74else
75HOST_LIBCXX_CPPFLAGS :=
76HOST_LIBCXX_LDFLAGS :=
77endif
78
79HOST_INCLUDE_DIRS += $(GLOBAL_UAPI_INCLUDES) $(GLOBAL_SHARED_INCLUDES) $(GLOBAL_USER_INCLUDES)
80
81# Enable LLVM Source-based Code Coverage
82# https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
83ifeq (true,$(call TOBOOL,$(HOST_COVERAGE_ENABLED)))
84HOST_FLAGS += \
85	-fprofile-instr-generate=$(HOST_TOOL_NAME).profraw \
86	-fcoverage-mapping
87
88HOST_LDFLAGS += \
89	-fprofile-instr-generate=$(HOST_TOOL_NAME).profraw \
90	-fcoverage-mapping
91endif
92
93# Compile tool library dependencies
94HOST_LIB_ARCHIVES :=
95include $(addsuffix /rules.mk, $(HOST_DEPS))
96
97# Compile tool sources.
98GENERIC_CC := $(HOST_CC)
99GENERIC_SRCS := $(HOST_SRCS)
100GENERIC_OBJ_DIR := $(BUILDDIR)/host_tools/obj/$(HOST_TOOL_NAME)
101GENERIC_FLAGS := -O1 -g -Wall -Wextra -Wno-unused-parameter -Werror $(HOST_SANITIZER_FLAGS) $(HOST_FLAGS) $(addprefix -I, $(HOST_INCLUDE_DIRS))
102GENERIC_CFLAGS := -std=c11 -D_POSIX_C_SOURCE=200809 -Wno-missing-field-initializers
103GENERIC_CPPFLAGS := -std=c++20 $(HOST_LIBCXX_CPPFLAGS)
104GENERIC_SRCDEPS := $(HOST_SRCDEPS)
105GENERIC_LOG_NAME := $(HOST_TOOL_NAME)
106include make/generic_compile.mk
107
108# Link
109HOST_TOOL_BIN := $(BUILDDIR)/host_tools/$(HOST_TOOL_NAME)
110$(HOST_TOOL_BIN): CC := $(HOST_CC)
111$(HOST_TOOL_BIN): LDFLAGS := -g $(HOST_SANITIZER_FLAGS) $(HOST_LDFLAGS) $(HOST_LIBCXX_LDFLAGS) $(addprefix -l, $(HOST_LIBS))
112$(HOST_TOOL_BIN): HOST_TOOL_NAME := $(HOST_TOOL_NAME)
113$(HOST_TOOL_BIN): $(GENERIC_OBJS) $(HOST_LIB_ARCHIVES)
114	@$(call ECHO,$(HOST_TOOL_NAME),linking,$@)
115	@$(MKDIR)
116	$(NOECHO)$(CC) $^ $(LDFLAGS) -o $@
117	@$(call ECHO_DONE_SILENT,$(HOST_TOOL_NAME),linking,$@)
118
119EXTRA_BUILDDEPS += $(HOST_TOOL_BIN)
120
121# Cleanup inputs
122HOST_TOOL_NAME:=
123HOST_SRCS :=
124HOST_INCLUDE_DIRS :=
125HOST_FLAGS :=
126HOST_LDFLAGS :=
127HOST_LIBS :=
128HOST_DEPS :=
129HOST_SRCDEPS :=
130HOST_STATIC_LINK :=
131# Cleanup internal
132HOST_CC :=
133HOST_SANITIZER_FLAGS :=
134HOST_SDK_LIBCXX_DIR :=
135HOST_TOOL_BIN :=
136HOST_OBJ_DIR :=
137GENERIC_OBJS :=
138HOST_LIB_ARCHIVES :=
139