diff options
author | Jukka Ojanen <jukka.ojanen@linkotec.net> | 2015-11-30 17:16:01 +0200 |
---|---|---|
committer | Jukka Ojanen <jukka.ojanen@linkotec.net> | 2015-11-30 17:18:31 +0200 |
commit | ae1b59ddd07cb66b0807bc2c7c981ce96c69acea (patch) | |
tree | 0b17e0271543e1fb897aba27c242b656378df858 | |
parent | c3e325911ae15524c814db75fe701df91d6f7c2a (diff) | |
download | ffts-ae1b59ddd07cb66b0807bc2c7c981ce96c69acea.zip ffts-ae1b59ddd07cb66b0807bc2c7c981ce96c69acea.tar.gz |
Enable building shared library and start version numbering from 0.9.0. On Windows when using FFTS as a DLL, define FFTS_SHARED. This is not mandatory, but it offers a little performance increase. Hide symbols when possible to improve compiler optimization and sizeof binary. Use CMake target alias "ffts" to choose between static and shared library, preferring static
-rw-r--r-- | CMakeLists.txt | 97 | ||||
-rw-r--r-- | include/ffts.h | 43 | ||||
-rw-r--r-- | src/ffts.c | 8 | ||||
-rw-r--r-- | src/ffts_nd.c | 6 | ||||
-rw-r--r-- | src/ffts_real.c | 2 | ||||
-rw-r--r-- | src/ffts_real_nd.c | 6 |
6 files changed, 134 insertions, 28 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6536ef0..6c72b5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,13 @@ cmake_minimum_required(VERSION 2.8) project(ffts C ASM) +# TODO: to support AutoConfigure building, this should came from "template" file +set(FFTS_MAJOR 0) +set(FFTS_MINOR 9) +set(FFTS_MICRO 0) + +set(FFTS_VERSION "ffts-${FFTS_MAJOR}.${FFTS_MINOR}.${FFTS_MICRO}") + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -27,15 +34,25 @@ option(ENABLE_RUNTIME_DYNAMIC_CODE "Enables the runtime generation of dynamic machine code." ON ) +option(GENERATE_POSITION_INDEPENDENT_CODE + "Generate position independent code" OFF +) + option(ENABLE_SHARED "Enable building a shared library." OFF ) +option(ENABLE_STATIC + "Enable building a static library." ON +) + include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckIncludeFile) -add_definitions(-DFFTS_CMAKE_GENERATED) +# Ensure defined when building FFTS (as opposed to using it from +# another project). Used to export functions from Windows DLL. +add_definitions(-DFFTS_BUILD) # check existence of various headers check_include_file(malloc.h HAVE_MALLOC_H) @@ -286,13 +303,24 @@ if(MSVC) # enable all warnings but also disable some.. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /wd4127") + # mark debug versions + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_USE_MATH_DEFINES) elseif(CMAKE_COMPILER_IS_GNUCC) + include(CheckCCompilerFlag) include(CheckLibraryExists) # enable all warnings set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") + # check if we can control visibility of symbols + check_c_compiler_flag(-fvisibility=hidden HAVE_GCC_VISIBILITY) + if(HAVE_GCC_VISIBILITY) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") + add_definitions(-DHAVE_GCC_VISIBILITY) + endif(HAVE_GCC_VISIBILITY) + # some systems need libm for the math functions to work check_library_exists(m pow "" HAVE_LIBM) if(HAVE_LIBM) @@ -385,16 +413,61 @@ else() ) endif(DISABLE_DYNAMIC_CODE) -add_library(ffts_static - ${FFTS_HEADERS} - ${FFTS_SOURCES} -) +if(GENERATE_POSITION_INDEPENDENT_CODE) + if(CMAKE_VERSION VERSION_LESS "2.8.9") + check_c_compiler_flag(-fPIC HAVE_GCC_PIC) + if(HAVE_GCC_PIC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -DPIC") + check_c_compiler_flag(-fPIE HAVE_GCC_PIE) + if(HAVE_GCC_PIE) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -DPIE") + endif(HAVE_GCC_PIE) + endif(HAVE_GCC_PIC) + else() + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif(CMAKE_VERSION VERSION_LESS "2.8.9") +endif(GENERATE_POSITION_INDEPENDENT_CODE) + +if(ENABLE_SHARED) + add_library(ffts_shared SHARED + ${FFTS_HEADERS} + ${FFTS_SOURCES} + ) -add_executable(ffts_test - tests/test.c -) + # On unix-like platforms the library is called "libffts.so" and on Windows "ffts.dll" + set_target_properties(ffts_shared PROPERTIES + DEFINE_SYMBOL FFTS_SHARED + OUTPUT_NAME ffts + VERSION ${FFTS_MAJOR}.${FFTS_MINOR}.${FFTS_MICRO} + ) +endif(ENABLE_SHARED) -target_link_libraries(ffts_test - ffts_static - ${FFTS_EXTRA_LIBRARIES} -) +if(ENABLE_STATIC) + add_library(ffts_static STATIC + ${FFTS_HEADERS} + ${FFTS_SOURCES} + ) + + if(UNIX) + # On unix-like platforms the library is called "libffts.a" + set_target_properties(ffts_static PROPERTIES OUTPUT_NAME ffts) + endif(UNIX) +endif(ENABLE_STATIC) + +if(ENABLE_STATIC OR ENABLE_SHARED) + add_executable(ffts_test + tests/test.c + ) + + # link with static library by default + if(ENABLE_STATIC) + add_library(ffts ALIAS ffts_static) + else() + add_library(ffts ALIAS ffts_shared) + endif(ENABLE_STATIC) + + target_link_libraries(ffts_test + ffts + ${FFTS_EXTRA_LIBRARIES} + ) +endif(ENABLE_STATIC OR ENABLE_SHARED) diff --git a/include/ffts.h b/include/ffts.h index 8e25cb4..d187e36 100644 --- a/include/ffts.h +++ b/include/ffts.h @@ -42,27 +42,54 @@ extern "C" { #endif +#if (defined(_WIN32) || defined(WIN32)) && defined(FFTS_SHARED) +# ifdef FFTS_BUILD +# define FFTS_API __declspec(dllexport) +# else +# define FFTS_API __declspec(dllimport) +# endif +#else +# if (__GNUC__ >= 4) || defined(HAVE_GCC_VISIBILITY) +# define FFTS_API __attribute__ ((visibility("default"))) +# else +# define FFTS_API +# endif +#endif + #define POSITIVE_SIGN 1 #define NEGATIVE_SIGN -1 struct _ffts_plan_t; typedef struct _ffts_plan_t ffts_plan_t; -ffts_plan_t *ffts_init_1d(size_t N, int sign); -ffts_plan_t *ffts_init_2d(size_t N1, size_t N2, int sign); -ffts_plan_t *ffts_init_nd(int rank, size_t *Ns, int sign); +FFTS_API ffts_plan_t* +ffts_init_1d(size_t N, int sign); + +FFTS_API ffts_plan_t* +ffts_init_2d(size_t N1, size_t N2, int sign); + +FFTS_API ffts_plan_t* +ffts_init_nd(int rank, size_t *Ns, int sign); /* For real transforms, sign == -1 implies a real-to-complex forwards tranform, and sign == 1 implies a complex-to-real backwards transform. The output of a real-to-complex transform is N/2+1 complex numbers, where the redundant outputs have been omitted. */ -ffts_plan_t *ffts_init_1d_real(size_t N, int sign); -ffts_plan_t *ffts_init_2d_real(size_t N1, size_t N2, int sign); -ffts_plan_t *ffts_init_nd_real(int rank, size_t *Ns, int sign); +FFTS_API ffts_plan_t* +ffts_init_1d_real(size_t N, int sign); + +FFTS_API ffts_plan_t* +ffts_init_2d_real(size_t N1, size_t N2, int sign); + +FFTS_API ffts_plan_t* +ffts_init_nd_real(int rank, size_t *Ns, int sign); + +FFTS_API void +ffts_execute(ffts_plan_t *p, const void *input, void *output); -void ffts_execute(ffts_plan_t *p, const void *input, void *output); -void ffts_free(ffts_plan_t *p); +FFTS_API void +ffts_free(ffts_plan_t *p); #ifdef __cplusplus } @@ -149,7 +149,8 @@ static FFTS_INLINE void ffts_vmem_free(void *addr, size_t length) #endif } -void ffts_execute(ffts_plan_t *p, const void *in, void *out) +FFTS_API void +ffts_execute(ffts_plan_t *p, const void *in, void *out) { /* TODO: Define NEEDS_ALIGNED properly instead */ #if defined(HAVE_SSE) || defined(HAVE_NEON) @@ -165,7 +166,8 @@ void ffts_execute(ffts_plan_t *p, const void *in, void *out) p->transform(p, (const float*) in, (float*) out); } -void ffts_free(ffts_plan_t *p) +FFTS_API void +ffts_free(ffts_plan_t *p) { if (p) { p->destroy(p); @@ -409,7 +411,7 @@ cleanup: return -1; } -ffts_plan_t* +FFTS_API ffts_plan_t* ffts_init_1d(size_t N, int sign) { const size_t leaf_N = 8; diff --git a/src/ffts_nd.c b/src/ffts_nd.c index 23338c1..72e21e7 100644 --- a/src/ffts_nd.c +++ b/src/ffts_nd.c @@ -281,7 +281,8 @@ static void ffts_execute_nd(ffts_plan_t *p, const void *in, void *out) } } -ffts_plan_t *ffts_init_nd(int rank, size_t *Ns, int sign) +FFTS_API ffts_plan_t* +ffts_init_nd(int rank, size_t *Ns, int sign) { ffts_plan_t *p; size_t vol; @@ -354,7 +355,8 @@ cleanup: return NULL; } -ffts_plan_t *ffts_init_2d(size_t N1, size_t N2, int sign) +FFTS_API ffts_plan_t* +ffts_init_2d(size_t N1, size_t N2, int sign) { size_t Ns[2]; diff --git a/src/ffts_real.c b/src/ffts_real.c index 6650d07..7f41069 100644 --- a/src/ffts_real.c +++ b/src/ffts_real.c @@ -599,7 +599,7 @@ ffts_execute_1d_real_inv(ffts_plan_t *p, const void *input, void *output) p->plans[0]->transform(p->plans[0], buf, output); } -ffts_plan_t* +FFTS_API ffts_plan_t* ffts_init_1d_real(size_t N, int sign) { ffts_plan_t *p; diff --git a/src/ffts_real_nd.c b/src/ffts_real_nd.c index 5eae44b..545e8f0 100644 --- a/src/ffts_real_nd.c +++ b/src/ffts_real_nd.c @@ -218,7 +218,8 @@ static void ffts_execute_nd_real_inv(ffts_plan_t *p, const void *in, void *out) } } -ffts_plan_t *ffts_init_nd_real(int rank, size_t *Ns, int sign) +FFTS_API ffts_plan_t* +ffts_init_nd_real(int rank, size_t *Ns, int sign) { int i; size_t vol = 1; @@ -327,7 +328,8 @@ cleanup: return NULL; } -ffts_plan_t *ffts_init_2d_real(size_t N1, size_t N2, int sign) +FFTS_API ffts_plan_t* +ffts_init_2d_real(size_t N1, size_t N2, int sign) { size_t Ns[2]; |