Skip to content

Commit 10391c2

Browse files
committed
Clean up CMake and MATLAB/CUDA build system
- Simplifies and unifies CMake setup - Adds developer tools: cppcheck, IWYU, clang-tidy - Enables proper LTO support - Cleans and speeds up CI pipeline - Improves compatibility across Linux, Windows, and macOS - Updates dependencies and fixes MATLAB + CUDA integration - Removes reliance on MATLAB OpenMP, adjusts CUDA/MEX handling - Fixes various typos, warnings, and deployment target issues # Conflicts: # CMakeLists.txt # cmake/toolchain.cmake
1 parent 18236ac commit 10391c2

File tree

1 file changed

+264
-49
lines changed

1 file changed

+264
-49
lines changed

CMakeLists.txt

Lines changed: 264 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
cmake_minimum_required(VERSION 3.24...3.31)
2-
cmake_policy(VERSION 3.24)
1+
cmake_minimum_required(VERSION 3.19...3.31)
32
project(FINUFFT VERSION 2.5.0 LANGUAGES C CXX)
43

5-
include(CMakeDependentOption)
4+
# windows MSVC runtime flags policy
5+
cmake_policy(SET CMP0091 NEW)
66

7-
if(NOT CMAKE_BUILD_TYPE)
8-
set(CMAKE_BUILD_TYPE Release CACHE STRING "Set the default build type to Release" FORCE)
9-
endif()
7+
include(CMakeDependentOption)
108

119
# gersemi: off
1210
# All options go here sphinx tag (don't remove): @cmake_opts_start
@@ -41,50 +39,283 @@ cmake_dependent_option(FINUFFT_INTERPROCEDURAL_OPTIMIZATION "LTO should be the o
4139
option(FINUFFT_IWYU_VERBOSE "Verbose IWYU tool output" ON)
4240
# gersemi: on
4341

44-
# Use the folder that contains this CMakeLists.txt, not the project root
45-
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
46-
4742
# When building shared libraries, we need to build with -fPIC in all cases
4843
if(FINUFFT_SHARED_LINKING)
4944
set(FINUFFT_POSITION_INDEPENDENT_CODE ON)
5045
endif()
5146

52-
if(FINUFFT_MATLAB_INSTALL)
53-
set(FINUFFT_BUILD_MATLAB ON)
54-
set(FINUFFT_ENABLE_INSTALL OFF)
47+
include(cmake/utils.cmake)
48+
49+
set(FINUFFT_CXX_FLAGS_RELEASE
50+
-funroll-loops
51+
-ffp-contract=fast
52+
-fno-math-errno
53+
-fno-signed-zeros
54+
-fno-trapping-math
55+
-fassociative-math
56+
-freciprocal-math
57+
-fmerge-all-constants
58+
-ftree-vectorize
59+
-fimplicit-constexpr
60+
-fcx-limited-range
61+
-O3
62+
/Ox
63+
/fp:contract
64+
/fp:except-
65+
/GF
66+
/GY
67+
/GS-
68+
/Ob
69+
/Oi
70+
/Ot
71+
/Oy
72+
)
73+
74+
filter_supported_compiler_flags(FINUFFT_CXX_FLAGS_RELEASE FINUFFT_CXX_FLAGS_RELEASE)
75+
message(STATUS "FINUFFT Release flags: ${FINUFFT_CXX_FLAGS_RELEASE}")
76+
set(FINUFFT_CXX_FLAGS_RELWITHDEBINFO ${FINUFFT_CXX_FLAGS_RELEASE})
77+
78+
set(FINUFFT_CXX_FLAGS_DEBUG
79+
-g
80+
-g3
81+
-ggdb
82+
-ggdb3
83+
-Wall
84+
-Wextra
85+
-Wpedantic
86+
-Wno-unknown-pragmas
87+
)
88+
89+
if(DEFINED ENV{GITHUB_ACTIONS})
90+
if($ENV{GITHUB_ACTIONS} STREQUAL "true")
91+
message("CMake is being executed inside a GitHub workflow")
92+
# if msvc use FS flag
93+
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_BUILD_TYPE STREQUAL "Release")
94+
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
95+
message("CMAKE_MSVC_DEBUG_INFORMATION_FORMAT TO Embedded")
96+
endif()
97+
endif()
98+
else()
99+
message("CMake is NOT being executed inside a GitHub workflow")
100+
# env variable is:
101+
message(STATUS "ENV{GITHUB_ACTIONS}: $ENV{GITHUB_ACTIONS}")
55102
endif()
103+
filter_supported_compiler_flags(FINUFFT_CXX_FLAGS_DEBUG FINUFFT_CXX_FLAGS_DEBUG)
104+
message(STATUS "FINUFFT Debug flags: ${FINUFFT_CXX_FLAGS_DEBUG}")
105+
list(APPEND FINUFFT_CXX_FLAGS_RELWITHDEBINFO ${FINUFFT_CXX_FLAGS_RELEASE} ${FINUFFT_CXX_FLAGS_DEBUG})
106+
message(STATUS "FINUFFT RelWithDebInfo flags: ${FINUFFT_CXX_FLAGS_RELWITHDEBINFO}")
56107

