build: Split up features into separate libraries

This makes it much more obvious when a feature is missing for a user.

Change-Id: Ibb17d7ab1f185a1976a32f48933c01a252450dd1
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include-dl/meson.build b/include-dl/meson.build
new file mode 100644
index 0000000..c2a2862
--- /dev/null
+++ b/include-dl/meson.build
@@ -0,0 +1,5 @@
+stdplus_headers += include_directories('.')
+
+install_headers(
+  'stdplus/dl.hpp',
+  subdir: 'stdplus')
diff --git a/include-dl/stdplus/dl.hpp b/include-dl/stdplus/dl.hpp
new file mode 100644
index 0000000..0526391
--- /dev/null
+++ b/include-dl/stdplus/dl.hpp
@@ -0,0 +1,55 @@
+#pragma once
+#include <dlfcn.h>
+#include <link.h>
+
+#include <stdplus/flags.hpp>
+#include <stdplus/handle/managed.hpp>
+
+namespace stdplus
+{
+
+enum class DlOpenType : int
+{
+    Lazy = RTLD_LAZY,
+    Now = RTLD_NOW,
+};
+
+enum class DlOpenFlag : int
+{
+    Global = RTLD_GLOBAL,
+    Local = RTLD_LOCAL,
+    NoDelete = RTLD_NODELETE,
+    NoLoad = RTLD_NOLOAD,
+    DeepBind = RTLD_DEEPBIND,
+};
+
+class DlOpenFlags : public stdplus::BitFlags<int, DlOpenFlag>
+{
+  public:
+    inline DlOpenFlags(DlOpenType type) :
+        BitFlags<int, DlOpenFlag>(static_cast<int>(type))
+    {
+    }
+
+    inline DlOpenFlags(BitFlags<int, DlOpenFlag> flags) :
+        BitFlags<int, DlOpenFlag>(flags)
+    {
+    }
+};
+
+class Dl
+{
+  public:
+    Dl(const char* filename, DlOpenFlags flags);
+
+    struct link_map* linkMap();
+
+  private:
+    void info(int request, void* info);
+
+    static void* open(const char* filename, int flags);
+    static void close(void*&& handle);
+    stdplus::Managed<void*>::Handle<close> handle;
+};
+
+} // namespace stdplus