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 to find and setup Trilinos correctly.
15# Created from the SundialsTPL.cmake template.
16# All SUNDIALS modules that find and setup a TPL must:
17#
18# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible.
19# 2. Find the TPL.
20# 3. Check if the TPL works with SUNDIALS, UNLESS the override option
21# TPL_WORKS is TRUE - in this case the tests should not be performed and it
22# should be assumed that the TPL works with SUNDIALS.
23# -----------------------------------------------------------------------------
24
25# -----------------------------------------------------------------------------
26# Section 1: Include guard
27# -----------------------------------------------------------------------------
28
29if(NOT DEFINED SUNDIALS_TRILINOS_INCLUDED)
30  set(SUNDIALS_TRILINOS_INCLUDED)
31else()
32  return()
33endif()
34
35# -----------------------------------------------------------------------------
36# Section 2: Check to make sure options are compatible
37# -----------------------------------------------------------------------------
38
39# -----------------------------------------------------------------------------
40# Section 3: Find the TPL
41# -----------------------------------------------------------------------------
42
43# Find Trilinos
44find_package(Trilinos REQUIRED)
45
46# Check if Trilinos was built with MPI
47if(";${Trilinos_TPL_LIST};" MATCHES ";MPI;")
48  set(Trilinos_MPI TRUE)
49else()
50  set(Trilinos_MPI FALSE)
51endif()
52
53# For XSDK compatibility, only use the user/spack provided compiler and flags to build
54# SUNDIALS modules that use Trilinos. If we are not in XSDK mode, we can use the imported
55# Trilinos compiler and flags by default, but allow the user to change it through CMake
56# the Trilinos_INTERFACE_* options.
57
58if(USE_XSDK_DEFAULTS)
59  if(Trilinos_MPI AND MPI_CXX_FOUND)
60    force_variable(Trilinos_INTERFACE_CXX_COMPILER     STRING "C++ compiler for Trilinos interface" "${MPI_CXX_COMPILER}")
61    set(Trilinos_INTERFACE_MPI_CXX_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C++ compiler MPI")
62  else()
63    force_variable(Trilinos_INTERFACE_CXX_COMPILER     STRING "C compiler for Trilinos interface" "${CMAKE_CXX_COMPILER}")
64    set(Trilinos_INTERFACE_MPI_CXX_FOUND FALSE CACHE INTERNAL "Is Trilinos interface C++ compiler MPI")
65  endif()
66  if(Trilinos_MPI AND MPI_C_FOUND)
67    force_variable(Trilinos_INTERFACE_C_COMPILER       STRING "C compiler for Trilinos interface" "${MPI_C_COMPILER}")
68    set(Trilinos_INTERFACE_MPI_C_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C compiler MPI")
69  else()
70    force_variable(Trilinos_INTERFACE_C_COMPILER       STRING "C compiler for Trilinos interface" "${CMAKE_C_COMPILER}")
71    set(Trilinos_INTERFACE_MPI_C_FOUND FALSE CACHE INTERNAL "Is Trilinos interface C compiler MPI")
72  endif()
73  force_variable(Trilinos_INTERFACE_CXX_COMPILER_FLAGS STRING "C++ compiler flags specific to Trilinos interface" "")
74  force_variable(Trilinos_INTERFACE_C_COMPILER_FLAGS   STRING "C compiler flags specific to Trilinos interface" "")
75  force_variable(Trilinos_INTERFACE_MPIEXEC            STRING "MPI executable for Trilinos interface" "${MPIEXEC_EXECUTABLE}")
76else()
77  force_variable(Trilinos_INTERFACE_CXX_COMPILER       STRING "C++ compiler for Trilinos interface" "${Trilinos_CXX_COMPILER}")
78  force_variable(Trilinos_INTERFACE_C_COMPILER         STRING "C compiler for Trilinos interface" "${Trilinos_C_COMPILER}")
79  force_variable(Trilinos_INTERFACE_CXX_COMPILER_FLAGS STRING "C++ compiler flags for Trilinos interface" "${Trilinos_CXX_COMPILER_FLAGS}")
80  force_variable(Trilinos_INTERFACE_C_COMPILER_FLAGS   STRING "C compiler flags for Trilinos interface" "${Trilinos_C_COMPILER_FLAGS}")
81  force_variable(Trilinos_INTERFACE_MPIEXEC            STRING "MPI executable for Trilinos interface" "${Trilinos_MPI_EXEC}")
82  set(Trilinos_INTERFACE_MPI_CXX_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C++ compiler MPI")
83  set(Trilinos_INTERFACE_MPI_C_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C compiler MPI")
84endif()
85
86message(STATUS "Trilinos_MPI:          ${Trilinos_MPI}")
87message(STATUS "Trilinos_LIBRARIES:    ${Trilinos_LIBRARIES}")
88message(STATUS "Trilinos_INCLUDE_DIRS: ${Trilinos_INCLUDE_DIRS}")
89
90# -----------------------------------------------------------------------------
91# Section 4: Test the TPL
92# -----------------------------------------------------------------------------
93
94if(Trilinos_FOUND AND (NOT Trilinos_WORKS))
95  # Do any checks which don't require compilation first.
96
97  # Create the Trilinos_TEST directory
98  set(Trilinos_TEST_DIR ${PROJECT_BINARY_DIR}/Trilinos_TEST)
99  file(MAKE_DIRECTORY ${Trilinos_TEST_DIR})
100
101  # Create a CMakeLists.txt file
102  file(WRITE ${Trilinos_TEST_DIR}/CMakeLists.txt
103    "CMAKE_MINIMUM_REQUIRED(VERSION 3.1.3)\n"
104    "PROJECT(ltest CXX)\n"
105    "SET(CMAKE_VERBOSE_MAKEFILE ON)\n"
106    "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n"
107    "SET(CMAKE_CXX_COMPILER \"${Trilinos_INTERFACE_CXX_COMPILER}\")\n"
108    "SET(CMAKE_CXX_FLAGS \"${Trilinos_INTERFACE_CXX_COMPILER_FLAGS}\")\n"
109    "SET(Trilinos_DIR \"${Trilinos_DIR}\")\n"
110    "INCLUDE(FindPackageHandleStandardArgs)\n"
111    "INCLUDE(${PROJECT_SOURCE_DIR}/cmake/tpl/FindTrilinos.cmake)\n"
112    "ADD_EXECUTABLE(ltest ltest.cpp)\n"
113    "TARGET_LINK_LIBRARIES(ltest SUNDIALS::TRILINOS)\n")
114
115  # Create a C++ source file which calls a Trilinos function
116  file(WRITE ${Trilinos_TEST_DIR}/ltest.cpp
117  "#include <Tpetra_Version.hpp>\n"
118  "int main(){\n"
119  "std::cout << Tpetra::version() << std::endl;\n"
120  "return(0);\n"
121  "}\n")
122
123  # Attempt to build and link the "ltest" executable
124  try_compile(COMPILE_OK ${Trilinos_TEST_DIR} ${Trilinos_TEST_DIR} ltest
125    OUTPUT_VARIABLE COMPILE_OUTPUT)
126
127  # Process test result
128  if(COMPILE_OK)
129    message(STATUS "Checking if Trilinos works with SUNDIALS... OK")
130    set(Trilinos_WORKS TRUE CACHE BOOL "Trilinos works with SUNDIALS as configured" FORCE)
131  else()
132    message(STATUS "Checking if Trilinos works with SUNDIALS... FAILED")
133    message(STATUS "Check output: ")
134    message("${COMPILE_OUTPUT}")
135    print_error("SUNDIALS interface to Trilinos is not functional.")
136  endif()
137
138elseif(Trilinos_FOUND AND Trilinos_WORKS)
139  message(STATUS "Skipped Trilinos tests, assuming Trilinos works with SUNDIALS. Set Trilinos_WORKS=FALSE to (re)run compatibility test.")
140endif()
141