1+ # This file is part of FNFT.
2+ #
3+ # FNFT is free software; you can redistribute it and/or
4+ # modify it under the terms of the version 2 of the GNU General
5+ # Public License as published by the Free Software Foundation.
6+ #
7+ # FNFT is distributed in the hope that it will be useful,
8+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+ # GNU General Public License for more details.
11+ #
12+ # You should have received a copy of the GNU General Public License
13+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
14+ #
15+ # Contributors:
16+ # Sander Wahls (TU Delft) 2017-2018.
17+ # Marius Brehler (TU Dortmund) 2018.
18+
119cmake_minimum_required (VERSION 3.5 )
220project (fnft C )
321
422set (FNFT_VERSION_MAJOR 0)
5- set (FNFT_VERSION_MINOR 1)
6- set (FNFT_VERSION_PATCH 1)
23+ set (FNFT_VERSION_MINOR 2)
24+ set (FNFT_VERSION_PATCH 0)
25+ set (FNFT_VERSION_SUFFIX "" ) # should not be longer than FNFT_SUFFIX_MAXLEN
26+ set (FNFT_VERSION ${FNFT_VERSION_MAJOR} .${FNFT_VERSION_MINOR} .${FNFT_VERSION_PATCH}${FNFT_VERSION_SUFFIX} )
727
828include (CheckIncludeFiles )
929include (CheckFunctionExists )
@@ -13,40 +33,59 @@ include(CheckLanguage)
1333# options
1434option (DEBUG "Compile with debugging symbols" OFF )
1535option (WITH_MATLAB "Build the Matlab interface" ON )
16- option (MACHINE_SPECIFIC_OPTIMIZATION "Activate optimizations specific for this machine" OFF )
36+ option (MACHINE_SPECIFIC_OPTIMIZATION "Activate optimizations specific for this machine" ON )
1737option (ADDRESS_SANITIZER "Enable address sanitzer for known compilers" OFF )
18- if (MACHINE_SPECIFIC_OPTIMIZATION)
19- message ("Optimizing for this specific machine." )
20- endif ()
38+ option (ENABLE_FFTW "Use FFTW if it is available" OFF )
39+ option (BUILD_TESTS "Build tests" ON )
2140
2241# check for complex.h
2342check_include_files (complex.h HAVE_COMPLEX_H )
2443if (NOT HAVE_COMPLEX_H)
25- message (ERROR "Compiler does not provide complex.h" )
44+ message (FATAL_ERROR "Compiler does not provide complex.h" )
2645endif ()
2746
2847# check if math code requires us to link libm
2948check_function_exists (log2 HAVE_LOG2 )
3049if (NOT HAVE_LOG2)
31- message ("Adding libm to the required libraries, repeating test." )
32- list (APPEND CMAKE_REQUIRED_LIBRARIES m)
33- check_function_exists (log2 HAVE_LOG2_2 )
34- if (NOT HAVE_LOG2_2)
35- message (ERROR "no log2" )
36- else ()
37- set (LIBM m)
38- endif ()
50+ message ("++ Adding libm to the required libraries, repeating test." )
51+ list (APPEND CMAKE_REQUIRED_LIBRARIES m)
52+ check_function_exists (log2 HAVE_LOG2_2 )
53+ if (NOT HAVE_LOG2_2)
54+ message (FATAL_ERROR "no log2" )
55+ else ()
56+ set (LIBM m)
57+ endif ()
3958else ()
40- set (LIBM )
59+ set (LIBM )
4160endif ()
4261
4362# check if thread local storage is available
44- check_c_source_compiles ("_Thread_local int g; int main() { g = 1; return g; }" HAVE__THREAD_LOCAL )
45- if (NOT HAVE__THREAD_LOCAL)
46- check_c_source_compiles ("__thread int g; int main() { g = 1; return g; }" HAVE___THREAD )
47- if (NOT HAVE___THREAD)
48- message (WARNING "Thread local storage is not available. fnft_errwarn_setprintf will not be thread-safe." )
49- endif ()
63+ check_c_source_compiles ("__thread int g; int main() { g = 1; return g; }" HAVE___THREAD )
64+ if (NOT HAVE___THREAD)
65+ check_c_source_compiles ("_Thread_local int g; int main() { g = 1; return g; }" HAVE__THREAD_LOCAL )
66+ if (NOT HAVE__THREAD_LOCAL)
67+ message (WARNING "Thread local storage is not available. fnft_errwarn_setprintf will not be thread-safe." )
68+ endif ()
69+ endif ()
70+
71+ # check if FFTW3 is available
72+ find_library (FFTW3_LIB fftw3 )
73+ find_path (FFTW3_INCLUDE fftw3.h )
74+ if (FFTW3_LIB AND FFTW3_INCLUDE)
75+ if (ENABLE_FFTW)
76+ message ("++ FFTW3 found and enabled. Run cmake with \" -DENABLE_FFTW=OFF\" to disable." )
77+ set (HAVE_FFTW3 1) # for updating fnft_config.h
78+ else ()
79+ message ("++ FFTW3 found but NOT enabled. Run cmake with \" -DENABLE_FFTW=ON\" to enable." )
80+ endif ()
81+ else ()
82+ if (ENABLE_FFTW)
83+ message (FATAL_ERROR "FFTW3 NOT found but set to enabled the by user. Run cmake WITHOUT \" -DENABLE_FFTW=ON\" to disable." )
84+ else ()
85+ set (FFTW3_LIB "" )
86+ set (FFTW3_INCLUDE "" )
87+ message ("++ FFTW3 NOT found. Using Kiss FFT instead." )
88+ endif ()
5089endif ()
5190
5291# header files
@@ -56,52 +95,68 @@ include(CheckCCompilerFlag)
5695
5796# configure C compiler
5897if (CMAKE_COMPILER_IS_GNUCC) # gcc
59- if (DEBUG)
60- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g" )
61- endif ()
98+ if (DEBUG)
99+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g" )
100+ message ("++ Enabling debugging symbols in the C compiler" )
101+ endif ()
62102 if (ADDRESS_SANITIZER)
63- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer" )
103+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer" )
104+ message ("++ Enabling address sanitizer" )
64105 endif ()
65106 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3" )
66- if (MACHINE_SPECIFIC_OPTIMIZATION)
67- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native" )
68- endif ()
69- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -pedantic -Werror=implicit-function-declaration" )
107+ if (MACHINE_SPECIFIC_OPTIMIZATION)
108+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native" )
109+ message ("++ Enabling machine specific optimization in the C compiler" )
110+ endif ()
111+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -pedantic -Werror=implicit-function-declaration" )
70112else ()
71- message (WARNING "Compiler is not gcc. Will try to use -O3 (or if debug) flag." )
72- if (DEBUG)
73- check_c_compiler_flag ("-g" HAS_C_G_FLAG )
74- if (HAS_C_G_FLAG)
75- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ -g" )
76- endif ()
77- else ()
78- check_c_compiler_flag ("-O3" HAS_C_O3_FLAG )
79- if (HAS_C_O3_FLAG)
80- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3" )
81- endif ()
82- if (MACHINE_SPECIFIC_OPTIMIZATION)
83- message (WARNING "Compiler is not gcc. Will try to use -march=native flag." )
84- check_c_compiler_flag ("-march=native" HAS_C_MARCH_NATIVE_FLAG )
85- if (HAS_C_MARCH_NATIVE_FLAG)
86- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native" )
87- endif ()
88- endif ()
89- endif ()
113+ message (WARNING "++ Compiler is not gcc. Will try to set flags anyway." )
114+ if (DEBUG)
115+ check_c_compiler_flag ("-g" HAS_C_G_FLAG )
116+ if (HAS_C_G_FLAG)
117+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g" )
118+ message ("++ Enabled -g flag in the C compiler" )
119+ endif ()
120+ else ()
121+ check_c_compiler_flag ("-O3" HAS_C_O3_FLAG )
122+ if (HAS_C_O3_FLAG)
123+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3" )
124+ message ("++ Enabled -O3 flag in the C compiler" )
125+ endif ()
126+ if (MACHINE_SPECIFIC_OPTIMIZATION)
127+ check_c_compiler_flag ("-march=native" HAS_C_MARCH_NATIVE_FLAG )
128+ if (HAS_C_MARCH_NATIVE_FLAG)
129+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native" )
130+ message ("++ Enabled -march=native flag in the C compiler" )
131+ endif ()
132+ endif ()
133+ endif ()
90134endif ()
91135
92136# generate config header file
93137configure_file (include /fnft_config.h.in ${CMAKE_CURRENT_SOURCE_DIR} /include/fnft_config.h )
94138include_directories (${CMAKE_CURRENT_SOURCE_DIR} /include )
95139include_directories (${CMAKE_CURRENT_SOURCE_DIR} /include/private )
96140include_directories (${CMAKE_CURRENT_SOURCE_DIR} /include/3rd_party/kiss_fft )
141+ include_directories (${FFTW3_INCLUDE} )
97142
98143# configure Fortran support
99144enable_language (Fortran )
100145if (CMAKE_Fortran_COMPILER_ID MATCHES GNU) # gfortran
101- set (CMAKE_Fortran_FLAGS " -O3 -cpp -ffree-line-length-none" )
146+ set (CMAKE_Fortran_FLAGS " -O3 -cpp -ffree-line-length-none" )
147+ if (DEBUG)
148+ set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g" )
149+ message ("++ Enabling debugging symbols in the Fortran compiler" )
150+ endif ()
151+ if (MACHINE_SPECIFIC_OPTIMIZATION)
152+ set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -march=native" )
153+ message ("++ Enabling machine specific optimization in the Fortran compiler" )
154+ endif ()
102155endif ()
103156
104- enable_testing ()
157+ if (BUILD_TESTS)
158+ enable_testing ()
159+ endif ()
105160
106161# sources
107162file (GLOB SOURCES "src/*.c" )
@@ -113,47 +168,51 @@ file(GLOB_RECURSE TEST_SOURCES "test/*_test*.c")
113168
114169# generate shared library
115170add_library (fnft SHARED ${SOURCES} ${PRIVATE_SOURCES} ${KISS_FFT_SOURCES} ${EISCOR_SOURCES} )
116- set_target_properties (fnft PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR} /lib" )
171+ target_link_libraries (fnft ${FFTW3_LIB} )
172+ file (GLOB PUBLIC_HEADERS "include/*.h" )
173+ set_target_properties (fnft PROPERTIES VERSION ${FNFT_VERSION} SOVERSION ${FNFT_VERSION_MAJOR} LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR} /lib" PUBLIC_HEADER "${PUBLIC_HEADERS} " )
117174
118175# installation under Linux
119- install (TARGETS fnft DESTINATION lib)
176+ install (TARGETS fnft LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include )
120177
121178# generate examples
122179foreach (srcfile ${EXAMPLE_SOURCES} )
123- get_filename_component (example ${srcfile} NAME_WE )
124- add_executable (${example} ${srcfile} )
125- target_link_libraries (${example} fnft ${LIBM} )
126- set_target_properties (${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR} /examples" )
180+ get_filename_component (example ${srcfile} NAME_WE )
181+ add_executable (${example} ${srcfile} )
182+ target_link_libraries (${example} fnft ${LIBM} ${FFTW3_LIB } )
183+ set_target_properties (${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR} /examples" )
127184endforeach ()
128185
129186# generate tests
130- foreach (srcfile ${TEST_SOURCES} )
131- get_filename_component (dir ${srcfile} DIRECTORY )
132- get_filename_component (test ${srcfile} NAME_WE )
133- add_executable (${test} ${srcfile} )
134- target_link_libraries (${test} fnft ${LIBM} )
135- add_test (NAME ${test} COMMAND ${test} )
136- set_target_properties (${test} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${dir} " )
137- endforeach ()
187+ if (BUILD_TESTS)
188+ foreach (srcfile ${TEST_SOURCES} )
189+ get_filename_component (dir ${srcfile} DIRECTORY )
190+ get_filename_component (test ${srcfile} NAME_WE )
191+ add_executable (${test} ${srcfile} )
192+ target_link_libraries (${test} fnft ${LIBM} ${FFTW3_LIB} )
193+ add_test (NAME ${test} COMMAND ${test} )
194+ set_target_properties (${test} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${dir} " )
195+ endforeach ()
196+ endif ()
138197
139198# Try to build the Matlab interface if requested
140199if (WITH_MATLAB)
141200 check_language (CXX )
142201 if (CMAKE_CXX_COMPILER )
143- enable_language (CXX ) # sometimes required by FindMatlab below
202+ enable_language (CXX ) # sometimes required by FindMatlab below
144203 else ()
145- message ("Could not find a C++ compiler, which is sometimes required to localize Matlab." )
146- message ("If the build process fails, deactivate the localization with the -DWITH_MATLAB=OFF switch." )
204+ message ("++ Could not find a C++ compiler, which is sometimes required to localize Matlab." )
205+ message ("++ If the build process fails, deactivate the localization with the -DWITH_MATLAB=OFF switch." )
147206 endif ()
148- find_package (Matlab COMPONENTS MX_LIBRARY )
149- if (Matlab_FOUND)
150- file (GLOB MEX_SOURCES "matlab/mex_*.c" )
151- foreach (srcfile ${MEX_SOURCES} )
152- get_filename_component (mexfile ${srcfile} NAME_WE )
153- matlab_add_mex (NAME ${mexfile} SRC ${srcfile} LINK_TO fnft ${LIBM} )
154- set_target_properties (${mexfile} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR} /matlab" )
155- target_compile_options (${mexfile} PRIVATE -DMEX_DOUBLE_HANDLE )
156- # -DMEX_DOUBLE_HANDLE avoids the new complex interleaved API
157- endforeach ()
158- endif ()
207+ find_package (Matlab COMPONENTS MX_LIBRARY )
208+ if (Matlab_FOUND)
209+ file (GLOB MEX_SOURCES "matlab/mex_*.c" )
210+ foreach (srcfile ${MEX_SOURCES} )
211+ get_filename_component (mexfile ${srcfile} NAME_WE )
212+ matlab_add_mex (NAME ${mexfile} SRC ${srcfile} LINK_TO fnft ${LIBM} ${FFTW3_LIB } )
213+ set_target_properties (${mexfile} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR} /matlab" )
214+ target_compile_options (${mexfile} PRIVATE -DMEX_DOUBLE_HANDLE )
215+ # -DMEX_DOUBLE_HANDLE avoids the new complex interleaved API
216+ endforeach ()
217+ endif ()
159218endif ()
0 commit comments