1# SPDX-License-Identifier: GPL-2.0 2# libtraceevent version 3EP_VERSION = 1 4EP_PATCHLEVEL = 7 5EP_EXTRAVERSION = 1 6EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) 7 8MAKEFLAGS += --no-print-directory 9 10 11# Makefiles suck: This macro sets a default value of $(2) for the 12# variable named by $(1), unless the variable has been set by 13# environment or command line. This is necessary for CC and AR 14# because make sets default values, so the simpler ?= approach 15# won't work as expected. 16define allow-override 17 $(if $(or $(findstring environment,$(origin $(1))),\ 18 $(findstring command line,$(origin $(1)))),,\ 19 $(eval $(1) = $(2))) 20endef 21 22# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix. 23$(call allow-override,CC,$(CROSS_COMPILE)gcc) 24$(call allow-override,AR,$(CROSS_COMPILE)ar) 25$(call allow-override,NM,$(CROSS_COMPILE)nm) 26$(call allow-override,PKG_CONFIG,pkg-config) 27$(call allow-override,LD_SO_CONF_PATH,/etc/ld.so.conf.d/) 28$(call allow-override,LDCONFIG,ldconfig) 29 30EXT = -std=gnu99 31INSTALL = install 32 33# Use DESTDIR for installing into a different root directory. 34# This is useful for building a package. The program will be 35# installed in this directory as if it was the root directory. 36# Then the build tool can move it later. 37DESTDIR ?= 38DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' 39 40LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) 41ifeq ($(LP64), 1) 42 libdir_relative_temp = lib64 43else 44 libdir_relative_temp = lib 45endif 46 47libdir_relative ?= $(libdir_relative_temp) 48prefix ?= /usr/local 49libdir ?= $(prefix)/$(libdir_relative) 50man_dir ?= $(prefix)/share/man 51man_dir_SQ = '$(subst ','\'',$(man_dir))' 52pkgconfig_dir ?= $(word 1,$(shell $(PKG_CONFIG) \ 53 --variable pc_path pkg-config | tr ":" " ")) 54includedir_relative = include/traceevent 55includedir = $(prefix)/$(includedir_relative) 56includedir_SQ = '$(subst ','\'',$(includedir))' 57 58export man_dir man_dir_SQ INSTALL 59export DESTDIR DESTDIR_SQ 60export EP_VERSION EVENT_PARSE_VERSION 61 62# copy a bit from Linux kbuild 63 64ifeq ("$(origin V)", "command line") 65 VERBOSE = $(V) 66endif 67ifndef VERBOSE 68 VERBOSE = 0 69endif 70 71SILENT := $(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),1) 72 73ifeq ("$(origin O)", "command line") 74 75 saved-output := $(O) 76 BUILD_OUTPUT := $(shell cd $(O) && /bin/pwd) 77 $(if $(BUILD_OUTPUT),, \ 78 $(error output directory "$(saved-output)" does not exist)) 79 80else 81 BUILD_OUTPUT = $(CURDIR) 82endif 83 84srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)) 85objtree := $(BUILD_OUTPUT) 86src := $(srctree) 87obj := $(objtree) 88bdir := $(obj)/lib 89 90export prefix src obj bdir 91 92PKG_CONFIG_SOURCE_FILE = libtraceevent.pc 93PKG_CONFIG_FILE := $(addprefix $(obj)/,$(PKG_CONFIG_SOURCE_FILE)) 94 95export Q SILENT VERBOSE EXT 96 97# Include the utils 98include scripts/utils.mk 99 100include $(src)/scripts/features.mk 101 102# Shell quotes 103libdir_SQ = $(subst ','\'',$(libdir)) 104libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) 105 106CONFIG_INCLUDES = 107CONFIG_LIBS = 108CONFIG_FLAGS = 109 110VERSION = $(EP_VERSION) 111PATCHLEVEL = $(EP_PATCHLEVEL) 112EXTRAVERSION = $(EP_EXTRAVERSION) 113 114OBJ = $@ 115N = 116 117LIBTRACEEVENT_STATIC = $(bdir)/libtraceevent.a 118LIBTRACEEVENT_SHARED = $(bdir)/libtraceevent.so.$(EVENT_PARSE_VERSION) 119 120EP_HEADERS_DIR = $(src)/include/traceevent 121 122INCLUDES = -I. -I $(srctree)/include -I $(EP_HEADERS_DIR) $(CONFIG_INCLUDES) 123 124export LIBTRACEEVENT_STATIC LIBTRACEEVENT_SHARED EP_HEADERS_DIR 125 126# Set compile option CFLAGS 127ifdef EXTRA_CFLAGS 128 CFLAGS := $(EXTRA_CFLAGS) 129else 130 CFLAGS := -g -Wall 131endif 132 133LIBS ?= -ldl 134export LIBS 135 136set_plugin_dir := 1 137 138# Set plugin_dir to prefered global plugin location 139# If we install under $HOME directory we go under 140# $(HOME)/.local/lib/traceevent/plugins 141# 142# We dont set PLUGIN_DIR in case we install under $HOME 143# directory, because by default the code looks under: 144# $(HOME)/.local/lib/traceevent/plugins by default. 145# 146ifeq ($(plugin_dir),) 147ifeq ($(prefix),$(HOME)) 148override plugin_dir = $(HOME)/.local/lib/traceevent/plugins 149set_plugin_dir := 0 150else 151override plugin_dir = $(libdir)/traceevent/plugins 152endif 153export plugin_dir 154endif 155 156ifeq ($(set_plugin_dir),1) 157PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)" 158PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' 159export PLUGIN_DIR PLUGIN_DIR_SQ 160endif 161 162# Append required CFLAGS 163override CFLAGS += -fPIC 164override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) 165override CFLAGS += $(udis86-flags) -D_GNU_SOURCE 166 167# Make sure 32 bit stat() works on large file systems 168override CFLAGS += -D_FILE_OFFSET_BITS=64 169 170ifeq ($(VERBOSE),1) 171 Q = 172else 173 Q = @ 174endif 175 176# Disable command line variables (CFLAGS) override from top 177# level Makefile (perf), otherwise build Makefile will get 178# the same command line setup. 179MAKEOVERRIDES= 180 181export srctree CC LD CFLAGS V 182build := -f $(srctree)/build/Makefile.build dir=. obj 183 184LIB_TARGET := libtraceevent.so libtraceevent.a 185 186CMD_TARGETS = $(LIB_TARGET) $(PKG_CONFIG_FILE) 187 188TARGETS = $(CMD_TARGETS) 189 190all: all_cmd plugins 191 192$(bdir): 193 $(Q)mkdir -p $(bdir) 194 195LIB_TARGET = libtraceevent.a libtraceevent.so 196LIB_INSTALL = libtraceevent.a libtraceevent.so* 197LIB_INSTALL := $(addprefix $(bdir)/,$(LIB_INSTALL)) 198 199LIBTRACEEVENT_SHARED_SO = $(bdir)/libtraceevent.so 200LIBTRACEEVENT_SHARED_VERSION = $(bdir)/libtraceevent.so.$(EP_VERSION) 201 202export LIBTRACEEVENT_SHARED_SO LIBTRACEEVENT_SHARED_VERSION 203 204all_cmd: $(CMD_TARGETS) 205 206libtraceevent.a: $(bdir) $(LIBTRACEEVENT_STATIC) 207libtraceevent.so: $(bdir) $(LIBTRACEEVENT_SHARED) 208 209libs: libtraceevent.a libtraceevent.so 210 211$(LIBTRACEEVENT_STATIC): force 212 $(Q)$(call descend,$(src)/src,$@) 213 214$(LIBTRACEEVENT_SHARED): force 215 $(Q)$(call descend,$(src)/src,libtraceevent.so) 216 217$(bdir)/libtraceevent.so: $(bdir)/libtraceevent.so.$(EP_VERSION) 218 @ln -sf $(<F) $@ 219 220define make_version.h 221 (echo '/* This file is automatically generated. Do not modify. */'; \ 222 echo \#define VERSION_CODE $(shell \ 223 expr $(VERSION) \* 256 + $(PATCHLEVEL)); \ 224 echo '#define EXTRAVERSION ' $(EXTRAVERSION); \ 225 echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \ 226 echo '#define FILE_VERSION '$(FILE_VERSION); \ 227 ) > $1 228endef 229 230define update_version.h 231 ($(call make_version.h, $@.tmp); \ 232 if [ -r $@ ] && cmp -s $@ $@.tmp; then \ 233 rm -f $@.tmp; \ 234 else \ 235 echo ' UPDATE $@'; \ 236 mv -f $@.tmp $@; \ 237 fi); 238endef 239 240VERSION_FILE = $(obj)/ep_version.h 241 242$(VERSION_FILE): force 243 $(Q)$(N)$(call update_version.h) 244 245define update_dir 246 (echo $1 > $@.tmp; \ 247 if [ -r $@ ] && cmp -s $@ $@.tmp; then \ 248 rm -f $@.tmp; \ 249 else \ 250 echo ' UPDATE $@'; \ 251 mv -f $@.tmp $@; \ 252 fi); 253endef 254 255UTEST_DIR = utest 256 257test: force $(LIBTRACEEVENT_STATIC) 258 $(Q)$(call descend,$(UTEST_DIR),test) 259 260VIM_TAGS = $(obj)/tags 261EMACS_TAGS = $(obj)/TAGS 262 263$(VIM_TAGS): force 264 $(RM) $(VIM_TAGS) 265 find $(src) -name '*.[ch]' | (cd $(obj) && xargs ctags --extra=+f --c-kinds=+px \ 266 --regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/') 267 268tags: $(VIM_TAGS) 269 270$(EMACS_TAGS): force 271 $(RM) $(EMACS_TAGS) 272 find $(src) -name '*.[ch]' | (cd $(obj) && xargs etags \ 273 --regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/') 274 275TAGS: $(EMACS_TAGS) 276 277define build_prefix 278 (echo $1 > $@.tmp; \ 279 if [ -r $@ ] && cmp -s $@ $@.tmp; then \ 280 rm -f $@.tmp; \ 281 else \ 282 $(PRINT_GEN) \ 283 mv -f $@.tmp $@; \ 284 fi); 285endef 286 287BUILD_PREFIX := $(obj)/build_prefix 288 289$(BUILD_PREFIX): force 290 $(Q)$(call build_prefix,$(prefix)) 291 292define do_make_pkgconfig_file 293 cp -f ${PKG_CONFIG_SOURCE_FILE}.template ${PKG_CONFIG_FILE}; \ 294 sed -i "s|INSTALL_PREFIX|${1}|g" ${PKG_CONFIG_FILE}; \ 295 sed -i "s|LIB_VERSION|${EVENT_PARSE_VERSION}|g" ${PKG_CONFIG_FILE}; \ 296 sed -i "s|LIB_DIR|${libdir_relative}|g" ${PKG_CONFIG_FILE}; \ 297 sed -i "s|HEADER_DIR|$(includedir_relative)|g" ${PKG_CONFIG_FILE}; 298endef 299 300$(PKG_CONFIG_FILE) : ${PKG_CONFIG_SOURCE_FILE}.template $(BUILD_PREFIX) $(VERSION_FILE) 301 $(Q)$(print_gen)$(call do_make_pkgconfig_file,$(prefix)) 302 303define do_install_pkgconfig_file 304 if [ -n "${pkgconfig_dir}" ]; then \ 305 $(call do_install,$(PKG_CONFIG_FILE),$(pkgconfig_dir),644); \ 306 else \ 307 (echo Failed to locate pkg-config directory) 1>&2; \ 308 fi 309endef 310 311 312ifeq ("$(DESTDIR)", "") 313# If DESTDIR is not defined, then test if after installing the library 314# and running ldconfig, if the library is visible by ld.so. 315# If not, add the path to /etc/ld.so.conf.d/trace.conf and run ldconfig again. 316define install_ld_config 317 if $(LDCONFIG); then \ 318 if ! grep -q "^$(libdir)$$" $(LD_SO_CONF_PATH)/* ; then \ 319 $(CC) -o $(objtree)/test $(srctree)/test.c -I $(includedir_SQ) \ 320 -L $(libdir_SQ) -ltraceevent &> /dev/null; \ 321 if ! $(objtree)/test &> /dev/null; then \ 322 $(call print_install, trace.conf, $(LD_SO_CONF_PATH)) \ 323 echo $(libdir_SQ) >> $(LD_SO_CONF_PATH)/trace.conf; \ 324 $(LDCONFIG); \ 325 fi; \ 326 $(RM) $(objtree)/test; \ 327 fi; \ 328 fi 329endef 330else 331# If installing to a location for another machine or package, do not bother 332# with running ldconfig. 333define install_ld_config 334endef 335endif # DESTDIR = "" 336 337install: install_libs install_plugins 338 339install_libs: libs install_headers install_pkgconfig 340 $(Q)$(call do_install,$(LIBTRACEEVENT_SHARED),$(libdir_SQ)); \ 341 cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ) 342 $(Q)$(call install_ld_config) 343 344install_pkgconfig: $(PKG_CONFIG_FILE) 345 $(Q)$(call do_install_pkgconfig_file,$(prefix)) 346 347install_headers: 348 $(Q)$(call do_install,$(EP_HEADERS_DIR)/event-parse.h,$(includedir_SQ),644); 349 $(Q)$(call do_install,$(EP_HEADERS_DIR)/event-utils.h,$(includedir_SQ),644); 350 $(Q)$(call do_install,$(EP_HEADERS_DIR)/trace-seq.h,$(includedir_SQ),644); 351 $(Q)$(call do_install,$(EP_HEADERS_DIR)/kbuffer.h,$(includedir_SQ),644) 352 353install: install_libs 354 355clean: clean_plugins clean_src 356 $(Q)$(call do_clean,\ 357 $(VERSION_FILE) $(obj)/tags $(obj)/TAGS $(PKG_CONFIG_FILE) \ 358 $(LIBTRACEEVENT_STATIC) $(LIBTRACEEVENT_SHARED) \ 359 $(LIBTRACEEVENT_SHARED_SO) $(LIBTRACEEVENT_SHARED_VERSION) \ 360 $(BUILD_PREFIX)) 361 362define build_uninstall_script 363 $(Q)mkdir $(BUILD_OUTPUT)/tmp_build 364 $(Q)$(MAKE) -C $(srctree) DESTDIR=$(BUILD_OUTPUT)/tmp_build/ O=$(BUILD_OUTPUT) $1 > /dev/null 365 $(Q)find $(BUILD_OUTPUT)/tmp_build ! -type d -printf "%P\n" > $(BUILD_OUTPUT)/build_$2 366 $(Q)$(RM) -rf $(BUILD_OUTPUT)/tmp_build 367endef 368 369build_uninstall: $(BUILD_PREFIX) 370 $(call build_uninstall_script,install,uninstall) 371 372$(BUILD_OUTPUT)/build_uninstall: build_uninstall 373 374define uninstall_file 375 if [ -f $(DESTDIR)/$1 -o -h $(DESTDIR)/$1 ]; then \ 376 $(call PRINT_UNINST,$(DESTDIR)$1)$(RM) $(DESTDIR)/$1; \ 377 fi; 378endef 379 380uninstall: $(BUILD_OUTPUT)/build_uninstall 381 @$(foreach file,$(shell cat $(BUILD_OUTPUT)/build_uninstall),$(call uninstall_file,$(file))) 382 383PHONY += doc 384doc: check_doc 385 $(Q)$(call descend,$(src)/Documentation,) 386 387PHONY += doc-clean 388doc-clean: 389 $(MAKE) -C $(src)/Documentation clean 390 391PHONY += doc-install 392doc-install: 393 $(Q)$(call descend,$(src)/Documentation,install) 394 395check_doc: force 396 $(Q)$(src)/check-manpages.sh $(src)/Documentation 397 398 399PHONY += doc-uninstall 400doc-uninstall: 401 $(MAKE) -C $(src)/Documentation uninstall 402 403PHONY += help 404help: 405 @echo 'Possible targets:' 406 @echo'' 407 @echo ' all - default, compile the library and the'\ 408 'plugins' 409 @echo ' plugins - compile the plugins' 410 @echo ' install - install the library, the plugins,'\ 411 'the header and pkgconfig files' 412 @echo ' clean - clean the library and the plugins object files' 413 @echo ' doc - compile the documentation files - man'\ 414 'and html pages, in the Documentation directory' 415 @echo ' doc-clean - clean the documentation files' 416 @echo ' doc-install - install the man pages' 417 @echo ' doc-uninstall - uninstall the man pages' 418 @echo'' 419 420PHONY += plugins 421plugins: 422 $(Q)$(call descend,plugins,) 423 424PHONY += install_plugins 425install_plugins: plugins 426 $(Q)$(call descend,plugins,install) 427 428samples: libtraceevent.a force 429 $(Q)$(call descend,$(src)/samples,all) 430 431PHONY += clean_plugins 432clean_plugins: 433 $(Q)$(call descend_clean,plugins) 434 435PHONY += clean_src 436clean_src: 437 $(Q)$(call descend_clean,src) 438 439force: 440 441# Declare the contents of the .PHONY variable as phony. We keep that 442# information in a variable so we can use it in if_changed and friends. 443.PHONY: $(PHONY) 444