57-
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
108+
if(FINUFFT_ARCH_FLAGS STREQUAL "native")
109+
set(FINUFFT_ARCH_FLAGS -march=native CACHE STRING "" FORCE)
110+
filter_supported_compiler_flags(FINUFFT_ARCH_FLAGS FINUFFT_ARCH_FLAGS)
111+
if(NOT FINUFFT_ARCH_FLAGS)
112+
set(FINUFFT_ARCH_FLAGS -mtune=native CACHE STRING "" FORCE)
113+
filter_supported_compiler_flags(FINUFFT_ARCH_FLAGS FINUFFT_ARCH_FLAGS)
114+
endif()
115+
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
116+
# -march=native emulation for MSVC
117+
check_arch_support()
118+
endif()
119+
if(NOT FINUFFT_ARCH_FLAGS)
120+
message(WARNING "No architecture flags are supported by the compiler.")
121+
else()
122+
message(STATUS "FINUFFT Arch flags: ${FINUFFT_ARCH_FLAGS}")
123+
endif()
124+
endif()
125+
126+
# Set default build type to Release
127+
if(NOT CMAKE_BUILD_TYPE)
128+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Set the default build type to Release" FORCE)
129+
endif()
130+
131+
# This set of sources is compiled twice, once in single precision and once in
132+
# double precision The single precision compilation is done with -DSINGLE
133+
set(FINUFFT_PRECISION_DEPENDENT_SOURCES)
134+
135+
# If we're building for Fortran, make sure we also include the translation
136+
# layer.
137+
if(FINUFFT_BUILD_FORTRAN)
138+
list(APPEND FINUFFT_PRECISION_DEPENDENT_SOURCES fortran/finufftfort.cpp)
139+
endif()
58140

59-
include(utils) # finds cmake/utils.cmake
60-
include(toolchain) # finds cmake/toolchain.cmake
141+
# set linker flags for sanitizer
142+
set(FINUFFT_SANITIZER_FLAGS)
143+
if(FINUFFT_ENABLE_SANITIZERS)
144+
set(FINUFFT_SANITIZER_FLAGS
145+
-fsanitize=address
146+
-fsanitize=undefined
147+
-fsanitize=bounds-strict
148+
/fsanitize=address
149+
/RTC1
150+
)
151+
filter_supported_compiler_flags(FINUFFT_SANITIZER_FLAGS FINUFFT_SANITIZER_FLAGS)
152+
set(FINUFFT_SANITIZER_FLAGS $<$<CONFIG:Debug,RelWithDebInfo>:${FINUFFT_SANITIZER_FLAGS}>)
153+
endif()
154+
# Utility function to enable ASAN on debug builds
155+
function(enable_asan target)
156+
target_compile_options(${target} PRIVATE ${FINUFFT_SANITIZER_FLAGS})
157+
if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC"))
158+
target_link_options(${target} PRIVATE ${FINUFFT_SANITIZER_FLAGS})
159+
endif()
160+
endfunction()
61161

