Skip to content

Commit 4db1c2c

Browse files
committed
Add missing CMakeLists.txt and fix .gitignore
1 parent b1c4910 commit 4db1c2c

2 files changed

Lines changed: 261 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*.txt
2+
!CMakeLists.txt
23
*.pyc
34
*.ndt
45
*.gch

CMakeLists.txt

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
cmake_minimum_required(VERSION 3.18...3.28)
2+
project(fidimag LANGUAGES C)
3+
4+
# Policy settings for modern CMake
5+
if(POLICY CMP0167)
6+
cmake_policy(SET CMP0167 NEW) # FindBoost compatibility
7+
endif()
8+
9+
# =============================================================================
10+
# Build Configuration
11+
# =============================================================================
12+
13+
# Default to Release build for optimization
14+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
15+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
16+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo")
17+
endif()
18+
19+
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
20+
21+
# C/C++ standards
22+
set(CMAKE_C_STANDARD 99)
23+
set(CMAKE_C_STANDARD_REQUIRED ON)
24+
25+
# Position independent code (required for Python extensions)
26+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
27+
28+
# =============================================================================
29+
# Add local library paths (for SUNDIALS/FFTW in ./local/)
30+
# =============================================================================
31+
32+
list(APPEND CMAKE_PREFIX_PATH
33+
"${PROJECT_SOURCE_DIR}/local"
34+
"${PROJECT_SOURCE_DIR}/local/lib/cmake"
35+
"${PROJECT_SOURCE_DIR}/local/lib64/cmake"
36+
)
37+
38+
# Also add to module path for custom Find modules
39+
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
40+
41+
message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
42+
43+
# =============================================================================
44+
# Find Dependencies
45+
# =============================================================================
46+
47+
# Python, NumPy, and Cython
48+
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module NumPy)
49+
message(STATUS "Python: ${Python_VERSION} (${Python_EXECUTABLE})")
50+
message(STATUS "NumPy include: ${Python_NumPy_INCLUDE_DIRS}")
51+
52+
# Cython
53+
find_program(CYTHON_EXECUTABLE NAMES cython cython3 REQUIRED)
54+
message(STATUS "Cython: ${CYTHON_EXECUTABLE}")
55+
56+
# OpenMP (required for parallel computation)
57+
find_package(OpenMP REQUIRED COMPONENTS C)
58+
message(STATUS "OpenMP found: C ${OpenMP_C_FLAGS}")
59+
60+
# BLAS and LAPACK (linear algebra)
61+
find_package(BLAS REQUIRED)
62+
find_package(LAPACK REQUIRED)
63+
message(STATUS "BLAS: ${BLAS_LIBRARIES}")
64+
message(STATUS "LAPACK: ${LAPACK_LIBRARIES}")
65+
66+
# FFTW3 (Fast Fourier Transform)
67+
# Look for both regular and OpenMP versions
68+
find_library(FFTW3_LIBRARY NAMES fftw3 REQUIRED
69+
HINTS ${PROJECT_SOURCE_DIR}/local/lib ${PROJECT_SOURCE_DIR}/local/lib64
70+
DOC "FFTW3 library"
71+
)
72+
find_library(FFTW3_OMP_LIBRARY NAMES fftw3_omp REQUIRED
73+
HINTS ${PROJECT_SOURCE_DIR}/local/lib ${PROJECT_SOURCE_DIR}/local/lib64
74+
DOC "FFTW3 OpenMP library"
75+
)
76+
find_path(FFTW3_INCLUDE_DIR fftw3.h
77+
HINTS ${PROJECT_SOURCE_DIR}/local/include $ENV{FFTW_INC}
78+
DOC "FFTW3 include directory"
79+
)
80+
message(STATUS "FFTW3: ${FFTW3_LIBRARY}")
81+
message(STATUS "FFTW3 OpenMP: ${FFTW3_OMP_LIBRARY}")
82+
message(STATUS "FFTW3 include: ${FFTW3_INCLUDE_DIR}")
83+
84+
# SUNDIALS (ODE/DAE solver) - Custom find module
85+
find_package(SUNDIALS 7.6 REQUIRED COMPONENTS cvodes nvecserial nvecopenmp)
86+
message(STATUS "SUNDIALS ${SUNDIALS_VERSION} found")
87+
message(STATUS " Include: ${SUNDIALS_INCLUDE_DIRS}")
88+
message(STATUS " Libraries: ${SUNDIALS_LIBRARIES}")
89+
90+
# =============================================================================
91+
# Common Compiler Flags
92+
# =============================================================================
93+
94+
# C compiler flags
95+
set(C_COMPILE_FLAGS
96+
-O3
97+
-Wall
98+
-Wno-cpp
99+
-Wno-unused-function
100+
)
101+
102+
# Common libraries for all extensions
103+
set(COMMON_LIBRARIES
104+
m # Math library
105+
${FFTW3_OMP_LIBRARY}
106+
${FFTW3_LIBRARY}
107+
${SUNDIALS_LIBRARIES}
108+
${BLAS_LIBRARIES}
109+
${LAPACK_LIBRARIES}
110+
OpenMP::OpenMP_C
111+
)
112+
113+
# Common include directories
114+
set(COMMON_INCLUDES
115+
${Python_INCLUDE_DIRS}
116+
${Python_NumPy_INCLUDE_DIRS}
117+
${PROJECT_SOURCE_DIR}/local/include
118+
${FFTW3_INCLUDE_DIR}
119+
${SUNDIALS_INCLUDE_DIRS}
120+
)
121+
122+
# Add environment variable paths if set
123+
if(DEFINED ENV{SUNDIALS_INC})
124+
list(APPEND COMMON_INCLUDES $ENV{SUNDIALS_INC})
125+
message(STATUS "Added SUNDIALS_INC: $ENV{SUNDIALS_INC}")
126+
endif()
127+
128+
if(DEFINED ENV{FFTW_INC})
129+
list(APPEND COMMON_INCLUDES $ENV{FFTW_INC})
130+
message(STATUS "Added FFTW_INC: $ENV{FFTW_INC}")
131+
endif()
132+
133+
# =============================================================================
134+
# Helper Function: Create Cython Extension
135+
# =============================================================================
136+
137+
function(add_fidimag_extension MODULE_NAME SOURCE_FILE)
138+
# Get the module name without "fidimag.extensions." prefix for target name
139+
string(REPLACE "." "_" TARGET_NAME ${MODULE_NAME})
140+
141+
# Determine output paths
142+
get_filename_component(SOURCE_DIR ${SOURCE_FILE} DIRECTORY)
143+
get_filename_component(SOURCE_NAME ${SOURCE_FILE} NAME_WE)
144+
145+
# Cython output file (always C)
146+
set(CYTHON_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${SOURCE_DIR}/${SOURCE_NAME}.c")
147+
148+
# Find additional C/C++ source files in the same directory
149+
file(GLOB EXTRA_SOURCES
150+
"${PROJECT_SOURCE_DIR}/fidimag/${SOURCE_DIR}/*.c"
151+
"${PROJECT_SOURCE_DIR}/fidimag/${SOURCE_DIR}/*.cpp"
152+
)
153+
154+
# Remove the cythonized output if it's in the source dir
155+
list(FILTER EXTRA_SOURCES EXCLUDE REGEX ".*${SOURCE_NAME}\\.c$")
156+
list(FILTER EXTRA_SOURCES EXCLUDE REGEX ".*${SOURCE_NAME}\\.cpp$")
157+
158+
message(STATUS "Extension ${MODULE_NAME}:")
159+
message(STATUS " Source: ${SOURCE_FILE}")
160+
message(STATUS " Cython output: ${CYTHON_OUTPUT}")
161+
message(STATUS " Extra sources: ${EXTRA_SOURCES}")
162+
message(STATUS " Language: C")
163+
164+
# Ensure output directory exists
165+
get_filename_component(CYTHON_OUTPUT_DIR ${CYTHON_OUTPUT} DIRECTORY)
166+
file(MAKE_DIRECTORY ${CYTHON_OUTPUT_DIR})
167+
168+
# Cythonize the .pyx file
169+
add_custom_command(
170+
OUTPUT ${CYTHON_OUTPUT}
171+
COMMAND ${CYTHON_EXECUTABLE}
172+
-3 # Python 3
173+
--directive linetrace=True
174+
--directive language_level=3
175+
-o ${CYTHON_OUTPUT}
176+
${PROJECT_SOURCE_DIR}/fidimag/${SOURCE_FILE}
177+
DEPENDS ${PROJECT_SOURCE_DIR}/fidimag/${SOURCE_FILE}
178+
COMMENT "Cythonizing ${SOURCE_FILE}"
179+
)
180+
181+
set_source_files_properties(${CYTHON_OUTPUT} PROPERTIES LANGUAGE C)
182+
set_source_files_properties(${EXTRA_SOURCES} PROPERTIES LANGUAGE C)
183+
184+
# Create the Python extension module
185+
Python_add_library(${TARGET_NAME} MODULE
186+
${CYTHON_OUTPUT}
187+
${EXTRA_SOURCES}
188+
WITH_SOABI
189+
)
190+
191+
# Set target properties
192+
set_target_properties(${TARGET_NAME} PROPERTIES
193+
OUTPUT_NAME ${SOURCE_NAME}
194+
PREFIX "" # No lib prefix
195+
LINKER_LANGUAGE C
196+
)
197+
198+
# Include directories
199+
target_include_directories(${TARGET_NAME} PRIVATE
200+
${COMMON_INCLUDES}
201+
${PROJECT_SOURCE_DIR}/fidimag/${SOURCE_DIR}
202+
)
203+
204+
# Compiler flags
205+
target_compile_options(${TARGET_NAME} PRIVATE ${C_COMPILE_FLAGS})
206+
207+
# Link libraries
208+
target_link_libraries(${TARGET_NAME} PRIVATE ${COMMON_LIBRARIES})
209+
210+
# RPATH for finding local libraries at runtime
211+
set_target_properties(${TARGET_NAME} PROPERTIES
212+
INSTALL_RPATH "${PROJECT_SOURCE_DIR}/local/lib;${PROJECT_SOURCE_DIR}/local/lib64"
213+
BUILD_RPATH "${PROJECT_SOURCE_DIR}/local/lib;${PROJECT_SOURCE_DIR}/local/lib64"
214+
)
215+
216+
# Install the extension to the proper location in the fidimag package
217+
# Extract the Python module path from MODULE_NAME
218+
string(REPLACE "." "/" MODULE_PATH ${MODULE_NAME})
219+
get_filename_component(INSTALL_DIR ${MODULE_PATH} DIRECTORY)
220+
221+
install(TARGETS ${TARGET_NAME}
222+
LIBRARY DESTINATION ${INSTALL_DIR}
223+
COMPONENT python
224+
)
225+
endfunction()
226+
227+
# =============================================================================
228+
# Define All Cython Extensions
229+
# =============================================================================
230+
231+
# Atomistic extensions
232+
add_fidimag_extension("fidimag.extensions.clib" "atomistic/lib/clib.pyx")
233+
234+
# Micromagnetic extensions
235+
add_fidimag_extension("fidimag.extensions.micro_clib" "micro/lib/micro_clib.pyx")
236+
add_fidimag_extension("fidimag.extensions.baryakhtar_clib" "micro/lib/baryakhtar/baryakhtar_clib.pyx")
237+
238+
# Common extensions
239+
add_fidimag_extension("fidimag.extensions.common_clib" "common/lib/common_clib.pyx")
240+
add_fidimag_extension("fidimag.extensions.cvode" "common/sundials/cvode.pyx")
241+
add_fidimag_extension("fidimag.extensions.dipolar" "common/dipolar/dipolar.pyx")
242+
add_fidimag_extension("fidimag.extensions.nebm_clib" "common/neb_method/nebm_clib.pyx")
243+
244+
# =============================================================================
245+
# Print Configuration Summary
246+
# =============================================================================
247+
248+
message(STATUS "")
249+
message(STATUS "========================================")
250+
message(STATUS "fidimag Build Configuration Summary")
251+
message(STATUS "========================================")
252+
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
253+
message(STATUS "C compiler: ${CMAKE_C_COMPILER}")
254+
message(STATUS "Python: ${Python_VERSION}")
255+
message(STATUS "NumPy: ${Python_NumPy_VERSION}")
256+
message(STATUS "SUNDIALS: ${SUNDIALS_VERSION}")
257+
message(STATUS "OpenMP: Enabled")
258+
message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
259+
message(STATUS "========================================")
260+
message(STATUS "")

0 commit comments

Comments
 (0)