Reputation: 3212
I have a library which can do GPU computation using the OpenCL framework. Sadly, OpenCL is not available on all platforms. However I would still like to be able to compile my code on those platforms, just excluding OpenCL functionality.
I think this question applies to all situations where you want to conditionally compile some external resource which may not always be available, and it messes with your library API.
Currently I have it set up like this:
CMake:
if(ENABLE_OPENCL)
add_definitions(-DENABLE_OPEN_CL)
find_package(OpenCL REQUIRED)
include_directories(${OpenCL_INCLUDE_DIR})
target_link_libraries(mylibrary ${OpenCL_LIBRARY})
endif()
C++
// settings.hpp, exposed to public API
class settings
{
int general_setting_1;
bool general_setting_2;
// ... Other general settings
#ifdef ENABLE_OPEN_CL
int open_cl_platform_id;
// ... Other settings available only when OpenCL is available
#endif
// More settings, possibly also conditionally compiled on other external libraries
};
// computation.cpp, internal to the library
#ifdef ENABLE_OPEN_CL
#include <CL/cl.hpp>
#endif
void do_things()
{
// ...
#ifdef ENABLE_OPEN_CL
if(settings.open_cl_platform_id != -1)
{
// Call OpenCL code
}
#endif
// ...
}
So when I compile the library, if I want to enable OpenCL I do cmake .. -DENABLE_OPEN_CL
.
This works, but if the client is consuming the library compiled with ENABLE_OPEN_CL
, it forces the client to define the same ENABLE_OPEN_CL
, otherwise the included library's header file don't match the one used in the client, and very bad things happen.
This opens a whole can of worms, for example what if the client forgets to do it? What if it uses the same identifier name for something else?
Can I avoid this? If not, is there some way I could verify that the header files match on the client and the library, and cause a compilation error? Or at least throw a run-time exception? What is the correct approach to this scenario?
Upvotes: 2
Views: 706
Reputation: 29017
The obvious way to do it, is to leave open_cl_platform_id
as a member of settings
even if OpenCL is not supported. The user then gets a run-time error if they try to use OpenCL functionality when the library hasn't been compiled for it.
Alternatively, have two header files settings_no_open_cl.hpp
and settings_open_cl.hpp
, and require the user to include the right one.
Upvotes: 2