Fix the cmake parser to identify more patterns
This commit is contained in:
parent
ec4daf420f
commit
fb891f33da
|
@ -15,35 +15,83 @@ endfunction ()
|
||||||
# Reads a Makefile into CMake vars.
|
# Reads a Makefile into CMake vars.
|
||||||
macro(ParseMakefileVars MAKEFILE_IN)
|
macro(ParseMakefileVars MAKEFILE_IN)
|
||||||
message(STATUS "Reading vars from ${MAKEFILE_IN}...")
|
message(STATUS "Reading vars from ${MAKEFILE_IN}...")
|
||||||
set (IfElse 0)
|
set (C_COMPILER ${CMAKE_C_COMPILER_ID})
|
||||||
set (ElseSeen 0)
|
set (IfElse 0)
|
||||||
|
set (ElseSeen 0)
|
||||||
|
set (SkipIfs 0)
|
||||||
|
set (SkipElse 0)
|
||||||
file(STRINGS ${MAKEFILE_IN} makefile_contents)
|
file(STRINGS ${MAKEFILE_IN} makefile_contents)
|
||||||
foreach (makefile_line ${makefile_contents})
|
foreach (makefile_line ${makefile_contents})
|
||||||
#message(STATUS "parsing ${makefile_line}")
|
#message(STATUS "parsing ${makefile_line}")
|
||||||
if (${IfElse} GREATER 0)
|
# Skip the entire scope of the else statement given that the if statement that precedes it has the valid condition.
|
||||||
|
# The variable SkipIfs is used to identify which endif statement closes the scope of the else statement.
|
||||||
|
if (${SkipElse} EQUAL 1)
|
||||||
|
#message(STATUS "skipping ${makefile_line}")
|
||||||
|
string(REGEX MATCH "(ifeq|ifneq|ifdef|ifndef) .*$" line_match "${makefile_line}")
|
||||||
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
|
MATH(EXPR SkipIfs "${SkipIfs}+1")
|
||||||
|
endif ()
|
||||||
string(REGEX MATCH "endif[ \t]*" line_match "${makefile_line}")
|
string(REGEX MATCH "endif[ \t]*" line_match "${makefile_line}")
|
||||||
if (NOT "${line_match}" STREQUAL "")
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
# message(STATUS "ENDIF ${makefile_line}")
|
if (${SkipIfs} EQUAL 0)
|
||||||
set (IfElse 0)
|
set (SkipElse 0)
|
||||||
set (ElseSeen 0)
|
else ()
|
||||||
|
MATH(EXPR SkipIfs "${SkipIfs}-1")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
continue ()
|
||||||
|
endif ()
|
||||||
|
# The variable IfElse is greater than 0 if and only if the previously parsed line is an if statement.
|
||||||
|
if (${IfElse} GREATER 0)
|
||||||
|
# If the current scope is the one that has to be skipped, the if/endif/else statements
|
||||||
|
# along with it till the endif that closes the current scope have to be ignored as well.
|
||||||
|
string(REGEX MATCH "(ifeq|ifneq|ifdef|ifndef) .*$" line_match "${makefile_line}")
|
||||||
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
|
if ((${IfElse} EQUAL 2 AND ${ElseSeen} EQUAL 0) OR (${IfElse} EQUAL 1 AND ${ElseSeen} EQUAL 1))
|
||||||
|
#message(STATUS "skipping ${makefile_line}")
|
||||||
|
MATH(EXPR SkipIfs "${SkipIfs}+1")
|
||||||
|
continue ()
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
string(REGEX MATCH "endif[ \t]*" line_match "${makefile_line}")
|
||||||
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
|
if (${SkipIfs} EQUAL 0)
|
||||||
|
#message(STATUS "ENDIF ${makefile_line}")
|
||||||
|
set (IfElse 0)
|
||||||
|
set (ElseSeen 0)
|
||||||
|
else ()
|
||||||
|
#message(STATUS "skipping ${makefile_line}")
|
||||||
|
MATH(EXPR SkipIfs "${SkipIfs}-1")
|
||||||
|
endif ()
|
||||||
continue ()
|
continue ()
|
||||||
endif ()
|
endif ()
|
||||||
string(REGEX MATCH "else[ \t]*" line_match "${makefile_line}")
|
string(REGEX MATCH "else[ \t]*" line_match "${makefile_line}")
|
||||||
if (NOT "${line_match}" STREQUAL "")
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
# message(STATUS "ELSE ${makefile_line}")
|
if (${SkipIfs} EQUAL 0)
|
||||||
set (ElseSeen 1)
|
#message(STATUS "ELSE ${makefile_line}")
|
||||||
continue ()
|
set (ElseSeen 1)
|
||||||
endif()
|
else ()
|
||||||
if ( (${IfElse} EQUAL 2 AND ${ElseSeen} EQUAL 0) OR ( ${IfElse} EQUAL 1 AND ${ElseSeen} EQUAL 1))
|
#message(STATUS "skipping ${makefile_line}")
|
||||||
# message(STATUS "skipping ${makefile_line}")
|
endif ()
|
||||||
continue ()
|
continue ()
|
||||||
|
endif()
|
||||||
|
# Skip the lines that are not part of the path that has to be taken.
|
||||||
|
if ((${IfElse} EQUAL 2 AND ${ElseSeen} EQUAL 0) OR (${IfElse} EQUAL 1 AND ${ElseSeen} EQUAL 1) OR (${SkipIfs} GREATER 0))
|
||||||
|
#message(STATUS "skipping ${makefile_line}")
|
||||||
|
continue ()
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
# Skip commented lines (the ones that start with '#')
|
||||||
|
string(REGEX MATCH "[ \t]*\\#.*$" line_match "${makefile_line}")
|
||||||
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
|
#message(STATUS "skipping ${makefile_line}")
|
||||||
|
continue ()
|
||||||
|
endif ()
|
||||||
string(REGEX MATCH "([0-9_a-zA-Z]+)[ \t]*=[ \t]*(.+)$" line_match "${makefile_line}")
|
string(REGEX MATCH "([0-9_a-zA-Z]+)[ \t]*=[ \t]*(.+)$" line_match "${makefile_line}")
|
||||||
if (NOT "${line_match}" STREQUAL "")
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
#message(STATUS "match on ${line_match}")
|
#message(STATUS "match on ${line_match}")
|
||||||
set(var_name ${CMAKE_MATCH_1})
|
set(var_name ${CMAKE_MATCH_1})
|
||||||
# set(var_value ${CMAKE_MATCH_2})
|
#set(var_value ${CMAKE_MATCH_2})
|
||||||
string(STRIP ${CMAKE_MATCH_2} var_value)
|
string(STRIP ${CMAKE_MATCH_2} var_value)
|
||||||
# check for Makefile variables in the string, e.g. $(TSUFFIX)
|
# check for Makefile variables in the string, e.g. $(TSUFFIX)
|
||||||
string(REGEX MATCHALL "\\$\\(([0-9_a-zA-Z]+)\\)" make_var_matches ${var_value})
|
string(REGEX MATCHALL "\\$\\(([0-9_a-zA-Z]+)\\)" make_var_matches ${var_value})
|
||||||
|
@ -54,39 +102,93 @@ macro(ParseMakefileVars MAKEFILE_IN)
|
||||||
string(REPLACE "$(${make_var})" "${${make_var}}" var_value ${var_value})
|
string(REPLACE "$(${make_var})" "${${make_var}}" var_value ${var_value})
|
||||||
endforeach ()
|
endforeach ()
|
||||||
set(${var_name} ${var_value})
|
set(${var_name} ${var_value})
|
||||||
else ()
|
continue ()
|
||||||
string(REGEX MATCH "include \\$\\(KERNELDIR\\)/(.+)$" line_match "${makefile_line}")
|
endif ()
|
||||||
if (NOT "${line_match}" STREQUAL "")
|
# Include a new file to be parsed
|
||||||
#message(STATUS "match on include ${line_match}")
|
string(REGEX MATCH "include \\$\\(KERNELDIR\\)/(.+)$" line_match "${makefile_line}")
|
||||||
ParseMakefileVars(${KERNELDIR}/${CMAKE_MATCH_1})
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
else ()
|
#message(STATUS "match on include ${line_match}")
|
||||||
# message(STATUS "unmatched line ${line_match}")
|
ParseMakefileVars(${KERNELDIR}/${CMAKE_MATCH_1})
|
||||||
string(REGEX MATCH "ifeq \\(\\$\\(([_A-Z]+)\\),[ \t]*([0-9_A-Z]+)\\)" line_match "${makefile_line}")
|
continue ()
|
||||||
if (NOT "${line_match}" STREQUAL "")
|
endif ()
|
||||||
# message(STATUS "IFEQ: ${line_match} first: ${CMAKE_MATCH_1} second: ${CMAKE_MATCH_2}")
|
# The if statement that precedes this else has the path taken
|
||||||
if (DEFINED ${${CMAKE_MATCH_1}} AND ${${CMAKE_MATCH_1}} STREQUAL ${CMAKE_MATCH_2})
|
# Thus, this else statement has to be skipped.
|
||||||
# message (STATUS "condition is true")
|
string(REGEX MATCH "else[ \t]*" line_match "${makefile_line}")
|
||||||
set (IfElse 1)
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
else ()
|
#message(STATUS "skipping ${makefile_line}")
|
||||||
set (IfElse 2)
|
set (SkipElse 1)
|
||||||
endif ()
|
continue()
|
||||||
|
endif()
|
||||||
|
# Example 1: ifdef HAVE_MSA
|
||||||
|
# Example 2: ifndef ZNRM2KERNEL
|
||||||
|
string(REGEX MATCH "(ifdef|ifndef) ([0-9_A-Z]+)" line_match "${makefile_line}")
|
||||||
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
|
#message(STATUS "${CMAKE_MATCH_1} first: ${CMAKE_MATCH_2}")
|
||||||
|
set (ElseSeen 0)
|
||||||
|
if (DEFINED ${CMAKE_MATCH_2})
|
||||||
|
if (${CMAKE_MATCH_1} STREQUAL "ifdef")
|
||||||
|
#message (STATUS "condition is true")
|
||||||
|
set (IfElse 1)
|
||||||
else ()
|
else ()
|
||||||
string(REGEX MATCH "ifneq \\(\\$\\(([_A-Z]+)\\),[ \t]*([0-9_A-Z]+)\\)" line_match "${makefile_line}")
|
set (IfElse 2)
|
||||||
if (NOT "${line_match}" STREQUAL "")
|
endif ()
|
||||||
# message(STATUS "IFNEQ: ${line_match} first: ${CMAKE_MATCH_1} second: ${CMAKE_MATCH_2}")
|
else ()
|
||||||
if ( ${CMAKE_MATCH_1} STREQUAL C_COMPILER)
|
if (${CMAKE_MATCH_1} STREQUAL "ifdef")
|
||||||
set (CMAKE_MATCH_1 CMAKE_C_COMPILER)
|
set (IfElse 2)
|
||||||
endif ()
|
else ()
|
||||||
if (NOT ( ${${CMAKE_MATCH_1}} STREQUAL ${CMAKE_MATCH_2}))
|
#message (STATUS "condition is true")
|
||||||
# message (STATUS "condition is true")
|
set (IfElse 1)
|
||||||
set (IfElse 1)
|
|
||||||
else ()
|
|
||||||
set (IfElse 2)
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
continue ()
|
||||||
endif ()
|
endif ()
|
||||||
|
# Example 1: ifeq ($(SGEMM_UNROLL_M), 16)
|
||||||
|
# Example 2: ifeq ($(SGEMM_UNROLL_M)x$(SGEMM_UNROLL_N), 8x8)
|
||||||
|
# Example 3: ifeq ($(__BYTE_ORDER__)$(ELF_VERSION),__ORDER_BIG_ENDIAN__2)
|
||||||
|
# Ignore the second group since (?:...) does not work on cmake
|
||||||
|
string(REGEX MATCH "ifeq \\(\\$\\(([0-9_A-Z]+)\\)(([0-9_A-Za-z]*)\\$\\(([0-9_A-Z]+)\\))?,[ \t]*([0-9_A-Za-z]+)\\)" line_match "${makefile_line}")
|
||||||
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
|
#message(STATUS "IFEQ: ${line_match} first: ${CMAKE_MATCH_1} second: ${CMAKE_MATCH_3} third: ${CMAKE_MATCH_4} fourth: ${CMAKE_MATCH_5}")
|
||||||
|
if (DEFINED ${CMAKE_MATCH_1})
|
||||||
|
if (DEFINED ${CMAKE_MATCH_4})
|
||||||
|
set (STR ${${CMAKE_MATCH_1}}${CMAKE_MATCH_3}${${CMAKE_MATCH_4}})
|
||||||
|
else ()
|
||||||
|
set (STR ${${CMAKE_MATCH_1}})
|
||||||
|
endif ()
|
||||||
|
if (${STR} STREQUAL ${CMAKE_MATCH_5})
|
||||||
|
#message (STATUS "condition is true")
|
||||||
|
set (IfElse 1)
|
||||||
|
continue ()
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
set (IfElse 2)
|
||||||
|
continue ()
|
||||||
|
endif ()
|
||||||
|
# Example 1 (Group 3): ifneq ($(SGEMM_UNROLL_M), $(SGEMM_UNROLL_N))
|
||||||
|
# Example 2 (Group 4): ifneq ($(C_COMPILER), PGI)
|
||||||
|
string(REGEX MATCH "ifneq \\(\\$\\(([0-9_A-Z]+)\\),[ \t]*(\\$\\(([0-9_A-Z]+)\\)|([0-9_A-Z]+))\\)" line_match "${makefile_line}")
|
||||||
|
if (NOT "${line_match}" STREQUAL "")
|
||||||
|
#message(STATUS "IFNEQ: ${line_match} first: ${CMAKE_MATCH_1} second: ${CMAKE_MATCH_3} third: ${CMAKE_MATCH_4}")
|
||||||
|
set (ElseSeen 0)
|
||||||
|
set (HasValidGroup 0)
|
||||||
|
if (DEFINED ${CMAKE_MATCH_3})
|
||||||
|
set (HasValidGroup 1)
|
||||||
|
set (STR ${${CMAKE_MATCH_3}})
|
||||||
|
elseif (NOT ${CMAKE_MATCH_4} STREQUAL "")
|
||||||
|
set (HasValidGroup 1)
|
||||||
|
set (STR ${CMAKE_MATCH_4})
|
||||||
|
endif ()
|
||||||
|
if (DEFINED ${CMAKE_MATCH_1} AND ${HasValidGroup} EQUAL 1)
|
||||||
|
if (NOT (${${CMAKE_MATCH_1}} STREQUAL ${STR}))
|
||||||
|
#message (STATUS "condition is true")
|
||||||
|
set (IfElse 1)
|
||||||
|
continue ()
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
set (IfElse 2)
|
||||||
|
continue ()
|
||||||
|
endif ()
|
||||||
|
#message(STATUS "unmatched line ${line_match}")
|
||||||
endforeach ()
|
endforeach ()
|
||||||
endmacro ()
|
endmacro ()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue