Fix quantifiers variable elimination for parametric datatypes (#7358)
[cvc5.git] / cmake / Helpers.cmake
1 ###############################################################################
2 # Top contributors (to current version):
3 # Mathias Preiner, Aina Niemetz, Andres Noetzli
4 #
5 # This file is part of the cvc5 project.
6 #
7 # Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8 # in the top-level source directory and their institutional affiliations.
9 # All rights reserved. See the file COPYING in the top-level source
10 # directory for licensing information.
11 # #############################################################################
12 ##
13
14 include(CheckCCompilerFlag)
15 include(CheckCXXCompilerFlag)
16
17 if(NOT WIN32)
18 string(ASCII 27 Esc)
19 set(Yellow "${Esc}[33m")
20 set(ResetColor "${Esc}[m")
21 endif()
22
23 # Add a C flag to the global list of C flags.
24 macro(add_c_flag flag)
25 if(CMAKE_C_FLAGS)
26 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
27 else()
28 set(CMAKE_C_FLAGS "${flag}")
29 endif()
30 message(STATUS "Configuring with C flag '${flag}'")
31 endmacro()
32
33 # Add a CXX flag to the global list of CXX flags.
34 macro(add_cxx_flag flag)
35 if(CMAKE_CXX_FLAGS)
36 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
37 else()
38 set(CMAKE_CXX_FLAGS "${flag}")
39 endif()
40 message(STATUS "Configuring with CXX flag '${flag}'")
41 endmacro()
42
43 # Add a C and CXX flag to the global list of C/CXX flags.
44 macro(add_c_cxx_flag flag)
45 add_c_flag(${flag})
46 add_cxx_flag(${flag})
47 endmacro()
48
49 # Check if C flag is supported and add to global list of C flags.
50 macro(add_check_c_flag flag)
51 string(REGEX REPLACE "[-=]" "_" flagname ${flag})
52 check_c_compiler_flag("${flag}" HAVE_FLAG${flagname})
53 if(HAVE_FLAG${flagname})
54 add_c_flag(${flag})
55 endif()
56 endmacro()
57
58 # Check if CXX flag is supported and add to global list of CXX flags.
59 macro(add_check_cxx_flag flag)
60 string(REGEX REPLACE "[-=]" "_" flagname ${flag})
61 check_cxx_compiler_flag("${flag}" HAVE_FLAG${flagname})
62 if(HAVE_FLAG${flagname})
63 add_cxx_flag(${flag})
64 endif()
65 endmacro()
66
67 # Check if C/CXX flag is supported and add to global list of C/CXX flags.
68 macro(add_check_c_cxx_flag flag)
69 add_check_c_flag(${flag})
70 add_check_cxx_flag(${flag})
71 endmacro()
72
73 # Add required CXX flag. Configuration fails if the CXX flag is not supported
74 # by the compiler.
75 macro(add_required_cxx_flag flag)
76 string(REGEX REPLACE "[-=]" "_" flagnamename ${flag})
77 check_cxx_compiler_flag("${flag}" HAVE_FLAG${flagname})
78 if (NOT HAVE_FLAG${flagname})
79 message(FATAL_ERROR "Required compiler flag ${flag} not supported")
80 endif()
81 add_cxx_flag(${flag})
82 endmacro()
83
84 # Add required C flag. Configuration fails if the C flag is not supported by
85 # the compiler.
86 macro(add_required_c_flag flag)
87 string(REGEX REPLACE "[-=]" "_" flagname ${flag})
88 check_c_compiler_flag("${flag}" HAVE_FLAG${flagname})
89 if (NOT HAVE_FLAG${flagname})
90 message(FATAL_ERROR "Required compiler flag ${flag} not supported")
91 endif()
92 add_c_flag(${flag})
93 endmacro()
94
95 # Add requied C/CXX flag. Configuration fails if the C/CXX flag is not
96 # supported by the compiler.
97 macro(add_required_c_cxx_flag flag)
98 add_required_c_flag(${flag})
99 add_required_cxx_flag(${flag})
100 endmacro()
101
102 # cvc5 Boolean options are three-valued to detect if an option was set by the
103 # user. The available values are: IGNORE (default), ON, OFF
104 # Default options do not override options that were set by the user, i.e.,
105 # cvc5_set_option only sets an option if it's value is still IGNORE.
106 # This e.g., allows the user to disable proofs for debug builds (where proofs
107 # are enabled by default).
108 macro(cvc5_option var description)
109 set(${var} IGNORE CACHE STRING "${description}")
110 # Provide drop down menu options in cmake-gui
111 set_property(CACHE ${var} PROPERTY STRINGS IGNORE ON OFF)
112 endmacro()
113
114 # Only set option if the user did not set an option.
115 macro(cvc5_set_option var value)
116 if(${var} STREQUAL "IGNORE")
117 set(${var} ${value})
118 endif()
119 endmacro()
120
121 # Prepend 'prepand_value' to each element of the list 'in_list'. The result
122 # is stored in 'out_list'.
123 function(list_prepend in_list prepand_value out_list)
124 foreach(_elem ${${in_list}})
125 list(APPEND ${out_list} "${prepand_value}${_elem}")
126 endforeach()
127 set(${out_list} ${${out_list}} PARENT_SCOPE)
128 endfunction()
129
130 macro(print_info msg)
131 message("${Blue}${msg}${ResetColor}")
132 endmacro()
133
134 # Helper to print the configuration of a 2-valued or 3-valued option 'var' with
135 # prefix 'str'. Optionally takes a `FOUND_SYSTEM` argument that is used to
136 # indicate when a given dependency is built as part of the cvc5 build.
137 function(print_config str var)
138 set(options)
139 set(oneValueArgs FOUND_SYSTEM)
140 set(multiValueArgs)
141 cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
142
143 if("${var}" STREQUAL "ON")
144 set(OPT_VAL_STR "on")
145 elseif("${var}" STREQUAL "OFF" OR "${var}" STREQUAL "IGNORE")
146 set(OPT_VAL_STR "off")
147 else()
148 set(OPT_VAL_STR "${var}")
149 endif()
150
151 if("${ARGS_FOUND_SYSTEM}" STREQUAL "TRUE")
152 set(OPT_FOUND_SYSTEM_STR " (system)")
153 elseif("${ARGS_FOUND_SYSTEM}" STREQUAL "FALSE")
154 set(OPT_FOUND_SYSTEM_STR " (local)")
155 else()
156 set(OPT_FOUND_SYSTEM_STR "")
157 endif()
158
159 message("${Blue}${str}: ${Green}${OPT_VAL_STR}${OPT_FOUND_SYSTEM_STR}${ResetColor}")
160 endfunction()
161
162
163 # Collect all source files that are required to build libcvc5 in LIBCVC5_SRCS
164 # or LIBCVC5_GEN_SRCS. If GENERATED is the first argument the sources are
165 # added to LIBCVC5_GEN_SRCS. All sources are prepended with the absolute
166 # current path path. CMAKE_CURRENT_BINARY_DIR is prepended
167 # to generated source files.
168 macro(libcvc5_add_sources)
169 set(_sources ${ARGV})
170
171 # Check if the first argument is GENERATED.
172 list(GET _sources 0 _generated)
173 if(${_generated} STREQUAL "GENERATED")
174 list(REMOVE_AT _sources 0)
175 set(_cur_path ${CMAKE_CURRENT_BINARY_DIR})
176 set(_append_to LIBCVC5_GEN_SRCS)
177 else()
178 set(_cur_path ${CMAKE_CURRENT_SOURCE_DIR})
179 set(_append_to LIBCVC5_SRCS)
180 endif()
181
182 # Prepend source files with current path.
183 foreach(_src ${_sources})
184 list(APPEND ${_append_to} "${_cur_path}/${_src}")
185 endforeach()
186
187 file(RELATIVE_PATH
188 _rel_path "${PROJECT_SOURCE_DIR}/src" "${CMAKE_CURRENT_SOURCE_DIR}")
189
190 # Make changes to list ${_append_to} visible to the parent scope if not
191 # called from src/.
192 # Note: ${_append_to} refers to the variable name whereas ${${_append_to}}
193 # refers to the contents of the variable.
194 if(_rel_path)
195 set(${_append_to} ${${_append_to}} PARENT_SCOPE)
196 endif()
197 endmacro()
198
199 # Check if given Python module is installed and raises a FATAL_ERROR error
200 # if the module cannot be found.
201 function(check_python_module module)
202 execute_process(
203 COMMAND
204 ${PYTHON_EXECUTABLE} -c "import ${module}"
205 RESULT_VARIABLE
206 RET_MODULE_TEST
207 ERROR_QUIET
208 )
209 set(module_name ${ARGN})
210 if(NOT module_name)
211 set(module_name ${module})
212 endif()
213
214 if(RET_MODULE_TEST)
215 message(FATAL_ERROR
216 "Could not find module ${module_name} for Python "
217 "version ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}. "
218 "Make sure to install ${module_name} for this Python version "
219 "via \n`${PYTHON_EXECUTABLE} -m pip install ${module_name}'.\n"
220 "Note: You need to have pip installed for this Python version.")
221 endif()
222 endfunction()