From dd8175cfcf9d8d34bffa4b647d8acf7049b54de7 Mon Sep 17 00:00:00 2001
From: Joel Uckelman <juckelman@strozfriedberg.co.uk>
Date: Tue, 18 Dec 2018 13:15:43 +0000
Subject: [PATCH] * Produce a .pc file for libtsk. * Move the libdl check to
 occur before the non-pkgconfig sqlite3 check, and do it only once. * Add
 dependency CFLAGS to CXXFLAGS, since there are now cpp files which need them.
 * Defined TSK_OPT_DEP_CHECK to eliminate duplicate code when checking for
 optional dependencies. * Added file for AX_PKG_CHECK_MODULES. Enabled use of
 pkg-config for depenencies which are known to support it. * Set library
 variable to "no" when AC_CHECK_HEADERS or AC_CHECK_LIB fails.

---
 .gitignore                 |   1 +
 configure.ac               | 249 +++++++++++++------------------------
 m4/ax_pkg_check_modules.m4 |  69 ++++++++++
 m4/tsk_opt_dep_check.m4    | 140 +++++++++++++++++++++
 tsk/Makefile.am            |  17 +++
 tsk/tsk.pc.in              |  15 +++
 6 files changed, 327 insertions(+), 164 deletions(-)
 create mode 100644 m4/ax_pkg_check_modules.m4
 create mode 100644 m4/tsk_opt_dep_check.m4
 create mode 100644 tsk/tsk.pc.in

diff --git a/.gitignore b/.gitignore
index 3f5987de7..27f171d90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,6 +107,7 @@ Makefile
 stamp-h1
 tsk/tsk_config.h
 tsk/tsk_incs.h
+tsk/tsk.pc
 aclocal.m4
 autom4te.cache
 config.log
diff --git a/configure.ac b/configure.ac
index 7d9e6b231..5520f8134 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,8 @@ AC_PROG_LN_S
 AC_PROG_MAKE_SET
 AC_PATH_PROG(PERL, perl)
 
+TSK_CHECK_PROG_PKGCONFIG
+
 dnl Checks for header files.
 AC_HEADER_STDC
 dnl AC_HEADER_MAJOR
@@ -124,97 +126,98 @@ AC_CHECK_HEADERS(string, , , AC_MSG_ERROR([missing STL string class header]))
 AC_CHECK_HEADERS(vector, , , AC_MSG_ERROR([missing STL vector class header]))
 
 dnl Check for sqlite and its dependencies
-AC_CHECK_HEADERS([sqlite3.h],
-                 [AC_CHECK_LIB(dl, dlopen)
-                  AC_CHECK_LIB(sqlite3, sqlite3_open)])
+AS_IF([test "x$ac_cv_prog_PKGCONFIG" = "xyes"],
+  [
+    SAVED_AX_PACKAGE_REQUIRES_PRIVATE="$AX_PACKAGE_REQUIRES_PRIVATE"
+    TSK_PKG_CHECK_MODULES([SQLITE3], [], [sqlite3],
+    [
+      CFLAGS="$CFLAGS $SQLITE3_CFLAGS"
+      CXXFLAGS="$CXXFLAGS $SQLITE3_CFLAGS"
+      LIBS="$LIBS $SQLITE3_LIBS"
+    ],
+    [
+      AX_PACKAGE_REQUIRES_PRIVATE="$SAVED_AX_PACKAGE_REQUIRES_PRIVATE"
+      ax_sqlite3=no
+    ]
+  )]
+)
+
+dnl needed for sqllite
+AC_CHECK_LIB(dl, dlopen)
+
+AC_CHECK_HEADERS([sqlite3.h], [AC_CHECK_LIB([sqlite3], [sqlite3_open])])
+AS_IF([test "x$ac_cv_lib_sqlite3_sqlite3_open" = "xyes"], [ax_sqlite3=yes])
+
 dnl Compile the bundled sqlite if there is no system one installed
 AC_MSG_CHECKING(which sqlite3 to use)
