+(at-init ()
+ (eval-when (:compile-toplevel :load-toplevel :execute)
+ (define-foreign-library glib
+ (:unix (:or "libglib-2.0.so.0" "libglib-2.0.so"))
+ (:windows "libglib-2.0-0.dll")
+ (t (:default "libglib-2.0"))))
+ (eval-when (:compile-toplevel :load-toplevel :execute)
+ (define-foreign-library gthread
+ (:unix (:or "libgthread-2.0.so.0" "libgthread-2.0.so"))
+ (:windows "libgthread-2.0-0.dll")
+ (t "libgthread-2.0")))
+
+ (use-foreign-library glib)
+ (use-foreign-library gthread))
+
+(defmacro push-library-version-features (library-name major-version-var minor-version-var &body versions)
+ `(eval-when (:load-toplevel :execute)
+ ,@(iter (for (major minor) on versions by #'cddr)
+ (collect
+ `(when (or (and (= ,major-version-var ,major) (>= ,minor-version-var ,minor))
+ (> ,major-version-var ,major))
+ (pushnew ,(intern (format nil "~A-~A.~A" (string library-name) major minor) (find-package :keyword)) *features*))))))
+
+(define-condition foreign-library-minimum-version-mismatch (error)
+ ((library :initarg :library :reader .library)
+ (minimum-version :initarg :minimum-version :reader .minimum-version)
+ (actual-version :initarg :actual-version :reader .actual-version))
+ (:report (lambda (c s)
+ (format s "Library ~A has too old version: it is ~A but required to be at least ~A"
+ (.library c)
+ (.actual-version c)
+ (.minimum-version c)))))
+
+(defun require-library-version (library min-major-version min-minor-version major-version minor-version)
+ (unless (or (> major-version min-major-version)
+ (and (= major-version min-major-version)
+ (>= minor-version min-minor-version)))
+ (restart-case
+ (error 'foreign-library-minimum-version-mismatch
+ :library library
+ :minimum-version (format nil "~A.~A" min-major-version min-minor-version)
+ :actual-version (format nil "~A.~A" major-version minor-version))
+ (ignore () :report "Ignore version requirement" nil))))