44
55# set up basic project info
66cmake_minimum_required (VERSION 3.18 )
7+ include (CheckFunctionExists )
8+
79enable_language (Fortran )
810project (Mystran)
911
@@ -139,7 +141,7 @@ if (WIN32)
139141 set (CMAKE_EXE_LINKER_FLAGS "-static" )
140142endif ()
141143
142- # build the SuperLU and BLAS static libs!
144+ # build the SuperLU ( and CBLAS if needed) static libs!
143145add_subdirectory (${SUPERLU_DIR} )
144146
145147# collect modules and interfaces into a module called MODULES
@@ -156,29 +158,62 @@ set(
156158 MODULES_ALL_FILES ${USE_IFs_FILES} ${Interfaces_FILES} ${Modules_FILES}
157159 ${Modules_LAPACK_FILES} ${Modules_ARPACK_FILES}
158160)
159- add_library (MODULES ${MODULES_ALL_FILES} )
161+ add_library (MODULES OBJECT ${MODULES_ALL_FILES} )
160162
161163# collect modules
162164list (APPEND modules_names ARPACK BANDIT LK1 LK2 LK3 LK4 LK5 LK6 LK9 EMG)
163165foreach (modname IN LISTS modules_names)
164166 file (GLOB_RECURSE TMP_MOD_FILES "${CMAKE_SOURCE_DIR} /${modname} /*.f*" )
165- add_library (${modname} ${TMP_MOD_FILES} ${TMP_MOD_FILES_PP} )
167+ add_library (${modname} OBJECT ${TMP_MOD_FILES} ${TMP_MOD_FILES_PP} )
166168 target_link_libraries (${modname} MODULES )
167169endforeach ()
168170
169- # add the DTRSV and DGSSV C modules.
171+ # add the DGSSV C module from SuperLU and link it against SuperLU's BLAS
170172add_library (dgssv "${SUPERLU_DIR} /FORTRAN/c_fortran_dgssv.c" )
171- #add_library(dtrsv "${SUPERLU_DIR}/SRC/dtrsv.c")
172173target_link_libraries (dgssv blas )
173174
175+ # if (and only if) SuperLU is compiled with its internal CBLAS, some subrs will
176+ # be missing, so we compile our own.
177+ # first, we check for the missing subroutines
178+ list (
179+ APPEND blas_fns dgemm dgemv dlamch dlanst dscal dsteqr dsterf dswap dtrsm
180+ dtrtri ilaenv lsame xerbla
181+ )
182+ foreach (fname IN LISTS blas_fns)
183+ check_function_exists (${fname} BLAS_FN_EXISTS )
184+ if (NOT BLAS_FN_EXISTS)
185+ string (TOUPPER ${fname} fname_upper)
186+ list (APPEND missing_blas_src "${CMAKE_SOURCE_DIR} /BLAS/${fname_upper} .f" )
187+ list (APPEND missing_blas_fns ${fname} )
188+ endif ()
189+ endforeach ()
190+ # if any subroutines have bene found, create an inner blas library
191+ list (LENGTH missing_blas_fns MISSING_FNS_TOTAL)
192+ if (MISSING_FNS_TOTAL GREATER 0)
193+ if (MISSING_FNS_TOTAL GREATER 1)
194+ message (
195+ STATUS
196+ "BLAS subrs (${missing_blas_fns} ) are absent and will be built locally."
197+ )
198+ else ()
199+ message (
200+ STATUS
201+ "BLAS subr ${missing_blas_fns} is absent and will be built locally."
202+ )
203+ endif ()
204+ add_library (my_blas OBJECT ${missing_blas_src} )
205+ endif ()
174206
175207# prepare the main executable, linked against the specifics and the m
176208# it appears utils used to be a module, but that is no longer the case?
177209file (GLOB_RECURSE UTIL_FILES "${CMAKE_SOURCE_DIR} /UTIL/*.f*" )
178210file (GLOB_RECURSE MAIN_FILES "${CMAKE_SOURCE_DIR} /MAIN/*.[fF]*" )
179211add_executable (mystran ${MAIN_FILES} ${MODULES_ALL_FILES} ${UTIL_FILES} )
180212target_link_libraries (mystran ${modules_names} )
181- target_link_libraries (mystran dgssv superlu f2c )
213+ target_link_libraries (mystran dgssv superlu f2c blas )
214+ if (MISSING_FNS_TOTAL GREATER 0)
215+ target_link_libraries (mystran my_blas )
216+ endif ()
182217set_target_properties (
183218 mystran PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}
184219)
0 commit comments