c++ - 如何实现条件编译而不弄乱库API?

标签 c++ cmake api-design conditional-compilation

我有一个可以使用 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, 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

    // ...
}

因此,当我编译库时,如果我想启用 OpenCL,我会执行 cmake .. -DENABLE_OPEN_CL

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

这会带来一大堆蠕虫,例如,如果客户忘记这样做怎么办?如果它对其他东西使用相同的标识符名称怎么办?

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

最佳答案

最明显的方法是,即使不支持 OpenCL,也将 open_cl_platform_id 保留为 settings 的成员。如果用户在尚未编译库的情况下尝试使用 OpenCL 功能,则会收到运行时错误。

或者,有两个头文件 settings_no_open_cl.hppsettings_open_cl.hpp,并要求用户包含正确的一个。

关于c++ - 如何实现条件编译而不弄乱库API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46541511/

相关文章:

api - 休息 API : reasonable to create associated resources given a verbose representation?

php - Symfony 中的 API 分页

c++ - 错误 C2679 : binary '+' : no operator found which takes a right-hand operand of type

c++ - 具有多个目标的 Makefile 并创建一个具有可执行文件的目录

CMake:Windows SDK 中的 "The C compiler identification is unknown"

linux - Yocto 生成的 nativesdk-cmake SDK 不完整

api - Java标准库: Which methods are with biggest number of arguments in the library?

c++ - G++ 编译器对我明确定义的函数给出 "undefined reference"错误

java - 如何获取未解码的文件名

c++ - 如何在 Windows 中将共享库 *dll 与 CMake 链接