         // Construct the system delegate.
         var _delegate = llb_buildsystem_delegate_t()
         _delegate.context = Unmanaged.passUnretained(self).toOpaque()
+        if delegate.fs != nil {
+            _delegate.fs_get_file_contents = { BuildSystem.toSystem($0!).fsGetFileContents(String(cString: $1!), $2!) }
+            _delegate.fs_get_file_info = { BuildSystem.toSystem($0!).fsGetFileInfo(String(cString: $1!), $2!) }
+            // FIXME: This should be a separate callback, not shared with getFileInfo (or get FileInfo should take a parameter).
+            _delegate.fs_get_link_info = { BuildSystem.toSystem($0!).fsGetFileInfo(String(cString: $1!), $2!) }
+        }
         _delegate.lookup_tool = { return BuildSystem.toSystem($0!).lookupTool($1!) }
         _delegate.had_command_failure = { BuildSystem.toSystem($0!).hadCommandFailure() }
         _delegate.handle_diagnostic = { BuildSystem.toSystem($0!).handleDiagnostic($1, String(cString: $2!), Int($3), Int($4), String(cString: $5!)) }

        llb_buildsystem_destroy(_system)
    }

    /// Build the default target.
    ///
    /// The client is responsible for ensuring only one build is ever executing concurrently.
    public func build() -> Bool {
        var data = llb_data_t(length: 0, data: nil)
        return llb_buildsystem_build(_system, &data)
    }

    /// Cancel any running build.

    /// Helper function for getting the command wrapper from the delegate context.
    static fileprivate func toCommandWrapper(_ context: UnsafeMutableRawPointer) -> CommandWrapper {
        return Unmanaged<CommandWrapper>.fromOpaque(UnsafeRawPointer(context)).takeUnretainedValue()
    }

    private func fsGetFileContents(_ path: String, _ data: UnsafeMutablePointer<llb_data_t>) -> Bool {
        let fs = delegate.fs!

        // Get the contents for the file.
        guard let contents = fs.readFileContents(path) else {
            return false
        }

        data.pointee = copiedDataFromBytes(contents)

        return true
    }

    private func fsGetFileInfo(_ path: String, _ info: UnsafeMutablePointer<llb_fs_file_info_t>) {
        // Ignore invalid paths.
        guard path.first == "/" else {
            info.pointee = llb_fs_file_info_t()
            return
        }

        // If the path doesn't exist, it is missing.
        let fs = delegate.fs!
        guard let s = try? fs.getFileInfo(path).statBuf else {
            info.pointee = llb_fs_file_info_t()
            return
        }

        // Otherwise, we have some kind of file.
        info.pointee.device = UInt64(s.st_dev)
        info.pointee.inode = UInt64(s.st_ino)
        info.pointee.mode = UInt64(s.st_mode)
        info.pointee.size = UInt64(s.st_size)
        info.pointee.mod_time.seconds = UInt64(s.st_mtimespec.tv_sec)
        info.pointee.mod_time.nanoseconds = UInt64(s.st_mtimespec.tv_nsec)
    }

    private func fsGetLinkInfo(_ path: String, _ info: UnsafeMutablePointer<llb_fs_file_info_t>) {
        // FIXME: We do not support this natively, yet.
        return fsGetFileInfo(path, info)
    }

    /// The owning list of all created tools.
