99import utils
1010import rtconfig
1111from utils import _make_path_relative
12+ from collections import defaultdict
1213
1314
14- def GenerateCFiles (env ,project ):
15+ def GenerateCFiles (env , project , project_name ):
1516 """
1617 Generate CMakeLists.txt files
1718 """
1819 info = utils .ProjectInfo (env )
20+
21+ PROJECT_NAME = project_name if project_name != "project" else "rtthread"
1922
20- CC = os .path .join (rtconfig .EXEC_PATH , rtconfig .CC ).replace ('\\ ' , "/" )
23+ tool_path_conv = defaultdict (lambda : {"name" :"" , "path" : "" })
24+ tool_path_conv_helper = lambda tool : {"name" : tool , "path" : os .path .join (rtconfig .EXEC_PATH , tool ).replace ('\\ ' , "/" )}
25+
26+ tool_path_conv ["CMAKE_C_COMPILER" ] = tool_path_conv_helper (rtconfig .CC )
2127 if 'CXX' in dir (rtconfig ):
22- CXX = os .path .join (rtconfig .EXEC_PATH , rtconfig .CXX ).replace ('\\ ' , "/" )
23- else :
24- CXX = ''
25- AS = os .path .join (rtconfig .EXEC_PATH , rtconfig .AS ).replace ('\\ ' , "/" )
26- AR = os .path .join (rtconfig .EXEC_PATH , rtconfig .AR ).replace ('\\ ' , "/" )
27- LINK = os .path .join (rtconfig .EXEC_PATH , rtconfig .LINK ).replace ('\\ ' , "/" )
28+ tool_path_conv ["CMAKE_CXX_COMPILER" ] = tool_path_conv_helper (rtconfig .CXX )
29+ tool_path_conv ["CMAKE_ASM_COMPILER" ] = tool_path_conv_helper (rtconfig .AS )
30+ tool_path_conv ["CMAKE_AR" ] = tool_path_conv_helper (rtconfig .AR )
31+ tool_path_conv ["CMAKE_LINKER" ] = tool_path_conv_helper (rtconfig .LINK )
2832 if rtconfig .PLATFORM in ['gcc' ]:
29- SIZE = os . path . join (rtconfig .EXEC_PATH , rtconfig . SIZE ). replace ( ' \\ ' , "/" )
30- OBJDUMP = os . path . join (rtconfig .EXEC_PATH , rtconfig . OBJDUMP ). replace ( ' \\ ' , "/" )
31- OBJCOPY = os . path . join (rtconfig .EXEC_PATH , rtconfig . OBJCPY ). replace ( ' \\ ' , "/" )
33+ tool_path_conv [ "CMAKE_SIZE" ] = tool_path_conv_helper (rtconfig .SIZE )
34+ tool_path_conv [ "CMAKE_OBJDUMP" ] = tool_path_conv_helper (rtconfig .OBJDUMP )
35+ tool_path_conv [ "CMAKE_OBJCOPY" ] = tool_path_conv_helper (rtconfig .OBJCPY )
3236 elif rtconfig .PLATFORM in ['armcc' , 'armclang' ]:
33- FROMELF = os .path .join (rtconfig .EXEC_PATH , 'fromelf' ).replace ('\\ ' , "/" )
37+ tool_path_conv ["CMAKE_FROMELF" ] = tool_path_conv_helper (rtconfig .FROMELF )
38+
39+ CC = tool_path_conv ["CMAKE_C_COMPILER" ]["path" ]
40+ CXX = tool_path_conv ["CMAKE_CXX_COMPILER" ]["path" ]
41+ AS = tool_path_conv ["CMAKE_ASM_COMPILER" ]["path" ]
42+ AR = tool_path_conv ["CMAKE_AR" ]["path" ]
43+ LINK = tool_path_conv ["CMAKE_LINKER" ]["path" ]
44+ SIZE = tool_path_conv ["CMAKE_SIZE" ]["path" ]
45+ OBJDUMP = tool_path_conv ["CMAKE_OBJDUMP" ]["path" ]
46+ OBJCOPY = tool_path_conv ["CMAKE_OBJCOPY" ]["path" ]
47+ FROMELF = tool_path_conv ["CMAKE_FROMELF" ]["path" ]
3448
3549 CFLAGS = rtconfig .CFLAGS .replace ('\\ ' , "/" ).replace ('\" ' , "\\ \" " )
3650 if 'CXXFLAGS' in dir (rtconfig ):
@@ -39,6 +53,27 @@ def GenerateCFiles(env,project):
3953 CXXFLAGS = CFLAGS
4054 AFLAGS = rtconfig .AFLAGS .replace ('\\ ' , "/" ).replace ('\" ' , "\\ \" " )
4155 LFLAGS = env ['LINKFLAGS' ].replace ('\\ ' , "/" ).replace ('\" ' , "\\ \" " )
56+
57+ POST_ACTION = rtconfig .POST_ACTION
58+ # replace the tool name with the cmake variable
59+ for cmake_var , each_tool in tool_path_conv .items ():
60+ tool_name = each_tool ['name' ]
61+ if tool_name == "" : continue
62+ if "win32" in sys .platform :
63+ while f"{ tool_name } .exe" in POST_ACTION : # find the tool with `.exe` suffix first
64+ POST_ACTION = POST_ACTION .replace (tool_name , "string_to_replace" )
65+ while tool_name in POST_ACTION :
66+ POST_ACTION = POST_ACTION .replace (tool_name , "string_to_replace" )
67+ while "string_to_replace" in POST_ACTION :
68+ POST_ACTION = POST_ACTION .replace ("string_to_replace" , f"${{{ cmake_var } }}" )
69+ # replace the `$TARGET` with `${CMAKE_PROJECT_NAME}.elf`
70+ while "$TARGET" in POST_ACTION :
71+ POST_ACTION = POST_ACTION .replace ("$TARGET" , "${CMAKE_PROJECT_NAME}.elf" )
72+ # add COMMAAND before each command
73+ POST_ACTION = POST_ACTION .split ('\n ' )
74+ POST_ACTION = [each_line .strip () for each_line in POST_ACTION ]
75+ POST_ACTION = [f"\t COMMAND { each_line } " for each_line in POST_ACTION if each_line != '' ]
76+ POST_ACTION = "\n " .join (POST_ACTION )
4277
4378 if "win32" in sys .platform :
4479 CC += ".exe"
@@ -58,8 +93,7 @@ def GenerateCFiles(env,project):
5893 print ("'Cannot found toolchain directory, please check RTT_CC and RTT_EXEC_PATH'" )
5994 sys .exit (- 1 )
6095
61- cm_file = open ('CMakeLists.txt' , 'w' )
62- if cm_file :
96+ with open ("CMakeLists.txt" , "w" ) as cm_file :
6397 cm_file .write ("CMAKE_MINIMUM_REQUIRED(VERSION 3.10)\n \n " )
6498
6599 cm_file .write ("SET(CMAKE_SYSTEM_NAME Generic)\n " )
@@ -100,11 +134,31 @@ def GenerateCFiles(env,project):
100134 LINKER_LIBS += ' ' + f .replace ("\\ " , "/" ) + '.lib'
101135 cm_file .write ("SET(CMAKE_EXE_LINKER_FLAGS \" " + re .sub (LINKER_FLAGS + '(\s*)' , LINKER_FLAGS + ' ${CMAKE_SOURCE_DIR}/' , LFLAGS ) + LINKER_LIBS + "\" )\n \n " )
102136
103- if CXX != '' :
104- cm_file .write ("SET(CMAKE_CXX_STANDARD 14)\n " )
105- cm_file .write ("PROJECT(rtthread C CXX ASM)\n " )
137+ # get the c/cpp standard version from compilation flags
138+ # not support the version with alphabet in `-std` param yet
139+ pattern = re .compile ('-std=[\w+]+' )
140+ c_standard = 11
141+ if '-std=' in CFLAGS :
142+ c_standard = re .search (pattern , CFLAGS ).group (0 )
143+ c_standard = "" .join ([each for each in c_standard if each .isdigit ()])
106144 else :
107- cm_file .write ("PROJECT(rtthread C ASM)\n " )
145+ print (f"Cannot find the param of the c standard in build flag, set to default { c_standard } " )
146+ cm_file .write (f"SET(CMAKE_C_STANDARD { c_standard } )\n " )
147+
148+ if CXX != '' :
149+ cpp_standard = 17
150+ if '-std=' in CXXFLAGS :
151+ cpp_standard = re .search (pattern , CXXFLAGS ).group (0 )
152+ cpp_standard = "" .join ([each for each in cpp_standard if each .isdigit ()])
153+ else :
154+ print (f"Cannot find the param of the cpp standard in build flag, set to default { cpp_standard } " )
155+ cm_file .write (f"SET(CMAKE_CXX_STANDARD { cpp_standard } )\n " )
156+
157+ cm_file .write ('\n ' )
158+
159+ cm_file .write (f"PROJECT({ PROJECT_NAME } C { 'CXX' if CXX != '' else '' } ASM)\n " )
160+
161+ cm_file .write ('\n ' )
108162
109163 cm_file .write ("INCLUDE_DIRECTORIES(\n " )
110164 for i in info ['CPPPATH' ]:
@@ -141,19 +195,27 @@ def GenerateCFiles(env,project):
141195 cm_file .write ( "\t " + "{}\n " .format (f .replace ("\\ " , "/" )))
142196 cm_file .write (")\n \n " )
143197
144- cm_file .write ("ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}.elf ${PROJECT_SOURCES})\n " )
145- cm_file .write ("ADD_CUSTOM_COMMAND(TARGET ${CMAKE_PROJECT_NAME}.elf POST_BUILD \n COMMAND ${CMAKE_OBJCOPY} -O binary ${CMAKE_PROJECT_NAME}.elf ${CMAKE_PROJECT_NAME}.bin COMMAND ${CMAKE_SIZE} ${CMAKE_PROJECT_NAME}.elf)" )
146- elif rtconfig .PLATFORM in ['armcc' , 'armclang' ]:
147- cm_file .write ("ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${PROJECT_SOURCES})\n " )
148- cm_file .write ("ADD_CUSTOM_COMMAND(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD \n COMMAND ${CMAKE_FROMELF} --bin ${CMAKE_PROJECT_NAME}.elf --output ${CMAKE_PROJECT_NAME}.bin COMMAND ${CMAKE_FROMELF} -z ${CMAKE_PROJECT_NAME}.elf)" )
149-
150- cm_file .close ()
198+ cm_file .write ("ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}.elf ${PROJECT_SOURCES})\n " )
199+ cm_file .write ("ADD_CUSTOM_COMMAND(TARGET ${CMAKE_PROJECT_NAME}.elf POST_BUILD \n " + POST_ACTION + '\n )\n ' )
200+
201+ # auto inclue `custom.cmake` for user custom settings
202+ custom_cmake = \
203+ '''
204+ # if custom.cmake is exist, add it
205+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/custom.cmake)
206+ include(${CMAKE_CURRENT_SOURCE_DIR}/custom.cmake)
207+ endif()
208+ '''
209+ custom_cmake = custom_cmake .split ('\n ' )
210+ custom_cmake = [each .strip () for each in custom_cmake ]
211+ custom_cmake = "\n " .join (custom_cmake )
212+ cm_file .write (custom_cmake )
151213
152214 return
153215
154- def CMakeProject (env ,project ):
216+ def CMakeProject (env , project , project_name ):
155217 print ('Update setting files for CMakeLists.txt...' )
156- GenerateCFiles (env ,project )
218+ GenerateCFiles (env , project , project_name )
157219 print ('Done!' )
158220
159221 return
0 commit comments