-
Notifications
You must be signed in to change notification settings - Fork 448
/
Copy pathP4CUtils.cmake
225 lines (209 loc) · 8.41 KB
/
P4CUtils.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
include (CheckCCompilerFlag)
include (CheckCXXCompilerFlag)
# test and add a C++ compiler option if supported
MACRO (add_cxx_compiler_option option)
string (REPLACE "+" "P" escaped_option1 ${option})
string (REPLACE "-" "" escaped_option ${escaped_option1})
set (_success "_HAVE_OPTION_${escaped_option}_")
set (__required_flags_backup "${CMAKE_REQUIRED_FLAGS}")
set (CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${P4C_CXX_FLAGS}")
check_cxx_compiler_flag (${option} ${_success})
set (CMAKE_REQUIRED_FLAGS ${__required_flags_backup})
if (${_success})
set (P4C_CXX_FLAGS "${P4C_CXX_FLAGS} ${option}")
endif (${_success})
endmacro (add_cxx_compiler_option)
include (CheckCXXSourceCompiles)
# check if a compiler supports a certain feature by compiling the program
MACRO (check_compiler_feature option program var)
set (__required_flags_backup "${CMAKE_REQUIRED_FLAGS}")
set (CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${option}")
check_cxx_source_compiles ("${program}" ${var})
IF (${var} AND NOT "${option}" STREQUAL "")
set (P4C_CXX_FLAGS "${P4C_CXX_FLAGS} ${option}")
ENDIF ()
if (${var})
add_definitions (-D${var})
endif ()
set (CMAKE_REQUIRED_FLAGS ${__required_flags_backup})
endmacro (check_compiler_feature)
# add a required library
include (CheckLibraryExists)
# checks if a library exists and adds it to the list of p4c dependencies
# supports an additional argument: REQUIRED. If present, it will throw
# a fatal error if the library does not exist.
macro (p4c_add_library name symbol var)
check_library_exists (${name} ${symbol} "" ${var})
if (${var})
set (P4C_LIB_DEPS "${P4C_LIB_DEPS};${name}")
else()
if("${ARGN}" STREQUAL "REQUIRED")
MESSAGE (FATAL_ERROR "Can not find required library: ${name}")
endif()
endif()
endmacro(p4c_add_library)
# Add files with the appropriate path to the list of linted files
macro(add_cpplint_files dir filelist)
foreach(__f ${filelist})
string(REGEX MATCH "^/.*" abs_path "${__f}")
if (NOT ${abs_path} EQUAL "")
list (APPEND __cpplintFileList "${__f}")
else()
list (APPEND __cpplintFileList "${dir}/${__f}")
endif()
endforeach(__f)
set (CPPLINT_FILES ${CPPLINT_FILES} ${__cpplintFileList} PARENT_SCOPE)
endmacro(add_cpplint_files)
# generate all the tests specified in the testsuites
# Arguments:
# - tag is a label for the set of tests, for example, p4, p14_to_16, bmv2, ebpf
# - driver is the script that is used to run the tests and compare the results
# - testsuite is a list of directory patterns, e.g.: testdata/p4_16_samples/*.p4
# - xfail is a set of tests that are expected to fail
#
# The macro generates the test files in a directory prefixed by tag.
#
macro(p4c_add_tests tag driver testsuites xfail)
set (__xfail_list "${xfail}")
set (__testCounter 0)
set (__xfailCounter 0)
foreach(ts "${testsuites}")
file (GLOB __testfiles RELATIVE ${P4C_SOURCE_DIR} ${ts})
list (LENGTH __testfiles __nTests)
foreach(t ${__testfiles})
set(__testfile "${P4C_BINARY_DIR}/${tag}/${t}.test")
file (WRITE ${__testfile} "#! /bin/bash\n")
file (APPEND ${__testfile} "# Generated file, modify with care\n\n")
file (APPEND ${__testfile} "cd ${P4C_BINARY_DIR}\n")
file (APPEND ${__testfile} "${driver} ${P4C_SOURCE_DIR} $* ${P4C_SOURCE_DIR}/${t}")
execute_process(COMMAND chmod +x ${__testfile})
set(__testname ${tag}/${t})
add_test (NAME ${__testname} COMMAND ${tag}/${t}.test WORKING_DIRECTORY ${P4C_BINARY_DIR})
set_tests_properties(${__testname} PROPERTIES LABELS ${tag})
list (LENGTH __xfail_list __xfail_length)
if (${__xfail_length} GREATER 0)
list (FIND __xfail_list ${t} __xfail_test)
if(__xfail_test GREATER -1)
set_tests_properties(${__testname} PROPERTIES WILL_FAIL 1 LABELS "XFAIL")
math (EXPR __xfailCounter "${__xfailCounter} + 1")
endif() # __xfail_test
endif() # __xfail_length
endforeach() # testfiles
math (EXPR __testCounter "${__testCounter} + ${__nTests}")
endforeach()
# add the tag to the list
set (TEST_TAGS ${TEST_TAGS} ${tag} CACHE INTERNAL "test tags")
MESSAGE(STATUS "Added ${__testCounter} tests to '${tag}' (${__xfailCounter} xfails)")
endmacro(p4c_add_tests)
# add rules to make check and recheck for a specific test suite
macro (p4c_add_make_check tag)
if ( "${tag}" STREQUAL "all")
set (__tests_regex "'.*'")
else()
# avoid escaping spaces
set (__tests_regex "'${tag}/.*'")
endif()
get_filename_component (__logDir ${P4C_XFAIL_LOG} DIRECTORY)
add_custom_target(check-${tag}
# list the xfail tests
COMMAND ${CMAKE_COMMAND} -E make_directory ${__logDir}
COMMAND ${CMAKE_COMMAND} -E echo "XFAIL tests:" > ${P4C_XFAIL_LOG} &&
${CMAKE_CTEST_COMMAND} --show-only -L XFAIL --tests-regex "${__tests_regex}" >> ${P4C_XFAIL_LOG}
COMMAND ${CMAKE_CTEST_COMMAND} ${P4C_TEST_FLAGS} --tests-regex "${__tests_regex}"
COMMENT "Running tests for tag ${tag}")
add_custom_target(recheck-${tag}
# list the xfail tests
COMMAND ${CMAKE_COMMAND} -E make_directory ${__logDir}
COMMAND ${CMAKE_COMMAND} -E echo "XFAIL tests:" > ${P4C_XFAIL_LOG} &&
${CMAKE_CTEST_COMMAND} --show-only -L XFAIL --tests-regex "${__tests_regex}" >> ${P4C_XFAIL_LOG}
COMMAND ${CMAKE_CTEST_COMMAND} ${P4C_TEST_FLAGS} --tests-regex "${__tests_regex}" --rerun-failed
COMMENT "Re-running failed tests for tag ${tag}")
endmacro(p4c_add_make_check)
# check for the number of cores on the machine and return them in ${var}
macro (p4c_get_nprocs var)
if(APPLE)
execute_process (COMMAND sysctl -n hw.logicalcpu
OUTPUT_VARIABLE ${var}
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE rc)
else()
execute_process (COMMAND nproc
OUTPUT_VARIABLE ${var}
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE rc)
endif()
# MESSAGE ("p4c_get_nprocs: ${rc} ${${var}}")
if (NOT ${rc} EQUAL 0)
set (${var} 4)
endif()
endmacro (p4c_get_nprocs)
# poor's cmake replacement for $(shell grep -L xxx $(shell -l yyy))
# It takes as arguments:
# - input_files: a pattern for files (full path)
# - test_list: a variable to be set to the resulting list of tests matching
# - pairs of:
# - pattern selector: INCLUDE or EXCLUDE
# - pattern list: a list of patterns that should be included or excluded
# Returns:
# - the list of tests matching search_patterns and not exclude_patterns
function(p4c_find_tests input_files test_list incl_excl patterns)
if (${ARGC} EQUAL 4)
if (${ARGV2} STREQUAL INCLUDE)
set(search_patterns "${ARGV3}")
elseif (${ARGV2} STREQUAL EXCLUDE)
set(exclude_patterns "${ARGV3}")
else()
MESSAGE (FATAL_ERROR "Invalid pattern selector ${ARGV2}")
endif()
elseif(${ARGC} EQUAL 6)
if (${ARGV2} STREQUAL INCLUDE AND ${ARGV4} STREQUAL EXCLUDE)
set(search_patterns "${ARGV3}")
set(exclude_patterns "${ARGV5}")
elseif (${ARGV4} STREQUAL INCLUDE AND ${ARGV2} STREQUAL EXCLUDE)
set(search_patterns "${ARGV5}")
set(exclude_patterns "${ARGV3}")
else()
MESSAGE (FATAL_ERROR "Invalid pattern selector combo: ${ARGV2}/${ARGV4}")
endif()
else()
MESSAGE(FATAL_ERROR "Invalid number of arguments ${ARGC} for find_tests")
endif()
if (DEFINED search_patterns)
list (LENGTH search_patterns __pLen)
# MESSAGE ("include pattern: ${search_patterns}, length ${__pLen}")
else()
# only exclude patterns
set(__pLen 0)
endif()
# if (DEFINED exclude_patterns)
# MESSAGE ("exclude pattern: ${exclude_patterns}, length ${__pLen}")
# endif()
set (inputList "")
foreach (l ${input_files})
file (GLOB __inputList ${l})
list (APPEND inputList ${__inputList})
endforeach()
list (REMOVE_DUPLICATES inputList)
foreach (f IN LISTS inputList)
set (__found 0)
foreach(p ${search_patterns})
file (STRINGS ${f} __found_strings REGEX ${p})
list (LENGTH __found_strings __found_len)
if (__found_len GREATER 0)
math (EXPR __found "${__found} + 1")
endif()
endforeach() # search_patterns
foreach(p ${exclude_patterns})
file (STRINGS ${f} __found_strings REGEX ${p})
list (LENGTH __found_strings __found_len)
if (__found_len GREATER 0)
set (__found -1)
endif()
endforeach() # exclude_patterns
if (__found EQUAL __pLen)
list (APPEND __p4tests ${f})
endif()
endforeach() # test files
# return
set(${test_list} ${__p4tests} PARENT_SCOPE)
endfunction(p4c_find_tests)