Связывание со статическими библиотеками 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
.