62-
# Versions for dependencies
63-
set(CPM_DOWNLOAD_VERSION "0.42.0" CACHE STRING "Version of CPM.cmake to use")
162+
set(CPM_DOWNLOAD_VERSION "0.40.5" CACHE STRING "Version of CPM.cmake to use")
64163
set(FFTW_VERSION "3.3.10" CACHE STRING "Version of FFTW to use")
164+
set(XTL_VERSION "0.7.7" CACHE STRING "Version of xtl to use")
65165
set(XSIMD_VERSION "13.2.0" CACHE STRING "Version of xsimd to use")
66-
set(DUCC0_VERSION "ducc0_0_38_0" CACHE STRING "Version of ducc0 to use")
166+
set(DUCC0_VERSION "ducc0_0_36_0" CACHE STRING "Version of ducc0 to use")
67167
set(CUDA11_CCCL_VERSION "2.8.5" CACHE STRING "Version of FINUFFT-cccl for cuda 11 to use")
68-
set(CUDA12_CCCL_VERSION "3.0.2" CACHE STRING "Version of FINUFFT-cccl for cuda 12 to use")
69-
70-
mark_as_advanced(
71-
CPM_DOWNLOAD_VERSION
72-
FFTW_VERSION
73-
XTL_VERSION
74-
XSIMD_VERSION
75-
DUCC0_VERSION
76-
CUDA11_CCCL_VERSION
77-
CUDA12_CCCL_VERSION
78-
)
168+
set(CUDA12_CCCL_VERSION "3.0.1" CACHE STRING "Version of FINUFFT-cccl for cuda 12 to use")
169+
mark_as_advanced(CPM_DOWNLOAD_VERSION)
170+
mark_as_advanced(FFTW_VERSION)
171+
mark_as_advanced(XTL_VERSION)
172+
mark_as_advanced(XSIMD_VERSION)
173+
mark_as_advanced(DUCC0_VERSION)
174+
mark_as_advanced(CUDA11_CCCL_VERSION)
175+
mark_as_advanced(CUDA12_CCCL_VERSION)
176+
177+
include(cmake/setupCPM.cmake)
178+
179+
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
180+
include(CTest)
181+
if(FINUFFT_BUILD_TESTS)
182+
enable_testing()
183+
endif()
184+
if(FINUFFT_BUILD_DOCS)
185+
include(cmake/setupSphinx.cmake)
186+
endif()
187+
endif()
188+
189+
if(FINUFFT_USE_CPU)
190+
# make apple with gnu use old linker, new linker breaks, see issue #360
191+
if((APPLE) AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
192+
add_link_options("-ld_classic")
193+
endif()
194+
set(FINUFFT_FFTW_LIBRARIES)
195+
include(cmake/setupXSIMD.cmake)
196+
if(FINUFFT_USE_DUCC0)
197+
include(cmake/setupDUCC.cmake)
198+
else()
199+
include(cmake/setupFFTW.cmake)
200+
endif()
201+
if(FINUFFT_USE_DUCC0)
202+
set(FINUFFT_FFTLIBS ducc0)
203+
else()
204+
set(FINUFFT_FFTLIBS ${FINUFFT_FFTW_LIBRARIES})
205+
endif()
206+
if(FINUFFT_USE_OPENMP)
207+
find_package(OpenMP COMPONENTS C CXX REQUIRED)
208+
endif()
209+
endif()
210+
# check if -Wno-deprecated-declarations is supported
211+
check_cxx_compiler_flag(-Wno-deprecated-declarations FINUFFT_HAS_NO_DEPRECATED_DECLARATIONS)
79212

80-
include(setupCPM)
213+
# Utility function to link static/dynamic lib
214+
function(finufft_link_test target)
215+
if(FINUFFT_USE_DUCC0)
216+
target_compile_definitions(${target} PRIVATE FINUFFT_USE_DUCC0)
217+
endif()
218+
target_link_libraries(${target} PRIVATE finufft xsimd ${FINUFFT_FFTLIBS})
219+
if(FINUFFT_USE_OPENMP)
220+
target_link_libraries(${target} PRIVATE OpenMP::OpenMP_CXX)
221+
target_link_options(${target} PRIVATE ${OpenMP_CXX_FLAGS})
222+
endif()
223+
enable_asan(${target})
224+
target_compile_features(${target} PRIVATE cxx_std_17)
225+
set_target_properties(
226+
${target}
227+
PROPERTIES
228+
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
229+
POSITION_INDEPENDENT_CODE ${FINUFFT_POSITION_INDEPENDENT_CODE}
230+
)
231+
# disable deprecated warnings for tests if supported
232+
if(FINUFFT_HAS_NO_DEPRECATED_DECLARATIONS)
233+
target_compile_options(${target} PRIVATE -Wno-deprecated-declarations)
234+
endif()
235+
endfunction()
236+
237+
# Utility function to set finufft compilation options.
238+
function(set_finufft_options target)
239+
target_compile_features(${target} PRIVATE cxx_std_17)
240+
target_compile_options(${target} PRIVATE $<$<CONFIG:Release,RelWithDebInfo>:${FINUFFT_ARCH_FLAGS}>)
241+
target_compile_options(${target} PRIVATE $<$<CONFIG:Release>:${FINUFFT_CXX_FLAGS_RELEASE}>)
242+
target_compile_options(${target} PRIVATE $<$<CONFIG:RelWithDebInfo>:${FINUFFT_CXX_FLAGS_RELWITHDEBINFO}>)
243+
target_compile_options(${target} PRIVATE $<$<CONFIG:Debug>:${FINUFFT_CXX_FLAGS_DEBUG}>)
244+
target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
245+
target_include_directories(${target} SYSTEM INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
246+
set_target_properties(
247+
${target}
248+
PROPERTIES
249+
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
250+
POSITION_INDEPENDENT_CODE ${FINUFFT_POSITION_INDEPENDENT_CODE}
251+
)
252+
enable_asan(${target})
253+
if(FINUFFT_USE_OPENMP)
254+
target_link_libraries(${target} PRIVATE OpenMP::OpenMP_CXX)
255+
target_link_options(${target} PRIVATE ${OpenMP_CXX_FLAGS})
256+
endif()
257+
if(FINUFFT_USE_DUCC0)
258+
target_compile_definitions(${target} PRIVATE FINUFFT_USE_DUCC0)
259+
endif()
260+
target_link_libraries(${target} PRIVATE xsimd)
261+
target_link_libraries(${target} PRIVATE ${FINUFFT_FFTLIBS})
262+
endfunction()
81263

82264
if(FINUFFT_USE_CPU)
83-
add_subdirectory(src)
265+
set(FINUFFT_SOURCES
266+
src/spreadinterp.cpp
267+
src/fft.cpp
268+
src/finufft_core.cpp
269+
src/c_interface.cpp
270+
src/finufft_utils.cpp
271+
src/utils.cpp
272+
)
273+
274+
if(FINUFFT_BUILD_FORTRAN)
275+
list(APPEND FINUFFT_SOURCES fortran/finufftfort.cpp)
276+
endif()
277+
278+
# Main finufft libraries
279+
if(NOT FINUFFT_STATIC_LINKING)
280+
add_library(finufft SHARED ${FINUFFT_SOURCES})
281+
else()
282+
add_library(finufft STATIC ${FINUFFT_SOURCES})
283+
endif()
284+
set_finufft_options(finufft)
285+
286+
if(WIN32 AND FINUFFT_SHARED_LINKING)
287+
target_compile_definitions(finufft PRIVATE dll_EXPORTS FINUFFT_DLL)
288+
endif()
289+
find_library(MATH_LIBRARY m)
290+
if(MATH_LIBRARY)
291+
target_link_libraries(finufft PRIVATE ${MATH_LIBRARY})
292+
endif()
293+
target_include_directories(finufft PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
294+
target_include_directories(finufft SYSTEM INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
295+
if(FINUFFT_ENABLE_INSTALL)
296+
file(GLOB FINUFFT_PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/finufft*.h")
297+
set_target_properties(finufft PROPERTIES PUBLIC_HEADER "${FINUFFT_PUBLIC_HEADERS}")
298+
endif()
299+
list(APPEND INSTALL_TARGETS finufft)
84300
endif()
85301

86302
if(FINUFFT_USE_CUDA)
87-
include(cuda_setup)
303+
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
304+
message(
305+
WARNING
306+
"FINUFFT WARNING: No CUDA architecture supplied via '-DCMAKE_CUDA_ARCHITECTURES=...', defaulting to 'native' See: https://developer.nvidia.com/cuda-gpus for more details on what architecture to supply."
307+
)
308+
detect_cuda_architecture()
309+
endif()
310+
if(CMAKE_CUDA_ARCHITECTURES MATCHES "compute_")
311+
message(
312+
FATAL_ERROR
313+
"CMAKE_CUDA_ARCHITECTURES must be a list of integers like 70;75;86, not strings like compute_89"
314+
)
315+
endif()
316+
enable_language(CUDA)
317+
find_package(CUDAToolkit REQUIRED)
318+
include(cmake/setupCCCL.cmake)
88319
add_subdirectory(src/cuda)
89320
if(BUILD_TESTING AND FINUFFT_BUILD_TESTS)
90321
add_subdirectory(perftest/cuda)
@@ -149,23 +380,7 @@ message(STATUS " CMAKE_CUDA_ARCHITECTURES: ${CMAKE_CUDA_ARCHITECTURES}")
149380

150381
if(FINUFFT_ENABLE_INSTALL)
151382
include(GNUInstallDirs)
152-
include(CMakePackageConfigHelpers)
153-
install(TARGETS ${INSTALL_TARGETS} EXPORT finufftTargets PUBLIC_HEADER)
154-
install(EXPORT finufftTargets NAMESPACE finufft:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/finufft)
155-
configure_package_config_file(
156-
cmake/finufftConfig.cmake.in
157-
${CMAKE_CURRENT_BINARY_DIR}/finufftConfig.cmake
158-
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/finufft
159-
)
160-
write_basic_package_version_file(
161-
${CMAKE_CURRENT_BINARY_DIR}/finufftConfigVersion.cmake
162-
VERSION ${PROJECT_VERSION}
163-
COMPATIBILITY SameMajorVersion
164-
)
165-
install(
166-
FILES ${CMAKE_CURRENT_BINARY_DIR}/finufftConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/finufftConfigVersion.cmake
167-
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/finufft
168-
)
383+
install(TARGETS ${INSTALL_TARGETS} PUBLIC_HEADER)
169384
install(FILES ${PROJECT_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/licenses/finufft)
170385
if(FINUFFT_USE_CPU)
171386
install(

0 commit comments

Comments
 (0)