Granular optimisation settings

Is it possible to set optimisation flags on a per file / folder / library basis?
The problem I’m running into is that fully optimised code (using -O0) doesn’t fit into memory, but there’s only a small section of code that I need debugged and thus unoptimised.

As per documentation on Advanced Scripting, it’s possible to arbitrarily modify the compiler flags of any file.

Example:

[env:nucleo_g071rb]
platform = ststm32
board = nucleo_g071rb
framework = arduino
build_type = debug 
extra_scripts = pre:modify_debug.py

and modify_debug.py in the root of the project

Import("env")

def exchange_debug_for_optimize_flag(node):
    # ignore certain files that are supposed to 
    # retain -Og
    sources_keep_debugging_info = [
        "main.cpp"
    ]
    #print("Node %s env.GetBuildType()=%s" % (node.name, str(env.GetBuildType())))
    # calculate compiler flags without optimization flags
    old_cflags = env["CCFLAGS"]
    new_cflags = [opt for opt in old_cflags if opt != "-Og" and opt != "-Os"]
    if node.name in sources_keep_debugging_info:
        new_cflags += ["-Og", "-g3", "-ggdb3"]
        return env.Object(
            node,
            CCFLAGS=new_cflags
        )
    else:
        new_cflags += ["-Os"]
        return env.Object(
            node,
            CCFLAGS=new_cflags
        )

# add modification functions to every file in build, but only for debug builds
if env.GetBuildType() == "debug":
    env.AddBuildMiddleware(exchange_debug_for_optimize_flag)

This will e.g. cause all files to be compiled with -Os, except the ones in the list sources_keep_debugging_info in which main.cpp is, which will get -Og -g3 -ggdb3. The whole thing is guarded by checking if the build type is “debug”, so the script does nothing during release build.

You can e.g. see that it works when you add build_type = debug in the platformio.ini to force a debug-mode compilation, and then use “Verbose Build” to see all compiler invocations.

For main.cpp

arm-none-eabi-g++ -o .pio\build\nucleo_g071rb\FrameworkArduino\main.cpp.o -c -std=gnu++14 -fno-threadsafe-statics -fno-rtti -fno-exceptions -fno-use-cxa-atexit -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -Wall -nostdlib --param max-inline-insns-single=500 -Og -g3 -ggdb3 -DPLATFORMIO=50200 […]

For all other files

arm-none-eabi-gcc -o .pio\build\nucleo_g071rb\FrameworkArduino\itoa.c.o -c -std=gnu11 -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -Wall -nostdlib --param max-inline-insns-single=500 -Os -DPLATFORMIO=50200 […]

3 Likes

I’m impressed with the answer!!! :pray:

I’m finding that this ends up missing out -I flags for libraries. They aren’t in the environment when the middle ware call back is executed. I think they are added to the environment by a later phase of SCons? :frowning:

-I is for include path – header files are not compiled with some optimization settings, c/cpp files are.

I’m having a hard time understanding what you mean. Can you open a new topic with your exact project and what compile flags you expect for each file?