diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,34 @@
+## Version 0.7.4.1 (2025-08-26)
+
+- Fix build with `-Werror=unused-packages`.
+- Tested with GHC 8.0 - 9.14 alpha1.
+
+## Version 0.7.4 (2025-03-27)
+
+- Add `wasm32-wasi` support
+  ([PR #16](https://github.com/haskell-pkg-janitors/unix-compat/pull/16)).
+- Tested with GHC 8.0 - 9.12.
+
+## Version 0.7.3 (2024-10-11)
+
+- Fix `sysmacros.h` include for GNU/Hurd
+  ([PR #12](https://github.com/haskell-pkg-janitors/unix-compat/pull/12)).
+- Tested with GHC 8.0 - 9.10.
+
+## Version 0.7.2 (2024-06-25)
+
+- Remove flag `old-time` and drop support for `old-time`.
+- Remove support for GHC 7.
+- Tested with GHC 8.0 - 9.10.
+
+## Version 0.7.1 (2023-12-06) Santa Clause edition
+
+- Add `System.PosixCompat.Process` module, exporting `getProcessID`.
+
+## Version 0.7 (2023-03-15)
+
+- Remove `System.PosixCompat.User` module.
+
 ## Version 0.6 (2022-05-22)
 
-- Better support for symbolic links
+- Better support for symbolic links.
diff --git a/cbits/HsUnixCompat.c b/cbits/HsUnixCompat.c
--- a/cbits/HsUnixCompat.c
+++ b/cbits/HsUnixCompat.c
@@ -2,7 +2,7 @@
 
 #ifdef SOLARIS
 #include <sys/mkdev.h>
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__GNU__)
 #include <sys/sysmacros.h>
 #endif
 
diff --git a/cbits/mktemp.c b/cbits/mktemp.c
--- a/cbits/mktemp.c
+++ b/cbits/mktemp.c
@@ -41,13 +41,21 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+
+#if defined(__wasm__)
+#include <sys/random.h>
+#else
 #include <windows.h>
 #include <wincrypt.h>
 
-static int random(uint32_t *);
+#define open _open
+#define stat _stat
+#endif
+
+static int unixcompat_random(uint32_t *);
 static int _gettemp(char *, int *);
 
-static const unsigned char padchar[] =
+static const char padchar[] =
 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
 int unixcompat_mkstemp(char *path)
@@ -64,7 +72,7 @@
 {
     char *start, *trv, *suffp, *carryp;
     char *pad;
-    struct _stat sbuf;
+    struct stat sbuf;
     int rval;
     uint32_t randidx, randval;
     char carrybuf[MAXPATHLEN];
@@ -84,7 +92,7 @@
 
     /* Fill space with random characters */
     while (trv >= path && *trv == 'X') {
-        if (!random(&randval)) {
+        if (!unixcompat_random(&randval)) {
             /* this should never happen */
             errno = EIO;
             return 0;
@@ -104,7 +112,7 @@
         for (; trv > path; --trv) {
             if (*trv == '/') {
                 *trv = '\0';
-                rval = _stat(path, &sbuf);
+                rval = stat(path, &sbuf);
                 *trv = '/';
                 if (rval != 0)
                     return (0);
@@ -120,11 +128,11 @@
     for (;;) {
         if (doopen) {
             if ((*doopen =
-                _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
+                open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
                 return (1);
             if (errno != EEXIST)
                 return (0);
-        } else if (_stat(path, &sbuf))
+        } else if (stat(path, &sbuf))
             return (errno == ENOENT);
 
         /* If we have a collision, cycle through the space of filenames */
@@ -154,8 +162,15 @@
     /*NOTREACHED*/
 }
 
-static int random(uint32_t *value)
+#if defined(__wasm__)
+static int unixcompat_random(uint32_t *value)
 {
+    int r = getentropy(value, sizeof(uint32_t));
+    return r == 0 ? 1 : 0;
+}
+#else
+static int unixcompat_random(uint32_t *value)
+{
     /* This handle is never released. Windows will clean up when the process
      * exits. Python takes this approach when emulating /dev/urandom, and if
      * it's good enough for them, then it's good enough for us. */
@@ -171,3 +186,4 @@
 
     return 1;
 }
+#endif
diff --git a/include/HsUnixCompat.h b/include/HsUnixCompat.h
--- a/include/HsUnixCompat.h
+++ b/include/HsUnixCompat.h
@@ -4,5 +4,3 @@
 unsigned int unix_major(dev_t dev);
 unsigned int unix_minor(dev_t dev);
 dev_t unix_makedev(unsigned int maj, unsigned int min);
-
-#define NEED_setSymbolicLinkOwnerAndGroup !HAVE_LCHOWN
diff --git a/src/System/PosixCompat.hs b/src/System/PosixCompat.hs
--- a/src/System/PosixCompat.hs
+++ b/src/System/PosixCompat.hs
@@ -7,20 +7,20 @@
 -}
 module System.PosixCompat (
       module System.PosixCompat.Files
+    , module System.PosixCompat.Process
     , module System.PosixCompat.Temp
     , module System.PosixCompat.Time
     , module System.PosixCompat.Types
     , module System.PosixCompat.Unistd
-    , module System.PosixCompat.User
     , usingPortableImpl
     ) where
 
 import System.PosixCompat.Files
+import System.PosixCompat.Process
 import System.PosixCompat.Temp
 import System.PosixCompat.Time
 import System.PosixCompat.Types
 import System.PosixCompat.Unistd
-import System.PosixCompat.User
 
 -- | 'True' if unix-compat is using its portable implementation,
 --   or 'False' if the unix package is simply being re-exported.
diff --git a/src/System/PosixCompat/Extensions.hsc b/src/System/PosixCompat/Extensions.hsc
--- a/src/System/PosixCompat/Extensions.hsc
+++ b/src/System/PosixCompat/Extensions.hsc
@@ -12,7 +12,7 @@
     ) where
 
 
-#ifndef mingw32_HOST_OS
+#if !(defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH))
 #include "HsUnixCompat.h"
 #endif
 
@@ -27,7 +27,7 @@
 --
 -- The portable implementation always returns @0@.
 deviceMajor :: DeviceID -> CMajor
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH)
 deviceMajor _ = 0
 #else
 deviceMajor dev = unix_major dev
@@ -39,7 +39,7 @@
 --
 -- The portable implementation always returns @0@.
 deviceMinor :: DeviceID -> CMinor
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH)
 deviceMinor _ = 0
 #else
 deviceMinor dev = unix_minor dev
@@ -49,7 +49,7 @@
 
 -- | Creates a 'DeviceID' for a device file given a major and minor number.
 makeDeviceID :: CMajor -> CMinor -> DeviceID
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH)
 makeDeviceID _ _ = 0
 #else
 makeDeviceID ma mi = unix_makedev ma mi
diff --git a/src/System/PosixCompat/Files.hsc b/src/System/PosixCompat/Files.hsc
--- a/src/System/PosixCompat/Files.hsc
+++ b/src/System/PosixCompat/Files.hsc
@@ -106,11 +106,11 @@
 
 #ifndef mingw32_HOST_OS
 
-#include "HsUnixCompat.h"
+#include "HsUnixConfig.h"
 
 import System.Posix.Files
 
-#if NEED_setSymbolicLinkOwnerAndGroup
+#if !HAVE_LCHOWN
 import System.PosixCompat.Types
 
 setSymbolicLinkOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO ()
diff --git a/src/System/PosixCompat/Internal/Time.hs b/src/System/PosixCompat/Internal/Time.hs
--- a/src/System/PosixCompat/Internal/Time.hs
+++ b/src/System/PosixCompat/Internal/Time.hs
@@ -10,16 +10,6 @@
     ) where
 
 import System.Posix.Types (EpochTime)
-
-#ifdef OLD_TIME
-
-import System.Time (ClockTime(TOD), getClockTime)
-
-clockTimeToEpochTime :: ClockTime -> EpochTime
-clockTimeToEpochTime (TOD s _) = fromInteger s
-
-#else
-
 import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime)
 
 type ClockTime = POSIXTime
@@ -29,5 +19,3 @@
 
 clockTimeToEpochTime :: ClockTime -> EpochTime
 clockTimeToEpochTime = fromInteger . floor
-
-#endif
diff --git a/src/System/PosixCompat/Process.hs b/src/System/PosixCompat/Process.hs
new file mode 100644
--- /dev/null
+++ b/src/System/PosixCompat/Process.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE CPP #-}
+
+{-|
+This module intends to make the operations of @System.Posix.Process@ available
+on all platforms.
+-}
+module System.PosixCompat.Process (
+      getProcessID
+    ) where
+
+#if defined(mingw32_HOST_OS)
+
+import System.Posix.Types (ProcessID)
+import System.Win32.Process (getCurrentProcessId)
+
+getProcessID :: IO ProcessID
+getProcessID = fromIntegral <$> getCurrentProcessId
+
+#elif defined(wasm32_HOST_ARCH)
+
+import System.Posix.Types (ProcessID)
+
+getProcessID :: IO ProcessID
+getProcessID = pure 1
+
+#else
+
+import System.Posix.Process
+
+#endif
diff --git a/src/System/PosixCompat/Temp.hs b/src/System/PosixCompat/Temp.hs
--- a/src/System/PosixCompat/Temp.hs
+++ b/src/System/PosixCompat/Temp.hs
@@ -11,13 +11,13 @@
       mkstemp
     ) where
 
-#ifndef mingw32_HOST_OS
+#if !(defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH))
 -- Re-export unix package
 
 import System.Posix.Temp
 
 #elif defined(__GLASGOW_HASKELL__)
--- Windows w/ GHC, we have fdToHandle so we
+-- Window/WASM w/ GHC, we have fdToHandle so we
 -- can use our own implementation of mkstemp.
 
 import System.IO (Handle)
diff --git a/src/System/PosixCompat/User.hsc b/src/System/PosixCompat/User.hsc
deleted file mode 100644
--- a/src/System/PosixCompat/User.hsc
+++ /dev/null
@@ -1,133 +0,0 @@
-{-# LANGUAGE CPP #-}
-
-{-|
-This module makes the operations exported by @System.Posix.User@
-available on all platforms. On POSIX systems it re-exports operations from
-@System.Posix.User@. On other platforms it provides dummy implementations.
--}
-module System.PosixCompat.User (
-    -- * User environment
-    -- ** Querying the user environment
-      getRealUserID
-    , getRealGroupID
-    , getEffectiveUserID
-    , getEffectiveGroupID
-    , getGroups
-    , getLoginName
-    , getEffectiveUserName
-
-    -- *** The group database
-    , GroupEntry(..)
-    , getGroupEntryForID
-    , getGroupEntryForName
-    , getAllGroupEntries
-
-    -- *** The user database
-    , UserEntry(..)
-    , getUserEntryForID
-    , getUserEntryForName
-    , getAllUserEntries
-
-    -- ** Modifying the user environment
-    , setUserID
-    , setGroupID
-    ) where
-
-#ifndef mingw32_HOST_OS
-
-#include "HsUnixCompat.h"
-
-import System.Posix.User
-
-#if __GLASGOW_HASKELL__<605
-getAllGroupEntries :: IO [GroupEntry]
-getAllGroupEntries = return []
-
-getAllUserEntries :: IO [UserEntry]
-getAllUserEntries = return []
-#endif
-
-#else /* Portable implementation */
-
-import System.IO.Error
-import System.PosixCompat.Types
-
-unsupported :: String -> IO a
-unsupported f = ioError $ mkIOError illegalOperationErrorType x Nothing Nothing
-    where x = "System.PosixCompat.User." ++ f ++ ": not supported"
-
--- -----------------------------------------------------------------------------
--- User environment
-
-getRealUserID :: IO UserID
-getRealUserID = unsupported "getRealUserID"
-
-getRealGroupID :: IO GroupID
-getRealGroupID = unsupported "getRealGroupID"
-
-getEffectiveUserID :: IO UserID
-getEffectiveUserID = unsupported "getEffectiveUserID"
-
-getEffectiveGroupID :: IO GroupID
-getEffectiveGroupID = unsupported "getEffectiveGroupID"
-
-getGroups :: IO [GroupID]
-getGroups = return []
-
-getLoginName :: IO String
-getLoginName = unsupported "getLoginName"
-
-setUserID :: UserID -> IO ()
-setUserID _ = return ()
-
-setGroupID :: GroupID -> IO ()
-setGroupID _ = return ()
-
--- -----------------------------------------------------------------------------
--- User names
-
-getEffectiveUserName :: IO String
-getEffectiveUserName = unsupported "getEffectiveUserName"
-
--- -----------------------------------------------------------------------------
--- The group database
-
-data GroupEntry = GroupEntry
-    { groupName     :: String
-    , groupPassword :: String
-    , groupID       :: GroupID
-    , groupMembers  :: [String]
-    } deriving (Show, Read, Eq)
-
-getGroupEntryForID :: GroupID -> IO GroupEntry
-getGroupEntryForID _ = unsupported "getGroupEntryForID"
-
-getGroupEntryForName :: String -> IO GroupEntry
-getGroupEntryForName _ = unsupported "getGroupEntryForName"
-
-getAllGroupEntries :: IO [GroupEntry]
-getAllGroupEntries = return []
-
--- -----------------------------------------------------------------------------
--- The user database (pwd.h)
-
-data UserEntry = UserEntry
-    { userName      :: String
-    , userPassword  :: String
-    , userID        :: UserID
-    , userGroupID   :: GroupID
-    , userGecos     :: String
-    , homeDirectory :: String
-    , userShell     :: String
-    } deriving (Show, Read, Eq)
-
-getUserEntryForID :: UserID -> IO UserEntry
-getUserEntryForID _ = unsupported "getUserEntryForID"
-
-getUserEntryForName :: String -> IO UserEntry
-getUserEntryForName _ = unsupported "getUserEntryForName"
-
-getAllUserEntries :: IO [UserEntry]
-getAllUserEntries = return []
-
-#endif
diff --git a/tests/ProcessSpec.hs b/tests/ProcessSpec.hs
new file mode 100644
--- /dev/null
+++ b/tests/ProcessSpec.hs
@@ -0,0 +1,12 @@
+module ProcessSpec (processSpec) where
+
+import System.PosixCompat
+import Test.HUnit
+import Test.Hspec
+
+processSpec :: Spec
+processSpec = do
+  describe "getProcessID" $ do
+    it "should work on Windows and Unix" $ do
+      pid <- getProcessID
+      assert $ pid > 0
diff --git a/tests/main.hs b/tests/main.hs
--- a/tests/main.hs
+++ b/tests/main.hs
@@ -2,6 +2,7 @@
 
 import MkstempSpec
 import LinksSpec
+import ProcessSpec
 
 import Test.Hspec
 
@@ -9,3 +10,4 @@
 main = hspec $ do
     mkstempSpec
     linksSpec
+    processSpec
diff --git a/unix-compat.cabal b/unix-compat.cabal
--- a/unix-compat.cabal
+++ b/unix-compat.cabal
@@ -1,148 +1,110 @@
+cabal-version:  1.18
 name:           unix-compat
-version:        0.6
+version:        0.7.4.1
 synopsis:       Portable POSIX-compatibility layer.
 description:    This package provides portable implementations of parts
                 of the unix package. This package re-exports the unix
                 package when available. When it isn't available,
                 portable implementations are used.
 
-homepage:       http://github.com/jacobstanley/unix-compat
+homepage:       https://github.com/haskell-pkg-janitors/unix-compat
 license:        BSD3
 license-file:   LICENSE
 author:         Björn Bringert, Duncan Coutts, Jacob Stanley, Bryan O'Sullivan
-maintainer:     Jacob Stanley <jacob@stanley.io>
+maintainer:     https://github.com/haskell-pkg-janitors
 category:       System
 build-type:     Simple
-cabal-version:  >= 1.10
 
-extra-source-files:
+tested-with:
+  GHC == 9.14.1
+  GHC == 9.12.2
+  GHC == 9.10.2
+  GHC == 9.8.4
+  GHC == 9.6.7
+  GHC == 9.4.8
+  GHC == 9.2.8
+  GHC == 9.0.2
+  GHC == 8.10.7
+  GHC == 8.8.4
+  GHC == 8.6.5
+  GHC == 8.4.4
+  GHC == 8.2.2
+  GHC == 8.0.2
+
+extra-doc-files:
   CHANGELOG.md
 
 source-repository head
   type:     git
-  location: git@github.com:jacobstanley/unix-compat.git
-
-flag old-time
-  description: build against old-time package
-  default: False
+  location: https://github.com/haskell-pkg-janitors/unix-compat.git
 
 Library
-  default-language: Haskell2010
   hs-source-dirs: src
-  ghc-options: -Wall
-  build-depends: base == 4.*
 
   exposed-modules:
     System.PosixCompat
     System.PosixCompat.Extensions
     System.PosixCompat.Files
+    System.PosixCompat.Process
     System.PosixCompat.Temp
     System.PosixCompat.Time
     System.PosixCompat.Types
     System.PosixCompat.Unistd
-    System.PosixCompat.User
 
+  build-depends: base >= 4.9 && < 5
+
   if os(windows)
     c-sources:
       cbits/HsUname.c
       cbits/mktemp.c
 
     extra-libraries: msvcrt
-    build-depends: Win32 >= 2.5.0.0
-    build-depends: filepath >= 1.0 && < 1.5
-
-    if flag(old-time)
-      build-depends: old-time >= 1.0.0.0 && < 1.2.0.0
-      cpp-options: -DOLD_TIME
-
-      if impl(ghc < 7)
-        build-depends: directory == 1.0.*
-        cpp-options: -DDIRECTORY_1_0
-      else
-        build-depends: directory == 1.1.*
-    else
-      build-depends: time >= 1.0 && < 1.13
-      build-depends: directory >= 1.3.1 && < 1.4
+    build-depends: Win32     >= 2.5.0.0  && < 3
+    build-depends: directory >= 1.3.1    && < 1.4
+    build-depends: filepath  >= 1.4.1.0  && < 1.6
+    build-depends: time      >= 1.6.0.1  && < 2
 
     other-modules:
       System.PosixCompat.Internal.Time
 
   else
-    build-depends: unix >= 2.6 && < 2.9
-    include-dirs: include
-    includes: HsUnixCompat.h
-    install-includes: HsUnixCompat.h
-    c-sources: cbits/HsUnixCompat.c
+    build-depends: unix      >= 2.7.2.0  && < 2.9
+    if arch(wasm32)
+      c-sources: cbits/mktemp.c
+    else
+      include-dirs: include
+      includes: HsUnixCompat.h
+      install-includes: HsUnixCompat.h
+      c-sources: cbits/HsUnixCompat.c
     if os(solaris)
       cc-options: -DSOLARIS
 
-Test-Suite unix-compat-testsuite
   default-language: Haskell2010
+  ghc-options:
+    -Wall
+    -Wcompat
+
+Test-Suite unix-compat-testsuite
   type: exitcode-stdio-1.0
   hs-source-dirs: tests
-  ghc-options: -Wall
   main-is: main.hs
 
   other-modules:
      MkstempSpec
      LinksSpec
-
-  -- ghc-options:
-  --   -Wall
-  --   -fwarn-tabs
-  --   -funbox-strict-fields
-  --   -threaded
-  --   -fno-warn-unused-do-bind
-  --   -fno-warn-type-defaults
-
-  -- extensions:
-  --   OverloadedStrings
-  --   ExtendedDefaultRules
-
-  -- if flag(lifted)
-  --    cpp-options: -DLIFTED
+     ProcessSpec
 
   build-depends:
       unix-compat
-    , base == 4.*
+    , base
     , monad-parallel
-    , hspec
+    , hspec >= 2.5.5
     , HUnit
-    , directory
-    , extra
+    , directory >= 1.3.1.0
+        -- directory-1.3.1.0 adds createFileLink
     , temporary
 
-  if os(windows)
-    -- c-sources:
-    --   cbits/HsUname.c
-    --   cbits/mktemp.c
-
-    -- extra-libraries: msvcrt
-    -- build-depends: Win32 >= 2.5.0.0
-
-    if flag(old-time)
-      build-depends: old-time >= 1.0.0.0 && < 1.2.0.0
-      cpp-options: -DOLD_TIME
-
-      if impl(ghc < 7)
-        build-depends: directory == 1.0.*
-        cpp-options: -DDIRECTORY_1_0
-      else
-        build-depends: directory == 1.1.*
-    else
-      build-depends: time >= 1.0 && < 1.13
-      build-depends: directory >= 1.3.1 && < 1.4
-
-    -- other-modules:
-    --   System.PosixCompat.Internal.Time
-
-  else
-    -- build-depends: unix >= 2.4 && < 2.9
-    -- include-dirs: include
-    -- includes: HsUnixCompat.h
-    -- install-includes: HsUnixCompat.h
-    -- c-sources: cbits/HsUnixCompat.c
-    if os(solaris)
-      cc-options: -DSOLARIS
-
-    build-depends: directory >= 1.3.1 && < 1.4
+  default-language: Haskell2010
+  ghc-options:
+    -Wall
+    -Wcompat
