xref: /spdk/mk/spdk.common.mk (revision e01cb43b8578f9155d07a9bc6eee4e70a3af96b0)
1#  SPDX-License-Identifier: BSD-3-Clause
2#  Copyright (C) 2015 Intel Corporation.
3#  Copyright (c) 2017, IBM Corporation.
4#  Copyright (c) 2019, 2021 Mellanox Corporation.
5#  Copyright (c) 2022, 2024 NVIDIA CORPORATION & AFFILIATES
6#  All rights reserved.
7#  Copyright (c) 2022 Dell Inc, or its subsidiaries.
8#
9
10ifeq ($(wildcard $(SPDK_ROOT_DIR)/mk/config.mk),)
11$(error mk/config.mk: file not found. Please run configure before make)
12endif
13
14include $(SPDK_ROOT_DIR)/mk/config.mk
15-include $(SPDK_ROOT_DIR)/mk/cc.flags.mk
16-include $(SPDK_ROOT_DIR)/mk/cc.mk
17
18ifneq ($(V),1)
19Q ?= @
20endif
21S ?= $(notdir $(CURDIR))
22
23DESTDIR?=
24EXEEXT?=
25
26ifneq ($(prefix),)
27CONFIG_PREFIX=$(prefix)
28endif
29
30bindir?=$(CONFIG_PREFIX)/bin
31ifeq ($(CONFIG_LIBDIR),)
32libdir?=$(CONFIG_PREFIX)/lib
33else
34libdir?=$(CONFIG_LIBDIR)
35endif
36includedir?=$(CONFIG_PREFIX)/include
37
38ifeq ($(MAKECMDGOALS),)
39MAKECMDGOALS=$(.DEFAULT_GOAL)
40endif
41
42TARGET_TRIPLET := $(shell $(CC) -dumpmachine)
43TARGET_TRIPLET_WORDS := $(subst -, ,$(TARGET_TRIPLET))
44
45ifneq ($(filter linux%,$(TARGET_TRIPLET_WORDS)),)
46OS = Linux
47endif
48ifneq ($(filter freebsd%,$(TARGET_TRIPLET_WORDS)),)
49OS = FreeBSD
50endif
51ifneq ($(filter mingw% windows%,$(TARGET_TRIPLET_WORDS)),)
52OS = Windows
53endif
54
55TARGET_ARCHITECTURE ?= $(CONFIG_ARCH)
56TARGET_MACHINE := $(firstword $(TARGET_TRIPLET_WORDS))
57
58ifeq ($(OS),Windows)
59EXEEXT = .exe
60endif
61
62COMMON_CFLAGS = -g -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing -I$(SPDK_ROOT_DIR)/include
63
64ifneq ($(filter powerpc% ppc%,$(TARGET_MACHINE)),)
65COMMON_CFLAGS += -mcpu=$(TARGET_ARCHITECTURE)
66else ifeq ($(TARGET_MACHINE),aarch64)
67COMMON_CFLAGS += -march=$(TARGET_ARCHITECTURE)
68COMMON_CFLAGS += -DPAGE_SIZE=$(shell getconf PAGESIZE)
69else ifeq ('$(TARGET_MACHINE)|$(TARGET_ARCHITECTURE)','riscv64|native')
70# -march=native is not yet supported by GCC on RISC-V. Falling back to default.
71else ifneq ($(filter loongarch%,$(TARGET_MACHINE)),)
72COMMON_CFLAGS += -march=$(TARGET_ARCHITECTURE)
73COMMON_CFLAGS += -DPAGE_SIZE=$(shell getconf PAGESIZE)
74else
75COMMON_CFLAGS += -march=$(TARGET_ARCHITECTURE)
76endif
77
78ifeq ($(TARGET_MACHINE),x86_64)
79ifeq ($(CC_TYPE),gcc)
80ifneq (,$(shell $(CC) --target-help 2>/dev/null | grep -e -mavx512f >/dev/null && echo 1))
81# Don't use AVX-512 instructions in SPDK code - it breaks Valgrind for
82# some cases where compiler decides to hyper-optimize a relatively
83# simple operation (like int-to-float conversion) using AVX-512
84COMMON_CFLAGS += -mno-avx512f
85endif
86endif
87ifeq ($(CC_TYPE),clang)
88LLC=llc$(shell echo $(CC) | grep -o -E  "\-[0-9]{2}")
89ifneq (,$(shell $(LLC) -march=x86-64 -mattr=help 2>&1 | grep -e avx512f >/dev/null && echo 1))
90COMMON_CFLAGS += -mno-avx512f
91endif
92endif
93endif
94
95ifeq ($(CONFIG_WERROR), y)
96COMMON_CFLAGS += -Werror
97endif
98
99ifeq ($(CONFIG_LTO),y)
100COMMON_CFLAGS += -flto=jobserver
101LDFLAGS += -flto=jobserver
102else
103COMMON_CFLAGS += -fno-lto
104LDFLAGS += -fno-lto
105endif
106
107ifeq ($(CONFIG_PGO_CAPTURE),y)
108COMMON_CFLAGS += -fprofile-generate=$(CONFIG_PGO_DIR)
109LDFLAGS += -fprofile-generate=$(CONFIG_PGO_DIR)
110endif
111
112ifeq ($(CONFIG_PGO_USE),y)
113COMMON_CFLAGS += -fprofile-use=$(CONFIG_PGO_DIR) -Wno-missing-profile
114LDFLAGS += -fprofile-use=$(CONFIG_PGO_DIR)
115endif
116
117ifeq ($(CONFIG_CET),y)
118COMMON_CFLAGS += -fcf-protection
119LDFLAGS += -fcf-protection
120endif
121
122COMMON_CFLAGS += -Wformat -Wformat-security
123
124COMMON_CFLAGS += -D_GNU_SOURCE
125
126# Always build PIC code so that objects can be used in shared libs and position-independent executables
127COMMON_CFLAGS += -fPIC
128
129# Enable stack buffer overflow checking
130COMMON_CFLAGS += -fstack-protector
131
132ifeq ($(OS).$(CC_TYPE),Windows.gcc)
133# Workaround for gcc bug 86832 - invalid TLS usage
134COMMON_CFLAGS += -mstack-protector-guard=global
135endif
136
137# Prevent accidental multiple definitions of global variables
138COMMON_CFLAGS += -fno-common
139
140# Enable full RELRO - no lazy relocation (resolve everything at load time).
141# This allows the GOT to be made read-only early in the loading process.
142ifneq ($(OS),Windows)
143LDFLAGS += -Wl,-z,relro,-z,now
144endif
145
146# Make the stack non-executable.
147# This is the default in most environments, but it doesn't hurt to set it explicitly.
148ifneq ($(OS),Windows)
149LDFLAGS += -Wl,-z,noexecstack
150endif
151
152# Specify the linker to use
153ifneq ($(LD_TYPE),)
154LDFLAGS += -fuse-ld=$(LD_TYPE)
155endif
156
157SYS_LIBS =
158
159ifeq ($(OS),FreeBSD)
160SYS_LIBS += -lexecinfo -L/usr/local/lib
161COMMON_CFLAGS += -I/usr/local/include
162endif
163
164ifeq ($(CONFIG_RDMA),y)
165SYS_LIBS += -libverbs -lrdmacm
166endif
167
168ifeq ($(CONFIG_URING),y)
169SYS_LIBS += -luring
170ifneq ($(strip $(CONFIG_URING_PATH)),)
171CFLAGS += -I$(CONFIG_URING_PATH)
172LDFLAGS += -L$(CONFIG_URING_PATH)
173endif
174endif
175
176ifeq ($(CONFIG_AVAHI),y)
177SYS_LIBS += -lavahi-common -lavahi-client
178endif
179
180IPSEC_MB_DIR=$(CONFIG_IPSEC_MB_DIR)
181
182ISAL_DIR=$(SPDK_ROOT_DIR)/isa-l
183ISAL_CRYPTO_DIR=$(SPDK_ROOT_DIR)/isa-l-crypto
184ISAL_BUILD_DIR=$(SPDK_ROOT_DIR)/isalbuild
185ISAL_CRYPTO_BUILD_DIR=$(SPDK_ROOT_DIR)/isalcryptobuild
186ifeq ($(CONFIG_ISAL), y)
187COMMON_CFLAGS += -I$(ISAL_DIR)/.. -I$(ISAL_BUILD_DIR)
188ifeq ($(CONFIG_SHARED),y)
189SYS_LIBS += -L$(ISAL_DIR)/.libs -lisal
190LDFLAGS += -Wl,-rpath=$(ISAL_DIR)/.libs
191else
192SYS_LIBS += $(ISAL_DIR)/.libs/libisal.a
193endif
194ifeq ($(CONFIG_ISAL_CRYPTO), y)
195COMMON_CFLAGS += -I$(ISAL_CRYPTO_DIR)/.. -I$(ISAL_CRYPTO_BUILD_DIR)
196ifeq ($(CONFIG_SHARED),y)
197SYS_LIBS += -L$(ISAL_CRYPTO_DIR)/.libs -lisal_crypto
198LDFLAGS += -Wl,-rpath=$(ISAL_CRYPTO_DIR)/.libs
199else
200SYS_LIBS += $(ISAL_CRYPTO_DIR)/.libs/libisal_crypto.a
201endif
202endif
203endif
204
205ifeq ($(CONFIG_VFIO_USER), y)
206ifneq ($(CONFIG_VFIO_USER_DIR),)
207VFIO_USER_SRC_DIR=$(CONFIG_VFIO_USER_DIR)
208else
209VFIO_USER_SRC_DIR=$(SPDK_ROOT_DIR)/libvfio-user
210endif
211ifeq ($(CONFIG_DEBUG), y)
212VFIO_USER_BUILD_TYPE=debug
213else
214VFIO_USER_BUILD_TYPE=release
215endif
216ifeq ($(CONFIG_SHARED), y)
217VFIO_USER_BUILD_SHARED=shared
218else
219VFIO_USER_BUILD_SHARED=static
220endif
221VFIO_USER_LIB_PREFIX=/usr/local/lib
222VFIO_USER_BUILD_DIR=$(SPDK_ROOT_DIR)/build/libvfio-user/build-$(VFIO_USER_BUILD_TYPE)
223VFIO_USER_INSTALL_DIR=$(SPDK_ROOT_DIR)/build/libvfio-user
224VFIO_USER_INCLUDE_DIR=$(VFIO_USER_INSTALL_DIR)/usr/local/include
225VFIO_USER_LIBRARY_DIR=$(VFIO_USER_INSTALL_DIR)$(VFIO_USER_LIB_PREFIX)
226
227CFLAGS += -I$(VFIO_USER_INCLUDE_DIR)
228LDFLAGS += -L$(VFIO_USER_LIBRARY_DIR)
229SYS_LIBS += -lvfio-user -ljson-c
230endif
231
232ifeq ($(CONFIG_DAOS),y)
233ifneq ($(CONFIG_DAOS_DIR),)
234CFLAGS += -I$(CONFIG_DAOS_DIR)/include
235LDFLAGS += -L$(CONFIG_DAOS_DIR)/lib64
236endif
237endif
238
239ifeq ($(CONFIG_UBLK),y)
240SYS_LIBS += -luring
241endif
242
243ifeq ($(CONFIG_VTUNE),y)
244SYS_LIBS += -ldl
245COMMON_CFLAGS += -I$(CONFIG_VTUNE_DIR)/include -I$(CONFIG_VTUNE_DIR)/sdk/src/ittnotify
246endif
247
248#Attach only if FreeBSD and RDMA is specified with configure
249ifeq ($(OS),FreeBSD)
250ifeq ($(CONFIG_RDMA),y)
251# Mellanox - MLX4 HBA Userspace Library
252ifneq ("$(wildcard /usr/lib/libmlx4.*)","")
253SYS_LIBS += -lmlx4
254endif
255# Mellanox - MLX5 HBA Userspace Library
256ifneq ("$(wildcard /usr/lib/libmlx5.*)","")
257SYS_LIBS += -lmlx5
258endif
259# Chelsio HBA Userspace Library
260ifneq ("$(wildcard /usr/lib/libcxgb4.*)","")
261SYS_LIBS += -lcxgb4
262endif
263endif
264endif
265
266ifeq ($(CONFIG_FC),y)
267ifneq ($(strip $(CONFIG_FC_PATH)),)
268SYS_LIBS += -L$(CONFIG_FC_PATH)
269endif
270SYS_LIBS += -lufc
271endif
272
273ifeq ($(CONFIG_DEBUG), y)
274COMMON_CFLAGS += -DDEBUG -g3 -O0 -fno-omit-frame-pointer
275else
276COMMON_CFLAGS += -DNDEBUG -O2
277# Enable _FORTIFY_SOURCE checks - these only work when optimizations are enabled.
278COMMON_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
279endif
280
281ifeq ($(CONFIG_COVERAGE), y)
282COMMON_CFLAGS += -fprofile-arcs -ftest-coverage
283LDFLAGS += -fprofile-arcs -ftest-coverage
284ifeq ($(OS),FreeBSD)
285LDFLAGS += --coverage
286endif
287endif
288
289ifeq ($(OS),Windows)
290WPDK_DIR = $(abspath $(CONFIG_WPDK_DIR))
291COMMON_CFLAGS += -I$(WPDK_DIR)/include/wpdk -I$(WPDK_DIR)/include
292LDFLAGS += -L$(WPDK_DIR)/lib
293ifeq ($(CONFIG_SHARED),y)
294SYS_LIBS += -lwpdk
295else
296SYS_LIBS += $(WPDK_DIR)/lib/libwpdk.a
297endif
298SYS_LIBS += -ldbghelp -lkernel32 -lsetupapi -lws2_32 -lrpcrt4 -liphlpapi
299endif
300
301include $(CONFIG_ENV)/env.mk
302
303ifeq ($(CONFIG_ASAN),y)
304COMMON_CFLAGS += -fsanitize=address
305LDFLAGS += -fsanitize=address
306endif
307
308ifeq ($(CONFIG_UBSAN),y)
309COMMON_CFLAGS += -fsanitize=undefined
310LDFLAGS += -fsanitize=undefined
311endif
312
313ifeq ($(CONFIG_TSAN),y)
314COMMON_CFLAGS += -fsanitize=thread
315LDFLAGS += -fsanitize=thread
316endif
317
318ifeq ($(CONFIG_FUZZER),y)
319COMMON_CFLAGS += -fsanitize=fuzzer-no-link
320LDFLAGS += -fsanitize=fuzzer-no-link
321SYS_LIBS += $(CONFIG_FUZZER_LIB)
322endif
323
324SPDK_GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null)
325ifneq (, $(SPDK_GIT_COMMIT))
326COMMON_CFLAGS += -DSPDK_GIT_COMMIT=$(SPDK_GIT_COMMIT)
327endif
328
329ifneq ($(OS),Windows)
330COMMON_CFLAGS += -pthread
331SYS_LIBS += -pthread
332endif
333
334ifeq ($(CONFIG_IDXD_KERNEL),y)
335SYS_LIBS += -laccel-config
336endif
337
338CFLAGS   += $(COMMON_CFLAGS) -Wno-pointer-sign -Wstrict-prototypes -Wold-style-definition -std=gnu11
339CXXFLAGS += $(COMMON_CFLAGS) -std=c++11
340
341SYS_LIBS += -lrt
342ifneq ($(OS),FreeBSD)
343SYS_LIBS += -luuid
344endif
345SYS_LIBS += -lssl
346SYS_LIBS += -lcrypto
347SYS_LIBS += -lm
348
349ifeq ($(CONFIG_HAVE_LZ4),y)
350SYS_LIBS += -llz4
351endif
352
353ifeq ($(CONFIG_DPDK_UADK),y)
354SYS_LIBS += -lwd -lwd_crypto -lwd_comp
355endif
356
357PKGCONF ?= pkg-config
358ifneq ($(strip $(CONFIG_OPENSSL_PATH)),)
359CFLAGS += -I$(CONFIG_OPENSSL_PATH)/include
360LDFLAGS += -L$(CONFIG_OPENSSL_PATH)
361else
362# `libssl11` name is unique to Centos7 via EPEL
363# So it's safe to add it here without additional check for Centos7
364ifeq ($(shell $(PKGCONF) --exists libssl11 && echo 1),1)
365CFLAGS  += $(shell $(PKGCONF) --cflags libssl11)
366LDFLAGS += $(shell $(PKGCONF) --libs libssl11)
367endif
368ifeq ($(CONFIG_DPDK_UADK),y)
369CFLAGS  += $(shell $(PKGCONF) --cflags libwd)
370LDFLAGS += $(shell $(PKGCONF) --libs libwd)
371endif
372endif
373
374ifneq ($(CONFIG_NVME_CUSE)$(CONFIG_FUSE),nn)
375SYS_LIBS += -lfuse3
376endif
377
378ifeq ($(OS).$(CC_TYPE),Windows.gcc)
379# Include libssp.a for stack-protector and _FORTIFY_SOURCE
380SYS_LIBS += -l:libssp.a
381endif
382
383ifeq ($(CONFIG_HAVE_KEYUTILS),y)
384SYS_LIBS += -lkeyutils
385endif
386
387MAKEFLAGS += --no-print-directory
388
389C_SRCS += $(C_SRCS-y)
390CXX_SRCS += $(CXX_SRCS-y)
391
392OBJS = $(C_SRCS:.c=.o) $(CXX_SRCS:.cpp=.o)
393
394DEPFLAGS = -MMD -MP -MF $*.d.tmp
395
396# Compile first input $< (.c) into $@ (.o)
397COMPILE_C=\
398	$(Q)echo "  CC $S/$@"; \
399	$(CC) -o $@ $(DEPFLAGS) $(CFLAGS) -c $< && \
400	mv -f $*.d.tmp $*.d && touch -c $@
401
402COMPILE_CXX=\
403	$(Q)echo "  CXX $S/$@"; \
404	$(CXX) -o $@ $(DEPFLAGS) $(CXXFLAGS) -c $< && \
405	mv -f $*.d.tmp $*.d && touch -c $@
406
407ENV_LDFLAGS = $(if $(SPDK_NO_LINK_ENV),,$(ENV_LINKER_ARGS))
408
409# LTO build results in lots of false positive maybe-uninitialized warnings during linking
410ifeq ($(CONFIG_LTO),y)
411LDFLAGS += -Wno-maybe-uninitialized
412endif
413
414# Link $(OBJS) and $(LIBS) into $@ (app)
415LINK_C=\
416	$(Q)+echo "  LINK $(notdir $@)"; \
417	$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) $(ENV_LDFLAGS) $(SYS_LIBS)
418
419LINK_CXX=\
420	$(Q)+echo "  LINK $(notdir $@)"; \
421	$(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) $(ENV_LDFLAGS) $(SYS_LIBS)
422
423# Provide function to ease build of a shared lib
424define spdk_build_realname_shared_lib
425	$(1) -o $@ -shared $(CFLAGS) $(LDFLAGS) \
426	    -Wl,-rpath=$(DESTDIR)/$(libdir) \
427	    -Wl,--soname,$(notdir $@) \
428	    -Wl,--whole-archive $(2) -Wl,--no-whole-archive \
429	    -Wl,--version-script=$(3) \
430	    $(4) -Wl,--no-as-needed $(5) -Wl,--as-needed
431endef
432
433BUILD_LINKERNAME_LIB=\
434	ln -sf $(notdir $<) $@
435
436# Archive $(OBJS) into $@ (.a)
437LIB_C=\
438	$(Q)echo "  LIB $(notdir $@)"; \
439	rm -f $@; \
440	mkdir -p $(dir $@); \
441	$(CCAR) crDs $@ $(OBJS)
442
443# Clean up generated files listed as arguments plus a default list
444CLEAN_C=\
445	$(Q)rm -f *.a *.lib *.o *.obj *.d *.d.tmp *.pdb *.gcno *.gcda
446
447# Install a library
448INSTALL_LIB=\
449	$(Q)echo "  INSTALL $(DESTDIR)$(libdir)/$(notdir $(LIB))"; \
450	install -d -m 755 "$(DESTDIR)$(libdir)"; \
451	install -m 644 "$(LIB)" "$(DESTDIR)$(libdir)/"
452
453# Uninstall a library
454UNINSTALL_LIB=\
455	$(Q)echo "  UNINSTALL $(DESTDIR)$(libdir)/$(notdir $(LIB))";\
456	rm -f "$(DESTDIR)$(libdir)/$(notdir $(LIB))"; \
457	if [ -d "$(DESTDIR)$(libdir)" ] && [ $$(ls -A "$(DESTDIR)$(libdir)" | wc -l) -eq 0 ]; then rm -rf "$(DESTDIR)$(libdir)"; fi
458
459define pkgconfig_install
460	echo "  INSTALL $(DESTDIR)$(libdir)/pkgconfig/$(notdir $(1))";
461	install -d -m 755 "$(DESTDIR)$(libdir)/pkgconfig";
462	install -m 644 "$(1)" "$(DESTDIR)$(libdir)/pkgconfig";
463endef
464
465define pkgconfig_uninstall
466	echo "  UNINSTALL $(DESTDIR)$(libdir)/pkgconfig/$(notdir $(1))";
467	rm -f "$(DESTDIR)$(libdir)/pkgconfig/$(notdir $(1))";
468	if [ -d "$(DESTDIR)$(libdir)/pkgconfig" ] && [ $$(ls -A "$(DESTDIR)$(libdir)/pkgconfig" | wc -l) -eq 0 ]; then rm -rf "$(DESTDIR)$(libdir)/pkgconfig"; fi;
469endef
470
471ifeq ($(OS),FreeBSD)
472INSTALL_REL_SYMLINK := install -l rs
473else
474INSTALL_REL_SYMLINK := ln -sf -r
475endif
476
477define spdk_install_lib_symlink
478	$(INSTALL_REL_SYMLINK) $(DESTDIR)$(libdir)/$(1) $(DESTDIR)$(libdir)/$(2)
479endef
480
481INSTALL_SHARED_LIB=\
482	$(Q)echo "  INSTALL $(DESTDIR)$(libdir)/$(notdir $(SHARED_LINKED_LIB))"; \
483	install -d -m 755 "$(DESTDIR)$(libdir)"; \
484	if file $(SHARED_REALNAME_LIB) | grep -q 'LSB shared object'; then \
485		perm_mode=755; \
486	else \
487		perm_mode=644; \
488	fi; \
489	install -m $$perm_mode "$(SHARED_REALNAME_LIB)" "$(DESTDIR)$(libdir)/"; \
490	$(call spdk_install_lib_symlink,$(notdir $(SHARED_REALNAME_LIB)),$(notdir $(SHARED_LINKED_LIB)));
491
492# Uninstall an shared library
493UNINSTALL_SHARED_LIB=\
494	$(Q)echo "  UNINSTALL $(DESTDIR)$(libdir)/$(notdir $(SHARED_LINKED_LIB))"; \
495	rm -f "$(DESTDIR)$(libdir)/$(notdir $(SHARED_LINKED_LIB))"; \
496	rm -f "$(DESTDIR)$(libdir)/$(notdir $(SHARED_REALNAME_LIB))"; \
497	if [ -d "$(DESTDIR)$(libdir)" ] && [ $$(ls -A "$(DESTDIR)$(libdir)" | wc -l) -eq 0 ]; then rm -rf "$(DESTDIR)$(libdir)"; fi
498
499
500# Install an app binary
501INSTALL_APP=\
502	$(Q)echo "  INSTALL $(DESTDIR)$(bindir)/$(notdir $<)"; \
503	install -d -m 755 "$(DESTDIR)$(bindir)"; \
504	install -m 755 "$<" "$(DESTDIR)$(bindir)/"; \
505	patchelf --remove-rpath "$(DESTDIR)$(bindir)/$(notdir $<)" || true
506
507# Uninstall an app binary
508UNINSTALL_APP=\
509	$(Q)echo "  UNINSTALL $(DESTDIR)$(bindir)/$(notdir $(APP))"; \
510	rm -f "$(DESTDIR)$(bindir)/$(notdir $(APP))"; \
511	if [ -d "$(DESTDIR)$(bindir)" ] && [ $$(ls -A "$(DESTDIR)$(bindir)" | wc -l) -eq 0 ]; then rm -rf "$(DESTDIR)$(bindir)"; fi
512
513INSTALL_EXAMPLE=\
514	$(Q)echo "  INSTALL $(DESTDIR)$(bindir)/spdk_$(strip $(subst /,_,$(subst $(SPDK_ROOT_DIR)/examples/, ,$(CURDIR))))"; \
515	install -d -m 755 "$(DESTDIR)$(bindir)"; \
516	install -m 755 "$<" "$(DESTDIR)$(bindir)/spdk_$(strip $(subst /,_,$(subst $(SPDK_ROOT_DIR)/examples/, ,$(CURDIR))))"; \
517	patchelf --remove-rpath "$(DESTDIR)$(bindir)/spdk_$(strip $(subst /,_,$(subst $(SPDK_ROOT_DIR)/examples/, ,$(CURDIR))))/$(notdir $<)" || true
518
519# Uninstall an example binary
520UNINSTALL_EXAMPLE=\
521	$(Q)echo "  UNINSTALL $(DESTDIR)$(bindir)/spdk_$(strip $(subst /,_,$(subst $(SPDK_ROOT_DIR)/examples/, ,$(CURDIR))))"; \
522	rm -f "$(DESTDIR)$(bindir)/spdk_$(strip $(subst /,_,$(subst $(SPDK_ROOT_DIR)/examples/, ,$(CURDIR))))"; \
523	if [ -d "$(DESTDIR)$(bindir)" ] && [ $$(ls -A "$(DESTDIR)$(bindir)" | wc -l) -eq 0 ]; then rm -rf "$(DESTDIR)$(bindir)"; fi
524
525# Install a header
526INSTALL_HEADER=\
527	$(Q)echo "  INSTALL $@"; \
528	install -d -m 755 "$(DESTDIR)$(includedir)/$(dir $(patsubst $(DESTDIR)$(includedir)/%,%,$@))"; \
529	install -m 644 "$(patsubst $(DESTDIR)$(includedir)/%,%,$@)" "$(DESTDIR)$(includedir)/$(dir $(patsubst $(DESTDIR)$(includedir)/%,%,$@))";
530
531# Uninstall a header
532UNINSTALL_HEADER=\
533	$(Q)echo "  UNINSTALL $@"; \
534	rm -rf "$(DESTDIR)$(includedir)/$(dir $(patsubst $(DESTDIR)$(includedir)/%,%,$@))$(notdir $@)"; \
535	if [ -d "$(DESTDIR)$(includedir)/$(dir $(patsubst $(DESTDIR)$(includedir)/%,%,$@))" ] \
536	&& [ $$(ls -A "$(DESTDIR)$(includedir)/$(dir $(patsubst $(DESTDIR)$(includedir)/%,%,$@))" | wc -l) -eq 0 ]; \
537	then rm -rf "$(DESTDIR)$(includedir)/$(dir $(patsubst $(DESTDIR)$(includedir)/%,%,$@))"; fi
538
539%.o: %.c %.d $(MAKEFILE_LIST)
540	$(COMPILE_C)
541
542%.o: %.cpp %.d $(MAKEFILE_LIST)
543	$(COMPILE_CXX)
544
545%.d: ;
546
547define spdk_lib_list_to_static_libs
548$(1:%=$(SPDK_ROOT_DIR)/build/lib/libspdk_%.a)
549endef
550
551define spdk_lib_list_to_shared_libs
552$(1:%=$(SPDK_ROOT_DIR)/build/lib/libspdk_%.so)
553endef
554
555define add_no_as_needed
556-Wl,--no-as-needed $(1) -Wl,-as-needed
557endef
558
559define add_whole_archive
560-Wl,--whole-archive $(1) -Wl,--no-whole-archive
561endef
562
563define pkgconfig_filename
564$(SPDK_ROOT_DIR)/build/lib/pkgconfig/$(1).pc
565endef
566
567define cc_version
568$(shell $(CC) --version | head -n1 | awk '{print $$3}')
569endef
570
571define cc_version_le
572$(shell printf '%s\n%s' $(1) $(call cc_version) | sort -CV && echo 0 || echo 1)
573endef
574
575define cc_version_ge
576$(shell printf '%s\n%s' $(1) $(call cc_version) | sort -CV && echo 1 || echo 0)
577endef
578
579define cc_version_eq
580$(shell [ "$(call cc_version)" = "$(1)" ] && echo 1 || echo 0)
581endef
582
583version_major := $(shell IFS='-.' read -r v _ _ _ < $(SPDK_ROOT_DIR)/VERSION; echo $$v)
584version_minor := $(shell IFS='-.' read -r _ v _ _ < $(SPDK_ROOT_DIR)/VERSION; echo $$v | sed -e 's/^0//g')
585version_patch := $(shell IFS='-.' read -r _ _ v _ < $(SPDK_ROOT_DIR)/VERSION; echo $$v)
586version_suffix := $(shell IFS='-.' read -r _ _ _ v < $(SPDK_ROOT_DIR)/VERSION; echo $${v:+-$$v})
587
588# _uniq returns the unique elements from the list specified. It does
589# not change the order of the elements. If the same element occurs
590# multiple times in the list, the last instance is kept and the others
591# removed.
592# Example: _uniq(conf log json log util util log util) = conf json log util
593define _uniq
594$(if $1,$(call _uniq,$(filter-out $(lastword $1),$1)) $(lastword $1))
595endef
596