OpenCL 프레임 워크를 사용하여 GPU 계산을 할 수있는 라이브러리가 있습니다. 슬프게도, 모든 플랫폼에서 OpenCL을 사용할 수있는 것은 아닙니다. 그러나 여전히 OpenCL 기능을 제외하고 해당 플랫폼에서 내 코드를 컴파일 할 수 있기를 원합니다.라이브러리 API를 엉망으로 만들지 않고 조건부 컴파일을 구현하는 방법은 무엇입니까?
이 질문은 항상 사용할 수없는 일부 외부 리소스를 조건부로 컴파일하려는 모든 상황에 적용되며 라이브러리 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
// ...
}
을 그래서 라이브러리를 컴파일 할 때, 만약 I OpenCL을 사용하고 싶습니다. cmake .. -DENABLE_OPEN_CL
. 이 작동하지만, 클라이언트가 ENABLE_OPEN_CL
로 컴파일 된 라이브러리를 소비하는 경우, 그렇지 않으면 포함 된 라이브러리의 헤더 파일은 클라이언트에서 사용 하나, 매우 나쁜 일이 일치하지 않는, 같은 ENABLE_OPEN_CL
을 정의하는 클라이언트를 강제
우연히 있다.
이렇게하면 웜이 완전히 열릴 수 있습니다. 예를 들어 클라이언트가 그 일을 잊어 버린 경우 어떻게됩니까? 다른 식별자에 동일한 식별자 이름을 사용하면 어떨까요?
이 문제를 방지 할 수 있습니까? 그렇지 않다면 헤더 파일이 클라이언트와 라이브러리에서 일치하는지 확인하고 컴파일 오류를 일으킬 수있는 방법이 있습니까? 아니면 적어도 런타임 예외가 발생합니까? 이 시나리오에 대한 올바른 접근 방법은 무엇입니까?
동적로드 및 후기 바인딩을 고려해 보셨습니까? –
그리고 헤더를 ENABLE_OPEN_CL 정의에 의존하지 않을 수 있습니까? 하지만이 플래그없이 컴파일 할 때 - 당신은 ERROR_NOTIMPLEMENTED를 반환하는 어떤 API에 대해서도 빈 스텁 함수 구현을 제공합니다. 그래서 클라이언트는 아무 것도 정의 할 필요가 없습니다. 그러나 OpenCL을 지원하지 않는 라이브러리에 링크되어 있으면 모든 호출이 실패합니다. 잘 문서화 된 방식)? –
또 다른 방법은 빌드 설정을 기반으로 모든 적절한 정의를 사용하여 헤더 파일 (library_config.h)을 생성하고 클라이언트가 추가 할 필요가 없도록이 헤더를 라이브러리 (배포하는 공용 h- 파일에 포함)와 함께 배포하는 것입니다 임의의 코드를 자체 코드로 정의 –