Я возился с OpenCL, где файлы обычно компилируются во время выполнения. Типичная структура проекта выглядит следующим образом:
foo/
cl/foo.cl
inc/foo.hpp
src/foo.cpp
CMakeLists.txt
, где foo.cpp
будет иметь команду для сборки ядра OpenCL. Что-то вроде:
buildKernelFromFile('cl/foo.cl'); // Note the relative path
Чтобы упростить это, я настраивал файл CMakeLists.txt
для копирования файлов .cl
в папку cl/
в двоичном каталоге:
set(kernels
foo.cl)
foreach (kernel IN ITEMS ${kernels})
configure_file(${CMAKE_CURRENT_LIST_DIR}/cl/${kernel} ${CMAKE_CURRENT_BINARY_DIR}/cl/${kernel} COPYONLY)
endforeach ()
Проблема заключается в том, что когда проект foo
является исполняемым файлом, этот подход подходит, поскольку файлы .cl
будут скопированы в то же место, что и исполняемый файл. Однако когда проект foo
является библиотекой, этот подход больше не работает, поскольку относительный путь относится к двоичному каталогу библиотеки, а не к двоичному каталогу исполняемого файла, использующего библиотеку.
Итак, мне бы хотелось как-то попросить CMake скопировать файлы .cl
в двоичный каталог любых зависимых целей. В частности, если я собираю проект OpenCL следующим образом
add_library(foo foo.cpp)
, а затем в отдельном файле CMakeLists.txt, ссылка на этот проект:
add_executable(something main.cpp)
target_link_library(something PRIVATE foo)
Мне нужно скопировать .cl
файлы в папку сборки CMAKE_CURRENT_BINARY_DIR
цели something
.
Единственное, чего я хотел бы избежать, - это сохранять файлы .cl в виде строковых литералов, а затем использовать их как включение. (Игнорируйте этот комментарий, если он вам не нужен).
РЕДАКТИРОВАТЬ:
Тем временем в файле CMakeLists.txt библиотеки OpenCL (foo/CMakeLists.txt
) я просто объявил функция
# Copy the OpenCL kernels to the build folder
set(KERNEL_DIR ${CMAKE_CURRENT_LIST_DIR}/cl PARENT_SCOPE)
function(copy_kernels)
set(kernels
foo.cl)
foreach (kernel IN ITEMS ${kernels})
configure_file(${KERNEL_DIR}/${kernel} ${CMAKE_CURRENT_BINARY_DIR}/cl/${kernel} COPYONLY)
endforeach ()
endfunction()
, которая должна вызываться зависимыми проектами. Затем в зависимом проекте, помимо ссылки на цель foo
, вам нужно вызвать эту функцию
copy_kernels()
target_link_library(something PRIVATE foo)
Я хотел бы выяснить, как избавиться от этого вызова copy_kernels()
, но Я не знаю достаточно хорошо, чтобы сделать это.