1# SPDX-License-Identifier: GPL-2.0-or-later 2# 3# Device Tree Compiler 4# 5 6# 7# Version information will be constructed in this order: 8# EXTRAVERSION might be "-rc", for example. 9# LOCAL_VERSION is likely from command line. 10# CONFIG_LOCALVERSION from some future config system. 11# 12VERSION = 1 13PATCHLEVEL = 7 14SUBLEVEL = 0 15EXTRAVERSION = 16LOCAL_VERSION = 17CONFIG_LOCALVERSION = 18 19# Control the assumptions made (e.g. risking security issues) in the code. 20# See libfdt_internal.h for details 21ASSUME_MASK ?= 0 22 23CPPFLAGS = -I libfdt -I . -DFDT_ASSUME_MASK=$(ASSUME_MASK) 24WARNINGS = -Wall -Wpointer-arith -Wcast-qual -Wnested-externs -Wsign-compare \ 25 -Wstrict-prototypes -Wmissing-prototypes -Wredundant-decls -Wshadow 26CFLAGS = -g -Os $(SHAREDLIB_CFLAGS) -Werror $(WARNINGS) $(EXTRA_CFLAGS) 27 28BISON = bison 29LEX = flex 30SWIG = swig 31PKG_CONFIG ?= pkg-config 32PYTHON ?= python3 33 34INSTALL = /usr/bin/install 35INSTALL_PROGRAM = $(INSTALL) 36INSTALL_LIB = $(INSTALL) 37INSTALL_DATA = $(INSTALL) -m 644 38INSTALL_SCRIPT = $(INSTALL) 39DESTDIR = 40PREFIX = $(HOME) 41BINDIR = $(PREFIX)/bin 42LIBDIR = $(PREFIX)/lib 43INCLUDEDIR = $(PREFIX)/include 44 45HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ 46 sed -e 's/\(cygwin\|msys\).*/\1/') 47 48NO_PYTHON ?= 0 49 50NO_VALGRIND := $(shell $(PKG_CONFIG) --exists valgrind; echo $$?) 51ifeq ($(NO_VALGRIND),1) 52 CPPFLAGS += -DNO_VALGRIND 53else 54 CFLAGS += $(shell $(PKG_CONFIG) --cflags valgrind) 55endif 56 57NO_YAML := $(shell $(PKG_CONFIG) --exists yaml-0.1; echo $$?) 58ifeq ($(NO_YAML),1) 59 CFLAGS += -DNO_YAML 60else 61 LDLIBS_dtc += $(shell $(PKG_CONFIG) --libs yaml-0.1) 62 CFLAGS += $(shell $(PKG_CONFIG) --cflags yaml-0.1) 63endif 64 65ifeq ($(HOSTOS),darwin) 66SHAREDLIB_EXT = dylib 67SHAREDLIB_CFLAGS = -fPIC 68SHAREDLIB_LDFLAGS = -fPIC -dynamiclib -Wl,-install_name -Wl, 69else ifeq ($(HOSTOS),$(filter $(HOSTOS),msys cygwin)) 70SHAREDLIB_EXT = so 71SHAREDLIB_CFLAGS = 72SHAREDLIB_LDFLAGS = -shared -Wl,--version-script=$(LIBFDT_version) -Wl,-soname, 73else 74SHAREDLIB_EXT = so 75SHAREDLIB_CFLAGS = -fPIC 76SHAREDLIB_LDFLAGS = -fPIC -shared -Wl,--version-script=$(LIBFDT_version) -Wl,-soname, 77endif 78 79# 80# Overall rules 81# 82ifdef V 83VECHO = : 84else 85VECHO = echo " " 86ARFLAGS = rc 87.SILENT: 88endif 89 90NODEPTARGETS = clean 91ifeq ($(MAKECMDGOALS),) 92DEPTARGETS = all 93else 94DEPTARGETS = $(filter-out $(NODEPTARGETS),$(MAKECMDGOALS)) 95endif 96 97# 98# Rules for versioning 99# 100 101DTC_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) 102VERSION_FILE = version_gen.h 103 104CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ 105 else if [ -x /bin/bash ]; then echo /bin/bash; \ 106 else echo sh; fi ; fi) 107 108nullstring := 109space := $(nullstring) # end of line 110 111localver_config = $(subst $(space),, $(string) \ 112 $(patsubst "%",%,$(CONFIG_LOCALVERSION))) 113 114localver_cmd = $(subst $(space),, $(string) \ 115 $(patsubst "%",%,$(LOCALVERSION))) 116 117localver_scm = $(shell $(CONFIG_SHELL) ./scripts/setlocalversion) 118localver_full = $(localver_config)$(localver_cmd)$(localver_scm) 119 120dtc_version = $(DTC_VERSION)$(localver_full) 121 122# Contents of the generated version file. 123define filechk_version 124 (echo "#define DTC_VERSION \"DTC $(dtc_version)\""; ) 125endef 126 127define filechk 128 set -e; \ 129 echo ' CHK $@'; \ 130 mkdir -p $(dir $@); \ 131 $(filechk_$(1)) < $< > $@.tmp; \ 132 if [ -r $@ ] && cmp -s $@ $@.tmp; then \ 133 rm -f $@.tmp; \ 134 else \ 135 echo ' UPD $@'; \ 136 mv -f $@.tmp $@; \ 137 fi; 138endef 139 140 141include Makefile.convert-dtsv0 142include Makefile.dtc 143include Makefile.utils 144 145BIN += convert-dtsv0 146BIN += dtc 147BIN += fdtdump 148BIN += fdtget 149BIN += fdtput 150BIN += fdtoverlay 151 152SCRIPTS = dtdiff 153 154all: $(BIN) libfdt 155 156# We need both Python and swig to build/install pylibfdt. 157# This builds the given make ${target} if those deps are found. 158check_python_deps = \ 159 if $(PKG_CONFIG) --cflags $(PYTHON) >/dev/null 2>&1; then \ 160 if which swig >/dev/null 2>&1; then \ 161 can_build=yes; \ 162 fi; \ 163 fi; \ 164 if [ "$${can_build}" = "yes" ]; then \ 165 $(MAKE) $${target}; \ 166 else \ 167 echo "\#\# Skipping pylibfdt (install python dev and swig to build)"; \ 168 fi ; 169 170.PHONY: maybe_pylibfdt 171maybe_pylibfdt: FORCE 172 target=pylibfdt; $(check_python_deps) 173 174ifeq ($(NO_PYTHON),0) 175all: maybe_pylibfdt 176endif 177 178 179ifneq ($(DEPTARGETS),) 180ifneq ($(MAKECMDGOALS),libfdt) 181-include $(DTC_OBJS:%.o=%.d) 182-include $(CONVERT_OBJS:%.o=%.d) 183-include $(FDTDUMP_OBJS:%.o=%.d) 184-include $(FDTGET_OBJS:%.o=%.d) 185-include $(FDTPUT_OBJS:%.o=%.d) 186-include $(FDTOVERLAY_OBJS:%.o=%.d) 187endif 188endif 189 190 191 192# 193# Rules for libfdt 194# 195LIBFDT_dir = libfdt 196LIBFDT_archive = $(LIBFDT_dir)/libfdt.a 197LIBFDT_lib = $(LIBFDT_dir)/$(LIBFDT_LIB) 198LIBFDT_include = $(addprefix $(LIBFDT_dir)/,$(LIBFDT_INCLUDES)) 199LIBFDT_version = $(addprefix $(LIBFDT_dir)/,$(LIBFDT_VERSION)) 200 201ifeq ($(STATIC_BUILD),1) 202 CFLAGS += -static 203 LIBFDT_dep = $(LIBFDT_archive) 204else 205 LIBFDT_dep = $(LIBFDT_lib) 206endif 207 208include $(LIBFDT_dir)/Makefile.libfdt 209 210.PHONY: libfdt 211libfdt: $(LIBFDT_archive) $(LIBFDT_lib) 212 213$(LIBFDT_archive): $(addprefix $(LIBFDT_dir)/,$(LIBFDT_OBJS)) 214 215$(LIBFDT_lib): $(addprefix $(LIBFDT_dir)/,$(LIBFDT_OBJS)) $(LIBFDT_version) 216 @$(VECHO) LD $@ 217 $(CC) $(LDFLAGS) $(SHAREDLIB_LDFLAGS)$(LIBFDT_soname) -o $(LIBFDT_lib) \ 218 $(addprefix $(LIBFDT_dir)/,$(LIBFDT_OBJS)) 219 ln -sf $(LIBFDT_LIB) $(LIBFDT_dir)/$(LIBFDT_soname) 220 221ifneq ($(DEPTARGETS),) 222-include $(LIBFDT_OBJS:%.o=$(LIBFDT_dir)/%.d) 223endif 224 225# This stops make from generating the lex and bison output during 226# auto-dependency computation, but throwing them away as an 227# intermediate target and building them again "for real" 228.SECONDARY: $(DTC_GEN_SRCS) $(CONVERT_GEN_SRCS) 229 230install-bin: all $(SCRIPTS) 231 @$(VECHO) INSTALL-BIN 232 $(INSTALL) -d $(DESTDIR)$(BINDIR) 233 $(INSTALL_PROGRAM) $(BIN) $(DESTDIR)$(BINDIR) 234 $(INSTALL_SCRIPT) $(SCRIPTS) $(DESTDIR)$(BINDIR) 235 236install-lib: all 237 @$(VECHO) INSTALL-LIB 238 $(INSTALL) -d $(DESTDIR)$(LIBDIR) 239 $(INSTALL_LIB) $(LIBFDT_lib) $(DESTDIR)$(LIBDIR) 240 ln -sf $(notdir $(LIBFDT_lib)) $(DESTDIR)$(LIBDIR)/$(LIBFDT_soname) 241 ln -sf $(LIBFDT_soname) $(DESTDIR)$(LIBDIR)/libfdt.$(SHAREDLIB_EXT) 242 $(INSTALL_DATA) $(LIBFDT_archive) $(DESTDIR)$(LIBDIR) 243 244install-includes: 245 @$(VECHO) INSTALL-INC 246 $(INSTALL) -d $(DESTDIR)$(INCLUDEDIR) 247 $(INSTALL_DATA) $(LIBFDT_include) $(DESTDIR)$(INCLUDEDIR) 248 249install: install-bin install-lib install-includes 250 251.PHONY: maybe_install_pylibfdt 252maybe_install_pylibfdt: FORCE 253 target=install_pylibfdt; $(check_python_deps) 254 255ifeq ($(NO_PYTHON),0) 256install: maybe_install_pylibfdt 257endif 258 259$(VERSION_FILE): Makefile FORCE 260 $(call filechk,version) 261 262 263dtc: $(DTC_OBJS) 264 265convert-dtsv0: $(CONVERT_OBJS) 266 @$(VECHO) LD $@ 267 $(LINK.c) -o $@ $^ 268 269fdtdump: $(FDTDUMP_OBJS) 270 271fdtget: $(FDTGET_OBJS) $(LIBFDT_dep) 272 273fdtput: $(FDTPUT_OBJS) $(LIBFDT_dep) 274 275fdtoverlay: $(FDTOVERLAY_OBJS) $(LIBFDT_dep) 276 277dist: 278 git archive --format=tar --prefix=dtc-$(dtc_version)/ HEAD \ 279 > ../dtc-$(dtc_version).tar 280 cat ../dtc-$(dtc_version).tar | \ 281 gzip -9 > ../dtc-$(dtc_version).tar.gz 282 283 284# 285# Rules for pylibfdt 286# 287PYLIBFDT_dir = pylibfdt 288 289include $(PYLIBFDT_dir)/Makefile.pylibfdt 290 291.PHONY: pylibfdt 292pylibfdt: $(PYLIBFDT_dir)/_libfdt.so 293 294# 295# Release signing and uploading 296# This is for maintainer convenience, don't try this at home. 297# 298ifeq ($(MAINTAINER),y) 299GPG = gpg2 300KUP = kup 301KUPDIR = /pub/software/utils/dtc 302 303kup: dist 304 $(GPG) --detach-sign --armor -o ../dtc-$(dtc_version).tar.sign \ 305 ../dtc-$(dtc_version).tar 306 $(KUP) put ../dtc-$(dtc_version).tar.gz ../dtc-$(dtc_version).tar.sign \ 307 $(KUPDIR)/dtc-$(dtc_version).tar.gz 308endif 309 310tags: FORCE 311 rm -f tags 312 find . \( -name tests -type d -prune \) -o \ 313 \( ! -name '*.tab.[ch]' ! -name '*.lex.c' \ 314 -name '*.[chly]' -type f -print \) | xargs ctags -a 315 316# 317# Testsuite rules 318# 319TESTS_PREFIX=tests/ 320 321TESTS_BIN += dtc 322TESTS_BIN += convert-dtsv0 323TESTS_BIN += fdtput 324TESTS_BIN += fdtget 325TESTS_BIN += fdtdump 326TESTS_BIN += fdtoverlay 327ifeq ($(NO_PYTHON),0) 328TESTS_PYLIBFDT += maybe_pylibfdt 329endif 330 331ifneq ($(MAKECMDGOALS),libfdt) 332include tests/Makefile.tests 333endif 334 335# 336# Clean rules 337# 338STD_CLEANFILES = *~ *.o *.$(SHAREDLIB_EXT) *.d *.a *.i *.s core a.out vgcore.* \ 339 *.tab.[ch] *.lex.c *.output 340 341clean: libfdt_clean pylibfdt_clean tests_clean 342 @$(VECHO) CLEAN 343 rm -f $(STD_CLEANFILES) 344 rm -f $(VERSION_FILE) 345 rm -f $(BIN) 346 rm -f dtc-*.tar dtc-*.tar.sign dtc-*.tar.asc 347 348# 349# Generic compile rules 350# 351%: %.o 352 @$(VECHO) LD $@ 353 $(LINK.c) -o $@ $^ $(LDLIBS_$*) 354 355%.o: %.c 356 @$(VECHO) CC $@ 357 $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< 358 359%.o: %.S 360 @$(VECHO) AS $@ 361 $(CC) $(CPPFLAGS) $(AFLAGS) -D__ASSEMBLY__ -o $@ -c $< 362 363%.d: %.c 364 @$(VECHO) DEP $< 365 $(CC) $(CPPFLAGS) $(CFLAGS) -MM -MG -MT "$*.o $@" $< > $@ 366 367%.d: %.S 368 @$(VECHO) DEP $< 369 $(CC) $(CPPFLAGS) -MM -MG -MT "$*.o $@" $< > $@ 370 371%.i: %.c 372 @$(VECHO) CPP $@ 373 $(CC) $(CPPFLAGS) -E $< > $@ 374 375%.s: %.c 376 @$(VECHO) CC -S $@ 377 $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -S $< 378 379%.a: 380 @$(VECHO) AR $@ 381 $(AR) $(ARFLAGS) $@ $^ 382 383%.lex.c: %.l 384 @$(VECHO) LEX $@ 385 $(LEX) -o$@ $< 386 387%.tab.c %.tab.h: %.y 388 @$(VECHO) BISON $@ 389 $(BISON) -b $(basename $(basename $@)) -d $< 390 391# Some checks expect dtc-parser.h, so create link 392dtc-parser.h: dtc-parser.tab.h 393 ln -s $^ $@ 394 395FORCE: 396 397ifeq ($(MAKE_RESTARTS),10) 398$(error "Make re-executed itself $(MAKE_RESTARTS) times. Infinite recursion?") 399endif 400