| @@ -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 (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) | 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}") | |||||
| # 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 (${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}") | string(REGEX MATCH "endif[ \t]*" line_match "${makefile_line}") | ||||
| if (NOT "${line_match}" STREQUAL "") | 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 () | 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 "") | |||||
| # 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 () | |||||
| 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 () | |||||
| 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 () | 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 () | 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 () | ||||
| endif () | endif () | ||||
| set (IfElse 2) | |||||
| continue () | |||||
| endif () | endif () | ||||
| #message(STATUS "unmatched line ${line_match}") | |||||
| endforeach () | endforeach () | ||||
| endmacro () | endmacro () | ||||