Makefile: Introduce LIBFDT_DIR to specify libfdt location

The arm, arm64, powerpc and riscv architectures require that libfdt is
installed on the system, however the library might not be available for
every architecture on the user's distro of choice. Or the static version of
the library, needed for the lkvm-static target, might be missing.
Fortunately, kvmtool has anticipated this situation and it includes
instructions to compile and install libfdt in the INSTALL file.
Unfortunately, those instructions do not always work (for example, because
the user is missing the needed permisssions), leaving the user unable to
compile kvmtool.

As an alternative to installing libfdt system-wide, provide the
LIBFDT_DIR variable when compiling kvmtool. For example, when compiling
with the command:

$ make ARCH=<arch> CROSS_COMPILE=<cross_compile> LIBFDT_DIR=<dir>

kvmtool will link the executable against the static version of the library
located in LIBFDT_DIR/libfdt.a.

LIBFDT_DIR takes precedence over the system library, as there are valid
reasons to prefer a self-compiled library over the one that the distro
provides (like the system library being older).

Note that this will slightly increase the size of the executable. For the
arm64 architecture, the increase has been measured to be about 100KB, or
about 5% of the total executable size.

Signed-off-by: Alexandru Elisei <>
Signed-off-by: Will Deacon <>
diff --git a/INSTALL b/INSTALL
index 951b123..2a65735 100644
@@ -91,10 +91,20 @@
 $ git clone git://
 $ cd dtc
 $ export CC=${CROSS_COMPILE}gcc
+$ make libfdt
+After compiling libfdt, the library can be installed system-wide:
 $ TRIPLET=$($CC -dumpmachine)
 $ SYSROOT=$($CC -print-sysroot)
-$ make libfdt
 $ sudo make DESTDIR=$SYSROOT PREFIX=/usr LIBDIR=/usr/lib/$TRIPLET install-lib install-includes
 This assumes a multiarch-enabled system, if there is no per-arch directory for
 libraries, replace the LIBDIR paths above with LIBDIR=/usr/lib or /usr/lib64.
+Alternatively, if installing the shared library is not desirable or possible,
+you can instruct kvmtool to use the static library when compiling by using the
+variable LIBFDT_DIR. LIBFDT_DIR should point to the dtc/libfdt directory.
+kvmtool will include the static library LIBFDT_DIR/libfdt.a in the executable,
+removing the need for the shared library to be present on the system.
+LIBFDT_DIR, when set, takes precedence over the system library.
diff --git a/Makefile b/Makefile
index faae0da..ed2414b 100644
--- a/Makefile
+++ b/Makefile
@@ -353,13 +353,28 @@
 ifeq (y,$(ARCH_WANT_LIBFDT))
-	ifneq ($(call try-build,$(SOURCE_LIBFDT),$(CFLAGS),-lfdt),y)
-          $(error No libfdt found. Please install libfdt-dev package)
-	else
+	ifneq ($(LIBFDT_DIR),)
+		ifeq ($(wildcard $(LIBFDT_DIR)),)
+                        $(error LIBFDT_DIR not found)
+		endif
+		LIBFDT_STATIC	:= $(LIBFDT_DIR)/libfdt.a
+		ifeq ($(wildcard $(LIBFDT_STATIC)),)
+                        $(error libfdt.a not found)
+		endif
+	else ifeq ($(call try-build,$(SOURCE_LIBFDT),$(CFLAGS),-lfdt),y)
 		LIBS_DYNOPT	+= -lfdt
 		LIBS_STATOPT	+= -lfdt
+	else
+                $(error No libfdt found. Please install libfdt-dev package or set LIBFDT_DIR)
@@ -433,13 +448,13 @@
 STATIC_DEPS	:= $(foreach obj,$(STATIC_OBJS),\
 		$(subst $(comma),_,$(dir $(obj)).$(notdir $(obj)).d))
 	$(E) "  LINK    " $@
 	$(E) "  LINK    " $@
 	$(E) "  LN      " $@