diff --git a/platformio/builder/tools/piomisc.py b/platformio/builder/tools/piomisc.py index 5ef48d20..87b3bf12 100644 --- a/platformio/builder/tools/piomisc.py +++ b/platformio/builder/tools/piomisc.py @@ -314,17 +314,26 @@ def ConfigureDebugFlags(env): if scope not in env: return unflags = ["-Os", "-g"] - for level in [0, 1, 2]: + for level in [0, 1, 2, 3]: for flag in ("O", "g", "ggdb"): unflags.append("-%s%d" % (flag, level)) env[scope] = [f for f in env.get(scope, []) if f not in unflags] env.Append(CPPDEFINES=["__PLATFORMIO_BUILD_DEBUG__"]) - debug_flags = ["-Og", "-g2", "-ggdb2"] for scope in ("ASFLAGS", "CCFLAGS", "LINKFLAGS"): _cleanup_debug_flags(scope) - env.Append(**{scope: debug_flags}) + + debug_flags = env.ParseFlags(env.GetProjectOption("debug_build_flags")) + env.MergeFlags(debug_flags) + optimization_flags = [f for f in debug_flags.get("CCFLAGS", []) if f.startswith( + ("-O", "-g"))] + + if optimization_flags: + env.AppendUnique( + ASFLAGS=optimization_flags, + LINKFLAGS=optimization_flags + ) def ConfigureTestTarget(env): diff --git a/platformio/project/options.py b/platformio/project/options.py index 7d4c5a71..f8a50a76 100644 --- a/platformio/project/options.py +++ b/platformio/project/options.py @@ -600,6 +600,16 @@ ProjectOptions = OrderedDict( name="debug_tool", description="A name of debugging tool", ), + ConfigEnvOption( + group="debug", + name="debug_build_flags", + description=( + "Custom debug flags/options for preprocessing, compilation, " + "assembly, and linking processes" + ), + multiple=True, + default=["-Og", "-g2", "-ggdb2"], + ), ConfigEnvOption( group="debug", name="debug_init_break", diff --git a/tests/test_builder.py b/tests/test_builder.py index 9dec2e0f..6e73da0a 100644 --- a/tests/test_builder.py +++ b/tests/test_builder.py @@ -112,3 +112,61 @@ int main() { assert "-DTMP_MACRO1" not in build_output assert "-Os" not in build_output assert str(tmpdir) not in build_output + + +def test_debug_default_build_flags(clirunner, validate_cliresult, tmpdir): + tmpdir.join("platformio.ini").write( + """ +[env:native] +platform = native +build_type = debug +""" + ) + + tmpdir.mkdir("src").join("main.c").write( + """ +int main() { +} +""" + ) + + result = clirunner.invoke(cmd_run, ["--project-dir", str(tmpdir), "--verbose"]) + validate_cliresult(result) + build_output = result.output[result.output.find("Scanning dependencies...") :] + for line in build_output.split("\n"): + if line.startswith("gcc"): + assert all(line.count(flag) == 1 for flag in ("-Og", "-g2", "-ggdb2")) + assert all(line.count("-%s%d" % (flag, level)) == 0 for flag in ( + "O", "g", "ggdb") for level in (0, 1, 3)) + assert "-Os" not in line + + +def test_debug_custom_build_flags(clirunner, validate_cliresult, tmpdir): + custom_debug_build_flags = ("-O3", "-g3", "-ggdb3") + + tmpdir.join("platformio.ini").write( + """ +[env:native] +platform = native +build_type = debug +debug_build_flags = %s + """ + % " ".join(custom_debug_build_flags) + ) + + tmpdir.mkdir("src").join("main.c").write( + """ +int main() { +} +""" + ) + + result = clirunner.invoke(cmd_run, ["--project-dir", str(tmpdir), "--verbose"]) + validate_cliresult(result) + build_output = result.output[result.output.find("Scanning dependencies...") :] + for line in build_output.split("\n"): + if line.startswith("gcc"): + assert all(line.count(f) == 1 for f in custom_debug_build_flags) + assert all(line.count("-%s%d" % (flag, level)) == 0 for flag in ( + "O", "g", "ggdb") for level in (0, 1, 2)) + assert all("-O%s" % optimization not in line for optimization in ("g", "s"))