-AS_IF([test "x$ac_cv_lib_sqlite3_sqlite3_open" = "xyes"],
-      [AC_MSG_RESULT([system])],
+AS_IF([test "x$ax_sqlite3" = "xyes"],
+      [AC_MSG_RESULT([system])
+       PACKAGE_LIBS_PRIVATE="$PACKAGE_LIBS_PRIVATE -lsqlite3"],
       [AC_MSG_RESULT([bundled])])
-AM_CONDITIONAL([HAVE_LIBSQLITE3],
-               [test "x$ac_cv_lib_sqlite3_sqlite3_open" = "xyes"])
+AM_CONDITIONAL([HAVE_LIBSQLITE3], [test "x$ax_sqlite3" = "xyes"])
+
 dnl check for postgresql	
 AC_CHECK_HEADERS([postgresql/libpq-fe.h],AC_CHECK_LIB([pq],[PQlibVersion]))      
 AC_CHECK_HEADERS([libpq-fe.h],AC_CHECK_LIB([pq],[PQlibVersion]))
 AM_CONDITIONAL([HAVE_POSTGRESQL],[test "x$ac_cv_lib_pq_PQlibVersion" = "xyes"])
-AM_COND_IF([HAVE_POSTGRESQL],[ax_libpq=yes],[ax_libpq=no])
-AM_COND_IF([HAVE_POSTGRESQL], [AC_DEFINE([HAVE_LIBPQ_], [1], [Define if using libpq.])])
-
-# Check if we should link afflib.
-AC_ARG_WITH([afflib],
-    [AS_HELP_STRING([--without-afflib],[Do not use AFFLIB even if it is installed])]
-    [AS_HELP_STRING([--with-afflib=dir],[Specify that AFFLIB is installed in directory 'dir'])],
-    dnl If --with-afflib or --without-afflib is given
-    [],
-    dnl If --with-afflib or --without-afflib is given
-    [with_afflib=yes])
-
-dnl check for the lib if they did not specify no
-AS_IF([test "x$with_afflib" != "xno"],
-    dnl Test the dir if they specified something beyond yes/no
-    [AS_IF([test "x$with_afflib" != "xyes"],
-        [AS_IF([test -d ${with_afflib}/include],
-            [CPPFLAGS="$CPPFLAGS -I${with_afflib}/include"
-                LDFLAGS="$LDFLAGS -L${with_afflib}/lib"],
-            dnl Dir given was not correct
-            [AC_MSG_FAILURE([AFFLIB directory not found at ${with_afflib}])])
-        ]
-    )]
-    dnl Check for the header file first to make sure they have the dev install
-    [AC_CHECK_HEADERS([afflib/afflib.h],
-      [AC_CHECK_LIB([afflib], [af_open])]
-    )]
-)
-AS_IF([test "x$ac_cv_lib_afflib_af_open" = "xyes"], [ax_afflib=yes], [ax_afflib=no])
-
-
-dnl Check if we should link zlib
-AC_ARG_WITH([zlib],
-    [AS_HELP_STRING([--without-zlib],[Do not use ZLIB even if it is installed])]
-    [AS_HELP_STRING([--with-zlib=dir],[Specify that ZLIB is installed in directory 'dir'])],
-    dnl If --with-zlib or --without-zlib is given
-    [],
-    dnl if nothing was specified, default to a test
-    [with_zlib=yes])
-
-dnl check for the lib if they did not specify no
-AS_IF(
-   [test "x$with_zlib" != "xno"],
-   [AC_MSG_NOTICE([checking for zlib])]
-   dnl Test the dir if they specified something beyond yes/no
-   [AS_IF([test "x$with_zlib" != "xyes"],
-       [AC_MSG_NOTICE([LOOKING for zlib in ${with_zlib}])]
-       [AS_IF([test -d ${with_zlib}],
-           [CPPFLAGS="$CPPFLAGS -I${with_zlib}/include"
-                LDFLAGS="$LDFLAGS -L${with_zlib}/lib"],
-           dnl Dir given was not correct
-           [AC_MSG_FAILURE([ZLIB directory not found at ${with_zlib}])]
-       )]
-    )]
-    dnl Check for the header file first to make sure they have the dev install
-    [AC_CHECK_HEADERS([zlib.h],
-      [AC_CHECK_LIB([z], [inflate],
-         [],
-         [AC_MSG_WARN([Found zlib headers, but could not link to zlib library.  Will build without zlib.])]
-         [with_zlib=no]
-      )],
-      [AC_MSG_WARN([Could not find usable zlib headers.  Will build without zlib.])]
-      [with_zlib=no]
-    )],
-    [AC_MSG_NOTICE([NOT checking for zlib because with_zlib is no])]
+AM_COND_IF([HAVE_POSTGRESQL],
+  [AC_DEFINE([HAVE_LIBPQ_], [1], [Define if using libpq.])
+   PACKAGE_LIBS_PRIVATE="$PACKAGE_LIBS_PRIVATE -lpq"
+   ax_libpq=yes],
+  [ax_libpq=no]
 )
-AS_IF([test "x$ac_cv_lib_z_inflate" = "xyes"], [ax_zlib=yes], [ax_zlib=no])
 
-AM_CONDITIONAL([X_ZLIB],[test "x$with_zlib" != "xno" && test "x$with_zlib" != "xyes"])
-AS_IF([test "x$with_zlib" != "xno"],
-   [Z_PATH="${with_zlib}/lib"],
-   [AC_MSG_NOTICE([failed to make Z_PATH])]
-)
-AC_SUBST(Z_PATH, $Z_PATH)
-
-dnl needed for sqllite
-AC_CHECK_LIB(dl, dlopen)
+dnl Check if we should link with afflib
+TSK_OPT_DEP_CHECK([afflib], [], [], [afflib/afflib.h], [afflib], [af_open])
+dnl Check if we should link with zlib
+TSK_OPT_DEP_CHECK([zlib], [ZLIB], [zlib], [zlib.h], [z], [inflate])
+dnl Check if we should link with libewf
+TSK_OPT_DEP_CHECK([libewf], [EWF], [libewf], [libewf.h], [ewf], [libewf_get_version])
+dnl Check if we should link with libvhdi
+TSK_OPT_DEP_CHECK([libvhdi], [VHDI], [libvhdi], [libvhdi.h], [vhdi], [libvhdi_get_version])
+dnl Check if we should link with libvmdk
+TSK_OPT_DEP_CHECK([libvmdk], [VMDK], [libvmdk], [libvmdk.h], [vmdk], [libvmdk_get_version])
+
+dnl check for cppunit
+AC_ARG_ENABLE([cppunit],
+    [AS_HELP_STRING([--disable-cppunit], [Build without cppunit tests])])
+
+ac_cv_cppunit=no
+AS_IF([test "x$enable_cppunit" != "xno"], [
+  AS_IF([test "x$ac_cv_prog_PKGCONFIG" = "xyes"],
+    [
+      dnl IGNOREs keep cppunit out of .pc file, as it's for testing only
+      TSK_PKG_CHECK_MODULES([CPPUNIT], [], [cppunit >= 1.12.1], [ac_cv_cppunit=yes], [ac_cv_cppunit=no], [IGNORE], [IGNORE])
+    ]
+  )
+
+  AS_IF([test "x$ac_cv_cppunit" != "xyes"],
+    [AM_PATH_CPPUNIT(1.12.1)
+     AS_IF([test "x$no_cppunit" = x], [ac_cv_cppunit=yes])]
+  )
+
+  AC_MSG_CHECKING([for TestRunner in -lcppunit])
+
+  SAVED_CFLAGS="$CFLAGS"
+  SAVED_LDFLAGS="$LDFLAGS"
+  CFLAGS="$CPPUNIT_CLFAGS"
+  LDFLAGS="$CPPUNIT_LIBS"
+
+  AC_LANG_PUSH([C++])
+  AC_LINK_IFELSE([AC_LANG_PROGRAM(
+    [[#include <cppunit/ui/text/TestRunner.h>]],
+    [[CppUnit::TextUi::TestRunner();]])],
+    [ax_cv_cppunit=yes],
+    [ax_cv_cppunit=no])
+  AC_LANG_POP([C++])
+
+  CFLAGS="$SAVED_CFLAGS"
+  LDFLAGS="$SAVED_LDFLAGS"
+
+  AC_MSG_RESULT([$ax_cv_cppunit])
+])
+
+AM_CONDITIONAL([HAVE_CPPUNIT],[test "x$ac_cv_cppunit" = xyes])
 
 dnl check for user online input
 
@@ -228,88 +231,6 @@ AC_ARG_ENABLE([offline],
 
 AM_CONDITIONAL([OFFLINE], [test "x$offline" = xtrue])
 
-
-dnl Check if we should link libewf.
-AC_ARG_WITH([libewf],
-    [AS_HELP_STRING([--without-libewf],[Do not use libewf even if it is installed])]
-    [AS_HELP_STRING([--with-libewf=dir],[Specify that libewf is installed in directory 'dir'])],
-    dnl If --with-libewf or --without-libewf is given
-    [],
-    dnl if nothing was specified, default to a test
-    [with_libewf=yes])
-
-dnl check for the lib if they did not specify no
-AS_IF([test "x$with_libewf" != "xno"],
-    dnl Test the dir if they specified something beyond yes/no
-    [AS_IF([test "x$with_libewf" != "xyes"],
-        [AS_IF([test -d ${with_libewf}/include],
-            [CPPFLAGS="$CPPFLAGS -I${with_libewf}/include"
-                LDFLAGS="$LDFLAGS -L${with_libewf}/lib"],
-            dnl Dir given was not correct
-            [AC_MSG_FAILURE([libewf directory not found at ${with_libewf}])])
-        ]
-    )]
-    dnl Check for the header file first to make sure they have the dev install
-    [AC_CHECK_HEADERS([libewf.h],
-      [AC_CHECK_LIB([ewf], [libewf_get_version], [], [NO_LIBEWF=true])]
-    )]
-)
-AS_IF([test "x$ac_cv_lib_ewf_libewf_get_version" = "xyes"], [ax_libewf=yes], [ax_libewf=no])
-
-dnl Check if we should link libvhdi.
-AC_ARG_WITH([libvhdi],
-    [AS_HELP_STRING([--without-libvhdi],[Do not use libvhdi even if it is installed])]
-    [AS_HELP_STRING([--with-libvhdi=dir],[Specify that libvhdi is installed in directory 'dir'])],
-    dnl If --with-libvhdi or --without-libvhdi is given
-    [],
-    dnl if nothing was specified, default to a test
-    [with_libvhdi=yes])
-
-dnl check for the lib if they did not specify no
-AS_IF([test "x$with_libvhdi" != "xno"],
-    dnl Test the dir if they specified something beyond yes/no
-    [AS_IF([test "x$with_libvhdi" != "xyes"],
-        [AS_IF([test -d ${with_libvhdi}/include],
-            [CPPFLAGS="$CPPFLAGS -I${with_libvhdi}/include"
-                LDFLAGS="$LDFLAGS -L${with_libvhdi}/lib"],
-            dnl Dir given was not correct
-            [AC_MSG_FAILURE([libvhdi directory not found at ${with_libvhdi}])])
-        ]
-    )]
-    dnl Check for the header file first to make sure they have the dev install
-    [AC_CHECK_HEADERS([libvhdi.h],
-      [AC_CHECK_LIB([vhdi], [libvhdi_get_version], [], [NO_libvhdi=true])]
-    )]
-)
-AS_IF([test "x$ac_cv_lib_vhdi_libvhdi_get_version" = "xyes"], [ax_libvhdi=yes], [ax_libvhdi=no])
-
-dnl Check if we should link libvmdk.
-AC_ARG_WITH([libvmdk],
-    [AS_HELP_STRING([--without-libvmdk],[Do not use libvmdk even if it is installed])]
-    [AS_HELP_STRING([--with-libvmdk=dir],[Specify that libvmdk is installed in directory 'dir'])],
-    dnl If --with-libvmdk or --without-libvmdk is given
-    [],
-    dnl if nothing was specified, default to a test
-    [with_libvmdk=yes])
-
-dnl check for the lib if they did not specify no
-AS_IF([test "x$with_libvmdk" != "xno"],
-    dnl Test the dir if they specified something beyond yes/no
-    [AS_IF([test "x$with_libvmdk" != "xyes"],
-        [AS_IF([test -d ${with_libvmdk}/include],
-            [CPPFLAGS="$CPPFLAGS -I${with_libvmdk}/include"
-                LDFLAGS="$LDFLAGS -L${with_libvmdk}/lib"],
-            dnl Dir given was not correct
-            [AC_MSG_FAILURE([libvmdk directory not found at ${with_libvmdk}])])
-        ]
-    )]
-    dnl Check for the header file first to make sure they have the dev install
-    [AC_CHECK_HEADERS([libvmdk.h],
-      [AC_CHECK_LIB([vmdk], [libvmdk_get_version], [], [NO_libvmdk=true])]
-    )]
-)
-AS_IF([test "x$ac_cv_lib_vmdk_libvmdk_get_version" = "xyes"], [ax_libvmdk=yes], [ax_libvmdk=no])
-
 dnl Test for the various java things that we need for bindings
 AS_IF([test "x$enable_java" != "xno"], [
     dnl javac is needed to compile the JAR file
diff --git a/m4/ax_pkg_check_modules.m4 b/m4/ax_pkg_check_modules.m4
new file mode 100644
index 000000000..f3af0f684
--- /dev/null
+++ b/m4/ax_pkg_check_modules.m4
@@ -0,0 +1,69 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_pkg_check_modules.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PKG_CHECK_MODULES(PREFIX, PUBLIC-MODULES, PRIVATE-MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [PUBLIC-VARIABLE], [PRIVATE-VARIABLE])
+#
+# DESCRIPTION
+#
+#   A wrapper around PKG_CHECK_MODULES which splits the list of modules into
+#   public and private dependencies, and produces two variables listing the
+#   dependencies across all invocations of AX_PKG_CHECK_MODULES. These two
+#   variables are exposed via AC_SUBST, and should be used in a pkg-config
+#   file as the substituted values for Requires and Requires.private.
+#
+#   The PREFIX, PUBLIC-MODULES and PRIVATE-MODULES arguments should be
+#   specified as for PKG_CHECK_MODULES, with the concatenation of
+#   PUBLIC-MODULES and PRIVATE-MODULES equaling the LIST-OF-MODULES from
+#   PKG_CHECK_MODULES.  The ACTION-IF-FOUND and ACTION-IF-NOT-FOUND
+#   arguments are optional, and should also be specified as for
+#   PKG_CHECK_MODULES.  ACTION-IF-FOUND is evaluated if the full
+#   LIST-OF-MODULES is found; ACTION-IF-NOT-FOUND similarly.
+#
+#   PUBLIC-VARIABLE defaults to AX_PACKAGE_REQUIRES, and PRIVATE-VARIABLE
+#   defaults to AX_PACKAGE_REQUIRES_PRIVATE.  Both variables are AC_SUBST-ed
+#   by this macro.
+#
+#   For example:
+#
+#     AX_PKG_CHECK_MODULES([GLIB],[glib-2.0 gio-2.0],[gthread-2.0])
+#     AX_PKG_CHECK_MODULES([DBUS],[],[dbus-glib-1 >= 0.98 dbus-1])
+#
+#   results in the substitutions:
+#
+#     AX_PACKAGE_REQUIRES="glib-2.0 gio-2.0"
+#     AX_PACKAGE_REQUIRES_PRIVATE="gthread-2.0 dbus-glib-1 >= 0.98 dbus-1"
+#
+#   and can be used with a template pkg-config file (.pc.in) using:
+#
+#     Requires: @AX_PACKAGE_REQUIRES@
+#     Requires.private: @AX_PACKAGE_REQUIRES_PRIVATE@
+#
+# LICENSE
+#
+#   Copyright (c) 2014 Philip Withnall <philip@tecnocode.co.uk>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 2
+
+AC_DEFUN([AX_PKG_CHECK_MODULES],[
+    m4_define([ax_package_requires],
+              [m4_default_quoted([$6],[AX_PACKAGE_REQUIRES])])
+    m4_define([ax_package_requires_private],
+              [m4_default_quoted([$7],[AX_PACKAGE_REQUIRES_PRIVATE])])
+
+    ax_package_requires="$[]ax_package_requires $2"
+    ax_package_requires_private="$[]ax_package_requires_private $3"
+
+    PKG_CHECK_MODULES([$1],[$2 $3],[$4],[$5])
+
+    # Substitute output.
+    AC_SUBST(ax_package_requires)
+    AC_SUBST(ax_package_requires_private)
+])dnl AX_PKG_CHECK_MODULES
diff --git a/m4/tsk_opt_dep_check.m4 b/m4/tsk_opt_dep_check.m4
new file mode 100644
index 000000000..2e5333bfb
--- /dev/null
+++ b/m4/tsk_opt_dep_check.m4
@@ -0,0 +1,140 @@
+#
+# Check if pkg-config is installed and set up variables used for producing
+# the tsk.pc.
+#
+# This MUST be run before any of the other macros in this file.
+#
+AC_DEFUN([TSK_CHECK_PROG_PKGCONFIG], [
+  AC_CHECK_PROG([PKGCONFIG], [pkg-config], [yes], [no])
+  AS_IF([test "x$ac_cv_prog_PKGCONFIG" = "xyes"], [
+    m4_ifdef([PKG_PROG_PKG_CONFIG], [PKG_PROG_PKG_CONFIG], [])
+    dnl Ask for static libs during static linking
+    AS_IF([test "x$enable_shared" != "xyes"], [PKG_CONFIG="$PKG_CONFIG --static"])
+  ])
+
+  PACKAGE_LIBS_PRIVATE=
+  AC_SUBST([PACKAGE_LIBS_PRIVATE])
+])
+
+#
+# Call AX_PKG_CHECK_MODULES only if PKG_CHECK_MODULES is defined, i.e.,
+# only if we have the pkg-config macros; otherwise make it a no-op
+#
+AC_DEFUN([TSK_PKG_CHECK_MODULES], [
+  m4_ifdef([PKG_CHECK_MODULES],
+           [AX_PKG_CHECK_MODULES([$1], [$2], [$3], [$4], [$5], [$6], [$7])])
+])
+
+#
+# Check for optional dependencies.
+#
+# TSK_OPT_DEP_CHECK(DISPLAY_NAME, PKG_VAR, PKG_MODULE, HEADER_LIST, CHECK_LIB_NAME, CHECK_LIB_FUNC)
+#
+# DISPLAY_NAME is the name of the library shown by 'configure --help'
+#
+# PKG_VAR is the prefix used for variables associated with the particular
+# dependency. Each dependency may have its own CPPFLAGS, CFLAGS, CXXFLAGS,
+# and LIBS variables. E.g., "FOO" would have FOO_CPPFLAGS, FOO_CFLAGS, etc.
+#
+# PKG_MODULE is the name of the library to be checked by pkg-config.
+#
+# HEADER_LIST is a list of header files to be checked by AC_CHECK_HEADERS.
+#
+# CHECK_LIB_NAME is the name of the library to be checked by AC_CHECK_LIB.
+#
+# CHECK_LIB FUNC is the name of the function to be checked by AC_CHECK_LIB.
+#
+# If the library is found, ax_DISPLAY_NAME will be set to 'yes'; otherwise
+# to 'no'.
+#
+AC_DEFUN([TSK_OPT_DEP_CHECK], [
+  dnl Check if we should link lib
+  AC_ARG_WITH(
+    [$1],
+    [AS_HELP_STRING([--without-$1],[Do not use $1 even if it is installed])]
+    [AS_HELP_STRING([--with-$1=dir],[Specify that $1 is installed in directory 'dir'])],
+    dnl If --with-lib or --without-lib is given
+    [],
+    dnl if nothing was specified, default to a test
+    [with_$1=yes]
+  )
+
+  dnl check for lib if they did not specify no
+  ax_$1=no
+  AS_IF(
+    [test "x[$]with_$1" != "xno"],
+    [
+      dnl Save flags so we can reset them if the library isn't found
+      SAVED_CPPFLAGS="$CPPFLAGS"
+      SAVED_CFLAGS="$CFLAGS"
+      SAVED_CXXFLAGS="$CXXFLAGS"
+      SAVED_LDFLAGS="$LDFLAGS"
+      SAVED_LIBS="$LIBS"
+
+      AS_IF([test "x[$]with_$1" = "xyes"],
+        [
+          dnl Check for lib using pkg-config, if we have it
+          m4_ifval([$2], [AS_IF([test "x$ac_cv_prog_PKGCONFIG" = "xyes"],
+            [
+              SAVED_AX_PACKAGE_REQUIRES="$AX_PACKAGE_REQUIRES"
+              SAVED_AX_PACKAGE_REQUIRES_PRIVATE="$AX_PACKAGE_REQUIRES_PRIVATE"
+              TSK_PKG_CHECK_MODULES([$2], [], [$3],
+              [
+                CPPFLAGS="$CPPFLAGS [$]$2[]_CFLAGS"
+                CFLAGS="$CFLAGS [$]$2[]_CFLAGS"
+                CXXFLAGS="$CXXFLAGS [$]$2[]_CFLAGS"
+                LIBS="$LIBS [$]$2[]_LIBS"
+                ax_$1=yes
+              ],
+              [
+                AX_PACKAGE_REQUIRES="$SAVED_AX_PACKAGE_REQUIRES"
+                AX_PACKAGE_REQUIRES_PRIVATE="$SAVED_AX_PACKAGE_REQUIRES_PRIVATE"
+                ax_$1=no
+              ]
+            )]
+          )])
+        ],
+        [
+          dnl A directory was given; check that it exists
+          AS_IF([test -d "[$]with_$1/include"],
+            [
+              CPPFLAGS="$CPPFLAGS -I[$]with_$1/include"
+              LDFLAGS="$LDFLAGS -L[$]with_$1/lib"
+            ],
+            [AC_MSG_FAILURE([$1 directory not found at [$]with_$1])]
+          )
+        ]
+      )
+
+      dnl Check if the library is usable
+      AC_CHECK_HEADERS([$4], [AC_CHECK_LIB([$5], [$6])])
+      AS_IF([test "x[$]ac_cv_lib_$5[]_$6" = "xyes"],
+        [
+          dnl Library found and usable
+          AS_IF([test "x[$]ax_$1" = "xyes"],
+            [
+              dnl Library found with pkg-config; reset CPPFLAGS so as not
+              dnl to duplicate flags pkg-config puts into CFLAGS
+              CPPFLAGS="$SAVED_CPPFLAGS"
+            ],
+            [
+              ax_$1=yes
+              dnl Library found without pkg-config; ensure that it is added
+              dnl to Libs.private in tsk.pc
+              PACKAGE_LIBS_PRIVATE="$PACKAGE_LIBS_PRIVATE -l$5"
+            ]
+          )
+        ],
+        [
+          dnl Library not found or unusable; reset flags
+          CPPFLAGS="$SAVED_CPPFLAGS"
+          CFLAGS="$SAVED_CFLAGS"
+          CXXFLAGS="$SAVED_CXXFLAGS"
+          LDFLAGS="$SAVED_LDFLAGS"
+          LIBS="$SAVED_LIBS"
+          ax_$1=no
+        ]
+      )
+    ]
+  )
+])
diff --git a/tsk/Makefile.am b/tsk/Makefile.am
index a17d3de69..6624382e7 100644
--- a/tsk/Makefile.am
+++ b/tsk/Makefile.am
@@ -11,3 +11,20 @@ libtsk_la_LIBADD = base/libtskbase.la img/libtskimg.la \
 libtsk_la_LDFLAGS = -version-info 20:1:1 $(LIBTSK_LDFLAGS)
 
 EXTRA_DIST = tsk_tools_i.h docs/Doxyfile docs/*.dox docs/*.html
+
+pkgconfigdir = $(libdir)/pkgconfig
+nodist_pkgconfig_DATA = tsk.pc
+
+tsk.pc: tsk.pc.in Makefile
+	sed -e 's![@]prefix[@]!$(prefix)!g' \
+      -e 's![@]exec_prefix[@]!$(exec_prefix)!g' \
+      -e 's![@]includedir[@]!$(includedir)!g' \
+      -e 's![@]libdir[@]!$(libdir)!g' \
+      -e 's![@]PACKAGE_NAME[@]!$(PACKAGE_NAME)!g' \
+      -e 's![@]PACKAGE_VERSION[@]!$(PACKAGE_VERSION)!g' \
+      -e 's![@]AX_PACKAGE_REQUIRES[@]!$(AX_PACKAGE_REQUIRES)!g' \
+      -e 's![@]PACKAGE_LIBS_PRIVATE[@]!$(PACKAGE_LIBS_PRIVATE)!g' \
+      -e 's![@]AX_PACKAGE_REQUIRES_PRIVATE[@]!$(AX_PACKAGE_REQUIRES_PRIVATE)!g' \
+      $< >$@
+
+CLEANFILES = tsk.pc
diff --git a/tsk/tsk.pc.in b/tsk/tsk.pc.in
new file mode 100644
index 000000000..fb0f35fee
--- /dev/null
+++ b/tsk/tsk.pc.in
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+libdir=@libdir@
+
+Name: @PACKAGE_NAME@
+Description: An open source forensic toolkit
+URL: http://www.sleuthkit.org/sleuthkit
+Version: @PACKAGE_VERSION@
+
+Cflags: -I${includedir}
+Libs: -L${libdir} -ltsk
+Libs.private: @PACKAGE_LIBS_PRIVATE@
+Requires: @AX_PACKAGE_REQUIRES@
+Requires.private: @AX_PACKAGE_REQUIRES_PRIVATE@ 
-- 
GitLab