Skip to content

Commit

Permalink
Merge pull request #52 from madebr/cmake_install
Browse files Browse the repository at this point in the history
Add cmake install + MSVC dll support
  • Loading branch information
mborgerding authored Nov 6, 2020
2 parents 0a70dfd + 1487038 commit 15debe8
Show file tree
Hide file tree
Showing 7 changed files with 310 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ language: python
python:
- "3.7"

dist: bionic
dist: focal

before_install:
- sudo apt-get install -y libfftw3-dev
Expand Down
135 changes: 131 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,136 @@
cmake_minimum_required(VERSION 2.8)
project(kissfft)
file(READ Makefile _MAKEFILE_CONTENTS)
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
kiss_fft.c)

target_include_directories(kissfft PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:.>)
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<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()
25 changes: 20 additions & 5 deletions kiss_fft.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
#include <math.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
extern "C" {
#endif
Expand Down Expand Up @@ -99,7 +114,7 @@ typedef struct kiss_fft_state* kiss_fft_cfg;
* 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)
Expand All @@ -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
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.
* */
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
buffer and can be simply free()d when no longer needed*/
Expand All @@ -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
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)
*/
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 */
#define kiss_fftr_next_fast_size_real(n) \
Expand Down
82 changes: 82 additions & 0 deletions kissfft-config.cmake.in
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions kissfft.pc.in
Original file line number Diff line number Diff line change
@@ -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 changes: 49 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 15debe8

Please sign in to comment.