如何在cmake中使用FFTW库?

Max*_*xim 3 c++ cmake fftw

我有使用FFTW 3.3.4的C++代码.Ubuntu 16.04,cmake版本3.7.2

$ locate *fftw*.so

/usr/lib/libsfftw.so
/usr/lib/libsfftw_mpi.so
/usr/lib/libsfftw_threads.so
/usr/lib/libsrfftw.so
/usr/lib/libsrfftw_mpi.so
/usr/lib/libsrfftw_threads.so
/usr/lib/x86_64-linux-gnu/libfftw3.so
/usr/lib/x86_64-linux-gnu/libfftw3_mpi.so
/usr/lib/x86_64-linux-gnu/libfftw3_omp.so
/usr/lib/x86_64-linux-gnu/libfftw3_threads.so
/usr/lib/x86_64-linux-gnu/libfftw3f.so
/usr/lib/x86_64-linux-gnu/libfftw3f_mpi.so
/usr/lib/x86_64-linux-gnu/libfftw3f_omp.so
/usr/lib/x86_64-linux-gnu/libfftw3f_threads.so
/usr/lib/x86_64-linux-gnu/libfftw3l.so
/usr/lib/x86_64-linux-gnu/libfftw3l_mpi.so
/usr/lib/x86_64-linux-gnu/libfftw3l_omp.so
/usr/lib/x86_64-linux-gnu/libfftw3l_threads.so
/usr/lib/x86_64-linux-gnu/libfftw3q.so
/usr/lib/x86_64-linux-gnu/libfftw3q_omp.so
/usr/lib/x86_64-linux-gnu/libfftw3q_threads.so


$ locate fftw3.h
/usr/include/fftw3.h
Run Code Online (Sandbox Code Playgroud)

我可以用这种方式编译它:

g++ main.cpp -o main -lfftw3
Run Code Online (Sandbox Code Playgroud)

但是我的cmake有问题.

这是我的CMakeLists.txt:

cmake_minimum_required(VERSION 3.5.1)
project (main)
SET(CMAKE_C_COMPILER gcc)
SET(CMAKE_CXX_COMPILER g++)
file(GLOB SOURCES "*.cpp") 
SET(CMAKE_CXX_FLAGS "-lm -lfftw3")
SET(CMAKE_C_FLAGS   "-lm -lfftw3")
INCLUDE_DIRECTORIES(/usr/include)
LINK_DIRECTORIES(/usr/lib/x86_64-linux-gnu)
add_library(fftw3 STATIC IMPORTED)
set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1) 
set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)
add_executable(main ${SOURCES})

cmake . && make
Run Code Online (Sandbox Code Playgroud)

undefined reference to `fftw_malloc'
Run Code Online (Sandbox Code Playgroud)

和其他fftw功能相同.

Soe*_*ren 6

该命令add_library将在您的项目中创建一个库(CMake - add_library).我认为这不是你想要的.

命令:g++ main.cpp -o main -lfftw3将可执行文件链接 fftw库.在CMake中,您可以重现以下链接:

add_executable(main ${SOURCES})
target_link_libraries(main fftw3)
Run Code Online (Sandbox Code Playgroud)

Docu:CMake - target_link_libraries
注意:add_executable命令在链接之前是很重要的.
享受FFTW :)


alf*_*lfC 4

我们将此委托给pkg-config

find_package(PkgConfig REQUIRED)
pkg_search_module(FFTW REQUIRED fftw3 IMPORTED_TARGET)
include_directories(PkgConfig::FFTW)
link_libraries(PkgConfig::FFTW)
Run Code Online (Sandbox Code Playgroud)

这适用于 cmake 3.11(至少,它也可以适用于早期版本)。


注意:这不适用于fftw3_thread组件,因为它们没有单独的.pc文件。(参见https://github.com/FFTW/fftw3/issues/180)。

可能可以添加组件(未经测试,在 Mac 中不起作用——请参阅评论——):

link_libraries(PkgConfig::FFTW -lfftw3_thread)
Run Code Online (Sandbox Code Playgroud)

注意 2:我在这里粘贴 @OlafWilkocx 解决方案来获取线程组件

cmake_minimum_required(VERSION 3.20)
...
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-math-errno -ffinite-math-only") # clang
find_package(OpenMP REQUIRED)

find_package(PkgConfig REQUIRED)     
pkg_check_modules(FFTW IMPORTED_TARGET REQUIRED fftw3)
          
if(NOT FFTW_ROOT AND DEFINED ENV{FFTWDIR})
    set(FFTW_ROOT $ENV{FFTWDIR})
endif()
          
find_library(
    FFTW_DOUBLE_THREADS_LIB
    NAMES "fftw3_threads"
    PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}
)
          
if (FFTW_DOUBLE_THREADS_LIB)
    set(FFTW_DOUBLE_THREADS_LIB_FOUND TRUE)
    set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_THREADS_LIB})
    add_library(FFTW::DoubleThreads INTERFACE IMPORTED)
    set_target_properties(FFTW::DoubleThreads
        PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}"
        INTERFACE_LINK_LIBRARIES "${FFTW_DOUBLE_THREADS_LIB}"
    )
else()
    set(FFTW_DOUBLE_THREADS_LIB_FOUND FALSE)
endif()
     
include_directories(PkgConfig::FFTW)
     
add_executable(solver_step src/solver_step.cc)
target_link_libraries(solver_step PRIVATE OpenMP::OpenMP_CXX ${VTK_LIBRARIES} PkgConfig::FFTW ${FFTW_DOUBLE_THREADS_LIB})
Run Code Online (Sandbox Code Playgroud)

注3

我被告知该行 include_directories(PkgConfig::FFTW)始终不正确,建议仅使用link_libraries(PkgConfig::FFTW) target_link_libraries(target_name PRIVATE PkgConfig::FFTW)

请参阅此处:避免 CMake 的 pkg-config 后备中出现错误的包含路径