1# ---------------------------------------------------------------
2# Programmer(s): Cody J. Balos @ LLNL
3# ---------------------------------------------------------------
4# SUNDIALS Copyright Start
5# Copyright (c) 2002-2021, Lawrence Livermore National Security
6# and Southern Methodist University.
7# All rights reserved.
8#
9# See the top-level LICENSE and NOTICE files for details.
10#
11# SPDX-License-Identifier: BSD-3-Clause
12# SUNDIALS Copyright End
13# ---------------------------------------------------------------
14# Module that sets up compilers for SUNDIALS.
15# ---------------------------------------------------------------
16
17# ===============================================================
18# Determine the index type for the compiler
19# ===============================================================
20
21include(SundialsIndexSize)
22
23# ===============================================================
24# Platform specifc settings
25# ===============================================================
26
27if(WIN32)
28  # Under Windows, add compiler directive to inhibit warnings
29  # about use of unsecure functions.
30  add_definitions(-D_CRT_SECURE_NO_WARNINGS)
31endif()
32
33if(APPLE)
34  # Allow undefined symbols that will be resolved by a user program.
35  set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -undefined dynamic_lookup")
36endif()
37
38# ===============================================================
39# RPath settings
40# ===============================================================
41
42# only apply rpath settings for builds using shared libs
43if(BUILD_SHARED_LIBS)
44  # use, i.e. don't skip the full RPATH for the build tree
45  set(CMAKE_SKIP_BUILD_RPATH FALSE)
46
47  # when building, don't use the install RPATH already
48  # (but later on when installing)
49  set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
50  set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
51  set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}")
52
53  # add the automatically determined parts of the RPATH
54  # which point to directories outside the build tree to the install RPATH
55  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
56
57  # the RPATH to be used when installing, but only if it's not a system directory
58  list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" isSystemDir)
59  if("${isSystemDir}" STREQUAL "-1")
60    set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
61  endif()
62endif()
63
64# ===============================================================
65# Fortran settings
66# ===============================================================
67
68# ---------------------------------------------------------------
69# A Fortran compiler is needed to:
70# (a) Determine compiler the name-mangling scheme if the F77
71#     interfaces or LAPACK are enabled
72# (b) Compile example programs if F77 or F90 examples are enabled
73# ---------------------------------------------------------------
74
75# Do we need a Fortran name-mangling scheme?
76if(BUILD_FORTRAN77_INTERFACE OR ENABLE_LAPACK)
77  set(NEED_FORTRAN_NAME_MANGLING TRUE)
78endif()
79
80# ------------------------------------------------------------------------------
81# Allow the user to manually specify the Fortran name-mangling scheme
82#
83# The build system tries to infer the Fortran name-mangling scheme using a
84# Fortran compiler and defaults to using lower case and one underscore if the
85# scheme can not be determined. If a working Fortran compiler is not available
86# or the user needs to override the inferred or default scheme, the following
87# options specify the case and number of appended underscores corresponding to
88# the Fortran name-mangling scheme of symbol names that do not themselves
89# contain underscores. This is all we really need for the FCMIX and LAPACK
90# interfaces. A working Fortran compiler is only necessary for building Fortran
91# example programs.
92# ------------------------------------------------------------------------------
93
94# The case to use in the name-mangling scheme
95sundials_option(SUNDIALS_F77_FUNC_CASE STRING
96                "case of Fortran function names (lower/upper)"
97                ""
98                ADVANCED)
99
100# The number of underscores of appended in the name-mangling scheme
101sundials_option(SUNDIALS_F77_FUNC_UNDERSCORES STRING
102                "number of underscores appended to Fortran function names (none/one/two)"
103                ""
104                ADVANCED)
105
106# If used, both case and underscores must be set
107if((NOT SUNDIALS_F77_FUNC_CASE) AND SUNDIALS_F77_FUNC_UNDERSCORES)
108  print_error("If SUNDIALS_F77_FUNC_UNDERSCORES is set, "
109                      "SUNDIALS_F77_FUNC_CASE must also be set.")
110endif()
111if(SUNDIALS_F77_FUNC_CASE AND (NOT SUNDIALS_F77_FUNC_UNDERSCORES))
112  print_error("If SUNDIALS_F77_FUNC_CASE is set, "
113                      "SUNDIALS_F77_FUNC_UNDERSCORES must also be set.")
114endif()
115
116# Did the user provide a name-mangling scheme?
117if(SUNDIALS_F77_FUNC_CASE AND SUNDIALS_F77_FUNC_UNDERSCORES)
118
119  string(TOUPPER ${SUNDIALS_F77_FUNC_CASE} SUNDIALS_F77_FUNC_CASE)
120  string(TOUPPER ${SUNDIALS_F77_FUNC_UNDERSCORES} SUNDIALS_F77_FUNC_UNDERSCORES)
121
122  # Based on the given case and number of underscores, set the C preprocessor
123  # macro definitions. Since SUNDIALS never uses symbols names containing
124  # underscores we set the name-mangling schemes to be the same. In general,
125  # names of symbols with and without underscore may be mangled differently
126  # (e.g. g77 mangles mysub to mysub_ and my_sub to my_sub__)
127  if(SUNDIALS_F77_FUNC_CASE MATCHES "LOWER")
128    if(SUNDIALS_F77_FUNC_UNDERSCORES MATCHES "NONE")
129      set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name")
130      set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name")
131    elseif(SUNDIALS_F77_FUNC_UNDERSCORES MATCHES "ONE")
132      set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name ## _")
133      set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name ## _")
134    elseif(SUNDIALS_F77_FUNC_UNDERSCORES MATCHES "TWO")
135      set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name ## __")
136      set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name ## __")
137    else()
138      print_error("Invalid SUNDIALS_F77_FUNC_UNDERSCORES option.")
139    endif()
140  elseif(SUNDIALS_F77_FUNC_CASE MATCHES "UPPER")
141    if(SUNDIALS_F77_FUNC_UNDERSCORES MATCHES "NONE")
142      set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME")
143      set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME")
144    elseif(SUNDIALS_F77_FUNC_UNDERSCORES MATCHES "ONE")
145      set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME ## _")
146      set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME ## _")
147    elseif(SUNDIALS_F77_FUNC_UNDERSCORES MATCHES "TWO")
148      set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME ## __")
149      set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME ## __")
150    else()
151      print_error("Invalid SUNDIALS_F77_FUNC_UNDERSCORES option.")
152    endif()
153  else()
154    print_error("Invalid SUNDIALS_F77_FUNC_CASE option.")
155  endif()
156
157  # name-mangling scheme has been manually set
158  set(NEED_FORTRAN_NAME_MANGLING FALSE)
159
160endif()
161
162# Do we need a Fortran compiler?
163if(BUILD_FORTRAN_MODULE_INTERFACE OR
164    EXAMPLES_ENABLE_F77 OR
165    EXAMPLES_ENABLE_F90 OR
166    NEED_FORTRAN_NAME_MANGLING)
167  include(SundialsSetupFortran)
168endif()
169
170# ===============================================================
171# C++ settings
172# ===============================================================
173
174# ---------------------------------------------------------------
175# A C++ compiler is only needed if:
176# (a) C++ examples are enabled
177# (b) CUDA is enabled
178# (c) HIP is enabled
179# (d) SYCL is enabled
180# (e) RAJA is enabled
181# (f) Trilinos is enabled
182# (g) SuperLU_DIST is enabled
183# (e) MAGMA is enabled
184# ---------------------------------------------------------------
185
186if(EXAMPLES_ENABLE_CXX OR
187    ENABLE_CUDA OR
188    ENABLE_HIP OR
189    ENABLE_SYCL OR
190    ENABLE_RAJA OR
191    ENABLE_TRILINOS OR
192    ENABLE_SUPERLUDIST OR
193    ENABLE_MAGMA)
194  include(SundialsSetupCXX)
195endif()
196
197# ===============================================================
198# CUDA settings
199# ===============================================================
200
201if(ENABLE_CUDA)
202  include(SundialsSetupCuda)
203  # we treat CUDA as both a TPL and a language
204  list(APPEND SUNDIALS_TPL_LIST "CUDA")
205endif()
206
207# ===============================================================
208# HIP settings
209# ===============================================================
210
211if(ENABLE_HIP)
212  include(SundialsSetupHIP)
213  list(APPEND SUNDIALS_TPL_LIST "HIP")
214endif()
215
216# ===============================================================
217# Configure presentation of language options
218# ===============================================================
219
220set(build_types DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
221set(_SUNDIALS_ENABLED_LANGS "C")
222
223if(CXX_FOUND)
224  list(APPEND _SUNDIALS_ENABLED_LANGS "CXX")
225endif()
226if(Fortran_FOUND)
227  list(APPEND _SUNDIALS_ENABLED_LANGS "Fortran")
228endif()
229if(CUDA_FOUND)
230  list(APPEND _SUNDIALS_ENABLED_LANGS "CUDA")
231endif()
232
233# Make build type specific flag options ADVANCED,
234# except for the one corresponding to the current build type
235foreach(lang ${_SUNDIALS_ENABLED_LANGS})
236  foreach(build_type ${build_types})
237    string(TOUPPER "${CMAKE_BUILD_TYPE}" _cmake_build_type)
238    if(${_cmake_build_type} MATCHES "${build_type}")
239      message("Appending ${lang} ${build_type} flags")
240      mark_as_advanced(CLEAR CMAKE_${lang}_FLAGS_${build_type})
241    else()
242      mark_as_advanced(FORCE CMAKE_${lang}_FLAGS_${build_type})
243    endif()
244  endforeach()
245  # show the language compiler and flags
246  mark_as_advanced(CLEAR CMAKE_${lang}_COMPILER CMAKE_${lang}_FLAGS)
247endforeach()
248