adds a program build interface to compile for a specific device (#102)

* adds a program build interface to compile for a specific device

This complements the existing program build interface to compile for a vector of devices.

* add a test for new program build interface
diff --git a/include/CL/cl2.hpp b/include/CL/cl2.hpp
index ced4b03..bc33499 100644
--- a/include/CL/cl2.hpp
+++ b/include/CL/cl2.hpp
@@ -2835,6 +2835,10 @@
         }
     }
 
+    /*! \brief Constructs a context including a specific device.
+     *
+     *  Wraps clCreateContext().
+     */
     Context(
         const Device& device,
         cl_context_properties* properties = NULL,
@@ -6614,6 +6618,27 @@
     }
 
     cl_int build(
+        const Device& device,
+        const char* options = NULL,
+        void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
+        void* data = NULL) const
+    {
+        cl_device_id deviceID = device();
+
+        cl_int buildError = ::clBuildProgram(
+            object_,
+            1,
+            &deviceID,
+            options,
+            notifyFptr,
+            data);
+
+        BuildLogType buildLog(1);
+        buildLog.push_back(std::make_pair(device, getBuildInfo<CL_PROGRAM_BUILD_LOG>(device)));
+        return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, buildLog);
+    }
+
+    cl_int build(
         const char* options = NULL,
         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
         void* data = NULL) const
@@ -6626,7 +6651,6 @@
             notifyFptr,
             data);
 
-
         return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
     }
 
diff --git a/tests/test_cl2hpp.cpp b/tests/test_cl2hpp.cpp
index 4ef5d64..0cc4bad 100644
--- a/tests/test_cl2hpp.cpp
+++ b/tests/test_cl2hpp.cpp
@@ -1645,9 +1645,8 @@
 
 }
 
-
 /****************************************************************************
-* Tests for getBuildInfo
+* Tests for building Programs
 ****************************************************************************/
 
 static cl_int clGetDeviceInfo_testGetBuildInfo(
@@ -1717,6 +1716,58 @@
     dev() = NULL;
 }
 
+static cl_int clBuildProgram_testBuildProgram(
+    cl_program           program,
+    cl_uint              num_devices,
+    const cl_device_id * device_list,
+    const char *         options,
+    void (CL_CALLBACK *  pfn_notify)(cl_program program, void * user_data),
+    void *               user_data,
+    int num_calls)
+{
+    TEST_ASSERT_EQUAL(program, make_program(0));
+    TEST_ASSERT_NOT_EQUAL(num_devices, 0);
+    TEST_ASSERT_NOT_EQUAL(device_list, NULL);
+    TEST_ASSERT_EQUAL(options, NULL);
+    TEST_ASSERT_EQUAL(pfn_notify, NULL);
+    TEST_ASSERT_EQUAL(user_data, NULL);
+
+    for (cl_uint i = 0; i < num_devices; i++) {
+        TEST_ASSERT_EQUAL(device_list[i], make_device_id(i));
+    }
+
+    return CL_SUCCESS;
+}
+
+void testBuildProgramSingleDevice()
+{
+    cl_program program = make_program(0);
+    cl_device_id device_id = make_device_id(0);
+    int sc = 0;
+
+    // Creating a device queries the platform version:
+    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
+    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
+
+    clBuildProgram_StubWithCallback(clBuildProgram_testBuildProgram);
+
+    // Building the program queries the program build log:
+    clRetainDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
+    clGetProgramBuildInfo_StubWithCallback(clGetProgramBuildInfo_testGetBuildInfo);
+    clGetProgramBuildInfo_StubWithCallback(clGetProgramBuildInfo_testGetBuildInfo);
+    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
+    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
+
+    clReleaseProgram_ExpectAndReturn(program, CL_SUCCESS);
+
+    cl::Program prog(program);
+    cl::Device dev(device_id);
+
+    cl_int errcode = prog.build(dev);
+
+    TEST_ASSERT_EQUAL(errcode, CL_SUCCESS);
+}
+
 /**
 * Stub implementation of clGetCommandQueueInfo that returns first one image then none
 */