cmake: копировать файлы в зависимые цели (специально для использования в OpenCL) - PullRequest
0 голосов
/ 27 января 2020

Я возился с 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(), но Я не знаю достаточно хорошо, чтобы сделать это.

...