CMake on STM32 | Episode 5: additional clean files
Tags: embedded, cpp, microcontrollers, cmake
Published: 2020-05-02 15:54:45

In this episode, we will see that some files generated during the build are not deleted during the clean process and we will solve this issue with CMake of corse.

## What is cleaned?

Once the build is done, we can have a look at the content of the output directory:

```bash
λ pwd
D:\cmake_stm32\cmake-build-debug

λ cmake --build .
...
[ 76%] Building C object CMakeFiles/nucleo-f413zh.out.dir/BSP/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c.obj
[ 80%] Building C object CMakeFiles/nucleo-f413zh.out.dir/BSP/Src/main.c.obj
[ 84%] Building C object CMakeFiles/nucleo-f413zh.out.dir/BSP/Src/stm32f4xx_hal_msp.c.obj
[ 88%] Building C object CMakeFiles/nucleo-f413zh.out.dir/BSP/Src/stm32f4xx_it.c.obj
[ 92%] Building C object CMakeFiles/nucleo-f413zh.out.dir/BSP/Src/system_stm32f4xx.c.obj
[ 96%] Building ASM object CMakeFiles/nucleo-f413zh.out.dir/BSP/startup_stm32f413xx.s.obj
[100%] Linking C executable nucleo-f413zh.out
   text    data     bss     dec     hex filename
   7564      20    2668   10252    280c nucleo-f413zh.out
mingw32-make[2]: Leaving directory 'D:/cmake_stm32/cmake-build-debug'
[100%] Built target nucleo-f413zh.out
mingw32-make[1]: Leaving directory 'D:/cmake_stm32/cmake-build-debug'

λ ls -l
total 632
-rw-r--r-- 1 z19100018 1049089   1427 avr.  29 12:17 cmake_install.cmake
-rw-r--r-- 1 z19100018 1049089  53118 mai    1 12:26 CMakeCache.txt
drwxr-xr-x 1 z19100018 1049089      0 mai    2 15:13 CMakeFiles/
-rw-r--r-- 1 z19100018 1049089  42893 mai    1 12:42 Makefile
-rw-r--r-- 1 z19100018 1049089   7584 mai    2 15:13 nucleo-f413zh.bin
-rw-r--r-- 1 z19100018 1049089  11154 mai    1 12:42 nucleo-f413zh.cbp
-rw-r--r-- 1 z19100018 1049089  21433 mai    2 15:13 nucleo-f413zh.hex
-rw-r--r-- 1 z19100018 1049089 203655 mai    2 15:13 nucleo-f413zh.map
-rw-r--r-- 1 z19100018 1049089 289884 mai    2 15:13 nucleo-f413zh.out

λ ls -l CMakeFiles\nucleo-f413zh.out.dir\BSP\Src\
total 52
-rw-r--r-- 1 z19100018 1049089 18416 mai    2 15:13 main.c.obj
-rw-r--r-- 1 z19100018 1049089 14956 mai    2 15:13 stm32f4xx_hal_msp.c.obj
-rw-r--r-- 1 z19100018 1049089  6224 mai    2 15:13 stm32f4xx_it.c.obj
-rw-r--r-- 1 z19100018 1049089  7916 mai    2 15:13 system_stm32f4xx.c.obj
```
Yes, it was 15:13 when I built the project. Let's clean it and see what files are still here and what files have been deleted.

We have several options to clean the project. In CLion, we have _Clean_ in the _Build_ menu:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7wkrs8zfki3q4074i02r.png)

From the command line, we can use Make directly (remember that CMake by itself does nothing, it simply generates and uses Makefiles):

```bash
λ mingw32-make clean
```

Or we can use a generic CMake command to invoke the clean target of the generated build scripts:

```bash
λ cmake --build . --target clean
```

Once the project has been cleaned, let's look again at the content of the directory:

```bash
λ ls -l CMakeFiles\nucleo-f413zh.out.dir\BSP\Src\
total 0

λ ls -l
total 348
-rw-r--r-- 1 z19100018 1049089   1427 avr.  29 12:17 cmake_install.cmake
-rw-r--r-- 1 z19100018 1049089  53118 mai    1 12:26 CMakeCache.txt
drwxr-xr-x 1 z19100018 1049089      0 mai    2 15:25 CMakeFiles/
-rw-r--r-- 1 z19100018 1049089  42893 mai    1 12:42 Makefile
-rw-r--r-- 1 z19100018 1049089   7584 mai    2 15:25 nucleo-f413zh.bin
-rw-r--r-- 1 z19100018 1049089  11154 mai    1 12:42 nucleo-f413zh.cbp
-rw-r--r-- 1 z19100018 1049089  21433 mai    2 15:25 nucleo-f413zh.hex
-rw-r--r-- 1 z19100018 1049089 203655 mai    2 15:25 nucleo-f413zh.map
```

All `*.obj` files and `nucleo-f413zh.out` have been deleted. Nevertheless we still have 3 files that would like to deleted too:

1. `nucleo-f413zh.bin`
2. `nucleo-f413zh.hex`
3. `nucleo-f413zh.map`

Why are these files still here?

`nucleo-f413zh.map` is generated because of `-Wl,-Map=${PROJECT_NAME}.map,--cref` linker option while `nucleo-f413zh.bin` and `nucleo-f413zh.hex` are created by the post-build actions that call `arm-none-eabi-objcopy`.

Cmake is completely unaware that these files exist. Hence there is no reason to delete them.

## Configure additional clean files

Telling CMake that some files must be deleted when the `clean` target is called is easy. We have to change the [`ADDITIONAL_CLEAN_FILES` property](https://cmake.org/cmake/help/latest/prop_dir/ADDITIONAL_CLEAN_FILES.html) of the target that generates them.

The function to do this is [`set_target_properties()`](https://cmake.org/cmake/help/latest/command/set_target_properties.html).

Add the following code to your `CMakeLists.txt`:

```cmake
# Improve clean target
set_target_properties(${EXECUTABLE} PROPERTIES ADDITIONAL_CLEAN_FILES
		"${PROJECT_NAME}.bin;${PROJECT_NAME}.hex;${PROJECT_NAME}.map")
```

Rebuild, clean, check result:

```bash
λ mingw32-make all
...

λ mingw32-make clean
...

D:\cmake_stm32\cmake-build-debug
λ ls -l
total 116
-rw-r--r-- 1 z19100018 1049089  1427 avr.  29 12:17 cmake_install.cmake
-rw-r--r-- 1 z19100018 1049089 53123 mai    2 15:44 CMakeCache.txt
drwxr-xr-x 1 z19100018 1049089     0 mai    2 15:44 CMakeFiles/
-rw-r--r-- 1 z19100018 1049089 42893 mai    2 15:44 Makefile
-rw-r--r-- 1 z19100018 1049089 11154 mai    2 15:44 nucleo-f413zh.cbp
```

Perfect!

## Conclusion

CMake may not be aware that some files are created during the build process. The consequence is that these files are not deleted during the clean process.

If you want a neat clean process, simply configure the additional clean files of the CMake target that generates them.