2 # This file is part of the GROMACS molecular simulation package.
4 # Copyright (c) 2013,2014,2016,2017, by the GROMACS development team, led by
5 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 # and including many others, as listed in the AUTHORS file in the
7 # top-level source directory and at http://www.gromacs.org.
9 # GROMACS is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public License
11 # as published by the Free Software Foundation; either version 2.1
12 # of the License, or (at your option) any later version.
14 # GROMACS is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # Lesser General Public License for more details.
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with GROMACS; if not, see
21 # http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 # If you want to redistribute modifications to GROMACS, please
25 # consider that scientific software is very special. Version
26 # control is crucial - bugs must be traceable. We will be happy to
27 # consider code for inclusion in the official distribution, but
28 # derived work must not be called official GROMACS. Details are found
29 # in the README & COPYING files - if they are missing, get the
30 # official version at http://www.gromacs.org.
32 # To help us fund GROMACS development, we humbly ask that you cite
33 # the research papers on the package. Check out http://www.gromacs.org.
35 # Helper function to call the correct language version of the CMake
36 # check_*_compiler_flag function.
37 function(gmx_check_compiler_flag FLAGS LANGUAGE RESULT_VARIABLE)
38 if (LANGUAGE STREQUAL "C")
39 check_c_compiler_flag("${FLAGS}" ${RESULT_VARIABLE})
40 elseif (LANGUAGE STREQUAL "CXX")
41 check_cxx_compiler_flag("${FLAGS}" ${RESULT_VARIABLE})
43 message(FATAL_ERROR "Language '${LANGUAGE}' is not supported by gmx_check_compiler_flag")
47 # Helper function to call the correct language version of the CMake
48 # check_*_source_compiles function.
49 function(gmx_check_source_compiles_with_flags SOURCE FLAGS LANGUAGE RESULT_VARIABLE)
50 set(CMAKE_REQUIRED_FLAGS "${FLAGS}")
51 if (LANGUAGE STREQUAL "C")
52 check_c_source_compiles("${SOURCE}" ${RESULT_VARIABLE})
53 elseif (LANGUAGE STREQUAL "CXX")
54 check_cxx_source_compiles("${SOURCE}" ${RESULT_VARIABLE})
56 message(FATAL_ERROR "Language '${LANGUAGE}' is not supported by gmx_check_source_compiles_with_flags")
60 # Helper routine to find flag (from a list) to compile a specific source (in C or C++).
61 # RESULT_VARIABLE Name of variable to set in the parent scope to true if
62 # we have found a flag that works (which could be "")
63 # SOURCE Source code to test
64 # LANGUAGE Specifies the language as "C" or "CXX"
65 # TOOLCHAIN_FLAGS_VARIABLE Name of a variable that contains any flags already known
66 # to be needed by the toolchain (unchanged)
67 # NEW_FLAGS_VARIABLE The first working flag will be set to this variable.
68 # Args 6 through N Multiple strings with compiler flags to test
70 # If gmx_check_compiler_flag() finds a working compiler flag, but the project in
71 # gmx_check_source_compiles_with_flags() fails to build source code that needs,
72 # the flag, this function sets SUGGEST_BINUTILS_UPDATE in the parent scope to
73 # suggest that the calling code tell the user about this issue if needed.
74 FUNCTION(GMX_FIND_FLAG_FOR_SOURCE RESULT_VARIABLE SOURCE LANGUAGE TOOLCHAIN_FLAGS_VARIABLE NEW_FLAGS_VARIABLE)
75 # Insert a blank element last in the list (ie. try without any flags too)
76 # This must come last, since some compilers (Intel) might try to emulate
77 # emulate AVX instructions with SSE4.1 otherwise.
78 foreach(_testflag ${ARGN} "")
79 # make valid variable names from the flag string: replace all non-alphanumerical chars
80 string(REGEX REPLACE "[^a-zA-Z0-9]+" "_" FLAG_ACCEPTED_VARIABLE "${LANGUAGE}_${_testflag}_FLAG_ACCEPTED")
81 string(REGEX REPLACE "[^a-zA-Z0-9]+" "_" COMPILE_WORKS_VARIABLE "${LANGUAGE}_${_testflag}_COMPILE_WORKS")
83 # Check that the flag itself is fine, and that it does not generate warnings either, but don't
84 # confuse the user by saying an empty flag was "accepted"
85 if("${_testflag}" STREQUAL "")
86 set(${FLAG_ACCEPTED_VARIABLE} 1)
87 # Give the empty flag variable a better name since we cannot control the CMake status messages
88 set(COMPILE_WORKS_VARIABLE "${LANGUAGE}_COMPILE_WORKS_WITHOUT_SPECIAL_FLAGS")
90 gmx_check_compiler_flag("${${TOOLCHAIN_FLAGS_VARIABLE}} ${_testflag}" "${LANGUAGE}" ${FLAG_ACCEPTED_VARIABLE})
93 if(${FLAG_ACCEPTED_VARIABLE})
94 IF(DEFINED ${COMPILE_WORKS_VARIABLE})
95 # This is a subsequent call to CMake, don't spam the status line
98 # Check that we can really compile source with the full
99 # toolchain (this does not catch compiler warnings).
100 gmx_check_source_compiles_with_flags("${SOURCE}" "${${TOOLCHAIN_FLAGS_VARIABLE}} ${_testflag}" "${LANGUAGE}" ${COMPILE_WORKS_VARIABLE})
102 if(NOT ${COMPILE_WORKS_VARIABLE})
104 if("${_testflag}" STREQUAL "")
105 message(STATUS "Could not find any flag to build test source (this could be due to either the compiler or binutils)")
107 message(STATUS "Flag was accepted, but it did not build test source (this could be due to either the compiler or binutils)")
108 set(SUGGEST_BINUTILS_UPDATE 1 PARENT_SCOPE)
112 if (${FLAG_ACCEPTED_VARIABLE} AND ${COMPILE_WORKS_VARIABLE})
113 set(${RESULT_VARIABLE} 1 PARENT_SCOPE)
114 set(${NEW_FLAGS_VARIABLE} "${_testflag}" PARENT_SCOPE)
119 # If no flag has been found, then leaving ${RESULT_VARIABLE} unset
120 # will be interpreted by CMake as false.
123 # Helper routine to find a flag (from a list) that will compile a specific source (in both C and C++).
124 # C_RESULT_VARIABLE Names a variable that will be set true if a way
125 # to compile the source as C was found
126 # CXX_RESULT_VARIABLE Names a variable that will be set true if a way
127 # to compile the source as C++ was found
128 # SOURCE Source code to test
129 # TOOLCHAIN_C_FLAGS_VARIABLE As input, names a variable that contains flags needed
130 # by the C toolchain.
131 # TOOLCHAIN_CXX_FLAGS_VARIABLE As input, names a variable that contains flags needed
132 # by the C++ toolchain.
133 # NEW_C_FLAGS_VARIABLE The first working C flag will be set to this variable
134 # NEW_CXX_FLAGS_VARIABLE The first working C++ flag will be set to this variable
135 # Args 8 through N Multiple strings with compiler flags to test
137 # If a compile flag is found, but the project in check_c/cxx_source_compiles
138 # fails to build, sets SUGGEST_BINUTILS_UPDATE in parent scope to suggest
139 # that the calling code tell the user about this issue if needed.
140 macro(gmx_find_flags C_RESULT_VARIABLE CXX_RESULT_VARIABLE SOURCE TOOLCHAIN_C_FLAGS_VARIABLE TOOLCHAIN_CXX_FLAGS_VARIABLE C_FLAGS_VARIABLE CXX_FLAGS_VARIABLE)
141 gmx_find_flag_for_source(${C_RESULT_VARIABLE} "${SOURCE}" "C" ${TOOLCHAIN_C_FLAGS_VARIABLE} ${C_FLAGS_VARIABLE} ${ARGN})
142 gmx_find_flag_for_source(${CXX_RESULT_VARIABLE} "${SOURCE}" "CXX" ${TOOLCHAIN_CXX_FLAGS_VARIABLE} ${CXX_FLAGS_VARIABLE} ${ARGN})