   ([source]
    (program-with-source *context* source)))
 
-;; TODO Callback function
-(defn build-program! [program]
-  (let [err (CL/clBuildProgram program 0 nil nil nil nil)]
-    (with-check err program)))
+(defn build-program!
+  ([ch program devices options user-data]
+   (with-check (CL/clBuildProgram program (count devices)
+                                  (if devices
+                                    (into-array cl_device_id devices)
+                                    nil)
+                                  options
+                                  (if ch (->BuildCallback ch) nil)
+                                  user-data)
+     ch))
+  ([ch program devices options]
+   (build-program! ch program devices options nil))
+  ([ch program options]
+   (build-program! ch program nil options nil))
+  ([ch program]
+   (build-program! ch program nil nil nil))
+  ([program]
+   (do
+     (build-program! nil program nil nil nil)
+     program)))
 
 ;; ============== Kernel =========================================
 

     (loop [i 5 es es]
       (if (< i len)
         (do (aset res i (first es))
             (recur (inc i) (rest es)))
         res)))))

(defrecord EventCallbackInfo [event status data])

    (with-check err (aget res 0))))

(defn kernels
  ([program name]
   (let [err (int-array 1)
         res (CL/clCreateKernel program name err)]
     (with-check-arr err res)))
