1@page page_scons SCons 2 3# Introduction to SCons 4 5SCons is an open source build system written in the Python language, similar to GNU Make. It uses a different approach than the usual Makefile, but instead uses SConstruct and SConscript files instead. These files are also Python scripts that can be written using standard Python syntax, so the Python standard library can be called in SConstruct, SConscript files for a variety of complex processing, not limited to the rules set by the Makefile. 6 7A detailed [SCons user manual](http://www.scons.org/doc/production/HTML/scons-user/index.html) can be found on the SCons website. This section describes the basic usage of SCons and how to use the SCons tool in RT-Thread. 8 9## What is Construction Tool 10 11A software construction tool is a piece of software that compiles source code into an executable binary program according to certain rules or instructions. This is the most basic and important feature of building tools. In fact, these are not the only functions of construction tools. Usually these rules have a certain syntax and are organized into files. These files are used to control the behavior of the build tool, and you can do other things besides software building. 12 13The most popular build tool today is GNU Make. Many well-known open source software, such as the Linux kernel, are built using Make. Make detects the organization and dependencies of the file by reading the Makefile and completes the commands specified in the Makefile. 14 15Due to historical reasons, the syntax of the Makefile is confusing, which is not conducive to beginners. In addition, it is not convenient to use Make on the Windows platform, you need to install the Cygwin environment. To overcome the shortcomings of Make, other build tools have been developed, such as CMake and SCons. 16 17## RT-Thread Construciton Tool 18 19RT-Thread was built using Make/Makefile in the earlier stage. Starting from 0.3.x, the RT-Thread development team gradually introduced the SCons build system. The only goal of introducing SCons is to get everyone out of the complex Makefile configuration, IDE configuration, and focus on RT-Thread function development. 20 21Some may doubt the difference between the build tools described here and the IDE. The IDE completes the build through the operation of the graphical interface. Most IDEs generate script files like Makefile or SConscript based on the source code added by the user, and call the tools like Make or SCons to build the source code. 22 23## Install SCons 24 25It needs to be installed on the PC host before using the SCons system because it is written in the Python language, so you need to install the Python runtime environment before using SCons. 26 27The Env configuration tool provided by RT-Thread comes with SCons and Python, so using SCons on Windows platforms does not require the installation of these two software. 28 29In Linux and BSD environments, Python should already be installed by default, which is also the Python environment of the 2.x version. At this time, you only need to install SCons. For example, in Ubuntu you can install SCons with the following command: 30 31`sudo apt-get install scons` 32 33# Basic Functions of SCons 34 35The RT-Thread build system supports multiple compilers, including ARM GCC, MDK, IAR, VisualStudio, and Visual DSP. The mainstream ARM Cortex M0, M3, M4 platforms, basically all support ARM GCC, MDK, IAR. Some BSPs may only support one compiler, and readers can read the currently supported compiler by reading the CROSS_TOOL option in rtconfig.py under the BSP directory. 36 37If it is a chip on the ARM platform, you can use the Env tool and enter the scons command to compile the BSP directly. At this time, the ARM GCC compiler is used by default because the Env tool comes with the ARM GCC compiler. Compile a BSP using the scons command as shown below, and the SCons will be based on this BSP. 38 39 40 41If the user wants to use another compiler that the BSP already supports to compile the project, or if the BSP is a non-ARM platform chip, then you can't compile the project directly with the scons command. You need to install the corresponding compiler yourself and specify the compiler path to use. Before compiling the project, you can use the following two commands in the Env command line interface to specify the compiler path for the MDK and the compiler path to MDK. 42 43```c 44set RTT_CC=keil 45set RTT_EXEC_PATH=C:/Keilv5 46``` 47 48## Commonly Used SCons Commands 49 50This section describes the SCons commands that are commonly used in RT-Thread. SCons not only completes basic compilation, but also generates MDK/IAR/VS projects. 51 52### scons 53 54Go to the BSP project directory to be compiled in the Env command line window, and then use this command to compile the project directly. If some source files are modified after executing the `scons` command, and the scons command is executed again, SCons will incrementally compile and compile only the modified source files and link them. 55 56 57`scons` can also be followed by a `-s` parameter, the command `scons -s`, which differs from the `scons` command in that it does not print specific internal commands. 58 59### scons -c 60 61Clear the compilation target. This command clears the temporary and target files generated when `scons` is executed. 62 63### scons --target=XXX 64 65If you use mdk/iar for project development, when you open or close some components, you need to use one of the following commands to regenerate the corresponding customized project, then compile and download in mdk/iar. 66 67```c 68scons --target=iar 69scons --target=mdk4 70scons --target=mdk5 71``` 72 73In the Env command line window, enter the BSP project directory to be compiled. After using the `scons --target=mdk5` command, a new MDK project file named project.uvprojx will be generated in the BSP directory. Double-click it to open and you can use MDK to compile and debug. Using the `scons --target=iar` command will generate a new IAR project file named project.eww. Users who are not used to SCons can use this method. If project.uvproj fails to open, please delete project.uvopt and rebuild the project. 74 75Under `bsp/simulator` directory , you can use the following command to generate a project for vs2012 or a project for vs2005. 76 77```c 78scons --target=vs2012 79Scons --target=vs2005 80``` 81 82If you provide template files for other IDE projects in the BSP directory, you can also use this command to generate corresponding new projects, such as ua, vs, cb, cdk. 83 84This command can also be followed by a `-s` parameter, such as the command `scons –target=mdk5 -s`, which does not print specific internal commands when executing this command. 85 86> To generate a MDK or IAR project file, the prerequisite is that there is a project template file in the BSP directory, and then the scons will add relevant source code, header file search path, compilation parameters, link parameters, etc. according to the template file. As for which chip this project is for, it is directly specified by this engineering template file. So in most cases, this template file is an empty project file that is used to assist SCons in generating project.uvprojx or project.eww. 87 88### scons -jN 89 90Multi-threaded compilation target, you can use this command to speed up compilation on multi-core computers. In general, a cpu core can support 2 threads. Use the `scons -j4` command on a dual-core machine. 91 92> If you just want to look at compilation errors or warnings, it's best not to use the -j parameter so that the error message won't be mixed with multiple files in parallel. 93 94### scons --dist 95 96Build a project framework. Using this command will generate the `dist` directory in the BSP directory, this is the directory structure of the development project, including RT-Thread source code and BSP related projects, irrelevant BSP folder and libcpu will be removed, and you can freely copy this work to any directory. 97 98### scons --verbose 99 100By default, output compiled with the scons command does not display compilation parameters as follows: 101 102```c 103D:\repository\rt-thread\bsp\stm32f10x>scons 104scons: Reading SConscript files ... 105scons: done reading SConscript files. 106scons: Building targets ... 107scons: building associated VariantDir targets: build 108CC build\applications\application.o 109CC build\applications\startup.o 110CC build\components\drivers\serial\serial.o 111... 112``` 113 114The effect of using the scons –verbose command is as follows: 115 116```c 117armcc -o build\src\mempool.o -c --device DARMSTM --apcs=interwork -ID:/Keil/ARM/ 118RV31/INC -g -O0 -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD -Iapplications -IF:\Projec 119t\git\rt-thread\applications -I. -IF:\Project\git\rt-thread -Idrivers -IF:\Proje 120ct\git\rt-thread\drivers -ILibraries\STM32F10x_StdPeriph_Driver\inc -IF:\Project 121\git\rt-thread\Libraries\STM32F10x_StdPeriph_Driver\inc -ILibraries\STM32_USB-FS 122-Device_Driver\inc -IF:\Project\git\rt-thread\Libraries\STM32_USB-FS-Device_Driv 123er\inc -ILibraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x -IF:\Project\git\rt-thre 124... 125``` 126 127# SCons Advanced 128 129SCons uses SConscript and SConstruct files to organize the source structure. Usually a project has only one SConstruct, but there will be multiple SConscripts. In general, an SConscript will be placed in each subdirectory where the source code is stored. 130 131In order to make RT-Thread better support multiple compilers and to easily adjust compilation parameters, RT-Thread creates a separate file for each BSP called `rtconfig.py`. So the following three files exist in every RT-Thread BSP directory: `rtconfig.py`, `SConstruct`, and `SConscript`, which control the compilation of the BSP. There is only one SConstruct file in a BSP, but there are multiple SConscript files. It can be said that the SConscript file is the main force of the organization source code. 132 133RT-Thread SConscript files are also present in most source folders. These files are "found" by the SConscript file in the BSP directory to add the source code corresponding to the macro defined in rtconfig.h to the compiler. The following article will take stm32f10x-HAL BSP as an example to explain how SCons builds the project. 134 135## SCons Build-In Functions 136 137If you want to add some of your own source code to the SCons build environment, you can usually create or modify an existing SConscript file. The SConscript file can control the addition of source files and can specify the group of files (similar to the concept of Groups in IDEs such as MDK/IAR). 138 139SCons provides a lot of built-in functions to help us quickly add source code, and with these simple Python statements we can add or remove source code to our project. The following is a brief introduction to some common functions. 140 141### GetCurrentDir() 142 143Get current directory. 144 145### Glob('\*.c') 146 147Get all C files in the current directory. Modify the value of the parameter to match the suffix to match all files of the current directory. 148 149### GetDepend(macro) 150 151This function is defined in the script file in the `tools` directory. It reads the configuration information from the rtconfig.h file with the macro name in rtconfig.h. This method (function) returns true if rtconfig.h has a macro turned on, otherwise it returns false. 152 153### Split(str) 154 155Split the string str into a list list. 156 157### DefineGroup(name, src, depend,**parameters) 158 159This is a method (function) of RT-Thread based on the SCons extension. DefineGroup is used to define a component. A component can be a directory (under a file or subdirectory) and a Group or folder in some subsequent IDE project files. 160 161Parameter description of `DefineGroup() ` : 162 163|**Parameter**|**D**escription | 164|-------|------------------------------------| 165| name | name of Group | 166| src | The files contained in the Group generally refer to C/C++ source files. For convenience, you can also use the Glob function to list the matching files in the directory where the SConscript file is located by using a wildcard. | 167| depend | The options that the Group depends on when compiling (for example, the FinSH component depends on the RT_USING_FINSH macro definition). The compile option generally refers to the RT_USING_xxx macro defined in rtconfig.h. When the corresponding macro is defined in the rtconfig.h configuration file, then this group will be added to the build environment for compilation. If the dependent macro is not defined in rtconfig.h, then this Group will not be added to compile. Similarly, when using scons to generate as an IDE project file, if the dependent macros are not defined, the corresponding Group will not appear in the project file. | 168| parameters | Configure other parameters, the values can be found in the table below. You do not need to configure all parameters in actual use. | 169 170parameters that could be added: 171 172|**P**arameter|**Description** | 173|------------|--------------------------------------------------| 174| CCFLAGS | source file compilation parameters | 175| CPPPATH | head file path | 176| CPPDEFINES | Link parameter | 177| LIBRARY | Include this parameter, the object file generated by the component will be packaged into a library file | 178 179### SConscript(dirs,variant_dir,duplicate) 180 181Read the new SConscript file, and the parameter description of the SConscript() function is as follows: 182 183|**Parameter** |**Description** | 184|-------------|---------------------------------------| 185| dirs | SConscript file path | 186| variant_dir | Specify the path to store the generated target file | 187| duiplicate | Set whether to copy or link the source file to variant_dir | 188 189# SConscript Examples 190 191Below we will use a few SConscript as an example to explain how to use the scons tool. 192 193## SConscript Example 1 194 195Let's start with the SConcript file in the stm32f10x-HAL BSP directory. This file manages all the other SConscript files under the BSP, as shown below. 196 197```c 198import os 199cwd = str(Dir('#')) 200objs = [] 201list = os.listdir(cwd) 202for d in list: 203 path = os.path.join(cwd, d) 204 if os.path.isfile(os.path.join(path, 'SConscript')): 205 objs = objs + SConscript(os.path.join(d, 'SConscript')) 206Return('objs') 207``` 208 209* `import os:` Importing the Python system programming os module, you can call the functions provided by the os module to process files and directories. 210 211* `cwd = str(Dir('#')):` Get the top-level directory of the project and assign it to the string variable cwd, which is the directory where the project's SConstruct is located, where it has the same effect as `cwd = GetCurrentDir()` . 212 213* `objs = []:` An empty list variable objs is defined. 214 215* `list = os.listdir(cwd):` Get all the subdirectories under the current directory and save them to the variable list. 216 217* This is followed by a python for loop that walks through all the subdirectories of the BSP and runs the SConscript files for those subdirectories. The specific operation is to take a subdirectory of the current directory, use `os.path.join(cwd,d)` to splicing into a complete path, and then determine whether there is a file named SConscript in this subdirectory. If it exists, execute `objs = objs + SConscript(os.path.join(d,'SConscript'))` . This sentence uses a built-in function `SConscript()` provided by SCons, which can read in a new SConscript file and add the source code specified in the SConscript file to the source compilation list objs. 218 219With this SConscript file, the source code required by the BSP project is added to the compilation list. 220 221## SConscript Example 2 222 223So what about stm32f10x-HAL BSP other SConcript files? Let's take a look at the SConcript file in the drivers directory, which will manage the source code under the drivers directory. The drivers directory is used to store the underlying driver code implemented by the driver framework provided by RT-Thread. 224 225```c 226Import('rtconfig') 227from building import * 228 229cwd = GetCurrentDir() 230 231# add the general drivers. 232src = Split(""" 233board.c 234stm32f1xx_it.c 235""") 236 237if GetDepend(['RT_USING_PIN']): 238 src += ['drv_gpio.c'] 239if GetDepend(['RT_USING_SERIAL']): 240 src += ['drv_usart.c'] 241if GetDepend(['RT_USING_SPI']): 242 src += ['drv_spi.c'] 243if GetDepend(['RT_USING_USB_DEVICE']): 244 src += ['drv_usb.c'] 245if GetDepend(['RT_USING_SDCARD']): 246 src += ['drv_sdcard.c'] 247 248if rtconfig.PLATFORM in ['gcc']: 249 src += ['gcc_startup.s'] 250 251CPPPATH = [cwd] 252 253group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) 254 255Return('group') 256 257``` 258 259* `Import('rtconfig'):` Import the rtconfig object, and the rtconfig.CROSS_TOOL used later is defined in this rtconfig module. 260 261* `from building import *:` All the contents of the building module are imported into the current module, and the DefineGroup used later is defined in this module. 262 263* `cwd = GetCurrentDir():` Get the current path and save it to the string variable cwd. 264 265The next line uses the `Split()` function to split a file string into a list, the effect of which is equivalent to 266 267`src = ['board.c','stm32f1xx_it.c']` 268 269Later, `if` judgement and `GetDepend ()` are used to check whether a macro in `rtconfig.h` is open or not, and if so, `src += [src_name]` is used to append the source code file to the list variable src. 270 271* `CPPPATH = [cwd]:` Save the current path to a list variable CPPPATH. 272 273The last line uses DefineGroup to create a group called Drivers, which corresponds to the grouping in the MDK or IAR. The source code file for this group is the file specified by src, and the dependency is empty to indicate that the group does not depend on any macros of rtconfig.h. 274 275`CPPPATH =CPPPATH` means to add the current path to the system's header file path. The CPPPATH on the left is a built-in parameter in the DefineGroup that represents the header file path. The CPPPATH on the right is defined in the previous line of this document. This way we can reference the header files in the drivers directory in other source code. 276 277## SConscript Example 3 278 279Let's take a look at the SConcript file in the applications directory, which will manage the source code under the applications directory for the user's own application code. 280 281```c 282from building import * 283 284cwd = GetCurrentDir() 285src = Glob('*.c') 286CPPPATH = [cwd, str(Dir('#'))] 287 288group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) 289 290Return('group') 291``` 292 293`src = Glob('*.c'):` Get all the C files in the current directory. 294 295`CPPPATH = [cwd, str(Dir('#'))]:` Save the current path and the path of the project's SConstruct to the list variable CPPPATH. 296 297The last line uses DefineGroup to create a group called `Applications`. The source code file for this group is the file specified by src. If the dependency is empty, the group does not depend on any rtconfig.h macros, and the path saved by CPPPATH is added to the system header search path. Such application directories and header files in the stm32f10x-HAL BSP directory can be referenced elsewhere in the source code. 298 299To sum up, this source program will add all c programs in the current directory to the group `Applications`, so if you add or delete files in this directory, you can add files to the project or delete them from the project. It is suitable for adding source files in batches. 300 301## SConscript Example 4 302 303Below is the contents of the RT-Thread source code `component/finsh/SConscript` file, which will manage the source code under the finsh directory. 304 305```c 306Import('rtconfig') 307from building import * 308 309cwd = GetCurrentDir() 310src = Split(''' 311shell.c 312symbol.c 313cmd.c 314''') 315 316fsh_src = Split(''' 317finsh_compiler.c 318finsh_error.c 319finsh_heap.c 320finsh_init.c 321finsh_node.c 322finsh_ops.c 323finsh_parser.c 324finsh_var.c 325finsh_vm.c 326finsh_token.c 327''') 328 329msh_src = Split(''' 330msh.c 331msh_cmd.c 332msh_file.c 333''') 334 335CPPPATH = [cwd] 336if rtconfig.PLATFORM in ['armcc', 'armclang']: 337 LINKFLAGS = '--keep *.o(FSymTab)' 338 339 if not GetDepend('FINSH_USING_MSH_ONLY'): 340 LINKFLAGS = LINKFLAGS + '--keep *.o(VSymTab)' 341else: 342 LINKFLAGS = '' 343 344if GetDepend('FINSH_USING_MSH'): 345 src = src + msh_src 346if not GetDepend('FINSH_USING_MSH_ONLY'): 347 src = src + fsh_src 348 349group = DefineGroup('finsh', src, depend = ['RT_USING_FINSH'], CPPPATH = CPPPATH, LINKFLAGS = LINKFLAGS) 350 351Return('group') 352``` 353 354Let's take a look at the contents of the first Python conditional statement in the file. If the compilation tool is keil, the variable `LINKFLAGS = '--keep *.o(FSymTab)'` left blank. 355 356DefinGroup also creates the file specified by src in the finsh directory as a finsh group. `depend = ['RT_USING_FINSH']` indicates that this group depends on the macro RT_USING_FINSH in `rtconfig.h`. When the macro RT_USING_FINSH is opened in rtconfig.h, the source code in the finsh group will be compiled, otherwise SCons will not compile. 357 358Then add the finsh directory to the system header directory so that we can reference the header files in the finsh directory in other source code. 359 360`LINKFLAGS = LINKFLAGS` has the same meaning as `CPPPATH = CPPPATH` . The LINKFLAGS on the left represents the link parameter, and the LINKFLAGS on the right is the value defined by the previous if else statement. That is, specify the link parameters for the project. 361 362# Manage Projects with SCons 363 364The previous section on the SConscript related to the RT-Thread source code is explained in detail, you should also know some common ways to write SConscript files, this section will guide you how to use SCons to manage your own projects. 365 366## Add App Code 367 368As mentioned earlier, the Applications folder under BSP is used to store the user's own application code. Currently there is only one main.c file. If the user's application code is not a lot, it is recommended that the relevant source files be placed under this folder. Two simple files hello.c and hello.h have been added under the Applications folder, as shown below. 369 370```c 371/* file: hello.h */ 372 373#ifndef _HELLO_H_ 374#define _HELLO_H_ 375 376int hello_world(void); 377 378#endif /* _HELLO_H_ */ 379 380/* file: hello.c */ 381#include <stdio.h> 382#include <finsh.h> 383#include <rtthread.h> 384 385int hello_world(void) 386{ 387 rt_kprintf("Hello, world!\n"); 388 389 return 0; 390} 391 392MSH_CMD_EXPORT(hello_world, Hello world!) 393``` 394 395The SConcript file in the applications directory will add all source files in the current directory to the project. You need to use the `scons --target=xxx` command to add the 2 new files to your project. Note that the project will be regenerated each time a new file is added. 396 397## Add Module 398 399As mentioned above, in the case that there are not many source code files, it is recommended that all source code files be placed in the applications folder. If the user has a lot of source code and wants to create your own project module, or need to use other modules that you have obtained, what would be appropriate? 400 401Take also hello.c and hello.h mentioned above for example, these two files will be managed in a separate folder, and have their own grouping in the MDK project file, and can be selected through menuconfig whether to use This module. Add a hello folder under BSP. 402 403 404 405Noticed that there is an additional SConscript file in the folder. If you want to add some of your own source code to the SCons build environment, you can usually create or modify an existing SConscript file. Refer to the above analysis of the SConscript file for the RT-Thread source code. The contents of this new hello module SConscript file are as follows: 406 407```c 408from building import * 409 410cwd = GetCurrentDir() 411include_path = [cwd] 412src = [] 413 414if GetDepend(['RT_USING_HELLO']): 415 src += ['hello.c'] 416 417group = DefineGroup('hello', src, depend = [''], CPPPATH = include_path) 418 419Return('group') 420``` 421 422Through the above simple lines of code, a new group hello is created, and the source file to be added to the group can be controlled by the macro definition, and the directory where the group is located is added to the system header file path. So how is the custom macro RT_USING_HELLO defined? Here is a new file called Kconfig. Kconfig is used to configure the kernel, and the configuration interface generated by the menuconfig command used when configuring the system with Env relies on the Kconfig file. The menuconfig command generates a configuration interface for the user to configure the kernel by reading the various Kconfig files of the project. Finally, all configuration-related macro definitions are automatically saved to the rtconfig.h file in the BSP directory. Each BSP has an rtconfig.h file. That is the configuration information of this BSP. 423 424There is already a Kconfig file for this BSP in the stm32f10x-HAL BSP directory, and we can add the configuration options we need based on this file. The following configuration options have been added to the hello module. The # sign is followed by a comment. 425 426```shell 427menu "hello module" # create a "hello module" menu 428 429 config RT_USING_HELLO # RT_USING_HELLO configuration options 430 bool "Enable hello module" # RT_USING_HELLO is a bool variable and display as "Enable hello module" 431 default y # RT_USING_HELLO can take values y and n, default y 432 help # If use help, it would display "this hello module only used for test" 433 this hello module only used for test 434 435 config RT_HELLO_NAME # RT_HELLO_NAME configuration options 436 string "hello name" # RT_HELLO_NAME is a string variable and the menu show as "hello name" 437 default "hello" # default name is "hello" 438 439 config RT_HELLO_VALUE # RT_HELLO_VALUE configuration options 440 int "hello value" # RT_HELLO_VALUE is an int variable and the menu show as "hello value" 441 default 8 # the default value is 8 442 443endmenu # the hello menu is end 444 445``` 446 447After entering the stm32f10x-HAL BSP directory using the Env tool, you can use the menuconfig command to see the configuration menu of the new hello module at the bottom of the main page. After entering the menu, the following figure is displayed. 448 449 450 451You can also modify the value of the hello value. 452 453 454 455After saving the configuration, exit the configuration interface and open the rtconfig.h file in the stm32f10x-HAL BSP directory. You can see that the configuration information of the hello module is available. 456 457 458 459**Note: Use the scons --target=XXX command to generate a new project each time menuconfig is configured.** 460 461Because the RT_USING_HELLO macro has been defined in rtconfig.h, the source file for hello.c is added to the new project when the project is newly built. 462 463The above simply enumerates the configuration options for adding your own modules to the Kconfig file. Users can also refer to @ref page_env, which also explains how to modify and add configuration options. They can also view the Kconfig documentation in your own Baidu to implement other more complex configuration options. 464 465## Add Library 466 467If you want to add an extra library to your project, you need to pay attention to the naming of the binary library by different toolchains. For example, the GCC toolchain, which recognizes library names such as `libabc.a`, specifies `abc` instead of `libabc` when specifying a library. So you need to pay special attention to the SConscript file when linking additional libraries. In addition, when specifying additional libraries, it is also a good idea to specify the corresponding library search path. Here is an example: 468 469```c 470Import('rtconfig') 471from building import * 472 473cwd = GetCurrentDir() 474src = Split(''' 475''') 476 477LIBPATH = [cwd + '/libs'] 478LIBS = ['abc'] 479 480group = DefineGroup('ABC', src, depend = [''], LIBS = LIBS, LIBPATH=LIBPATH) 481``` 482 483LIBPATH specifies the path to the library, and LIBS specifies the name of the library. If the toolchain is GCC, the name of the library should be libabc.a; if the toolchain is armcc, the name of the library should be abc.lib.`LIBPATH = [cwd + '/libs']` indicates that the search path for the library is the 'libs' directory in the current directory. 484 485## Compiler Options 486 487`rtconfig.py` is a RT-Thread standard compiler configuration file that controls most of the compilation options. It is a script file written in Python and is used to do the following: 488 489* Specify the compiler (choose one of the multiple compilers you support). 490- Specify compiler parameters such as compile options, link options, and more. 491 492When we compile the project using the scons command, the project is compiled according to the compiler configuration options of `rtconfig.py`. The following code is part of the rtconfig.py code in the stm32f10x-HAL BSP directory. 493 494```c 495import os 496 497# toolchains options 498ARCH='arm' 499CPU='cortex-m3' 500CROSS_TOOL='gcc' 501 502if os.getenv('RTT_CC'): 503 CROSS_TOOL = os.getenv('RTT_CC') 504 505# cross_tool provides the cross compiler 506# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR 507 508if CROSS_TOOL == 'gcc': 509 PLATFORM = 'gcc' 510 EXEC_PATH = '/usr/local/gcc-arm-none-eabi-5_4-2016q3/bin/' 511elif CROSS_TOOL == 'keil': 512 PLATFORM = 'armcc' 513 EXEC_PATH = 'C:/Keilv5' 514elif CROSS_TOOL == 'iar': 515 PLATFORM = 'iccarm' 516 EXEC_PATH = 'C:/Program Files/IAR Systems/Embedded Workbench 6.0 Evaluation' 517 518if os.getenv('RTT_EXEC_PATH'): 519 EXEC_PATH = os.getenv('RTT_EXEC_PATH') 520 521BUILD = 'debug' 522 523if PLATFORM == 'gcc': 524 # toolchains 525 PREFIX = 'arm-none-eabi-' 526 CC = PREFIX + 'gcc' 527 AS = PREFIX + 'gcc' 528 AR = PREFIX + 'ar' 529 LINK = PREFIX + 'gcc' 530 TARGET_EXT = 'elf' 531 SIZE = PREFIX + 'size' 532 OBJDUMP = PREFIX + 'objdump' 533 OBJCPY = PREFIX + 'objcopy' 534 535 DEVICE = '-mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections' 536 CFLAGS = DEVICE 537 AFLAGS = '-c' + DEVICE + '-x assembler-with-cpp' 538 LFLAGS = DEVICE + '-Wl,--gc-sections,-Map=rtthread-stm32.map,-cref,-u,Reset_Handler -T stm32_rom.ld' 539``` 540 541Where CFLAGS is the compile option for C files, AFLAGS is the compile option for assembly files, and LFLAGS is the link option. The BUILD variable controls the level of code optimization. The default BUILD variable takes the value 'debug', which is compiled using debug mode, with an optimization level of 0. If you modify this variable to something else, it will compile with optimization level 2. The following are all possible ways to write (in short, no 'debug'). 542 543```shell 544BUILD = '' 545BUILD = 'release' 546BUILD = 'hello, world' 547``` 548 549It is recommended to use the debug mode to compile during the development phase, without optimization, and then consider optimization after the product is stable. 550 551The specific meaning of these options needs to refer to the compiler manual, such as `armcc` used above is the underlying compiler of MDK. The meaning of its compile options is detailed in MDK help. 552 553As mentioned earlier, if the user wants to compile the project with another compiler when executing the scons command, you can use the relevant commands to specify the compiler and compiler paths on the command line side of Env. However, this modification is only valid for the current Env process. When you open it again, you need to re-use the command settings. We can directly modify the `rtconfig.py` file to achieve the purpose of permanently configuring the compiler. In general, we only need to modify the CROSS_TOOL and EXEC_PATH options below. 554 555* CROSS_TOOL:Specify the compiler. The optional values are keil, gcc, iar. Browse `rtconfig.py` to see the compilers supported by the current BSP. If MDK is installed on your machine, you can modify CROSS_TOOL to keil and use MDK to compile the project. 556 557* EXEC_PATH: The installation path of the compiler. There are two points to note here: 558 559(1) When installing the compiler (such as MDK, GNU GCC, IAR, etc.), do not install it in a path with Chinese or spaces. Otherwise, some errors will occur when parsing the path. Some programs are installed by default into the `C:\Program Files` directory with spaces in between. It is recommended to choose other paths during installation to develop good development habits. 560 561(2) When modifying EXEC_PATH, you need to pay attention to the format of the path. On Windows platforms, the default path splitter is the backslash `“\”`, which is used for escape characters in both C and Python. So when modifying the path, you can change `“\”` to `“/”`or add r (python-specific syntax for raw data). 562 563Suppose a compiler is installed under `D:\Dir1\Dir2`. The following are the correct ways to write: 564 565* EXEC_PATH = `r'D:\\Dir1\\Dir2'` Note that with the string `r` in front of the string, `“\”`can be used normally. 566 567* EXEC_PATH = `'D:/Dir1/Dir2'` Note that instead of `“/”`, there is no `r` in front. 568 569* EXEC_PATH = `'D:\\Dir1\\Dir2'` Note that the escapement of `“\”` s used here to escape `“\”` itself. 570 571* This is the wrong way to write: EXEC_PATH = `'D:\\Dir1\\Dir2'`。 572 573If the rtconfig.py file has the following code, comment out the following code when configuring your own compiler. 574 575```c 576if os.getenv('RTT_CC'): 577 CROSS_TOOL = os.getenv('RTT_CC') 578... ... 579if os.getenv('RTT_EXEC_PATH'): 580 EXEC_PATH = os.getenv('RTT_EXEC_PATH') 581``` 582 583The above 2 `if` judgments will set CROSS_TOOL and EXEC_PATH to the default value of Env. 584 585After the compiler is configured, we can use SCons to compile the BSP of RT-Thread. Open a command line window in the BSP directory and execute the `scons` command to start the compilation process. 586 587## RT-Thread Auxiliary Compilation Script 588 589In the tools directory of the RT-Thread source code, there are some auxiliary compiled scripts defined by RT-Thread, such as the project files for automatically generating RT-Thread for some IDE. The most important of these is the building.py script. 590 591## SCons Further Usage 592 593For a complex, large-scale system, it is obviously more than just a few files in a directory. It is probably a combination of several folders at the first level. 594 595In SCons, you can write SConscript script files to compile files in these relatively independent directories, and you can also use the Export and Import functions in SCons to share data between SConstruct and SConscript files (that is, an object data in Python). For more information on how to use SCons, please refer to the [SCons Official Documentation](https://scons.org/documentation.html). 596 597