Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在不破坏库API的情况下实现条件编译?_C++_Cmake_Api Design_Conditional Compilation - Fatal编程技术网

C++ 如何在不破坏库API的情况下实现条件编译?

C++ 如何在不破坏库API的情况下实现条件编译?,c++,cmake,api-design,conditional-compilation,C++,Cmake,Api Design,Conditional Compilation,我有一个库,可以使用OpenCL框架进行GPU计算。遗憾的是,OpenCL并非在所有平台上都可用。然而,我仍然希望能够在这些平台上编译我的代码,只是不包括OpenCL功能 我认为这个问题适用于所有需要有条件地编译某些外部资源的情况,这些资源可能并不总是可用的,并且会干扰库API 目前我将其设置为: CMake: if(ENABLE_OPENCL) add_definitions(-DENABLE_OPEN_CL) find_package(OpenCL REQUIRED)

我有一个库,可以使用OpenCL框架进行GPU计算。遗憾的是,OpenCL并非在所有平台上都可用。然而,我仍然希望能够在这些平台上编译我的代码,只是不包括OpenCL功能

我认为这个问题适用于所有需要有条件地编译某些外部资源的情况,这些资源可能并不总是可用的,并且会干扰库API

目前我将其设置为:

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,公开于公共API
班级设置
{
国际通用设置1;
bool一般设置2;
//…其他一般设置
#ifdef启用\u打开\u CL
int open_cl_平台id;
//…其他设置仅在OpenCL可用时可用
#恩迪夫
//更多设置,也可能在其他外部库上有条件地编译
};
//computation.cpp,库内部
#ifdef启用\u打开\u CL
#包括
#恩迪夫
虚度光阴
{
// ... 
#ifdef启用\u打开\u CL
如果(settings.open\u cl\u platform\u id!=-1)
{
//调用OpenCL代码
}
#恩迪夫
// ...
}
因此,当我编译库时,如果我想启用OpenCL,我会
cmake-可更改的\u打开\u CL

这是可行的,但是如果客户机正在使用使用
ENABLE\u OPEN\u CL
编译的库,它会强制客户机定义相同的
ENABLE\u OPEN\u CL
,否则包含的库头文件与客户机中使用的头文件不匹配,并且会发生非常糟糕的事情

这会打开一整罐蠕虫,例如,如果客户机忘记这么做怎么办?如果它对其他东西使用相同的标识符名称呢


我能避免这个吗?如果没有,是否有某种方法可以验证客户端和库上的头文件是否匹配,并导致编译错误?或者至少抛出一个运行时异常?对于这种情况,正确的方法是什么?

最明显的方法是,即使不支持OpenCL,也将
open\u cl\u platform\u id
作为
设置的成员。如果用户在库尚未编译时尝试使用OpenCL功能,则会出现运行时错误


或者,有两个头文件
settings\u no\u open\u cl.hpp
settings\u open\u cl.hpp
,并要求用户包含正确的头文件。

是否考虑过动态加载和后期绑定?是否可以使头文件不依赖于ENABLE\u open\u cl定义?但在cpp中,当编译时没有此标志-您为任何API提供一个空存根函数实现-返回错误\u NOTIMPLEMENTED-因此客户端不需要定义任何内容-但是如果它链接到库而不支持OpenCL,任何依赖于它的调用都将失败(以有充分文档记录的方式)?另一种方法是根据构建设置生成具有所有正确定义的头文件(library_config.h),并将此头文件与库一起分发(包括在您分发的任何公共h文件中)因此,客户机不需要在自己的代码中添加任何定义规范的CMake所要做的事情不是强迫用户在其构建行上启用OpenCL,但让CMake对一个小型OpenCL程序进行测试编译,看看它是否在该平台上工作,然后定义
have_OpenCL
或类似的东西,让您的代码知道OpenCL是否可用。我最后做的是按照建议将
open_cl_platform_id
保留在中。但我觉得这使得API不够明确,所以我还添加了另一个设置
bool use\u open\u cl
,该设置必须设置为true才能明确显示使用该功能的意图。如果
use\u open\u cl
为true,但未定义
ENABLE\u open\u cl
,则抛出异常。