CMake: как использовать LINK_INTERFACE_MULTIPLICITY? - PullRequest
0 голосов
/ 04 мая 2018

Связывание со статическими библиотеками Intel MKL вводит циклические зависимости. Когда я импортирую библиотеки,

set(LIBRARIES mkl_intel_lp64 mkl_sequential mkl_core)
foreach(_lib ${LIBRARIES})
  add_library(${_lib} UNKNOWN IMPORTED)
  set_target_properties(${_lib} PROPERTIES IMPORTED_LOCATION
    /opt/intel/mkl/lib/intel64/lib${_lib}.a)
endforeach()

и ссылка на мой исполняемый файл,

target_link_libraries(main PRIVATE ${LIBRARIES})

Я получаю массу неопределенных ссылок на вызовы линейной алгебры. Например,

ztrevc3_gen.f:(.text+0x1af7): undefined reference to `mkl_blas_zdscal'

Один из способов обойти это - использовать соответствующие флаги компоновщика:

target_link_libraries(main PRIVATE -Wl,--start-group ${LIBRARIES} -Wl,--end-group)

Другой вариант сделать это:

target_link_libraries(main PRIVATE ${LIBRARIES} ${LIBRARIES} ${LIBRARIES})

Однако, когда я искал более элегантное решение, я наткнулся на свойство LINK_INTERFACE_MULTIPLICITY. Если установить это свойство вместе с импортированным местоположением библиотеки,

set(LIBRARIES mkl_intel_lp64 mkl_sequential mkl_core)
foreach(_lib ${LIBRARIES})
  add_library(${_lib} UNKNOWN IMPORTED)
  set_target_properties(${_lib} PROPERTIES IMPORTED_LOCATION
    /opt/intel/mkl/lib/intel64/lib${_lib}.a
    LINK_INTERFACE_MULTIPLICITY 3)
endforeach()

Я получаю те же неопределенные ссылки, что и раньше, так что, видимо, это не работает. Как правильно использовать LINK_INTERFACE_MULTIPLICITY и есть ли более элегантный способ обойти циклические зависимости?

EDIT

Вот минимальный пример, который дает сбой, на этот раз с правильной переменной IMPORTED_LINK_INTERFACE_MULTIPLICITY.

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(test Fortran)
add_executable(main main.f90)
set(LIBRARIES mkl_intel_lp64 mkl_sequential mkl_core)
foreach(_lib ${LIBRARIES})
  add_library(${_lib} UNKNOWN IMPORTED)
  set_target_properties(${_lib} PROPERTIES IMPORTED_LOCATION
    /opt/intel/mkl/lib/intel64/lib${_lib}.a
    IMPORTED_LINK_INTERFACE_MULTIPLICITY 3)
endforeach()
list(APPEND LIBRARIES dl pthread)
target_link_libraries(main ${LIBRARIES})
#target_link_libraries(main ${LIBRARIES} ${LIBRARIES} ${LIBRARIES})

# main.f90
  call zpotrf
end program

Если вы раскомментируете последнюю строку, то сборка завершится успешно. К сожалению, MKL не является бесплатным (за исключением некоторых случаев), но, надеюсь, кто-нибудь сможет это проверить. Я должен отметить, что он не работает с некоторыми вызовами линейной алгебры, а не с такими, как dgemm.

1 Ответ

0 голосов
/ 04 мая 2018

Свойство LINK_INTERFACE_MULTIPLICITY предназначено для "нормальной" STATIC библиотеки. Для IMPORTED библиотеки IMPORTED_LINK_INTERFACE_MULTIPLICITY следует использовать свойство вместо:

  set_target_properties(${_lib} PROPERTIES
    IMPORTED_LOCATION /opt/intel/mkl/lib/intel64/lib${_lib}.a
    IMPORTED_LINK_INTERFACE_MULTIPLICITY 3)
...