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_TEST : name of the test 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_LIBS : list of host-provided libraries to link against
30# HOST_DEPS : list of libraries to build and link against. Recursive
31#             dependencies are not supported.
32# HOST_COVERAGE_ENABLED : true/false enable LLVM Source-based code coverage
33
34
35# Validate arguments.
36ifeq ($(HOST_TEST), )
37$(error HOST_TEST must be specified)
38endif
39
40ifeq ($(HOST_SRCS), )
41$(error HOST_SRCS must be specified)
42endif
43
44# Select same builddir when included form user-space or kernel
45ifeq ($(strip $(TRUSTY_TOP_LEVEL_BUILDDIR)),)
46HOST_TEST_BUILDDIR := $(BUILDDIR)
47else
48HOST_TEST_BUILDDIR := $(TRUSTY_TOP_LEVEL_BUILDDIR)
49endif
50
51# We should use the prebuilt linker rather than the host linker
52HOST_LDFLAGS := -B$(CLANG_BINDIR) -fuse-ld=lld
53
54HOST_CC := $(CLANG_BINDIR)/clang
55HOST_SANITIZER_FLAGS := -fsanitize=address -fno-omit-frame-pointer
56HOST_RUN_ENV := ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=$(CLANG_BINDIR)/llvm-symbolizer
57HOST_LIBCXX_CPPFLAGS := -stdlib=libc++ -isystem$(CLANG_BINDIR)/../include/c++/v1
58HOST_LIBCXX_LDFLAGS := -L$(CLANG_HOST_LIBDIR) -stdlib=libc++ -Wl,-rpath,$(CLANG_HOST_LIBDIR)
59# ASAN is not compatible with GDB.
60HOST_DEBUGGER :=
61
62HOST_INCLUDE_DIRS += $(GLOBAL_UAPI_INCLUDES) $(GLOBAL_SHARED_INCLUDES) $(GLOBAL_USER_INCLUDES)
63
64# Enable LLVM Source-based Code Coverage
65# https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
66ifeq (true,$(call TOBOOL,$(HOST_COVERAGE_ENABLED)))
67HOST_FLAGS += \
68	-fprofile-instr-generate=$(HOST_TEST).profraw \
69	-fcoverage-mapping \
70	-mllvm -enable-value-profiling=false
71
72HOST_LDFLAGS += \
73	-fprofile-instr-generate=$(HOST_TEST).profraw \
74	-fcoverage-mapping \
75	-mllvm -enable-value-profiling=false
76endif
77
78# Compile test library dependencies
79HOST_LIB_ARCHIVES :=
80$(foreach t,$(HOST_DEPS),\
81	$(eval include $(addsuffix /rules.mk,$(t))))
82
83# Compile test sources.
84GENERIC_CC := $(HOST_CC)
85GENERIC_SRCS := $(HOST_SRCS)
86GENERIC_OBJ_DIR := $(HOST_TEST_BUILDDIR)/host_tests/obj/$(HOST_TEST)
87GENERIC_FLAGS := -O1 -g -Wall -Wextra -Wno-unused-parameter -Werror $(HOST_SANITIZER_FLAGS) $(HOST_FLAGS) $(addprefix -I, $(HOST_INCLUDE_DIRS))
88GENERIC_CFLAGS := -std=c11 -D_POSIX_C_SOURCE=200809 -Wno-missing-field-initializers
89GENERIC_CPPFLAGS := -std=c++20 -Wno-c99-designator $(HOST_LIBCXX_CPPFLAGS)
90GENERIC_LOG_NAME := $(HOST_TEST)
91include make/generic_compile.mk
92
93# Link
94HOST_TEST_BIN := $(HOST_TEST_BUILDDIR)/host_tests/$(HOST_TEST)
95$(HOST_TEST_BIN): CC := $(HOST_CC)
96$(HOST_TEST_BIN): LDFLAGS := -g $(HOST_SANITIZER_FLAGS) $(HOST_LDFLAGS) $(HOST_LIBCXX_LDFLAGS) $(addprefix -l, $(HOST_LIBS))
97$(HOST_TEST_BIN): HOST_TEST := $(HOST_TEST)
98$(HOST_TEST_BIN): $(GENERIC_OBJS) $(HOST_LIB_ARCHIVES)
99	@$(call ECHO,$(HOST_TEST),linking,$@)
100	@$(MKDIR)
101	$(NOECHO)$(CC) $^ $(LDFLAGS) -o $@
102	@$(call ECHO_DONE_SILENT,$(HOST_TEST),linking,$@)
103
104# Build host test by default
105all:: $(HOST_TEST_BIN)
106
107# Aliases
108host_tests: $(HOST_TEST_BIN)
109
110run_$(HOST_TEST): RUN_ENV := $(HOST_RUN_ENV)
111run_$(HOST_TEST): DEBUGGER := $(HOST_DEBUGGER)
112run_$(HOST_TEST): $(HOST_TEST_BIN) .PHONY
113	@echo running $<
114	$(NOECHO)$(RUN_ENV) $(DEBUGGER) $<
115
116run_host_tests: run_$(HOST_TEST) .PHONY
117
118# Cleanup inputs
119HOST_TEST :=
120HOST_TEST_BUILDDIR :=
121HOST_SRCS :=
122HOST_INCLUDE_DIRS :=
123HOST_FLAGS :=
124HOST_LIBS :=
125HOST_DEPS :=
126HOST_COVERAGE_ENABLED :=
127# Cleanup internal
128HOST_CC :=
129HOST_SANITIZER_FLAGS :=
130HOST_RUN_ENV :=
131HOST_LIBCXX_CPPFLAGS :=
132HOST_LDFLAGS :=
133HOST_LIBCXX_LDFLAGS :=
134HOST_DEBUGGER :=
135HOST_TEST_BIN :=
136HOST_OBJ_DIR :=
137GENERIC_OBJS :=
138HOST_LIB_ARCHIVES :=
139