| @@ -15,35 +15,83 @@ endfunction () | |||
| # Reads a Makefile into CMake vars. | |||
| macro(ParseMakefileVars MAKEFILE_IN) | |||
| message(STATUS "Reading vars from ${MAKEFILE_IN}...") | |||
| set (IfElse 0) | |||
| set (ElseSeen 0) | |||
| set (C_COMPILER ${CMAKE_C_COMPILER_ID}) | |||
| set (IfElse 0) | |||
| set (ElseSeen 0) | |||
| set (SkipIfs 0) | |||
| set (SkipElse 0) | |||
| file(STRINGS ${MAKEFILE_IN} makefile_contents) | |||
| foreach (makefile_line ${makefile_contents}) | |||
| #message(STATUS "parsing ${makefile_line}") | |||
| #message(STATUS "parsing ${makefile_line}") | |||
| # 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}") | |||
| if (NOT "${line_match}" STREQUAL "") | |||
| if (${SkipIfs} EQUAL 0) | |||
| set (SkipElse 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 "") | |||
| # message(STATUS "ENDIF ${makefile_line}") | |||
| set (IfElse 0) | |||
| set (ElseSeen 0) | |||
| 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 () | |||
| endif () | |||
| string(REGEX MATCH "else[ \t]*" line_match "${makefile_line}") | |||
| if (NOT "${line_match}" STREQUAL "") | |||
| # message(STATUS "ELSE ${makefile_line}") | |||
| set (ElseSeen 1) | |||
| continue () | |||
| endif() | |||
| if ( (${IfElse} EQUAL 2 AND ${ElseSeen} EQUAL 0) OR ( ${IfElse} EQUAL 1 AND ${ElseSeen} EQUAL 1)) | |||
| # message(STATUS "skipping ${makefile_line}") | |||
| continue () | |||
| if (NOT "${line_match}" STREQUAL "") | |||
| if (${SkipIfs} EQUAL 0) | |||
| #message(STATUS "ELSE ${makefile_line}") | |||
| set (ElseSeen 1) | |||
| else () | |||
| #message(STATUS "skipping ${makefile_line}") | |||
| endif () | |||
| 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 () | |||
| # 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}") | |||
| 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_value ${CMAKE_MATCH_2}) | |||
| #set(var_value ${CMAKE_MATCH_2}) | |||
| string(STRIP ${CMAKE_MATCH_2} var_value) | |||
| # check for Makefile variables in the string, e.g. $(TSUFFIX) | |||
| 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}) | |||
| endforeach () | |||
| set(${var_name} ${var_value}) | |||
| else () | |||
| string(REGEX MATCH "include \\$\\(KERNELDIR\\)/(.+)$" line_match "${makefile_line}") | |||
| if (NOT "${line_match}" STREQUAL "") | |||
| #message(STATUS "match on include ${line_match}") | |||
| ParseMakefileVars(${KERNELDIR}/${CMAKE_MATCH_1}) | |||
| continue () | |||
| endif () | |||
| # Include a new file to be parsed | |||
| string(REGEX MATCH "include \\$\\(KERNELDIR\\)/(.+)$" line_match "${makefile_line}") | |||
| if (NOT "${line_match}" STREQUAL "") | |||
| #message(STATUS "match on include ${line_match}") | |||
| ParseMakefileVars(${KERNELDIR}/${CMAKE_MATCH_1}) | |||
| continue () | |||
| endif () | |||
| # The if statement that precedes this else has the path taken | |||
| # Thus, this else statement has to be skipped. | |||
| string(REGEX MATCH "else[ \t]*" line_match "${makefile_line}") | |||
| if (NOT "${line_match}" STREQUAL "") | |||
| #message(STATUS "skipping ${makefile_line}") | |||
| set (SkipElse 1) | |||
| 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 () | |||
| set (IfElse 2) | |||
| endif () | |||
| else () | |||
| # message(STATUS "unmatched line ${line_match}") | |||
| string(REGEX MATCH "ifeq \\(\\$\\(([_A-Z]+)\\),[ \t]*([0-9_A-Z]+)\\)" line_match "${makefile_line}") | |||
| if (NOT "${line_match}" STREQUAL "") | |||
| # message(STATUS "IFEQ: ${line_match} first: ${CMAKE_MATCH_1} second: ${CMAKE_MATCH_2}") | |||
| if (DEFINED ${${CMAKE_MATCH_1}} AND ${${CMAKE_MATCH_1}} STREQUAL ${CMAKE_MATCH_2}) | |||
| # message (STATUS "condition is true") | |||
| set (IfElse 1) | |||
| else () | |||
| set (IfElse 2) | |||
| endif () | |||
| if (${CMAKE_MATCH_1} STREQUAL "ifdef") | |||
| set (IfElse 2) | |||
| else () | |||
| string(REGEX MATCH "ifneq \\(\\$\\(([_A-Z]+)\\),[ \t]*([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_2}") | |||
| if ( ${CMAKE_MATCH_1} STREQUAL C_COMPILER) | |||
| set (CMAKE_MATCH_1 CMAKE_C_COMPILER) | |||
| endif () | |||
| if (NOT ( ${${CMAKE_MATCH_1}} STREQUAL ${CMAKE_MATCH_2})) | |||
| # message (STATUS "condition is true") | |||
| set (IfElse 1) | |||
| else () | |||
| set (IfElse 2) | |||
| endif () | |||
| endif () | |||
| #message (STATUS "condition is true") | |||
| set (IfElse 1) | |||
| endif () | |||
| endif () | |||
| continue () | |||
| 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 () | |||
| endmacro () | |||