CMake cannot find OneAPI libraries mkl_gf_lp64 and mkl_gnu_thread - cmake

I am trying to adapt a source code originally written for Intel MKL to the latest OneAPI and compile it under MacOS.
I have modified the CMakeLists to find OneAPI libraries like this:
option (USE_ONEAPI "Enable MKL solver support via OneAPI Base Toolkit" ON)
...
if (USE_ONEAPI)
message(STATUS "Seeking OneAPI libraries...")
list(APPEND MKL_LIBS "mkl_core" "mkl_gf_lp64" "mkl_gnu_thread" "pthread")
foreach (f ${MKL_LIBS})
if (INTEL_ONEAPI_DIR)
# user provided OneAPI directory
set(oneapiMklDir "${INTEL_ONEAPI_DIR}/mkl/latest")
message(STATUS " Seeking for ${f} in custom path: ${oneapiMklDir}...")
find_library (${f}_LIB ${f} PATH "${INTEL_ONEAPI_DIR}/mkl/lib/intel64/" DOC "MKLPARDISO (library)")
include_directories ("${INTEL_ONEAPI_DIR}/mkl/include")
else ()
set(oneapiDir "/opt/intel/oneapi")
set(oneapiMklDir "${oneapiDir}/mkl/latest")
message(STATUS " Seeking for ${f} in default path: ${oneapiMklDir}...")
find_library (${f}_LIB ${f} HINTS "${oneapiMklDir}/lib" DOC "MKLPARDISO (library)")
include_directories ("${oneapiMklDir}/include")
endif ()
if (${${f}_LIB} STREQUAL "${f}_LIB-NOTFOUND")
message (FATAL_ERROR "OneAPI ${f} library not found")
else()
message (STATUS "OK: ${f} library successfully found")
endif ()
list (APPEND EXT_LIBS ${${f}_LIB})
endforeach ()
list (APPEND MODULE_LIST "MKLPARDISO")
endif ()
And this is the outcome:
-- Seeking OneAPI libraries...
-- Seeking for mkl_core in default path: /opt/intel/oneapi/mkl/latest...
-- OK: mkl_core_LIB library successfully found
-- Seeking for mkl_gf_lp64 in default path: /opt/intel/oneapi/mkl/latest...
CMake Error at CMakeLists.txt:379 (message):
OneAPI mkl_gf_lp64 library not found
I am not sure why CMake fails to find those libraries. Are they not installed with OneAPI base and HPC toolkits?

This is old so likely you already found a solution, but since I'm going through oneapi questions I figured I'd answer for the next person.
The mkl_gf_lp64 is not included but mkl_intel_lp64 is. The two are not equivalent so you would likely need mkl_intel_thread.
You can also use the oneAPI MKL Library Link Line Advisor to figure out exactly what you need.
https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl-link-line-advisor.html

Related

CMake check if CUDA environment exists without find_package

As stated here https://cmake.org/cmake/help/latest/module/FindCUDA.html
find_package(CUDA)
is a deprecated way to use CUDA in CXX project. We have to use
project(MY_PROJECT LANGUAGES CUDA CXX)
but how can I detect whether the current platform supports CUDA. The goal is to exclude some targets from build if CUDA is not installed.
Just found a solution thanks to a comment posted on the question referring to this Stack Overflow answer, and in turn this piece of documentation.
Here is a code snippet :
cmake_minimum_required(VERSION 3.8)
include(CheckLanguage)
project(my_project)
check_language(CUDA)
if (CMAKE_CUDA_COMPILER)
message(STATUS "CUDA is OK")
else()
message(STATUS "No CUDA")
endif()

Static linking of OpenSSL Crypto in CMake

I need to make a cross-compiled OpenSSL for a MIPS device. I've tried following the documentation. Set OPENSSL_USE_STATIC_LIBS to true and set target_link_libraries to the library files you need.
CMakeLists.txt:
compileAsC99()
if(NOT ${use_http})
message(FATAL_ERROR "program being generated without HTTP support")
endif()
set(program_c_files
...
)
set(program_h_files
...
)
include_directories(...)
add_executable(program ${program_c_files} ${program_h_files})
set(OPENSSL_USE_STATIC_LIBS TRUE)
#target_link_libraries(program OpenSSL::Crypto)
target_link_libraries(program /home/program/mips/lib/libssl.so.1.1)
target_link_libraries(program /home/program/mips/lib/libcrypto.so.1.1)
It compiles fine without warnings, but checking the resulting binary tells me that it's still shared library.
readelf -d program:
Dynamic section at offset 0x1bc contains 35 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libssl.so.1.1]
0x00000001 (NEEDED) Shared library: [libcrypto.so.1.1]
0x0000000f (RPATH) Library rpath: [/home/program/mips/lib]
I don't understand what I'm doing wrong.
EDIT: Already looked at Linking statically OpenSSL crypto library in CMake but it didn't tell me anything new.
EDIT 2: Updated the CMakeLists.txt file according to the reply:
CMakeLists.txt:
compileAsC99()
if(NOT ${use_http})
message(FATAL_ERROR "program being generated without HTTP support")
endif()
set(program_c_files
...
)
set(program_h_files
...
)
include_directories(...)
add_executable(program ${program_c_files} ${program_h_files})
find_package(OpenSSL REQUIRED)
if(OPENSSL_FOUND)
set(OPENSSL_USE_STATIC_LIBS TRUE)
message("OPENSSL FOUND!")
endif()
target_link_libraries(program OpenSSL::Crypto)
Output:
-- IoT Client SDK Version = 1.2.11
-- Provisioning client OFF
-- target architecture: GENERIC
-- Cross compiling not using pkg-config
-- Found CURL: /home/program/mips/lib/libcurl.a (found version "7.63.0")
-- Found CURL: /home/program/mips/lib/libcurl.a
-- target architecture: GENERIC
-- target architecture: GENERIC
-- target architecture: GENERIC
-- target architecture: GENERIC
-- iothub architecture: GENERIC
OPENSSL FOUND!
-- Configuring done
-- Generating done
EDIT PROSPERITY:
If you, future people, run into the undefined reference to dlopen, I added the following to my CMakeLists.txt file
target_link_libraries(program ${CMAKE_DL_LIBS})
Setting to TRUE, variable OPENSSL_USE_STATIC_LIBS forces find_package(OpenSSL) to search the static library. So this variable works only with that call, and if you use its results:
set(OPENSSL_USE_STATIC_LIBS TRUE)
find_package(OpenSSL REQUIRED)
target_link_libraries(program OpenSSL::Crypto)
If you have already executed cmake without setting of OPENSSL_USE_STATIC_LIBS, then you need to remove CMake cache (CMakeCache.txt under build directory) before new attempt. Otherwise, already found (shared!) libraries will be used and no re-search will be performed.

Linking against external library with CMake

I'm currently at a bit of a loss when trying to use the Libspotify SDK in my CMake project.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.2)
project(spotti)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
find_package(Spotify REQUIRED)
include_directories(${Spotify_INCLUDE_DIR})
set(LIBS ${LIBS} ${Spotify_LIBRARIES})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
set(SOURCE_FILES main.cpp)
add_executable(spotti ${SOURCE_FILES})
FindSpotify.cmake:
# - Find Spotify
# Find the native Google Sparse Hash Etc includes
#
# Spotify_INCLUDE_DIR - where to find sparse_hash_set, etc.
# Spotify_FOUND - True if Spotify found.
if (Spotify_INCLUDE_DIR)
# Already in cache, be silent
set(Spotify_FIND_QUIETLY TRUE)
endif ()
find_path(Spotify_INCLUDE_DIR api.h PATHS
/opt/local/include/libspotify
/usr/local/include/libspotify
/usr/include/libspotify
/home/denvercoder21/Development/cpp/spotti/libspotify/include/libspotify/
)
set(Spotify_LIB_PATHS /usr/local/lib /opt/local/lib /home/denvercoder21/Development/cpp/spotti/libspotify/lib/)
find_library(Spotify_LIB NAMES spotify PATHS ${Spotify_LIB_PATHS})
if (Spotify_INCLUDE_DIR AND Spotify_LIB)
set(Spotify_FOUND TRUE)
else ()
set(Spotify_FOUND FALSE)
endif ()
if (Spotify_FOUND)
if (NOT Spotify_FIND_QUIETLY)
message(STATUS "Found Spotify: ${Spotify_INCLUDE_DIR}")
endif ()
else ()
message(STATUS "Not Found Spotify: ${Spotify_INCLUDE_DIR}")
if (Spotify_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find Spotify includes")
endif ()
endif ()
mark_as_advanced(
Spotify_LIB
Spotify_INCLUDE_DIR
)
My libspotify folder is in the project root directory. I think I might be missing a target_link_libraries() in my CMakeLists.txt. Or not?
Anyway, CMake runs without errors with these files, but compiling my project gives me undefined reference errors. What's wrong?
I think I might be missing a target_link_libraries() in my CMakeLists.txt.
Yes, you should explicitly link with Spotify:
target_link_libraries(spotti Spotify)
find_package() does not perform automatic linking.

CMake compile options for libpng

I am using libpng in my project. Right now, I can compile my project with: g++ *.cpp `libpng-config --ldflags`
I want to switch to using CMake for easy recompiling but I don't know what to do for the libpng part. How do I provide `libpng-config --ldflags` with CMake?
I finally solved it using find_package. Thanks to this blog post.
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
target_link_libraries(${MY_EXEC} ${PNG_LIBRARY})
I think the recommended and portable way it should be done using pkg-config, something like this:
# search for pkg-config
include (FindPkgConfig)
if (NOT PKG_CONFIG_FOUND)
message (FATAL_ERROR "pkg-config not found")
endif ()
# check for libpng
pkg_check_modules (LIBPNG libpng16 REQUIRED)
if (NOT LIBPNG_FOUND)
message(FATAL_ERROR "You don't seem to have libpng16 development libraries installed")
else ()
include_directories (${LIBPNG_INCLUDE_DIRS})
link_directories (${LIBPNG_LIBRARY_DIRS})
link_libraries (${LIBPNG_LIBRARIES})
endif ()
add_executable (app_png ${_MYSOURCES} ${LIBPNG_LINK_FLAGS})

Find BLAS giving the path to the lib

I use blas/lapack in my C++ code built with CMake 2.8.9. I want to find BLAS and LAPACK libraries with the CMake commands :
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
But it can found it because the libraries are in a specific directory. The error is the following :
CMake Error at /softs/cmake/2.8.9/64/gcc/4.7.2/share/cmake-2.8/Modules/FindBLAS.cmake:594 (message):
A required library with BLAS API not found. Please specify library
My question : How can I specify an additional path to help FindBLAS to work, in the same way I do it for Boost (see below) ?
set(PATH_BOOST "/softs/boost/1.53.0/${ARCH}/${COMPILER_NAME}/${COMPILER_VERSION}")
set(BOOST_INCLUDEDIR "${PATH_BOOST}/include")
set(BOOST_LIBRARYDIR "${PATH_BOOST}/lib")
set(Boost_USE_MULTITHREAD ON)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.53.0 REQUIRED COMPONENTS thread system)
You are looking for is BLAS_DIR and LAPACK_DIR variable.
set(BLAS_DIR /path/to/blas)
find_package(BLAS REQUIRED)
set(LAPACK_DIR /path/to/lapack)
find_package(LAPACK REQUIRED)