diff --git a/bin/identify-library-abi.c b/bin/identify-library-abi.c
new file mode 100644
index 0000000000000000000000000000000000000000..6482997148bef5cb14952b64b3a4e516cab9a79d
--- /dev/null
+++ b/bin/identify-library-abi.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <ftw.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <sysexits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include <steam-runtime-tools/glib-backports-internal.h>
+#include <steam-runtime-tools/utils-internal.h>
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(Elf, elf_end);
+
+/* nftw() doesn't have a user_data argument so we need to use a global
+ * variable */
+static GPtrArray *nftw_libraries = NULL;
+
+static gchar *opt_directory = FALSE;
+static gboolean opt_ldconfig = FALSE;
+static gboolean opt_print0 = FALSE;
+static gboolean opt_print_version = FALSE;
+static gboolean opt_skip_unversioned = FALSE;
+
+static const GOptionEntry option_entries[] =
+{
+  { "directory", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME,
+    &opt_directory, "Check the word size for the libraries recursively found in this directory",
+    NULL },
+  { "ldconfig", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
+    &opt_ldconfig, "Check the word size for the libraries listed in ldconfig", NULL },
+  { "print0", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
+    &opt_print0, "The generated library=value pairs are terminated with a "
+    "null character instead of a newline", NULL },
+  { "skip-unversioned", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
+    &opt_skip_unversioned, "Skip the libraries that have a filename that end with "
+    "just \".so\"", NULL },
+  { "version", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_print_version,
+    "Print version number and exit", NULL },
+  { NULL }
+};
+
+static gint
+list_libraries_helper (const char *fpath,
+                       const struct stat *sb,
+                       int typeflag,
+                       struct FTW *ftwbuf)
+{
+  if (typeflag == FTW_SL)
+    {
+      if (strstr (fpath, ".so.") != NULL
+          || (!opt_skip_unversioned && g_str_has_suffix (fpath, ".so")))
+        g_ptr_array_add (nftw_libraries, g_strdup (fpath));
+    }
+  return 0;
+}
+
+static void
+print_library_details (const gchar *library_path,
+                       const gchar separator,
+                       FILE *original_stdout)
+{
+  glnx_autofd int fd = -1;
+  g_autoptr(Elf) elf = NULL;
+  int class = ELFCLASSNONE;
+  const gchar *identifier = NULL;
+
+  GElf_Ehdr eh;
+
+  if ((fd = open (library_path, O_RDONLY | O_CLOEXEC, 0)) < 0)
+    {
+      int saved_errno = errno;
+      g_debug ("Error reading \"%s\": %s\n",
+               library_path, strerror (saved_errno));
+      return;
+    }
+
+    if ((elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL)
+      {
+        g_debug ("Error reading the library ELF: %s", elf_errmsg (elf_errno ()));
+        return;
+      }
+
+    if (gelf_getehdr(elf, &eh) == NULL)
+      {
+        g_debug ("Error reading the library ELF header: %s",
+                 elf_errmsg (elf_errno ()));
+        return;
+      }
+
+    class = gelf_getclass (elf);
+
+    if (class == ELFCLASS32 && eh.e_machine == EM_386)
+      identifier = "i386-linux-gnu";
+    else if (class == ELFCLASS32 && eh.e_machine == EM_X86_64)
+      identifier = "x86_64-linux-gnux32";
+    else if (class == ELFCLASS64 && eh.e_machine == EM_X86_64)
+      identifier = "x86_64-linux-gnu";
+    else
+      identifier = "?";
+
+    fprintf (original_stdout, "%s=%s%c", library_path, identifier, separator);
+}
+
+static gboolean
+run (int argc,
+     char **argv,
+     GError **error)
+{
+  g_autoptr(FILE) original_stdout = NULL;
+  g_autofree gchar *output = NULL;
+  gint wait_status = 0;
+  gsize i;
+  const gchar *ldconfig_argv[] =
+    {
+      "/sbin/ldconfig", "-XNv", NULL,
+    };
+  char separator = '\n';
+
+  /* stdout is reserved for machine-readable output, so avoid having
+   * things like g_debug() pollute it. */
+  original_stdout = _srt_divert_stdout_to_stderr (error);
+
+  if (original_stdout == NULL)
+    return FALSE;
+
+  if (opt_print0)
+    separator = '\0';
+
+  if (elf_version (EV_CURRENT) == EV_NONE)
+    return glnx_throw (error, "elf_version(EV_CURRENT): %s", elf_errmsg (elf_errno ()));
+
+  if (opt_ldconfig)
+    {
+      g_auto(GStrv) ldconfig_entries = NULL;
+      g_autofree gchar *library_prefix = NULL;
+
+      if (!g_spawn_sync (NULL,   /* working directory */
+                        (gchar **) ldconfig_argv,
+                        NULL,    /* envp */
+                        G_SPAWN_SEARCH_PATH,
+                        NULL,    /* child setup */
+                        NULL,    /* user data */
+                        &output, /* stdout */
+                        NULL,    /* stderr */
+                        &wait_status,
+                        error))
+        {
+          return FALSE;
+        }
+
+      if (wait_status != 0)
+        return glnx_throw (error, "Cannot run ldconfig: wait status %d", wait_status);
+
+      if (output == NULL)
+        return glnx_throw (error, "ldconfig didn't produce anything in output");
+
+      ldconfig_entries = g_strsplit (output, "\n", -1);
+
+      if (ldconfig_entries == NULL)
+        return glnx_throw (error, "ldconfig didn't produce anything in output");
+
+      for (i = 0; ldconfig_entries[i] != NULL; i++)
+        {
+          g_auto(GStrv) line_elements = NULL;
+          const gchar *library = NULL;
+          const gchar *colon = NULL;
+          g_autofree gchar *library_path = NULL;
+
+          /* skip empty lines */
+          if (ldconfig_entries[i][0] == '\0')
+            continue;
+
+          colon = strchr (ldconfig_entries[i], ':');
+
+          if (colon != NULL)
+            {
+              g_clear_pointer (&library_prefix, g_free);
+              library_prefix = g_strndup (ldconfig_entries[i], colon - ldconfig_entries[i]);
+              continue;
+            }
+
+          line_elements = g_strsplit (ldconfig_entries[i], " -> ", 2);
+          library = g_strstrip (line_elements[0]);
+          library_path = g_build_filename (library_prefix, library, NULL);
+
+          print_library_details (library_path, separator, original_stdout);
+        }
+    }
+  else if (opt_directory != NULL)
+    {
+      g_autofree gchar *real_directory = NULL;
+
+      nftw_libraries = g_ptr_array_new_full (512, g_free);
+      real_directory = realpath (opt_directory, NULL);
+
+      if (real_directory == NULL)
+        return glnx_throw_errno_prefix (error, "Unable to realpath \"%s\"", opt_directory);
+
+      if (nftw (real_directory, list_libraries_helper, 10, FTW_DEPTH|FTW_PHYS) < 0)
+        {
+          g_ptr_array_free (nftw_libraries, TRUE);
+          return glnx_throw_errno_prefix (error, "Unable to iterate through \"%s\"", opt_directory);
+        }
+
+      for (i = 0; i < nftw_libraries->len; i++)
+        print_library_details (g_ptr_array_index (nftw_libraries, i), separator,
+                               original_stdout);
+
+      g_ptr_array_free (nftw_libraries, TRUE);
+    }
+
+  return TRUE;
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  g_autoptr(GOptionContext) option_context = NULL;
+  g_autoptr(GError) error = NULL;
+  int status = EXIT_SUCCESS;
+
+  option_context = g_option_context_new ("");
+  g_option_context_add_main_entries (option_context, option_entries, NULL);
+
+  if (!g_option_context_parse (option_context, &argc, &argv, &error))
+    {
+      status = EX_USAGE;
+      goto out;
+    }
+
+  if (opt_print_version)
+    {
+      /* Output version number as YAML for machine-readability,
+       * inspired by `ostree --version` and `docker version` */
+      g_print ("%s:\n"
+               " Package: steam-runtime-tools\n"
+               " Version: %s\n",
+               g_get_prgname (), VERSION);
+      goto out;
+    }
+
+  if (opt_ldconfig && opt_directory != NULL)
+    {
+      glnx_throw (&error, "--ldconfig and --directory cannot be used at the same time");
+      status = EX_USAGE;
+      goto out;
+    }
+
+  if (!opt_ldconfig && opt_directory == NULL)
+    {
+      glnx_throw (&error, "Either --ldconfig or --directory are required");
+      status = EX_USAGE;
+      goto out;
+    }
+
+  if (!run (argc, argv, &error))
+    status = EXIT_FAILURE;
+
+out:
+  if (status != EXIT_SUCCESS)
+    g_printerr ("%s: %s\n", g_get_prgname (), error->message);
+
+  return status;
+}
diff --git a/bin/identify-library-abi.md b/bin/identify-library-abi.md
new file mode 100644
index 0000000000000000000000000000000000000000..de2c46b1890d4be11f2648fbc2ebe54fd86069a6
--- /dev/null
+++ b/bin/identify-library-abi.md
@@ -0,0 +1,56 @@
+---
+title: steam-runtime-identify-library-abi
+section: 1
+...
+
+# NAME
+
+steam-runtime-identify-library-abi - Identify the ABI of the libraries stored in a specific directory or from the ldconfig output list
+
+# SYNOPSIS
+
+**steam-runtime-identify-library-abi**
+
+# DESCRIPTION
+
+# OPTIONS
+
+**--directory** *DIR*
+:   The list of libraries to identify is gathered by recursively search in *DIR*.
+
+**--ldconfig**
+:   Identify the ABI of the libraries listed by the executable `ldconfig`.
+
+**--print0**
+:   The generated library_path=library_ABI pairs are terminated with a null
+    character instead of a newline.
+
+**--skip-unversioned**
+:   If a library filename ends with just `.so`, its ABI will not be identified
+    and will not be printed in output.
+
+**--version**
+:   Instead of performing the libraries identification, write in output the
+    version number as YAML.
+
+# OUTPUT
+
+**steam-runtime-identify-library-abi** standard output is machine parsable, with
+pairs of `library_path=library_ABI` separated by a null character, with the option
+**--print0**, or by newlines.
+Where `library_ABI` follows the Debian-style multiarch tuples convention and
+currently can have the following values: `i386-linux-gnu`, `x86_64-linux-gnu`,
+`x86_64-linux-gnux32`, or `?` that groups all the other possible ABIs.
+
+# EXIT STATUS
+
+0
+:   Success.
+
+64
+:   Invalid arguments were given (EX_USAGE).
+
+Other Nonzero
+:   An error occurred.
+
+<!-- vim:set sw=4 sts=4 et: -->
diff --git a/bin/meson.build b/bin/meson.build
index d0d1975479c3430cf7e72ca3a5fd81be96de28d9..0706659af464caa6d47e658e4ea9f9a21513609e 100644
--- a/bin/meson.build
+++ b/bin/meson.build
@@ -1,4 +1,4 @@
-# Copyright © 2019 Collabora Ltd.
+# Copyright © 2019-2021 Collabora Ltd.
 #
 # SPDX-License-Identifier: MIT
 #
@@ -41,6 +41,16 @@ executable(
   install_rpath : bin_rpath,
 )
 
+executable(
+  'steam-runtime-identify-library-abi',
+  'identify-library-abi.c',
+  dependencies : [glib, gio_unix, libelf, libglnx_dep, libsteamrt_static_dep],
+  install : true,
+  # Use GLib from the adjacent libdir, ignoring LD_LIBRARY_PATH
+  build_rpath : bin_rpath,
+  install_rpath : bin_rpath,
+)
+
 executable(
   'steam-runtime-input-monitor',
   'input-monitor.c',
@@ -74,6 +84,7 @@ executable(
 if get_option('man')
   foreach bin_name : [
     'check-requirements',
+    'identify-library-abi',
     'input-monitor',
     'steam-remote',
     'system-info',
diff --git a/tests/identify-library-abi-cli.c b/tests/identify-library-abi-cli.c
new file mode 100644
index 0000000000000000000000000000000000000000..05bd126d9a88406d9db76f5fd208582055dce994
--- /dev/null
+++ b/tests/identify-library-abi-cli.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <steam-runtime-tools/steam-runtime-tools.h>
+#include <steam-runtime-tools/glib-backports-internal.h>
+#include <steam-runtime-tools/utils-internal.h>
+
+#include <glib.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <sysexits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "test-utils.h"
+
+static const char *argv0;
+static gchar *empty_temp_dir;
+
+typedef struct
+{
+  gchar *srcdir;
+  gchar *builddir;
+} Fixture;
+
+typedef struct
+{
+  int unused;
+} Config;
+
+typedef struct
+{
+  const gchar *path;
+  const gchar *abi;
+} LibInfo;
+
+typedef struct
+{
+  const gchar *argv[5];
+  int exit_status;
+  const gchar *stdout_contains;
+  const gchar *stderr_contains;
+} IdentifyLibraryAbi;
+
+static void
+setup (Fixture *f,
+       gconstpointer context)
+{
+  G_GNUC_UNUSED const Config *config = context;
+
+  /* For the tests we currently have they are not used yet */
+  f->srcdir = g_strdup (g_getenv ("G_TEST_SRCDIR"));
+  f->builddir = g_strdup (g_getenv ("G_TEST_BUILDDIR"));
+
+  if (f->srcdir == NULL)
+    f->srcdir = g_path_get_dirname (argv0);
+
+  if (f->builddir == NULL)
+    f->builddir = g_path_get_dirname (argv0);
+}
+
+static void
+teardown (Fixture *f,
+          gconstpointer context)
+{
+  G_GNUC_UNUSED const Config *config = context;
+
+  g_free (f->srcdir);
+  g_free (f->builddir);
+}
+
+static void
+_spawn_and_check_output (const IdentifyLibraryAbi *t)
+{
+  g_autofree gchar *child_stdout = NULL;
+  g_autofree gchar *child_stderr = NULL;
+  g_autoptr(GError) error = NULL;
+  gboolean ret;
+  int wait_status = -1;
+
+  ret = g_spawn_sync (NULL,    /* working directory */
+                      (gchar **) t->argv,
+                      NULL,    /* envp */
+                      G_SPAWN_SEARCH_PATH,
+                      NULL,    /* child setup */
+                      NULL,    /* user data */
+                      &child_stdout,
+                      &child_stderr,
+                      &wait_status,
+                      &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+  g_assert_true (WIFEXITED (wait_status));
+  g_assert_cmpint (WEXITSTATUS (wait_status), ==, t->exit_status);
+  g_assert_nonnull (child_stdout);
+  g_assert_true (g_utf8_validate (child_stdout, -1, NULL));
+  g_assert_nonnull (child_stderr);
+  g_assert_true (g_utf8_validate (child_stderr, -1, NULL));
+  if (t->stdout_contains != NULL)
+    g_assert_cmpstr (strstr (child_stdout, t->stdout_contains), !=, NULL);
+  if (t->stderr_contains != NULL)
+    g_assert_cmpstr (strstr (child_stderr, t->stderr_contains), !=, NULL);
+}
+
+static void
+test_arguments_validation (Fixture *f,
+                           gconstpointer context)
+{
+  const IdentifyLibraryAbi identify_lib_abi[] =
+  {
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        "--ldconfig",
+        NULL,
+      },
+      .exit_status = 0,
+    },
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        "--ldconfig",
+        "--print0",
+        NULL,
+      },
+      .exit_status = 0,
+    },
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        "--directory",
+        empty_temp_dir,
+        NULL,
+      },
+      .exit_status = 0,
+    },
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        "--this-option-is-unsupported",
+        NULL,
+      },
+      .exit_status = EX_USAGE,
+      .stderr_contains = "Unknown option",
+    },
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        "this-argument-is-unsupported",
+        NULL,
+      },
+      .exit_status = EX_USAGE,
+      .stderr_contains = "Either --ldconfig or --directory are required",
+    },
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        "--ldconfig",
+        "--directory",
+        empty_temp_dir,
+        NULL,
+      },
+      .exit_status = EX_USAGE,
+      .stderr_contains = "cannot be used at the same time",
+    },
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        NULL,
+      },
+      .exit_status = EX_USAGE,
+      .stderr_contains = "Either --ldconfig or --directory are required",
+    },
+    {
+      .argv =
+      {
+        "steam-runtime-identify-library-abi",
+        "--directory",
+        "/this_directory_does_not_exist",
+        NULL,
+      },
+      .exit_status = 1,
+      .stderr_contains = "Unable to realpath",
+    },
+  };
+
+  for (gsize i = 0; i < G_N_ELEMENTS (identify_lib_abi); i++)
+    _spawn_and_check_output (&identify_lib_abi[i]);
+}
+
+/*
+ * Test `steam-runtime-identify-library-abi --help` and `--version`.
+ */
+static void
+test_help_and_version (Fixture *f,
+                       gconstpointer context)
+{
+  const IdentifyLibraryAbi identify_lib_abi[] =
+  {
+    {
+      .argv =
+      {
+        "env",
+        "LC_ALL=C",
+        "steam-runtime-identify-library-abi",
+        "--version",
+        NULL,
+      },
+      .exit_status = 0,
+      .stdout_contains = VERSION,
+    },
+    {
+      .argv =
+      {
+        "env",
+        "LC_ALL=C",
+        "steam-runtime-identify-library-abi",
+        "--help",
+        NULL,
+      },
+      .exit_status = 0,
+      .stdout_contains = "OPTION",
+    },
+  };
+
+  for (gsize i = 0; i < G_N_ELEMENTS (identify_lib_abi); i++)
+    _spawn_and_check_output (&identify_lib_abi[i]);
+}
+
+static void
+test_library_identification (Fixture *f,
+                             gconstpointer context)
+{
+  gboolean ret;
+  int exit_status = -1;
+  GError *error = NULL;
+  gchar *child_stdout = NULL;
+  gchar *child_stderr = NULL;
+  gsize i;
+  const gchar *argv[] =
+  {
+    "steam-runtime-identify-library-abi",
+    "--ldconfig",
+    NULL,
+    NULL,
+  };
+
+  ret = g_spawn_sync (NULL,    /* working directory */
+                      (gchar **) argv,
+                      NULL,    /* envp */
+                      G_SPAWN_SEARCH_PATH,
+                      NULL,    /* child setup */
+                      NULL,    /* user data */
+                      &child_stdout,
+                      &child_stderr,
+                      &exit_status,
+                      &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+  g_assert_cmpint (exit_status, ==, 0);
+  g_assert_nonnull (child_stdout);
+  g_assert_cmpstr (child_stdout, !=, "");
+  g_assert_true (g_utf8_validate (child_stdout, -1, NULL));
+  g_assert_nonnull (child_stderr);
+
+  const LibInfo libc_info[] =
+  {
+    {
+      .path = "/usr/lib/x86_64-linux-gnu/libc.so.6",
+      .abi = "x86_64-linux-gnu",
+    },
+    {
+      .path = "/lib/x86_64-linux-gnu/libc.so.6",
+      .abi = "x86_64-linux-gnu",
+    },
+    {
+      .path = "/usr/lib/i386-linux-gnu/libc.so.6",
+      .abi = "i386-linux-gnu",
+    },
+    {
+      .path = "/lib/i386-linux-gnu/libc.so.6",
+      .abi = "i386-linux-gnu",
+    },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (libc_info); i++)
+    {
+      g_autofree gchar *expected_out_line = NULL;
+      gchar *out_line = strstr (child_stdout, libc_info[i].path);
+      if (out_line != NULL)
+        {
+          gchar *end_of_line = strstr (out_line, "\n");
+          g_assert_nonnull (end_of_line);
+          end_of_line[0] = '\0';
+          expected_out_line = g_strdup_printf ("%s=%s", libc_info[i].path, libc_info[i].abi);
+          g_assert_cmpstr (out_line, ==, expected_out_line);
+          end_of_line[0] = '\n';
+        }
+      else
+        {
+          g_test_message ("\"%s\" seems to not be available in ldconfig output, "
+                          "skipping this part of the test", libc_info[i].path);
+        }
+    }
+
+  g_free (child_stdout);
+  g_free (child_stderr);
+
+  argv[1] = "--directory";
+  for (i = 0; i < G_N_ELEMENTS (libc_info); i++)
+    {
+      g_autofree gchar *libc_dirname = NULL;
+      g_autofree gchar *expected_out_line = NULL;
+      const gchar *out_line;
+      gchar *end_of_line;  /* not owned */
+
+      if (!g_file_test (libc_info[i].path, G_FILE_TEST_EXISTS))
+        {
+          g_test_message ("\"%s\" is not available in the filesystem, skipping this "
+                          "part of the test", libc_info[i].path);
+          continue;
+        }
+
+      libc_dirname = g_path_get_dirname (libc_info[i].path);
+      argv[2] = libc_dirname;
+
+      ret = g_spawn_sync (NULL,    /* working directory */
+                          (gchar **) argv,
+                          NULL,    /* envp */
+                          G_SPAWN_SEARCH_PATH,
+                          NULL,    /* child setup */
+                          NULL,    /* user data */
+                          &child_stdout,
+                          &child_stderr,
+                          &exit_status,
+                          &error);
+      g_assert_no_error (error);
+      g_assert_true (ret);
+      g_assert_cmpint (exit_status, ==, 0);
+      g_assert_nonnull (child_stdout);
+      g_assert_cmpstr (child_stdout, !=, "");
+      g_assert_true (g_utf8_validate (child_stdout, -1, NULL));
+      g_assert_nonnull (child_stderr);
+
+      out_line = strstr (child_stdout, libc_info[i].path);
+      g_assert_nonnull (out_line);
+      end_of_line = strstr (out_line, "\n");
+      g_assert_nonnull (end_of_line);
+      end_of_line[0] = '\0';
+      expected_out_line = g_strdup_printf ("%s=%s", libc_info[i].path, libc_info[i].abi);
+      g_assert_cmpstr (out_line, ==, expected_out_line);
+      end_of_line[0] = '\n';
+
+      g_free (child_stdout);
+      g_free (child_stderr);
+    }
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  int status;
+  GError *error = NULL;
+
+  argv0 = argv[0];
+
+  g_test_init (&argc, &argv, NULL);
+  /* Creates an empty temporary directory to test the --directory option */
+  empty_temp_dir = g_dir_make_tmp ("empty-dir-XXXXXX", &error);
+  g_test_add ("/identify-library-abi-cli/arguments_validation", Fixture, NULL,
+              setup, test_arguments_validation, teardown);
+  g_test_add ("/identify-library-abi-cli/help-and-version", Fixture, NULL,
+              setup, test_help_and_version, teardown);
+  g_test_add ("/identify-library-abi-cli/library-identification", Fixture, NULL,
+              setup, test_library_identification, teardown);
+
+  status = g_test_run ();
+
+  _srt_rm_rf (empty_temp_dir);
+  g_free (empty_temp_dir);
+
+  return status;
+}
diff --git a/tests/meson.build b/tests/meson.build
index a372c1ca1353c03a1bef17ce7d375954073757cf..101e75e31900a75015316012b12cd4b6e6627e54 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -52,6 +52,7 @@ tests = [
 if get_option('bin')
   tests += [
     {'name': 'check-requirements-cli'},
+    {'name': 'identify-library-abi-cli'},
     {'name': 'system-info-cli', 'static': true, 'slow': true},
   ]
 endif