9
9
import utils
10
10
import rtconfig
11
11
from utils import _make_path_relative
12
+ from collections import defaultdict
12
13
13
14
14
- def GenerateCFiles (env ,project ):
15
+ def GenerateCFiles (env , project , project_name ):
15
16
"""
16
17
Generate CMakeLists.txt files
17
18
"""
18
19
info = utils .ProjectInfo (env )
20
+
21
+ PROJECT_NAME = project_name if project_name != "project" else "rtthread"
19
22
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 )
21
27
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 )
28
32
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 )
32
36
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" ]
34
48
35
49
CFLAGS = rtconfig .CFLAGS .replace ('\\ ' , "/" ).replace ('\" ' , "\\ \" " )
36
50
if 'CXXFLAGS' in dir (rtconfig ):
@@ -39,6 +53,27 @@ def GenerateCFiles(env,project):
39
53
CXXFLAGS = CFLAGS
40
54
AFLAGS = rtconfig .AFLAGS .replace ('\\ ' , "/" ).replace ('\" ' , "\\ \" " )
41
55
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 )
42
77
43
78
if "win32" in sys .platform :
44
79
CC += ".exe"
@@ -58,8 +93,7 @@ def GenerateCFiles(env,project):
58
93
print ("'Cannot found toolchain directory, please check RTT_CC and RTT_EXEC_PATH'" )
59
94
sys .exit (- 1 )
60
95
61
- cm_file = open ('CMakeLists.txt' , 'w' )
62
- if cm_file :
96
+ with open ("CMakeLists.txt" , "w" ) as cm_file :
63
97
cm_file .write ("CMAKE_MINIMUM_REQUIRED(VERSION 3.10)\n \n " )
64
98
65
99
cm_file .write ("SET(CMAKE_SYSTEM_NAME Generic)\n " )
@@ -100,11 +134,31 @@ def GenerateCFiles(env,project):
100
134
LINKER_LIBS += ' ' + f .replace ("\\ " , "/" ) + '.lib'
101
135
cm_file .write ("SET(CMAKE_EXE_LINKER_FLAGS \" " + re .sub (LINKER_FLAGS + '(\s*)' , LINKER_FLAGS + ' ${CMAKE_SOURCE_DIR}/' , LFLAGS ) + LINKER_LIBS + "\" )\n \n " )
102
136
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 ()])
106
144
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 ' )
108
162
109
163
cm_file .write ("INCLUDE_DIRECTORIES(\n " )
110
164
for i in info ['CPPPATH' ]:
@@ -141,19 +195,27 @@ def GenerateCFiles(env,project):
141
195
cm_file .write ( "\t " + "{}\n " .format (f .replace ("\\ " , "/" )))
142
196
cm_file .write (")\n \n " )
143
197
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 )
151
213
152
214
return
153
215
154
- def CMakeProject (env ,project ):
216
+ def CMakeProject (env , project , project_name ):
155
217
print ('Update setting files for CMakeLists.txt...' )
156
- GenerateCFiles (env ,project )
218
+ GenerateCFiles (env , project , project_name )
157
219
print ('Done!' )
158
220
159
221
return
0 commit comments