• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# SPDX-License-Identifier: LGPL-2.1
2# libtracefs version
3TFS_VERSION = 1
4TFS_PATCHLEVEL = 8
5TFS_EXTRAVERSION = 1
6TRACEFS_VERSION = $(TFS_VERSION).$(TFS_PATCHLEVEL).$(TFS_EXTRAVERSION)
7
8export TFS_VERSION
9export TFS_PATCHLEVEL
10export TFS_EXTRAVERSION
11export TRACEFS_VERSION
12
13# Note, samples and utests need 1.8.1
14LIBTRACEEVENT_MIN_VERSION = 1.8
15
16# taken from trace-cmd
17MAKEFLAGS += --no-print-directory
18
19# Makefiles suck: This macro sets a default value of $(2) for the
20# variable named by $(1), unless the variable has been set by
21# environment or command line. This is necessary for CC and AR
22# because make sets default values, so the simpler ?= approach
23# won't work as expected.
24define allow-override
25  $(if $(or $(findstring environment,$(origin $(1))),\
26            $(findstring command line,$(origin $(1)))),,\
27    $(eval $(1) = $(2)))
28endef
29
30# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
31$(call allow-override,CC,$(CROSS_COMPILE)gcc)
32$(call allow-override,AR,$(CROSS_COMPILE)ar)
33$(call allow-override,PKG_CONFIG,pkg-config)
34$(call allow-override,LD_SO_CONF_PATH,/etc/ld.so.conf.d/)
35$(call allow-override,LDCONFIG,ldconfig)
36
37EXT = -std=gnu99
38INSTALL = install
39
40# Use DESTDIR for installing into a different root directory.
41# This is useful for building a package. The program will be
42# installed in this directory as if it was the root directory.
43# Then the build tool can move it later.
44DESTDIR ?=
45DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
46
47LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1)
48ifeq ($(LP64), 1)
49  libdir_relative_temp = lib64
50else
51  libdir_relative_temp = lib
52endif
53
54libdir_relative ?= $(libdir_relative_temp)
55prefix ?= /usr/local
56man_dir ?= $(prefix)/share/man
57man_dir_SQ = '$(subst ','\'',$(man_dir))'
58libdir ?= $(prefix)/$(libdir_relative)
59libdir_SQ = '$(subst ','\'',$(libdir))'
60includedir_relative ?= include/tracefs
61includedir ?= $(prefix)/$(includedir_relative)
62includedir_SQ = '$(subst ','\'',$(includedir))'
63pkgconfig_dir ?= $(word 1,$(shell $(PKG_CONFIG) 		\
64			--variable pc_path pkg-config | tr ":" " "))
65
66TEST_LIBTRACEEVENT = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEEVENT_MIN_VERSION) libtraceevent > /dev/null 2>&1 && echo y")
67
68ifeq ("$(TEST_LIBTRACEEVENT)", "y")
69LIBTRACEEVENT_INCLUDES = $(shell sh -c "$(PKG_CONFIG) --cflags libtraceevent")
70LIBTRACEEVENT_LIBS = $(shell sh -c "$(PKG_CONFIG) --libs libtraceevent")
71else
72 ifneq ($(MAKECMDGOALS),clean)
73   $(error libtraceevent.so minimum version of $(LIBTRACEEVENT_MIN_VERSION) not installed)
74 endif
75endif
76
77ifndef NO_VSOCK
78VSOCK_DEFINED := $(shell if (echo "$(pound)include <linux/vm_sockets.h>" | $(CC) -E - >/dev/null 2>&1) ; then echo 1; else echo 0 ; fi)
79else
80VSOCK_DEFINED := 0
81endif
82
83ifndef NO_PERF
84PERF_DEFINED := $(shell if (echo "$(pound)include <linux/perf_event.h>" | $(CC) -E - >/dev/null 2>&1) ; then echo 1; else echo 0 ; fi)
85else
86PREF_DEFINED := 0
87endif
88
89etcdir ?= /etc
90etcdir_SQ = '$(subst ','\'',$(etcdir))'
91
92export man_dir man_dir_SQ html_install html_install_SQ INSTALL
93export img_install img_install_SQ
94export DESTDIR DESTDIR_SQ
95export VSOCK_DEFINED PERF_DEFINED
96
97pound := \#
98
99HELP_DIR = -DHELP_DIR=$(html_install)
100HELP_DIR_SQ = '$(subst ','\'',$(HELP_DIR))'
101#' emacs highlighting gets confused by the above escaped quote.
102
103BASH_COMPLETE_DIR ?= $(etcdir)/bash_completion.d
104
105# copy a bit from Linux kbuild
106
107ifeq ("$(origin V)", "command line")
108  VERBOSE = $(V)
109endif
110ifndef VERBOSE
111  VERBOSE = 0
112endif
113
114SILENT := $(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),1)
115
116# $(call test-build, snippet, ret) -> ret if snippet compiles
117#                                  -> empty otherwise
118test-build = $(if $(shell sh -c 'echo "$(1)" | \
119	$(CC) -o /dev/null -c -x c - > /dev/null 2>&1 && echo y'), $2)
120
121ifeq ("$(origin O)", "command line")
122
123  saved-output := $(O)
124  BUILD_OUTPUT := $(shell cd $(O) && /bin/pwd)
125  $(if $(BUILD_OUTPUT),, \
126    $(error output directory "$(saved-output)" does not exist))
127
128else
129  BUILD_OUTPUT = $(CURDIR)
130endif
131
132srctree		:= $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))
133objtree		:= $(BUILD_OUTPUT)
134src		:= $(srctree)
135obj		:= $(objtree)
136bdir		:= $(obj)/lib
137
138export prefix src obj bdir
139
140LIBTRACEFS_STATIC = $(bdir)/libtracefs.a
141LIBTRACEFS_SHARED = $(bdir)/libtracefs.so.$(TRACEFS_VERSION)
142
143LIBTRACEFS_SHARED_SO = $(bdir)/libtracefs.so
144LIBTRACEFS_SHARED_VERSION = $(bdir)/libtracefs.so.$(TFS_VERSION)
145
146PKG_CONFIG_SOURCE_FILE = libtracefs.pc
147PKG_CONFIG_FILE := $(addprefix $(obj)/,$(PKG_CONFIG_SOURCE_FILE))
148
149LPTHREAD ?= -lpthread
150LIBS = $(LIBTRACEEVENT_LIBS) $(LPTHREAD)
151
152export LIBS
153export LIBTRACEFS_STATIC LIBTRACEFS_SHARED
154export LIBTRACEEVENT_LIBS LIBTRACEEVENT_INCLUDES
155export LIBTRACEFS_SHARED_SO LIBTRACEFS_SHARED_VERSION
156
157export Q SILENT VERBOSE EXT
158
159# Include the utils
160include scripts/utils.mk
161
162INCLUDES = -I$(src)/include
163INCLUDES += -I$(src)/include/tracefs
164
165include $(src)/scripts/features.mk
166
167# Set compile option CFLAGS if not set elsewhere
168ifdef EXTRA_CFLAGS
169  CFLAGS ?= $(EXTRA_CFLAGS)
170else
171  CFLAGS ?= -g -Wall
172endif
173
174CFLAGS ?= -g -Wall
175CPPFLAGS ?=
176LDFLAGS ?=
177
178CUNIT_INSTALLED := $(shell if (printf "$(pound)include <CUnit/Basic.h>\n void main(){CU_initialize_registry();}" | $(CC) -x c - -lcunit -o /dev/null >/dev/null 2>&1) ; then echo 1; else echo 0 ; fi)
179export CUNIT_INSTALLED
180
181# Append required CFLAGS
182override CFLAGS += -D_GNU_SOURCE $(LIBTRACEEVENT_INCLUDES) $(INCLUDES)
183
184# Make sure 32 bit stat() works on large file systems
185override CFLAGS += -D_FILE_OFFSET_BITS=64
186
187export CFLAGS
188export INCLUDES
189
190all: all_cmd
191
192LIB_TARGET  = libtracefs.a libtracefs.so.$(TRACEFS_VERSION)
193LIB_INSTALL = libtracefs.a libtracefs.so*
194LIB_INSTALL := $(addprefix $(bdir)/,$(LIB_INSTALL))
195
196TARGETS = libtracefs.so libtracefs.a
197
198all_cmd: $(TARGETS) $(PKG_CONFIG_FILE)
199
200libtracefs.a: $(bdir) $(LIBTRACEFS_STATIC)
201libtracefs.so: $(bdir) $(LIBTRACEFS_SHARED)
202
203libs: libtracefs.a libtracefs.so
204
205VALGRIND = $(shell which valgrind)
206UTEST_DIR = utest
207UTEST_BINARY = trace-utest
208
209test: force $(LIBTRACEFS_STATIC)
210ifneq ($(CUNIT_INSTALLED),1)
211	$(error CUnit framework not installed, cannot build unit tests))
212endif
213	$(Q)$(call descend,$(src)/$(UTEST_DIR),$@)
214
215test_mem: test
216ifeq (, $(VALGRIND))
217	$(error "No valgrind in $(PATH), cannot run memory test")
218endif
219ifneq ($(shell id -u), 0)
220	$(error "The unit test should be run as root, as it reuqires full access to tracefs")
221endif
222	CK_FORK=no LD_LIBRARY_PATH=$(bdir) $(VALGRIND) \
223		--show-leak-kinds=all --leak-resolution=high \
224		--leak-check=full --show-possibly-lost=yes \
225		--track-origins=yes -s \
226		$(src)/$(UTEST_DIR)/$(UTEST_BINARY)
227
228define find_tag_files
229	find $(src) -name '\.pc' -prune -o -name '*\.[ch]' -print -o -name '*\.[ch]pp' \
230		! -name '\.#' -print
231endef
232
233define do_make_pkgconfig_file
234	cp -f ${PKG_CONFIG_SOURCE_FILE}.template ${PKG_CONFIG_FILE};	\
235	sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; 		\
236	sed -i "s|LIB_VERSION|${TRACEFS_VERSION}|g" ${PKG_CONFIG_FILE}; \
237	sed -i "s|LIB_DIR|${libdir_relative}|g" ${PKG_CONFIG_FILE}; \
238	sed -i "s|HEADER_DIR|$(includedir_relative)|g" ${PKG_CONFIG_FILE}; \
239	sed -i "s|LIBTRACEEVENT_MIN|$(LIBTRACEEVENT_MIN_VERSION)|g" ${PKG_CONFIG_FILE};
240endef
241
242BUILD_PREFIX := $(BUILD_OUTPUT)/build_prefix
243
244VERSION_FILE = tfs_version.h
245
246$(BUILD_PREFIX): force
247	$(Q)$(call build_prefix,$(prefix))
248
249$(PKG_CONFIG_FILE) : ${PKG_CONFIG_SOURCE_FILE}.template $(BUILD_PREFIX) $(VERSION_FILE)
250	$(Q) $(call do_make_pkgconfig_file,$(prefix))
251
252VIM_TAGS = $(obj)/tags
253EMACS_TAGS = $(obj)/TAGS
254CSCOPE_TAGS = $(obj)/cscope
255
256$(VIM_TAGS): force
257	$(RM) $@
258	$(call find_tag_files) | (cd $(obj) && xargs ctags --extra=+f --c-kinds=+px)
259
260$(EMACS_TAGS): force
261	$(RM) $@
262	$(call find_tag_files) | (cd $(obj) && xargs etags)
263
264$(CSCOPE_TAGS): force
265	$(RM) $(obj)/cscope*
266	$(call find_tag_files) | xargs cscope -b -q
267
268tags: $(VIM_TAGS)
269TAGS: $(EMACS_TAGS)
270cscope: $(CSCOPE_TAGS)
271
272ifeq ("$(DESTDIR)", "")
273# If DESTDIR is not defined, then test if after installing the library
274# and running ldconfig, if the library is visible by ld.so.
275# If not, add the path to /etc/ld.so.conf.d/trace.conf and run ldconfig again.
276define install_ld_config
277	if $(LDCONFIG); then \
278		if ! grep -q "^$(libdir)$$" $(LD_SO_CONF_PATH)/* ; then \
279			$(CC) -o $(objtree)/test $(srctree)/test.c -I $(includedir_SQ) \
280				-L $(libdir_SQ) -ltracefs &> /dev/null; \
281			if ! $(objtree)/test &> /dev/null; then \
282				$(call print_install, trace.conf, $(LD_SO_CONF_PATH)) \
283				echo $(libdir_SQ) >> $(LD_SO_CONF_PATH)/trace.conf; \
284				$(LDCONFIG); \
285			fi; \
286			$(RM) $(objtree)/test; \
287		fi; \
288	fi
289endef
290else
291# If installing to a location for another machine or package, do not bother
292# with running ldconfig.
293define install_ld_config
294endef
295endif # DESTDIR = ""
296
297install_libs: libs install_pkgconfig
298	$(Q)$(call do_install,$(LIBTRACEFS_SHARED),$(libdir_SQ)); \
299		cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ)
300	$(Q)$(call do_install,$(src)/include/tracefs.h,$(includedir_SQ),644)
301	$(Q)$(call install_ld_config)
302
303install: install_libs
304
305install_pkgconfig: $(PKG_CONFIG_FILE)
306	$(Q)$(call , $(PKG_CONFIG_FILE)) \
307		$(call do_install_pkgconfig_file,$(prefix))
308
309doc: check_doc
310	$(Q)$(call descend,$(src)/Documentation,all)
311
312doc_clean:
313	$(Q)$(call descend,$(src)/Documentation,clean)
314
315install_doc:
316	$(Q)$(call descend,$(src)/Documentation,install)
317
318check_doc: force
319	$(Q)$(src)/check-manpages.sh $(src)/Documentation
320
321define build_uninstall_script
322	$(Q)mkdir $(BUILD_OUTPUT)/tmp_build
323	$(Q)$(MAKE) -C $(src) DESTDIR=$(BUILD_OUTPUT)/tmp_build/ O=$(BUILD_OUTPUT) $1 > /dev/null
324	$(Q)find $(BUILD_OUTPUT)/tmp_build ! -type d -printf "%P\n" > $(BUILD_OUTPUT)/build_$2
325	$(Q)$(RM) -rf $(BUILD_OUTPUT)/tmp_build
326endef
327
328build_uninstall: $(BUILD_PREFIX)
329	$(call build_uninstall_script,install,uninstall)
330
331$(BUILD_OUTPUT)/build_uninstall: build_uninstall
332
333define uninstall_file
334	if [ -f $(DESTDIR)/$1 -o -h $(DESTDIR)/$1 ]; then \
335		$(call print_uninstall,$(DESTDIR)/$1)$(RM) $(DESTDIR)/$1; \
336	fi;
337endef
338
339uninstall: $(BUILD_OUTPUT)/build_uninstall
340	@$(foreach file,$(shell cat $(BUILD_OUTPUT)/build_uninstall),$(call uninstall_file,$(file)))
341
342PHONY += force
343force:
344
345# Declare the contents of the .PHONY variable as phony.  We keep that
346# information in a variable so we can use it in if_changed and friends.
347.PHONY: $(PHONY)
348
349DEFAULT_TARGET = $(LIBTRACEFS_STATIC)
350
351OBJS =
352OBJS += tracefs-utils.o
353OBJS += tracefs-instance.o
354OBJS += tracefs-events.o
355
356OBJS := $(OBJS:%.o=$(bdir)/%.o)
357
358all: $(DEFAULT_TARGET)
359
360$(bdir):
361	@mkdir -p $(bdir)
362
363VERSION = $(TFS_VERSION)
364PATCHLEVEL = $(TFS_PATCHLEVEL)
365EXTRAVERSION = $(TFS_EXTRAVERSION)
366
367define make_version.h
368  (echo '/* This file is automatically generated. Do not modify. */';		\
369   echo \#define VERSION_CODE $(shell						\
370   expr $(VERSION) \* 256 + $(PATCHLEVEL));					\
371   echo '#define EXTRAVERSION ' $(EXTRAVERSION);				\
372   echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"';	\
373  ) > $1
374endef
375
376define update_version.h
377  ($(call make_version.h, $@.tmp);		\
378    if [ -r $@ ] && cmp -s $@ $@.tmp; then	\
379      rm -f $@.tmp;				\
380    else					\
381      echo '  UPDATE             $@';		\
382      mv -f $@.tmp $@;				\
383    fi);
384endef
385
386$(VERSION_FILE): force
387	$(Q)$(call update_version.h)
388
389$(LIBTRACEFS_STATIC): force
390	$(Q)$(call descend,$(src)/src,$@)
391
392$(bdir)/libtracefs.so.$(TRACEFS_VERSION): force
393	$(Q)$(call descend,$(src)/src,libtracefs.so)
394
395samples/sqlhist: libtracefs.a
396	$(Q)$(call descend,$(src)/samples,sqlhist)
397
398sqlhist: samples/sqlhist
399
400samples: libtracefs.a force
401	$(Q)$(call descend,$(src)/samples,all)
402
403clean: clean_meson
404	$(Q)$(call descend_clean,utest)
405	$(Q)$(call descend_clean,src)
406	$(Q)$(call descend_clean,samples)
407	$(Q)$(call do_clean, \
408	  $(TARGETS) $(bdir)/*.a $(bdir)/*.so $(bdir)/*.so.* $(bdir)/*.o $(bdir)/.*.d \
409	  $(PKG_CONFIG_FILE) \
410	  $(VERSION_FILE) \
411	  $(BUILD_PREFIX))
412
413meson:
414	$(MAKE) -f Makefile.meson
415
416meson_install:
417	$(MAKE) -f Makefile.meson install
418
419meson_docs:
420	$(MAKE) -f Makefile.meson docs
421
422PHONY += clean_meson
423clean_meson:
424	$(Q)$(MAKE) -f Makefile.meson $@
425
426.PHONY: clean
427
428# libtracefs.a and libtracefs.so would concurrently enter the same directory -
429# a recipe for collisions.
430.NOTPARALLEL:
431