Merge pull request #52 from madebr/cmake_install

Add cmake install + MSVC dll support
This commit is contained in:
mborgerding 2020-11-05 21:34:50 -05:00 committed by GitHub
commit 15debe8ed3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 310 additions and 10 deletions

View File

@ -3,7 +3,7 @@ language: python
python: python:
- "3.7" - "3.7"
dist: bionic dist: focal
before_install: before_install:
- sudo apt-get install -y libfftw3-dev - sudo apt-get install -y libfftw3-dev

View File

@ -1,9 +1,136 @@
cmake_minimum_required(VERSION 2.8) file(READ Makefile _MAKEFILE_CONTENTS)
project(kissfft) string(REGEX MATCH "KFVER=([0-9]+)\n" KFVER_MATCH "${_MAKEFILE_CONTENTS}")
if(NOT KFVER_MATCH)
message(FATAL_ERROR "Cannot extract version from Makefile")
endif()
set(MAKEFILE_EXTRACTED_VERSION "${CMAKE_MATCH_1}")
cmake_minimum_required(VERSION 3.13)
project(kissfft VERSION "${MAKEFILE_EXTRACTED_VERSION}")
option(KISSFFT_SIMD "Build kissfft with SIMD" OFF)
option(KISSFFT_FLOAT "Build kissfft with float type" ON)
option(KISSFFT_OPENMP "Build kissfft with openmp" OFF)
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
add_compile_options(-ffast-math -fomit-frame-pointer
-W -Wall -Waggregate-return -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings
"$<$<COMPILE_LANGUAGE:C>:-Wstrict-prototypes;-Wmissing-prototypes;-Wnested-externs;-Wbad-function-cast>")
endif()
set(KISSFFT_FIXED_WIDTH_VALID 16 32)
set(KISSFFT_FIXED_WIDTH "16" CACHE STRING "Width of kissfft fixed integer (16/32)")
set_property(CACHE KISSFFT_FIXED_WIDTH PROPERTY STRINGS ${KISSFFT_FIXED_WIDTH_VALID})
if(NOT KISSFFT_FIXED_WIDTH IN_LIST KISSFFT_FIXED_WIDTH_VALID)
message(FATAL_ERROR "KISSFFT_FIXED_WIDTH must be 16 or 32")
endif()
set(KISSFFT_FLOAT_TYPE_VALID float double)
set(KISSFFT_FLOAT_TYPE "float" CACHE STRING "Floating type of kissfft (float/double)")
set_property(CACHE KISSFFT_FLOAT_TYPE PROPERTY STRINGS ${KISSFFT_FLOAT_TYPE_VALID})
if(NOT KISSFFT_FLOAT_TYPE IN_LIST KISSFFT_FLOAT_TYPE_VALID)
message(FATAL_ERROR "KISSFFT_FLOAT_TYPE must be float or double")
endif()
add_library(kissfft add_library(kissfft
kiss_fft.c) kiss_fft.c)
target_include_directories(kissfft PUBLIC target_include_directories(kissfft PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:.>) $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
set(KISSFFT_COMPILE_DEFINITIONS)
if(KISSFFT_SIMD)
list(APPEND KISSFFT_COMPILE_DEFINITIONS USE_SIMD)
set(KISSFFT_DATATYPE "simd")
else()
if(KISSFFT_FLOAT)
list(APPEND KISSFFT_COMPILE_DEFINITIONS kiss_fft_scalar=${KISSFFT_FLOAT_TYPE})
set(KISSFFT_DATATYPE "${KISSFFT_FLOAT_TYPE}")
else()
list(APPEND KISSFFT_COMPILE_DEFINITIONS KISSFFT_FIXED_POINT=${KISSFFT_FIXED_WIDTH})
set(KISSFFT_DATATYPE "int${KISSFFT_FIXED_WIDTH}")
endif()
endif()
if(KISSFFT_OPENMP)
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
target_compile_options(kissfft PRIVATE -fopenmp)
target_link_options(kissfft PUBLIC -fopenmp)
else()
message(FATAL_ERROR "Don't know how to enable openmp for this compiler")
endif()
endif()
message(STATUS "Building KissFFT with datatype=${KISSFFT_DATATYPE}")
if(BUILD_SHARED_LIBS)
list(APPEND KISSFFT_COMPILE_DEFINITIONS KISS_FFT_SHARED)
set_target_properties(kissfft PROPERTIES
C_VISIBILITY_PRESET hidden)
set(KISSFFT_EXPORT_SUFFIX "-shared")
else()
set(KISSFFT_EXPORT_SUFFIX "-static")
endif()
target_compile_definitions(kissfft PUBLIC ${KISSFFT_COMPILE_DEFINITIONS})
set(KISSFFT_OUTPUT_NAME "kissfft_${KISSFFT_DATATYPE}")
set_target_properties(kissfft PROPERTIES
OUTPUT_NAME "${KISSFFT_OUTPUT_NAME}"
DEFINE_SYMBOL KISS_FFT_BUILD
EXPORT_NAME "kissfft-${KISSFFT_DATATYPE}"
VERSION ${PROJECT_VERSION})
add_library(kissfft::kissfft ALIAS kissfft)
add_library(kissfft::kissff-${KISSFFT_DATATYPE} ALIAS kissfft)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(kissfft PRIVATE m)
endif()
function(add_kissfft_executable NAME)
add_executable(${NAME} ${ARGN})
target_link_libraries(${NAME} PRIVATE kissfft::kissfft)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(${NAME} PRIVATE m)
endif()
set_target_properties(${NAME} PROPERTIES
OUTPUT_NAME "${NAME}_${KISSFFT_DATATYPE}")
endfunction()
option(KISSFFT_TOOLS "Build kissfft tools" ON)
if(KISSFFT_TOOLS)
add_subdirectory(tools)
endif()
option(KISSFFT_TEST "Build and enable kissfft tests" ON)
if(KISSFFT_TEST)
enable_testing()
add_subdirectory(test)
endif()
option(KISSFFT_INSTALL "Enable kissfft install" ON)
if (KISSFFT_INSTALL)
include(GNUInstallDirs)
install(TARGETS kissfft EXPORT kissfft
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(FILES "kiss_fft.h" "kissfft.hh" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
set(KISSFFT_INSTALL_CMAKE "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE FILEPATH "Install destination of kissfft cmake modules")
mark_as_advanced(KISSFFT_INSTALL_CMAKE)
install(EXPORT kissfft DESTINATION "${KISSFFT_INSTALL_CMAKE}"
NAMESPACE "kissfft::"
FILE "${PROJECT_NAME}-${KISSFFT_DATATYPE}${KISSFFT_EXPORT_SUFFIX}-targets.cmake")
include(CMakePackageConfigHelpers)
configure_package_config_file(kissfft-config.cmake.in kissfft-config.cmake
INSTALL_DESTINATION "${KISSFFT_INSTALL_CMAKE}")
write_basic_package_version_file(kissfft-config-version.cmake COMPATIBILITY AnyNewerVersion)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kissfft-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/kissfft-config-version.cmake"
DESTINATION "${KISSFFT_INSTALL_CMAKE}")
set(PKG_KISSFFT_DEFS)
foreach(_def ${KISSFFT_COMPILE_DEFINITIONS})
set(PKG_KISSFFT_DEFS "${PKG_KISSFFT_DEFS} -D${_def}")
endforeach()
configure_file(kissfft.pc.in "kissfft-${KISSFFT_DATATYPE}.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kissfft-${KISSFFT_DATATYPE}.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif()

View File

@ -14,6 +14,21 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
// Define KISS_FFT_SHARED macro to properly export symbols
#ifdef KISS_FFT_SHARED
# ifdef _WIN32
# ifdef KISS_FFT_BUILD
# define KISS_FFT_API __declspec(dllexport)
# else
# define KISS_FFT_API __declspec(dllimport)
# endif
# else
# define KISS_FFT_API __attribute__ ((visibility ("default")))
# endif
#else
# define KISS_FFT_API
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -99,7 +114,7 @@ typedef struct kiss_fft_state* kiss_fft_cfg;
* buffer size in *lenmem. * buffer size in *lenmem.
* */ * */
kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); kiss_fft_cfg KISS_FFT_API kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
/* /*
* kiss_fft(cfg,in_out_buf) * kiss_fft(cfg,in_out_buf)
@ -111,12 +126,12 @@ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
* Note that each element is complex and can be accessed like * Note that each element is complex and can be accessed like
f[k].r and f[k].i f[k].r and f[k].i
* */ * */
void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); void KISS_FFT_API kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
/* /*
A more generic version of the above function. It reads its input from every Nth sample. A more generic version of the above function. It reads its input from every Nth sample.
* */ * */
void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); void KISS_FFT_API kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
/* If kiss_fft_alloc allocated a buffer, it is one contiguous /* If kiss_fft_alloc allocated a buffer, it is one contiguous
buffer and can be simply free()d when no longer needed*/ buffer and can be simply free()d when no longer needed*/
@ -126,13 +141,13 @@ void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout
Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
your compiler output to call this before you exit. your compiler output to call this before you exit.
*/ */
void kiss_fft_cleanup(void); void KISS_FFT_API kiss_fft_cleanup(void);
/* /*
* Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
*/ */
int kiss_fft_next_fast_size(int n); int KISS_FFT_API kiss_fft_next_fast_size(int n);
/* for real ffts, we need an even size */ /* for real ffts, we need an even size */
#define kiss_fftr_next_fast_size_real(n) \ #define kiss_fftr_next_fast_size_real(n) \

82
kissfft-config.cmake.in Normal file
View File

@ -0,0 +1,82 @@
# kissfft-config.ccmake accept the following components:
#
# SHARED/STATIC:
# This components allows one to choose a shared/static kissfft library.
# The default is selected by BUILD_SHARED_LIBS.
# They are to be used exclusively. Using them together is an error.
#
# example:
# find_package(kissfft CONFIG REQUIRED COMPONENTS STATIC)
#
# simd/int16/int32/float/double:
# This components allows one to choose the datatype.
# When using this component, the target kissfft::kissfft becomes available.
# When not using this component, you will have to choose the correct kissfft target.
#
# example:
# find_package(kissfft CONFIG REQUIRED)
# # - kissfft::kissfft-float, kissfft::kissfft-int32_t/ ... are available (if they are installed)
# # - kissfft::kissfft is not available,
#
# find_package(kissfft CONFIG REQUIRED COMPONENTS int32_t)
# # - kissfft::kissfft-float, kissfft::kissfft-int32_t/ ... are available (if they are installed)
# # - kissfft::kissfft is available (as an alias for kissfft::kissfft-int32_t),
@PACKAGE_INIT@
cmake_minimum_required(VERSION 3.3)
# Set include glob of config files using SHARED/static component, BUILD_SHARED_LIBS by default
set(_kissfft_shared_detected OFF)
set(_kissfft_shared ${BUILD_SHARED_LIBS})
if("SHARED" IN_LIST kissfft_FIND_COMPONENTS)
set(_kissfft_shared_detected ON)
set(_kissfft_shared ON)
endif()
if("STATIC" IN_LIST kissfft_FIND_COMPONENTS)
if(_kissfft_shared_detected)
message(FATAL_ERROR "SHARED and STATIC components cannot be used together")
endif()
set(_kissfft_shared_detected ON)
set(_kissfft_shared OFF)
endif()
if(_kissfft_shared)
set(_kissfft_config_glob "kissfft-*-shared-targets.cmake")
else()
set(_kissfft_config_glob "kissfft-*-static-targets.cmake")
endif()
# Load information for all configured kissfft
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/${_kissfft_config_glob}")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# If a datatype component is passed, create kissfft::kissfft
set(_kissfft_datatype_detected)
foreach(_kissfft_datatype simd int16 int32 float double)
if(_kissfft_datatype IN_LIST kissfft_FIND_COMPONENTS)
if(_kissfft_datatype_detected)
message(FATAL_ERROR "Cannot define datatype COMPONENT twice: ${_kissfft_datatype_detected} and ${_kissfft_datatype}")
endif()
set(_kissfft_datatype_detected ${_kissfft_datatype})
endif()
endforeach()
if(_kissfft_datatype_detected)
if(NOT TARGET kissfft::kissfft-${_kissfft_datatype_detected})
message(FATAL_ERROR "kissfft with datatype=${_kissfft_datatype_detected} is not installed")
endif()
if(TARGET kissfft::kissfft)
message(SEND_ERROR "kissfft::kissfft already exists. You cannot use 2 find_package's with datatype that are visible to eachother.")
else()
add_library(kissfft::kissfft INTERFACE IMPORTED)
set_property(TARGET kissfft::kissfft PROPERTY INTERFACE_LINK_LIBRARIES kissfft::kissfft-${_kissfft_datatype_detected})
endif()
endif()
set(kissfft_FOUND ON)
set(KISSFFT_VERSION @kissfft_VERSION@)

9
kissfft.pc.in Normal file
View File

@ -0,0 +1,9 @@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: kissfft
Description: A Fast Fourier Transform (FFT) library that tries to Keep it Simple, Stupid
Version: @kissfft_VERSION@
Libs: -L${libdir} -l@KISSFFT_OUTPUT_NAME@
Cflags: -I${includedir} @PKG_KISSFFT_DEFS@

49
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,49 @@
add_library(kissfft_help_library OBJECT
pstats.c
../tools/kfc.c
../tools/kiss_fftnd.c
../tools/kiss_fftr.c
../tools/kiss_fftndr.c
)
target_link_libraries(kissfft_help_library PRIVATE kissfft::kissfft)
target_include_directories(kissfft_help_library PRIVATE ../tools)
function(add_kissfft_test_executable NAME)
add_kissfft_executable(${NAME} ${ARGN} $<TARGET_OBJECTS:kissfft_help_library>)
target_include_directories(${NAME} PRIVATE ../tools)
add_test(NAME ${NAME} COMMAND ${NAME})
set_tests_properties(${NAME} PROPERTIES TIMEOUT 10)
endfunction()
set(KISSFFT_TEST_NUMFFTS 10000)
add_kissfft_test_executable(bm_kiss benchkiss.c)
# add_test(NAME benchmar COMMAND ${NAME})
# set_tests_properties(${NAME} PROPERTIES TIMEOUT 10)
include(FindPkgConfig)
if(KISSFFT_FLOAT)
set(fftw3_pkg fftw3f)
else()
set(fftw3_pkg fftw3)
endif()
pkg_check_modules(fftw3 REQUIRED IMPORTED_TARGET ${fftw3_pkg})
add_kissfft_test_executable(bm_fftw benchfftw.c)
target_link_libraries(bm_fftw PRIVATE PkgConfig::fftw3)
add_kissfft_test_executable(st twotonetest.c)
add_kissfft_test_executable(tkfc twotonetest.c)
target_compile_definitions(tkfc PRIVATE KFC_TEST)
add_kissfft_test_executable(ffr twotonetest.c)
add_kissfft_test_executable(tr test_real.c)
add_kissfft_test_executable(testcpp testcpp.cc)
find_package(PythonInterp REQUIRED)
add_test(NAME testkiss.py COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/testkiss.py")
set_tests_properties(testkiss.py PROPERTIES
TIMEOUT 20
ENVIRONMENT "DATATYPE=${KISSFFT_DATATYPE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")

18
tools/CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
add_kissfft_executable(fastconvr kiss_fastfir.c kiss_fftr.c)
target_compile_definitions(fastconvr PRIVATE REAL_FASTFIR FAST_FILT_UTIL)
add_kissfft_executable(fastconv kiss_fastfir.c)
target_compile_definitions(fastconv PRIVATE FAST_FILT_UTIL)
add_kissfft_executable(fft fftutil.c kiss_fftnd.c kiss_fftr.c kiss_fftndr.c)
# psdpng does not build with "simd" datatype
if(NOT KISSFFT_DATATYPE MATCHES "simd")
include(FindPkgConfig)
pkg_check_modules(libpng REQUIRED IMPORTED_TARGET libpng)
add_kissfft_executable(psdpng psdpng.c kiss_fftr.c)
target_link_libraries(psdpng PRIVATE PkgConfig::libpng)
endif()
#FIXME: dumphdr.c is not available
#add_kissfft_executable(dumphdr dumphdr.c)