如何在 cmake 中使用 FFTW 库?
How to use FFTW library in cmake?
我有使用 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
我可以这样编译:
g++ main.cpp -o main -lfftw3
但是我对 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
给予
undefined reference to `fftw_malloc'
其他 fftw 函数也一样。
命令 add_library
将在您的项目中创建一个库 (CMake -
add_library)。我认为这不是你想要的。
命令:g++ main.cpp -o main -lfftw3
将 link 可执行文件 到 fftw 库。在 CMake 中,您可以使用以下方法重现 linking:
add_executable(main ${SOURCES})
target_link_libraries(main fftw3)
文档:CMake - target_link_libraries
注意:重要的是 add_executable 命令出现在 linking.
之前
玩得开心 FFTW :)
我们委托给 pkg-config
:
find_package(PkgConfig REQUIRED)
pkg_search_module(FFTW REQUIRED fftw3 IMPORTED_TARGET)
include_directories(PkgConfig::FFTW)
link_libraries (PkgConfig::FFTW)
这适用于 cmake 3.11(至少,它也适用于早期版本)。
注意: 这不适用于 fftw3_thread
组件,因为它们没有单独的 .pc
文件。 (参见 https://github.com/FFTW/fftw3/issues/180)。
这 可能 可以添加组件(未经测试,在 Mac 中不起作用 -- 查看评论 --):
link_libraries (PkgConfig::FFTW -lfftw3_thread)
注意 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})
注 3
有人告诉我 include_directories(PkgConfig::FFTW)
行总是不正确,建议只使用 link_libraries(PkgConfig::FFTW)
或 target_link_libraries(target_name PRIVATE PkgConfig::FFTW)
。
看这里:Avoid bad include paths in CMake's pkg-config fallback
我有使用 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
我可以这样编译:
g++ main.cpp -o main -lfftw3
但是我对 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
给予
undefined reference to `fftw_malloc'
其他 fftw 函数也一样。
命令 add_library
将在您的项目中创建一个库 (CMake -
add_library)。我认为这不是你想要的。
命令:g++ main.cpp -o main -lfftw3
将 link 可执行文件 到 fftw 库。在 CMake 中,您可以使用以下方法重现 linking:
add_executable(main ${SOURCES})
target_link_libraries(main fftw3)
文档:CMake - target_link_libraries
注意:重要的是 add_executable 命令出现在 linking.
之前
玩得开心 FFTW :)
我们委托给 pkg-config
:
find_package(PkgConfig REQUIRED)
pkg_search_module(FFTW REQUIRED fftw3 IMPORTED_TARGET)
include_directories(PkgConfig::FFTW)
link_libraries (PkgConfig::FFTW)
这适用于 cmake 3.11(至少,它也适用于早期版本)。
注意: 这不适用于 fftw3_thread
组件,因为它们没有单独的 .pc
文件。 (参见 https://github.com/FFTW/fftw3/issues/180)。
这 可能 可以添加组件(未经测试,在 Mac 中不起作用 -- 查看评论 --):
link_libraries (PkgConfig::FFTW -lfftw3_thread)
注意 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})
注 3
有人告诉我 include_directories(PkgConfig::FFTW)
行总是不正确,建议只使用 link_libraries(PkgConfig::FFTW)
或 target_link_libraries(target_name PRIVATE PkgConfig::FFTW)
。
看这里:Avoid bad include paths in CMake's pkg-config fallback